Видео 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:
Попробуй это:
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 с расширениями медиа-источника.