在 Chrome 中。我在用着媒体记录器 https://developer.mozilla.org/en-US/docs/Web/API/MediaStream_Recording_API and canvas.captureStream() https://developer.mozilla.org/en-US/docs/Web/API/HTMLCanvasElement/captureStream创建画布的 webm 文件。
let recorder = new MediaRecorder(document.querySelector('canvas').captureStream(), {mimeType: 'video/webm'});
let chunks = [];
let blob;
recorder.ondataavailable = function(event) {
if (event.data.size > 0) {
chunks.push(event.data);
}
};
recorder.onstop = function() {
blob = new Blob(chunks, {type: 'video/webm'});
let url = URL.createObjectURL(blob);
let a = document.createElement('a');
document.body.appendChild(a);
a.href = url;
a.download = Date.now()+'.webm';
a.click();
window.URL.revokeObjectURL(url);
a.parentNode.removeChild(a);
}
recorder.onstart = function() {
chunks = [];
}
这是基本的录音和下载代码以及调用recorder.start()
开始录音并recorder.stop()
to end.
输出的 webm 文件很好,我遇到的问题是,由于计算机/开销很差,我不能总是足够快地绘制画布以使其达到完整的 60 fps。在画布本身上,我不介意较低的帧速率,但绘制到画布上的延迟会转化为 webm,并且我留下的是 x0.9 速度的视频。
我尝试通过使用来解决这个问题canvas.captureStream(0)
一次仅捕获一帧并将其与每个画布渲染相匹配。但这失败了,因为我无法指定每个帧应持续的持续时间,并且文件大小变得巨大,因为每个帧都有所有标头信息。
我可以在我的 blob 数组中看到,前 131 个 blob 是常量,而第 132 个 blob 的数据量非常大。之后,通常有大约 7 个间隔 blob(每个 1 字节),然后是一个包含大量数据的单个 blob。我知道前 132 个 blob 是标头信息 + 我的第一帧。我想象每帧都有大量数据的斑点。我还假设 1 字节间隔块与帧持续时间或暂停一定时间有关。
我想做的是能够修改这些间隔块以指定帧的确切持续时间。我尝试手动执行此操作,方法是在我知道帧速率理想的 2 帧之间复制 7 个间隔块,然后删除所有其他间隔块并在每个帧之间粘贴这些理想的间隔块,但输出文件无法播放。
我是否误解了 blob 数据?有没有办法通过修改 blob 数据来手动指定帧持续的持续时间,或者我是否坚持可以绘制到画布上的任何帧速率?