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

379 lines
11 KiB
Markdown
Raw Permalink Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 🎬 Интеграция: Мобильное приложение + Сервер KazicCAM
## 📋 Быстрый старт (5 минут)
### 1⃣ Запустить сервер на компьютере
```bash
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
### Подключение
```kotlin
val wsManager = WebSocketManager(
onConnected = { /* уведомление UI */ },
onDisconnected = { /* очистка ресурсов */ },
onError = { error -> /* обработка ошибок */ },
onMessage = { msg -> /* получение команд */ }
)
wsManager.connect("ws://server:8000/ws/client/roomId/password")
```
### Отправка видео
```kotlin
// Отправка байтов кадра
wsManager.sendBinary(frameData)
// Отправка команд JSON
wsManager.sendMessage(VideoCommands.rotate(90).toJson())
```
### Получение команд
```kotlin
onMessage = { message ->
val command = Gson().fromJson(message, VideoCommand::class.java)
// Обработка команды...
}
```
---
## 📊 Статистика и мониторинг
### Метрики приложения
```
FPS (Frames Per Second)
└─ Обновляется каждую секунду
└─ Отправляется в логи
Объем переданных данных
└─ Суммируется размер каждого кадра
└─ Отображается в МБ
Статус подключения
└─ Idle → Connecting → Connected → Disconnected/Error
└─ Обновляется в реальном времени
```
### Просмотр логов
```bash
# Все логи приложения
adb logcat | grep "camControl"
# Только WebSocket
adb logcat | grep "WebSocket"
# Только видеопоток
adb logcat | grep "VideoStreamingManager"
# Только ViewModel
adb logcat | grep "StreamViewModel"
```
---
## 🔐 Безопасность соединения
### Текущая реализация
- ✅ WebSocket соединение
- ✅ Аутентификация по Room ID и пароль
- ❌ Шифрование не включено
### Для продакшена используйте WSS (WebSocket Secure)
```kotlin
// Вместо 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
```
**Решение:**
- Проверьте разрешение на камеру
- Перезагрузите приложение
- Проверьте, что другие приложения не используют камеру
### Проблема: Приложение крашится
**Решение:**
```bash
# Очистить кэш
adb shell pm clear com.example.camcontrol
# Переустановить
./gradlew installDebug
```
---
## 🚀 Оптимизация производительности
### На стороне приложения
1. **Качество видео**
```kotlin
// В ImageAnalysis.Builder()
.setOutputImageFormat(ImageAnalysis.OUTPUT_IMAGE_FORMAT_YUV_420_888)
// Более эффективный формат
```
2. **Частота кадров**
```kotlin
// Отправлять кадры реже, если нужно
if (frameCount % 2 == 0) { // Каждый 2-й кадр
wsManager.sendBinary(frameData)
}
```
3. **Размер буфера**
```kotlin
// Сжимать кадры перед отправкой
val compressed = compressFrame(frameData)
wsManager.sendBinary(compressed)
```
### На стороне сервера
Отредактируйте `server.py`:
```python
SERVER_CONFIG = {
"video_width": 480, # Уменьшить разрешение
"video_height": 320,
"jpeg_quality": 70, # Уменьшить качество
"frame_rate": 15, # Снизить FPS
}
```
---
## 📚 Дополнительные примеры
### Отправка команды с параметром
```kotlin
// Отправить команду яркости
val command = VideoCommand(type = "brightness", value = 50)
viewModel.sendCommand(command)
```
### Обработка разных типов команд на сервере
```python
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. Перезагрузите телефон и компьютер