#android #post #video #send #mediarecorder
#Android #Публикация #Видео #Отправить #mediarecorder
Вопрос:
Я работаю над приложением, которое записывает видео в фоновом режиме и отправляет его на сервер по частям, считывая байты и сохраняя их в байтовом массиве. На данный момент алгоритм довольно прост:
- начать запись;
- чтение части видеофайла в байтовый массив;
- отправьте массив байтов по почте (с помощью дооснащения).
Проблема возникает, если соединение каким-то образом прерывается и последняя часть не отправляется. Сервер просто не может создать читаемый видеофайл, так как moov atom будет записан только после остановки записи. Мой вопрос — возможно ли каким-то образом создавать полные видеофайлы из частей байтового массива или любым другим способом? Я могу изменить видеокодек, если это решит проблему. p.s. Я могу отправлять данные только через POST. p.p.s Я не могу что-то изменить на стороне сервера, включая потоковое видео непосредственно на сервер.
Комментарии:
1. Не используйте MP4. Используйте flv, webm, ts или фрагментированный MP4
2. Спасибо за ответ, но как я могу сделать соответствующий разрез, например, webm. И еще один вопрос — как я могу настроить mediarecorder для записи фрагментированного mp4?
Ответ №1:
РЕШЕНИЕ
Я решил записывать небольшие фрагменты видео рекурсивным способом. Следующее решение подходит для первой версии Camera API. Если вы используете Camera2 или что-то еще — вы можете попробовать использовать тот же алгоритм.
В классе обслуживания, который записывает видео, убедитесь, что mediarecorder настроен следующим образом:
mediaRecorder.setMaxDuration(10000);
//or
mMediaRecorder.setMaxFileSize(10000);
Затем вам нужно реализовать интерфейс setOnInfoListener следующим образом:
mediaRecorder.setOnInfoListener(new MediaRecorder.OnInfoListener() {
@Override
public void onInfo(MediaRecorder mr, int what, int extra) {
if (what == MediaRecorder.MEDIA_RECORDER_INFO_MAX_DURATION_REACHED) {
//Use next condition if you decided to use max file size
//if (what == MediaRecorder.MEDIA_RECORDER_INFO_MAX_FILESIZE_REACHED)
stopRecording();
setRecordingStatus(false);
startRecording(surfaceHolder);
}
}
});
Не забудьте передать экземпляр SurfaceHolder для следующей итерации, иначе вы можете получить ошибку «Приложение потеряло поверхность».
Следующее, что вам нужно сделать, это объявить FileObserver в методе onCreate:
FileObserver fileObserver = new FileObserver(pathToFolder, FileObserver.CLOSE_WRITE) {
//FileObserver.CLOSE_WRITE mask means that this observer would be triggered when it receive end of writing to file system event
@Override
public void onEvent(int event, String path) {
//here path is name of file (with extension) but not the full path to file
if (event == FileObserver.CLOSE_WRITE amp;amp; path.endsWith(".mp4")) {
String name = String.valueOf(Long.parseLong(path.substring(0, path.length() - 4)) / 1000);
sendNewVideo(pathToFolder "/" path, name);
}
}
};
В методе onStartCommand:
fileObserver.startWatching();
Комментарии:
1. Похоже, это сработало для нас, но камера прекращает запись во время сохранения фрагментов видео. Какие-либо решения для этого?
2. Проверьте, отпускаете ли вы камеру при остановке записи