ffmpeg создает поток mp4, который приводит к ошибке Firefox - PullRequest
0 голосов
/ 22 января 2020

Я собираюсь воспроизвести видео элемент fmp4 в HTML5.

Я успешно создал веб-сокет для передачи вывода ffmpeg в MSE.

Однако, когда я пытаюсь открыть страница в Firefox (72.0.1, 64-битная, под Ubuntu 18.04LTS) всегда выдает ошибку:

Media resource blob:http://localhost/XXXX could not be decoded, error: Error Code: NS_ERROR_FAILURE (0x80004005)
Details: virtual mozilla::MediaResult mozilla::MP4ContainerParser::IsInitSegmentPresent(const mozilla::MediaSpan &): Invalid Top-Level Box:f"

Это строка моего FFMPEG:

ffmpeg -r 5 -i rtsp://IPCAMERA -c:v copy -an -movflags +frag_keyframe+empty_moov+default_base_moof -f mp4 pipe:1

Это как серверная сторона Java (с механизмом Tomcat) анализирует выходные данные этой команды (это может быть неэффективно, но на данный момент все в порядке):

ProcessBuilder b = new ProcessBuilder(FFMPEGCOMMAND.split("\\s+"));
try {
    p = b.start();
} catch (IOException e) {
    e.printStackTrace();
}
InputStream input = p.getInputStream();
int bytes_read = 0;
byte buffer[] = new byte[512];
try {
    while (0 < (bytes_read = input.read(buffer, 0, 512))) {
        System.out.println("Bytes read:" + bytes_read);
        this.session.getBasicRemote().sendBinary(ByteBuffer.wrap(buffer));
    }
} catch (IOException e) {
    e.printStackTrace();
}

Тогда клиентская сторона представляет собой websocket-MSE, как в это репо .

Результаты:

  1. Когда я отлаживаю на стороне сервера, и перед sendBinary существует точка останова позвоните, и я подожду несколько секунд, прежде чем разрешить запуск на стороне сервера, затем в браузере отобразится первое изображение, но затем сразу же появится сообщение об ошибке, приведенное выше.

  2. Если я запустил на стороне сервера (без каких-либо точек останова), браузер не показывает изображение, оно сразу переходит на ошибка.

Недопустимое поле верхнего уровня За сообщением об ошибке всегда следует (а) случайный символ (ы) мусора.

Доказательство то, что это должно работать, находится в пункте 1. Если я подожду некоторое время, прежде чем позволить откатить данные клиенту, он может декодировать 1 (или, может быть, больше кадров), прежде чем достигнет этой ошибки.

Это может быть ошибка с моей командной строкой ffmpeg.

Однако я не смог найти хороших ресурсов по этой теме c (нашел только те, которые относились к более старым версиям Firefox).

Update1

Вот журнал FFMPEG, когда эта же команда создает файл mp4 вместо канала: https://pastebin.com/Gjq2vxeT

Вот подробный Firefox журнал с неправильное поле:

Details: virtual mozilla::MediaResult mozilla::MP4ContainerParser::IsInitSegmentPresent(const mozilla::MediaSpan &): Invalid Top-Level Box:f

Обратите внимание, в поле верхнего уровня всегда указывается 'f', когда я выполняю сценарий, отмеченный в пункте 2 (работающий без точек останова).

Update2:

Вот токовый выход ffmpeg (с номерами c и alphanumeri c представление, для первых 128 элементов): https://pastebin.com/DeJMfNYs

Интересно то, что первые 4 байта кажутся мне недействительными. Однако, начиная с байта 4 (5-й байт), кажется, что все в порядке ("ftyp").

Не могли бы вы подтвердить это?

1 Ответ

1 голос
/ 23 января 2020

Проблема была на стороне сервера.

С этой строкой:

this.session.getBasicRemote().sendBinary(ByteBuffer.wrap(buffer));

Это не хорошо, потому что, когда в буфере есть 0, метод переноса ByteBuffer останавливается.

Хорошая вещь такая:

this.session.getBasicRemote().sendBinary(ByteBuffer.wrap(buffer, 0, bytes_read));

Какая глупая ошибка - теперь работает отлично :)

...