Intereting Posts

Потоковое видео с MediaRecorder через LocalSocket

Я пытаюсь отправить h264 / AAC видео из MediaRecorder от Android через локальный Socket. Цель состоит в том, чтобы отправить видео на сервер WOWZA через RTMP или RTSP, но это дает мне массу проблем, и на данный момент я просто пытаюсь записать данные в файл из LocalServerSocket.

Вот какой код. Извините, это не очень чисто, но я много часов проверял много вещей, и мой проект сейчас беспорядок.

В операции «Камера» настройка выходного файла:

LocalSocket outSocket = new LocalSocket(); try { outSocket.connect(new LocalSocketAddress(LOCAL_SOCKET)); } catch (Exception e) { Log.i(LOG_TAG, "Error connecting socket: "+e); } mMediaRecorder.setOutputFile(outSocket.getFileDescriptor()); 

Реализация LocalServerSocket:

 try { mLocalServerSocket = new LocalServerSocket(mName); } catch (Exception e) { Log.e(LOG_TAG, "Error creating server socket: "+e); return; } while (true) { File out = null; FileOutputStream fop = null; try { mLocalClientSocket = mLocalServerSocket.accept(); InputStream in = mLocalClientSocket.getInputStream(); out = new File(mContext.getExternalFilesDir(null), "testfile.mp4"); fop = new FileOutputStream(out); int len = 0; byte[] buffer = new byte[1024]; while ((len = in.read(buffer)) >= 0) { Log.i(LOG_TAG, "Writing "+len+" bytes"); fop.write(buffer, 0, len); } } catch (Exception e) { e.printStackTrace(); } finally{ try { fop.close(); mLocalClientSocket.close(); } catch (Exception e2) {} } } 

Проблема в том, что файл, полученный в результате этого, не читается никаким медиаплеером. Как вы думаете, это из-за проблемы с кодировкой? Этот код должен генерировать двоичный файл, если я хорошо понимаю?

Спасибо заранее, приветствую.

Хорошо, я нашел, почему файлы не могут играть. В файлах MP4 и 3GPP есть заголовок, содержащий байты:

Ftyp3gp4 3gp43gp6 wide mdat

В HEX

0000001866747970336770340000030033677034336770360000000877696465000392D86D6461740000

4 байта перед тегом «mdat» представляют позицию другого тега «moov», расположенного в конце файла. Положение обычно устанавливается, когда запись завершена, но поскольку MediaRecorder не может искать сокеты, он не может установить эти байты в правильное значение в нашем случае.

Моя проблема теперь заключается в том, чтобы найти способ сделать такой файл доступным, поскольку он включает в себя его воспроизведение до завершения записи.

Вы можете попробовать использовать mp4box для реструктуризации вашего файла. Коробка moov дает индексы для каждого образца аудио и видео. Если это находится в конце файла, это затрудняет поток.

Это может помочь: http://boliston.wordpress.com/tag/moov-box/

Или это: mp4box -inter 0.5 some_file.mp4

(У меня нет возможности попробовать в настоящее время)

Если вам нужно это для работы с вашим приложением, я не знаю о каких-либо действиях по переносу mp4box на Android.

Я пробовал сегодня делать то же самое, но mp4 не очень легко передать (как сказано, прежде чем некоторые части написаны в конце). Я не говорю, что это невозможно, но кажется, по крайней мере, довольно сложно.

Таким образом, обходной путь для новых API Android (4.3) может быть следующим:

  • Установите предварительный просмотр камеры в SurfaceTexture: camera.setPreviewTexture
  • Запись этой текстуры с использованием OpenGL и MediaCodex + Muxer

Недостатком этого решения является то, что размер предварительного просмотра камеры может быть меньше размера видео. Это означает, что в зависимости от вашего устройства вы не можете записывать с самым высоким разрешением. Подсказка: некоторые камеры говорят, что они не поддерживают более высокие размеры предварительного просмотра, но они делают, и вы можете попытаться настроить камеру, чтобы установить размер предварительного просмотра на размер видео. Если вы это сделаете, перехватите исключение RuntimeException для параметров camera.setParameters, и если он не работает, используйте только поддерживаемые размеры предварительного просмотра.

Некоторые ссылки, как записывать из SurfaceTexture:

Bigflage: отличные примеры для материалов MediaCodec.

Класс VideoRecorder из Lablet.

Может также быть полезно: spydroid-ipcamera передает данные из сокета MediaRecorder в виде потоков RTP, но я не нашел способа передать это MediaCodec. (Я уже застрял, читая правильные размеры блока NAL, как и они …)