Проблема с запуском воспроизведения видео с высоким переменным битрейтом с использованием API Media Source Extension

Вопрос: Что приводит к зависанию воспроизведения видео на неопределенный срок?

Я использую Сафари.

У меня есть видеофайл с довольно высоким битрейтом:

10596496 бит/сек

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

Используемая строка кодека mime-типа:

"video/mp4; codecs=\"avc1.4d0028, mp4a.40.2\""

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

Сервер, который я использую, обслуживает файл как живой поток, а не с запросами ранжированных байтов.

ПРИМЕЧАНИЕ. Это означает, что при поиске определенного времени в файле запускается новый прямой эфир (я удаляю старый объект расширения источника мультимедиа вместе с его исходным буфером). Я создаю новый объект источника мультимедиа, а затем добавляю новый источник буфер с использованием той же строки кодека mime-типа. По сути, поиск похож на начало нового сеанса воспроизведения.

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

Я попытался очистить видеоплеер, а затем перезагрузить его до и после каждого нового запроса при поиске:

videoPlayer = document.getElementsByTagName('video')[0];
videoPlayer.src = '';
videoPlayer.load();
videoPlayer.src = URL.createObjectURL(myMediaSource);
videoPlayer.load();

Я добавил прослушиватели событий в собственный видеоплеер html5, которые регистрируют все события.

Если я произвольно ищу точку в файле с успешным воспроизведением, я вижу следующие журналы консоли:

[Log] EMPTIED (bundle.js, line 7131)
[Log] PLAY (bundle.js, line 7131)
[Log] WAITING (bundle.js, line 7131)
[Log] LOADSTART (bundle.js, line 7131)
[Log] LOADEDMETADATA (bundle.js, line 7131)
[Log] LOADEDDATA (bundle.js, line 7131)
[Log] CANPLAY (bundle.js, line 7131)
[Log] PLAYING (bundle.js, line 7131)
[Log] CANPLAYTHROUGH (bundle.js, line 7131)
[Log] PROGRESS (bundle.js, line 7131)
[Log] PROGRESS (bundle.js, line 7131)
[Log] RESULT.DONE (bundle.js, line 75634)
[Log] PROGRESS (bundle.js, line 7131)
[Log] STALLED (bundle.js, line 7131)

Если я произвольно ищу точку в файле, которая НЕ успешно запускает воспроизведение, я вижу следующие журналы консоли:

[Log] EMPTIED (bundle.js, line 7131)
[Log] PLAY (bundle.js, line 7131)
[Log] WAITING (bundle.js, line 7131)
[Log] LOADSTART (bundle.js, line 7131)
[Log] LOADEDMETADATA (bundle.js, line 7131)
[Log] PROGRESS (bundle.js, line 7131)
[Log] RESULT.DONE (bundle.js, line 75634)
[Log] PROGRESS (bundle.js, line 7131)
[Log] STALLED (bundle.js, line 7131)

На вкладке сети я вижу, что при каждом поиске запрос на выборку, отправляемый серверной части, действительно получает данные (до 100 МБ — я ограничил его до 100 МБ, чтобы исходный буфер не исчерпал память ). Как видно из журналов, видеопроигрыватель html5 действительно распознает получение данных, но в некоторых случаях считает, что их недостаточно для начала воспроизведения.

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

videoPlayer.buffered.end(0)
145.22842222222224

Из-за чего воспроизведение видео зависает на неопределенный срок?


person arcman77    schedule 25.07.2019    source источник


Ответы (1)


Я считаю, что нашел причину и жизнеспособный обходной путь.

Как я уже упоминал, в случаях, когда проигрыватель зависает на неопределенное время без запуска воспроизведения, вызов videoPlayer.buffered.end(0) вернет некоторое разумное значение, например 145.22842222222224. Однако в этих случаях время начала буферизации постоянно устанавливается равным 0,08342222222222222.

Итак, у нас есть:

videoPlayer.buffered.start(0) // returns 0.08342222222222222
videoPlayer.buffered.end(0)   // returns 145.22842222222224
videoPlayer.currentTime // returns 0

Это обманывает видеоплеер сафари, заставляя его поверить, что у него недостаточно данных для начала воспроизведения, поскольку текущее время видеоплеера не попадает в диапазон времени начала и окончания буферизации. Я могу исправить это, просто установив текущее время видеоплеера на что-то в пределах этого диапазона, например:

videoPlayer.currentTime = 0.9;
videoPlayer.play();

На самом деле этого достаточно, чтобы решить проблему в моем случае и начать воспроизведение видео.

person arcman77    schedule 04.09.2019