Files
cam_control_android/INTEGRATION.md
2025-12-03 19:39:42 +09:00

11 KiB
Raw Permalink Blame History

🎬 Интеграция: Мобильное приложение + Сервер KazicCAM

📋 Быстрый старт (5 минут)

1 Запустить сервер на компьютере

python server.py

Сохраните IP адрес, который будет показан (например: 192.168.1.100)

2 Создать комнату в веб-интерфейсе

  1. Откройте браузер → http://192.168.1.100:8000
  2. Вход: admin / admin123
  3. Нажмите "Create Room"
  4. Заполните форму и сохраните Room ID и пароль

3 Подключить приложение на телефоне

  1. Запустите приложение CamControl на Android
  2. Введите:
    • IP сервера: 192.168.1.100
    • Порт: 8000
    • Room ID: (из шага 2)
    • Пароль: (из шага 2)
  3. Нажмите "Подключиться"

4 Просмотреть трансляцию

Вернитесь в веб-интерфейс → откройте комнату → нажмите "View" на клиенте


🏗️ Архитектура приложения

Структура слоев

┌─────────────────────────────────────────┐
│     UI Layer (Compose)                  │
│  MainActivity, Screens, Components      │
└────────────┬────────────────────────────┘
             │
┌────────────▼────────────────────────────┐
│  ViewModel Layer (StreamViewModel)      │
│  State Management, Business Logic       │
└────────────┬────────────────────────────┘
             │
┌────────────▼────────────────────────────┐
│  Service Layer                          │
│  WebSocketManager, VideoStreamingMgr   │
└────────────┬────────────────────────────┘
             │
┌────────────▼────────────────────────────┐
│  External Services                      │
│  WebSocket, CameraX, Android APIs      │
└─────────────────────────────────────────┘

Основные компоненты

Компонент Назначение
MainActivity.kt Главный экран приложения
StreamViewModel.kt Управление состоянием и логикой
WebSocketManager.kt WebSocket соединение с сервером
VideoStreamingManager.kt Захват видео с камеры
CameraManager.kt Управление камерой
Models.kt Модели данных

📡 Процесс трансляции видео

Диаграмма потока данных

Камера телефона
    ↓
CameraX (ImageAnalysis)
    ↓
VideoStreamingManager (обработка кадров)
    ↓
StreamViewModel (отправка на сервер)
    ↓
WebSocketManager (WebSocket)
    ↓
Сервер KazicCAM
    ↓
Веб-интерфейс (просмотр)

Этапы подключения

1. Инициализация ViewModel
   └─ Создание WebSocketManager
   └─ Создание VideoStreamingManager

2. Подключение к серверу
   └─ WebSocket.connect(serverUrl)
   └─ Ожидание onOpen()

3. Запуск захвата видео
   └─ CameraX.startStreaming()
   └─ onFrameAvailable() callback

4. Отправка кадров
   └─ WebSocket.sendBinary(frameData)
   └─ Повторяется для каждого кадра

5. Отключение
   └─ WebSocket.disconnect()
   └─ CameraX.stopStreaming()

🔌 Интеграция с WebSocket

Подключение

val wsManager = WebSocketManager(
    onConnected = { /* уведомление UI */ },
    onDisconnected = { /* очистка ресурсов */ },
    onError = { error -> /* обработка ошибок */ },
    onMessage = { msg -> /* получение команд */ }
)

wsManager.connect("ws://server:8000/ws/client/roomId/password")

Отправка видео

// Отправка байтов кадра
wsManager.sendBinary(frameData)

// Отправка команд JSON
wsManager.sendMessage(VideoCommands.rotate(90).toJson())

Получение команд

onMessage = { message ->
    val command = Gson().fromJson(message, VideoCommand::class.java)
    // Обработка команды...
}

📊 Статистика и мониторинг

Метрики приложения

FPS (Frames Per Second)
└─ Обновляется каждую секунду
└─ Отправляется в логи

Объем переданных данных
└─ Суммируется размер каждого кадра
└─ Отображается в МБ

Статус подключения
└─ Idle → Connecting → Connected → Disconnected/Error
└─ Обновляется в реальном времени

Просмотр логов

