379 lines
11 KiB
Markdown
379 lines
11 KiB
Markdown
# 🎬 Интеграция: Мобильное приложение + Сервер 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. Перезагрузите телефон и компьютер
|
||
|
||
|