Как осуществлять потоковую передачу видеокамеры по сети, создавая действительный видеофайл, используя Android?
Я пытаюсь записать записи видеокамеры в сетевой поток, см. Следующий фрагмент:
ParcelFileDescriptor fd = ParcelFileDescriptor.fromSocket(socket);
this.camera.lock(); // this.camera refers to an android.hardware.Camera instance.
this.camera.unlock();
this.mediaRecorder = new MediaRecorder();
this.mediaRecorder.setCamera(this.camera);
this.mediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
this.mediaRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);
this.mediaRecorder.setProfile(CamcorderProfile.get(0, CamcorderProfile.QUALITY_HIGH));
this.mediaRecorder.setOutputFile(fd.getFileDescriptor());
this.mediaRecorder.prepare();
this.mediaRecorder.start();
Затем я пытаюсь захватить его на другой стороне соединения: с Socket.getInputStream()
Я читаю байты, и да, байты приходят. На самом деле байты записываются по сети.
Но когда попытаться сохранить его в файл, используя FileOutputStream
класс, и откройте файл с VLC, он просто не может быть прочитан.
Как я могу в конечном итоге сделать файл "воспроизводимым", это означает, что это допустимый видеофайл?
Редактировать:
Когда я использую this.mediaRecorder.setOutputFile("/sdcard/out.mp4");
Я могу открыть видеофайл из Android, и он будет успешно воспроизведен. Тем не менее, когда я использую this.mediaRecorder.setOutputFile(fd.getFileDescriptor());
не будет.
1 ответ
Проблема может быть связана с тем, что вы не настраиваете все в своем профиле видеокамеры.
Вместо этого:
this.mediaRecorder.setProfile(CamcorderProfile.get(0, CamcorderProfile.QUALITY_HIGH));
попробуйте например это:
CamcorderProfile profile = CamcorderProfile.get(CamcorderProfile.QUALITY_HIGH);
profile.fileFormat = MediaRecorder.OutputFormat.MPEG_4;
profile.videoCodec = MediaRecorder.VideoEncoder.MPEG_4_SP;
this.mediaRecorder.setProfile(profile);
Кстати, вы пытаетесь передать это видео после завершения записи или в режиме реального времени, когда получаете данные с видеокамеры?
РЕДАКТИРОВАТЬ:
Если я правильно помню, формат файла mpeg4 не имеет нижнего колонтитула, поэтому не нужно "ждать весь файл"... НО: этот тип файла имеет структуру, которую вы не можете нарушить, если хотите ее прочитать. Поэтому может возникнуть проблема, если вы отправляете необработанные байты видео, которые были подготовлены в формате файла mpeg4, и вы хотите открыть файл после получения случайного числа этих байтов. Вы можете быть почти уверены, что вам не повезет получить правильное количество байтов вашего видео.
Я бы посоветовал вам сделать следующее:
Проверь это. Например: отправьте видео на другую сторону и используйте какое-то программное обеспечение, позволяющее проверить структуру файла. Возможно, один из них скажет вам, имеет ли ваш файл правильную структуру. Я могу попытаться связать некоторые инструменты, но я не пробовал ни один из них сам, поэтому, возможно, вам придется искать что-то другое (если ни один из них не работает достаточно хорошо). Вы можете попробовать, например, тот или иной.
Если шаг 1. подтверждает, что ваш файл обрезается не в том месте, вы можете попытаться каким-то образом это контролировать. Например, информирование получателя о местах файла, которые при использовании для его резки не приведут к нарушению структуры (позволит вам открыть файл).
Альтернативой может быть попытка отправить некие "сырые" видеокадры. Под "необработанными" я подразумеваю какие-то низкоуровневые данные с камеры, которые можно отправить и применить определенный кодек на принимающей стороне. Я никогда не пытался сделать это, поэтому вам может понадобиться проверить, возможно ли это вообще (чтобы получить данные такого типа).