# Все логи приложения
adb logcat | grep "camControl"

# Только WebSocket
adb logcat | grep "WebSocket"

# Только видеопоток
adb logcat | grep "VideoStreamingManager"

# Только ViewModel
adb logcat | grep "StreamViewModel"

🔐 Безопасность соединения

Текущая реализация

  • WebSocket соединение
  • Аутентификация по Room ID и пароль
  • Шифрование не включено

Для продакшена используйте WSS (WebSocket Secure)

// Вместо ws:// используйте wss://
wsManager.connect("wss://server:8000/ws/client/roomId/password")

Требуется SSL сертификат на сервере.


🐛 Отладка проблем

Проблема: Приложение не подключается

Логи:

[WebSocket] Connection error: java.net.ConnectException

Решение:

  • Проверьте IP адрес: ping <server-ip>
  • Убедитесь, что сервер запущен
  • Проверьте firewall: netstat -an | findstr :8000

Проблема: Видео не передается

Логи:

[VideoStreamingManager] Error processing frame

Решение:

  • Проверьте разрешение на камеру
  • Перезагрузите приложение
  • Проверьте, что другие приложения не используют камеру

Проблема: Приложение крашится

Решение:

# Очистить кэш
adb shell pm clear com.example.camcontrol

# Переустановить
./gradlew installDebug

🚀 Оптимизация производительности

На стороне приложения

  1. Качество видео

    // В ImageAnalysis.Builder()
    .setOutputImageFormat(ImageAnalysis.OUTPUT_IMAGE_FORMAT_YUV_420_888)
    // Более эффективный формат
    
  2. Частота кадров

    // Отправлять кадры реже, если нужно
    if (frameCount % 2 == 0) {  // Каждый 2-й кадр
        wsManager.sendBinary(frameData)
    }
    
  3. Размер буфера

    // Сжимать кадры перед отправкой
    val compressed = compressFrame(frameData)
    wsManager.sendBinary(compressed)
    

На стороне сервера

Отредактируйте server.py:

SERVER_CONFIG = {
    "video_width": 480,      # Уменьшить разрешение
    "video_height": 320,
    "jpeg_quality": 70,      # Уменьшить качество
    "frame_rate": 15,        # Снизить FPS
}

📚 Дополнительные примеры

Отправка команды с параметром

// Отправить команду яркости
val command = VideoCommand(type = "brightness", value = 50)
viewModel.sendCommand(command)

Обработка разных типов команд на сервере

if cmd_type == "rotate":
    angle = command.get("angle", 0)
    frame = cv2.rotate(frame, cv2.ROTATE_90_CLOCKWISE)
elif cmd_type == "brightness":
    value = command.get("value", 0)
    frame = cv2.convertScaleAbs(frame, alpha=1, beta=value)

🔄 Жизненный цикл приложения

onCreate()
    ↓
Запрос разрешений
    ↓
setContent() - Рисование UI
    ↓
Ввод параметров подключения
    ↓
initializeConnection()
    ↓
WebSocket подключение
    ↓
CameraX запуск
    ↓
Отправка видеокадров
    ↓
(пользователь нажимает отключиться)
    ↓
disconnect()
    ↓
Закрытие WebSocket
    ↓
Остановка камеры
    ↓
onDestroy()

💡 Советы по использованию

  1. Используйте кабель USB для более стабильного соединения при разработке
  2. Монитор батареи - приложение интенсивно использует камеру и сеть
  3. Тестируйте на реальном устройстве - эмулятор может быть медленнее
  4. Сохраняйте логи - полезно для отладки проблем

📝 Контрольный список подготовки к использованию

  • Сервер запущен и доступен
  • Веб-интерфейс работает
  • Комната создана в веб-интерфейсе
  • Android устройство подключено в ту же сеть
  • Приложение установлено на устройстве
  • Разрешение на камеру выдано
  • IP адрес введен правильно
  • Room ID и пароль скопированы корректно

📞 Помощь и поддержка

Если возникают проблемы:

  1. Проверьте логи Logcat
  2. Убедитесь, что все требования соблюдены
  3. Попробуйте переустановить приложение
  4. Перезагрузите телефон и компьютер