Видео H264 работает с использованием атрибута src. Сбой того же видео с использованием MediaSource API (Chromium)

http://www.youtube.com/html5 указывает, что Google Chrome совместим с расширениями MediaSource и H.264.

Я делаю простой тест, проверяя, поддерживает ли мое видео Chromium, используя

Видео воспроизводится плавно.

Вторая альтернатива, которая также отлично работает, состоит в загрузке через AJAX цепочки байтов и преобразовании буфера в объект URI. Затем присваивает такой URI атрибуту (video) source.src.

Наконец, я пытаюсь загрузить то же видео через AJAX и вставить его в буфер MediaSource. Сбой с ошибкой 4. (Источник не поддерживается).

Используемый код похож на:

var mediaSource = new (window.MediaSource || window.WebKitMediaSource)();
window.video = document.getElementById('video1');
window.video.addEventListener("error", function onError(err) {
    alert("window.video error detected:");
    console.dir(window.video.error); window.worker.terminate();
}); 
window.video.pause();
window.video.src = URL.createObjectURL(mediaSource);
var onMediaSourceOpen = function (e) {
    mediaSource.removeEventListener('sourceopen', onMediaSourceOpen);
    window.videoSource = mediaSource.addSourceBuffer('video/mp4;codecs="avc1.4d001e,mp4a.40.2"');
    injectVideoIntoBuffer();
}   

mediaSource.addEventListener('sourceopen', onMediaSourceOpen);

var injectVideoIntoBuffer = function onResponse() {
    var xhr = new XMLHttpRequest();
    xhr.open('GET', "test.mp4");
    xhr.responseType = 'arraybuffer';
    xhr.addEventListener("readystatechange", function () {
         // Next line raises a MediaError, code: 4, (MEDIA_ERR_SRC_NOT_SUPPORTED)
         videoSource.appendBuffer(new Uint8Array(xhr.response));
          ... 
    }, false);
    xhr.send();
}

Я пробовал разные файлы mp4, созданные с помощью ffmpeg/avconv или MP4Box. Не удача в этот момент. Подобный код прекрасно работает с тестовыми файлами VP8/WebM.

Заранее спасибо за любую помощь / подсказку или ссылку!

Энрике

3 ответа

Решение

Спасибо всем за ваши ответы. Похоже, что более новые версии Chrome решают проблему.

Я ошибочно предположил, что если кодек поддерживается браузером, он будет автоматически поддерживаться MSE. На практике это не так. Браузер может поддерживать набор видеокодеков (h264/webM/theora/...), он также может поддерживать MSE, но только подмножество видеокодеков, когда "вводит" видео в буферы MSE.

Матрица совместимости между MSE и кодеками зависит не только от браузера, но и от ОС. Так, например, Google Chrome поддерживает MSE+h264 в Windows и Android, но не (пока?) В Linux. VP9+MSE поддерживается в Windows и Linux, но не в Android.

У YouTube есть очень полезная тестовая страница для проверки поддержки браузером кодеков MSE & h264/VP9:

https://www.youtube.com/html5

Попробуй это:

var injectVideoIntoBuffer = function onResponse() {
   var xhr = new XMLHttpRequest();
   xhr.open('GET', "test.mp4");
   xhr.responseType = 'arraybuffer';
   xhr.addEventListener("readystatechange", function () {
       if (xhr.readyState == xhr.DONE) {
           videoSource.appendBuffer(new Uint8Array(xhr.response));
       }
      ... 
   }, false);

Возможно, вы только добавляете фрагмент mp4. Это было бы хорошо, если фрагмент из запроса AJAX состоит из целых атомов mp4, т.е. moov, moof, mdat. Но я думаю, что это может быть не так.

Если это не помогло, попробуйте снова перекодировать фильм с помощью: (ПРИМЕЧАНИЕ! Это удалит звук)

ffmpeg -an -codec:v libx264 -profile:v baseline -level 3 -b:v 2000k -i in.mp4 out.mp4

и MP4Box с:

MP4Box -dash 10000 -rap -frag-rap out.mp4

Просто чтобы посмотреть, работает ли фильм.

Я думаю, что на данный момент Chrome может поддерживать только WebM с расширениями медиа-источника.

Другие вопросы по тегам