gpt4 book ai didi

javascript - 无法附加到源缓冲区

转载 作者:行者123 更新时间:2023-11-29 15:39:45 25 4
gpt4 key购买 nike

我编写了一个 VideoBuffer 类来加载 webm 视频片段。每个片段在视频元素中作为 blob 打开或直接在单独的浏览器选项卡中打开时单独工作,但在将它们附加到源缓冲区时我似乎无法让它工作。

没有错误或异常被抛出,MediaSource 的就绪状态被关闭并且 SourceBufferList 被清空。我的代码很大程度上基于 this working example ,主要区别在于我将每个 xhr 响应附加到缓冲区,而不是附加来自 FileReader 的结果。

关于为什么这不起作用或我应该如何调试它的任何想法?

var EventEmitter = require("events").EventEmitter;

function VideoBuffer(options) {
this.video = options.video;
this.source = new MediaSource();
this.video.src = URL.createObjectURL(this.source);
this.url = options.url;
this.segment = 0;
this.time = 0;
this.duration = options.duration;
this.segments = Math.ceil(this.duration/10);
this.preset = options.preset;
this.source.addEventListener("sourceopen", this.onSourceOpen.bind(this));
this.source.addEventListener("sourceended", this.onSourceEnded.bind(this));
this.video.addEventListener("progress", this.onVideoProgress.bind(this));

this.on("error", function(err){
try {
throw err;
} catch (e) {
console.error(e.stack);
}
});
}

VideoBuffer.prototype = Object.create(EventEmitter.prototype);

VideoBuffer.prototype.onSourceOpen = function (e) {
this.debug("Source opened:", this.source);
var buffer = this.source.addSourceBuffer('video/webm; codecs="vorbis,vp8"');
buffer.addEventListener("updatestart", this.onBufferUpdateStart.bind(this));
buffer.addEventListener("update", this.onBufferUpdate.bind(this));
buffer.addEventListener("updateend", this.onBufferUpdateEnd.bind(this));
this.debug("Added source buffer:", buffer);
this.emit("source:open", e);
};

VideoBuffer.prototype.onSourceEnded = function (e) {
this.debug("Source ended:", this.mediaSource);
this.emit("source:ended", e);
};

VideoBuffer.prototype.onBufferUpdateStart = function (e) {
this.emit("buffer:updatestart", e);
};

VideoBuffer.prototype.onBufferUpdate = function (e) {
this.emit("buffer:update", e);
};

VideoBuffer.prototype.onBufferUpdateEnd = function (e) {
this.emit("buffer:updateend", e);
if (this.segment === 0) {
this.debug("Got first segment, starting playback");
this.debug(this);
this.video.play();
}
};

VideoBuffer.prototype.onVideoProgress = function (e) {
this.debug("Video progress:", e);
this.segment++;
this.loadNextSegment();
}

VideoBuffer.prototype.loadNextSegment = function () {
var url = this.url
.replace("%segment", this.segment)
.replace("%time", this.time)
.replace("%preset", this.preset);

this.debug("Loading segment:", this.segment, url);

this.request = new XMLHttpRequest();
this.request.responseType = "arraybuffer";
this.request.open("GET", url, true);
this.request.onload = this.onRequestLoad.bind(this);
this.request.send(null);
}

VideoBuffer.prototype.onRequestLoad = function(e) {
if (this.request.status != 200) {
this.emit("error", new Error("Unexpected status code"));
return false;
}
var ms = this.source;
var sb = ms.sourceBuffers.length ? ms.sourceBuffers[0] : false;
var buffer = new Uint8Array(this.request.response);

this.debug("Got segment:", buffer.length, "bytes");

if (buffer.length && sb) {
try {
this.debug("Appending segment to source buffer");
sb.appendBuffer(buffer);
} catch (e) {
this.emit("error", new Error(e));
return false;
}
if (this.segment === this.segments) {
ms.endOfStream();
return;
}
} else {
this.emit("error", new Error("Empty response or missing source buffer"));
}
}

VideoBuffer.prototype.play = function (time) {
this.time = 0;
this.segment = Math.floor(this.time/10);
this.loadNextSegment();
};

VideoBuffer.prototype.debug = (function () {
return console.log.bind(console);
}());

module.exports = VideoBuffer;

注意:上面的代码是用 browserify 加载的,这就是它是 CommonJS 模块的原因。

Gist对于那些喜欢和/或希望尝试的人。

最佳答案

你确定没有错误?尝试去掉 onRequestLoad 中的 try/catch。

我怀疑正在发生的事情是您试图附加到您的 SourceBuffer 实例,而它的 updating 属性仍然是 true

每次附加到 SourceBuffer 时,它都必须做一些工作,并且暂时无法接受新 block 。最好的方法是使用某种排队机制,或者等待 updateend 事件触发,然后再发送下一个 XHR。

关于javascript - 无法附加到源缓冲区,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21369073/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com