使用媒体源扩展流式传输视频时出现问题
Problem streaming video using media source extensions
我好像遇到了一个很奇怪的问题。我正在尝试播放正在使用网络浏览器直播的视频。为此,我正在查看 MediaSource 对象。我以某种方式获得它,以便视频从服务器中以块的形式获取以进行播放。问题是第一个块正确播放然后播放停止。
更奇怪的是,如果我在开始流式传输后让计算机进入睡眠状态,然后将其唤醒,视频就会按预期播放。
一些注意事项:
- 我目前正在使用 chrome。
我都试过了,无论是否调用 MediaSource 的 endOfStream。
var VF = 'video/webm; codecs="vp8,opus"';
var FC = 0;
alert(MediaSource.isTypeSupported(VF));
var url = window.URL || window.webkitURL;
var VSRC = new MediaSource();
var VURL = URL.createObjectURL(VSRC);
var bgi, idx = 1;
var str, rec, dat = [], datb, brl;
var sbx;
//connect the mediasource to the <video> elment first.
vid2.src = VURL;
VSRC.addEventListener("sourceopen", function () {
// alert(VSRC.readyState);
//Setup the source only once.
if (VSRC.sourceBuffers.length == 0) {
var sb = VSRC.addSourceBuffer(VF);
sb.mode = 'sequence';
sb.addEventListener("updateend", function () {
VSRC.endOfStream();
});
sbx = sb;
}
});
//This function will be called each time we get more chunks from the stream.
dataavailable = function (e) {
//video is appended to the sourcebuffer, but does not play in video element
//Unless the computer is put to sleep then awaken!?
sbx.appendBuffer(e.result);
FC += 1;
//These checks behave as expected.
len.innerHTML = "" + sbx.buffered.length + "|" + VSRC.duration;
CTS.innerHTML = FC;
};
你犯了两个大错误:
只能在sbx.updating属性为false时调用sbx.appendBuffer,否则appendBuffer会失败。所以实际上你需要做的是有一个块队列,如果 sbx.updating 为真,则向队列添加一个块:
if (sbx.updating || segmentsQueue.length > 0)
segmentsQueue.push(e.result);
else
sbx.appendBuffer(e.result);
您的代码明确表示在第一个块后停止播放:
sb.addEventListener("updateend", function () {
VSRC.endOfStream();
});
这是您真正需要做的事情:
sb.addEventListener("updateend", function () {
if (!sbx.updating && segmentsQueue.length > 0) {
sbx.appendBuffer(segmentsQueue.shift());
}
});
我好像遇到了一个很奇怪的问题。我正在尝试播放正在使用网络浏览器直播的视频。为此,我正在查看 MediaSource 对象。我以某种方式获得它,以便视频从服务器中以块的形式获取以进行播放。问题是第一个块正确播放然后播放停止。
更奇怪的是,如果我在开始流式传输后让计算机进入睡眠状态,然后将其唤醒,视频就会按预期播放。
一些注意事项:
- 我目前正在使用 chrome。
我都试过了,无论是否调用 MediaSource 的 endOfStream。
var VF = 'video/webm; codecs="vp8,opus"'; var FC = 0; alert(MediaSource.isTypeSupported(VF)); var url = window.URL || window.webkitURL; var VSRC = new MediaSource(); var VURL = URL.createObjectURL(VSRC); var bgi, idx = 1; var str, rec, dat = [], datb, brl; var sbx; //connect the mediasource to the <video> elment first. vid2.src = VURL; VSRC.addEventListener("sourceopen", function () { // alert(VSRC.readyState); //Setup the source only once. if (VSRC.sourceBuffers.length == 0) { var sb = VSRC.addSourceBuffer(VF); sb.mode = 'sequence'; sb.addEventListener("updateend", function () { VSRC.endOfStream(); }); sbx = sb; } }); //This function will be called each time we get more chunks from the stream. dataavailable = function (e) { //video is appended to the sourcebuffer, but does not play in video element //Unless the computer is put to sleep then awaken!? sbx.appendBuffer(e.result); FC += 1; //These checks behave as expected. len.innerHTML = "" + sbx.buffered.length + "|" + VSRC.duration; CTS.innerHTML = FC; };
你犯了两个大错误:
只能在sbx.updating属性为false时调用sbx.appendBuffer,否则appendBuffer会失败。所以实际上你需要做的是有一个块队列,如果 sbx.updating 为真,则向队列添加一个块:
if (sbx.updating || segmentsQueue.length > 0) segmentsQueue.push(e.result); else sbx.appendBuffer(e.result);
您的代码明确表示在第一个块后停止播放:
sb.addEventListener("updateend", function () { VSRC.endOfStream(); });
这是您真正需要做的事情:
sb.addEventListener("updateend", function () { if (!sbx.updating && segmentsQueue.length > 0) { sbx.appendBuffer(segmentsQueue.shift()); } });