【发布时间】:2017-11-13 15:36:22
【问题描述】:
但在 Firefox 中运行良好。
谷歌浏览器版本:61.0.3163.100(官方版本)(64位)
Mozilla Firefox 版本:56.0.2(64 位)
我的视频是分段的 MP4,通过 WebSocket 流式传输到客户端 html 页面,在那里它被提取到 MSE。视频编解码器是 H264 Main Profile。已在 FFPROBE 和其他检查员中检查视频信息,以确保数据完整性正常。多路复用 FMP4 时使用以下标志:
"empty_moov+default_base_moof+frag_keyframe"
我还仔细检查了第一个碎片是所谓的“初始化段”,大小为 24 字节。 正如我所说,Firefox 播放很好。
这是客户端代码(大部分是从here借来的):
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>MSE Demo</title>
</head>
<body>
<h1>MSE Demo</h1>
<div>
<video id="video1" controls width="80%" autoplay="true"> </video>
</div>
<script type="text/javascript">
(function () {
var mime = 'video/mp4; codecs="avc1.4D401E"';
if (!MediaSource.isTypeSupported(mime)) {
document.querySelector('h1').append(' - Unsuported mime type :(');
return;
}
var buffer;
var websocket;
var buffer_size = 4 * 1024 * 1024;
var buffer_index = 0;
var frag_mp4_buffer = new Uint8Array(buffer_size);
var video = document.querySelector('video');
var mediaSource = new MediaSource();
mediaSource.addEventListener('sourceended', function (e) { console.log('sourceended: ' + mediaSource.readyState); });
mediaSource.addEventListener('sourceclose', function (e) { console.log('sourceclose: ' + mediaSource.readyState); });
mediaSource.addEventListener('error', function (e) { console.log('error: ' + mediaSource.readyState); });
video.src = window.URL.createObjectURL(mediaSource);
video.crossOrigin = 'anonymous';
mediaSource.addEventListener('sourceopen', function (e) {
console.log('sourceopen: ' + mediaSource.readyState);
//doesn't help:
// var playPromise = video.play();
// In browsers that don’t yet support this functionality,
// playPromise won’t be defined.
/*
if (playPromise !== undefined) {
playPromise.then(function () {
// Automatic playback started!
}).catch(function (error) {
// Automatic playback failed.
// Show a UI element to let the user manually start playback.
});
}
*/
buffer = mediaSource.addSourceBuffer(mime);
buffer.addEventListener('updateend', function (e) {
if (video.duration && !video.currentTime) {
video.currentTime = video.duration;
}
});
var websocket = new WebSocket('ws://' + document.location.hostname + ':8080');
websocket.binaryType = 'arraybuffer';
websocket.addEventListener('message', function (e) {
var data = new Uint8Array(e.data);
console.log("got packet! size:" + data.length);
if (data.length) {
if ((buffer_index + data.length) <= buffer_size) {
frag_mp4_buffer.set(data, buffer_index);
buffer_index = buffer_index + data.length;
if (!buffer.updating && mediaSource.readyState == 'open')
{
var appended = frag_mp4_buffer.slice(0, buffer_index);
buffer.appendBuffer(appended);
frag_mp4_buffer.fill(0);
buffer_index = 0;
}
}
}
}, false);
}, false);
})();
</script>
</body>
另一个重要信息,你可以看到我注释掉了video.play() 电话。这实际上是应用启动时唯一引发错误的地方:
Uncaught (in promise) DOMException: Failed to load because no 找到支持的来源
我从here 尝试了以下解决方案:
var playPromise = video.play();
if (playPromise !== undefined) {
playPromise.then(function () {
// Automatic playback started!
}).catch(function (error) {
// Automatic playback failed.
$(document).on('click', '#video1', function (e) {
var video = $(this).get(0);
if (video.paused === false) {
video.pause();
} else {
video.play();
}
return false;
});
});
}
但它什么也没改变。视频区域始终为白色。
【问题讨论】:
标签: javascript html google-chrome video video-streaming