# Исправление: Отправка видео на сервер ## Проблема Приложение показывало превью камеры локально, но **видео вообще не отправлялось на сервер**. ### Анализ логов Из `logcat` было видно: - ✓ WebSocket подключился успешно: `Connected! Response code=101` - ✓ Сервер ответил: `Message received: {"error": "Invalid room or password"}` - ❌ Но фреймы не отправлялись: в логах нет сообщений о `sendBinary` - ❌ Функция `StreamViewModel.sendVideoFrame()` вообще не вызывалась ## Корень проблемы ### 1. CameraManager не обрабатывал фреймы Файл `CameraManager.kt` только показывал превью, но не захватывал видео фреймы. - Использовался только `Preview` use case для отображения - Отсутствовал `ImageAnalysis` use case для захвата фреймов ### 2. Нет связи между камерой и ViewModel `MainActivity.kt` запускал камеру, но не передавал фреймы в `ViewModel`: ```kotlin // ДО: просто стартует камеру без callback cameraManager.startCamera(lifecycleOwner, pv.surfaceProvider, onError) // НУЖНО: передать фреймы в ViewModel cameraManager.startCamera(lifecycleOwner, pv.surfaceProvider, onError, onFrame = { frameData -> viewModel.sendVideoFrame(frameData) } ) ``` ### 3. Проблемы с отправкой бинарных данных `WebSocketManager.sendBinary()` использовал рефлексию вместо стандартного API: ```kotlin // ДО: сложная рефлексия val byteStringClass = Class.forName("okhttp3.ByteString") val ofMethod = byteStringClass.getMethod("of", ByteArray::class.java) // ... и так далее // ПОСЛЕ: простой и надёжный API val byteString = ByteString.of(*data) webSocket?.send(byteString) ``` ## Решение ### 1. ✅ Обновлен CameraManager Добавлен `ImageAnalysis` для захвата видео фреймов: ```kotlin val imageAnalysis = ImageAnalysis.Builder() .setBackpressureStrategy(ImageAnalysis.STRATEGY_KEEP_ONLY_LATEST) .setOutputImageFormat(ImageAnalysis.OUTPUT_IMAGE_FORMAT_RGBA_8888) .build() .apply { setAnalyzer(analysisExecutor) { imageProxy -> processFrame(imageProxy) } } // Добавлена обработка фреймов private fun processFrame(imageProxy: ImageProxy) { // Преобразование в ByteArray val frameData = ByteArray(buffer.remaining()) buffer.get(frameData) // Отправка через callback onFrameAvailable?.invoke(frameData) } ``` ### 2. ✅ Обновлена MainActivity Добавлен callback для передачи фреймов: ```kotlin cameraManager.startCamera( lifecycleOwner, pv.surfaceProvider, onError = { err -> Log.e("CameraManager", "Camera error: $err") }, onFrame = { frameData -> viewModel.sendVideoFrame(frameData) } ) ``` ### 3. ✅ Исправлен WebSocketManager Заменена рефлексия на стандартный API: ```kotlin import okhttp3.ByteString fun sendBinary(data: ByteArray) { try { val byteString = ByteString.of(*data) webSocket?.send(byteString) Log.d("WebSocket", "Binary data sent: ${data.size} bytes") } catch (e: Exception) { Log.e("WebSocket", "Binary send error: ${e.message}") onError(e.message ?: "Failed to send binary data") } } ``` ### 4. ✅ Улучшено логирование Добавлены логи для отслеживания передачи: - `CameraManager`: "Processing X frames/5s, sending to server" - `StreamViewModel`: "FPS: X, Total bytes sent: Y" - `WebSocket`: "Binary data sent: X bytes" ## Проверка После исправления в логах должны появиться: 1. При подключении: ``` WebSocket: Connected! Response code=101 CameraManager: Camera started successfully with video streaming StreamViewModel: Connected to server ``` 2. При потоке видео: ``` CameraManager: Processing 25 frames/5s, sending to server WebSocket: Binary data sent: 12345 bytes StreamViewModel: FPS: 25, Total bytes sent: 308640 ``` ## Файлы изменены - ✅ `CameraManager.kt` - Добавлен ImageAnalysis и обработка фреймов - ✅ `MainActivity.kt` - Добавлена передача фреймов в ViewModel - ✅ `WebSocketManager.kt` - Исправлена отправка бинарных данных - ✅ `StreamViewModel.kt` - Улучшено логирование ## Результат Теперь видео из камеры будет **отправляться на сервер** сразу после успешного подключения WebSocket.