我想从上传到我的网站的多个图像创建一个视频文件。
到目前为止,我所做的就是拍摄这些图像,将它们一一绘制在画布上,然后使用 APIMediaRecorder
来记录它们。不过,空闲时间还是很多的。
相反,我想使用VideoEncoder
API。
我创建了一个编码器,将每个块保存为缓冲区:
const chunks = [];
let encoder = new VideoEncoder({
output: (chunk) => {
const buffer = new ArrayBuffer(chunk.byteLength)
chunk.copyTo(buffer);
chunks.push(buffer);
},
error: (e) => console.error(e.message)
});
Run Code Online (Sandbox Code Playgroud)
并使用我的设置对其进行配置:
encoder.configure({
codec: 'vp8',
width: 256,
height: 256,
bitrate: 2_000_000,
framerate: 25
});
Run Code Online (Sandbox Code Playgroud)
然后,我将每个图像编码为帧:
const frame = new VideoFrame(await createImageBitmap(image));
encoder.encode(frame, {keyFrame: true});
frame.close();
Run Code Online (Sandbox Code Playgroud)
最后,我尝试用它创建一个视频:
await encoder.flush();
const blob = new Blob(chunks, {type: 'video/webm; codecs=vp8'});
const url = URL.createObjectURL(blob);
Run Code Online (Sandbox Code Playgroud)
但是,该 URL 块无法播放。如果我尝试下载它,VLC 不会显示它。如果我将其设置为元素的源video
,我会得到: …
我希望能够在视频到达某些指定帧时稳健地停止视频,以便根据使用 Blender、Manim 制作的视频进行口头演示...
我知道这个问题,但问题是视频没有完全停在好帧处。有时它会继续前进一帧,当我强制它返回到初始帧时,我们会看到视频向后退,这很奇怪。更糟糕的是,如果下一帧完全不同(不同的背景......),这将非常明显。
为了说明我的问题,我在这里创建了一个演示项目(只需单击“下一步”即可看到当视频停止时,有时会倒退)。完整的代码在这里。
我正在使用的代码的重要部分是:
var video = VideoFrame({
id: 'video',
frameRate: 24,
callback: function(curr_frame) {
// Stops the video when arriving on a frames to stop at.
if (stopFrames.includes(curr_frame)) {
console.log("Automatic stop: found stop frame.");
pauseMyVideo();
// Ensure we are on the proper frame.
video.seekTo({frame: curr_frame});
}
}
});
Run Code Online (Sandbox Code Playgroud)
到目前为止,我通过在结束前停止一帧然后使用seekTo
(不确定这听起来如何)来避免这个问题,如此处所示。但正如您所看到的,有时当进入下一帧时,它会有点“冻结”:我想这是在seekTo
.
PS:如果你知道 JS 中一种可靠的方法来了解给定视频的帧数,我也很感兴趣。
关于在桌面上预先剪切视频的想法,可以使用......但我过去在这方面有过不好的经验,特别是更改视频有时会产生一些故障。此外,它的使用可能会更复杂,这意味着视频应该手动剪切很多时间,重新编码......
编辑是否有任何解决方案,例如基于WebAssembly(与旧浏览器更兼容)或Webcodec(更高效,但尚未广泛传播)?Webcodec 似乎允许非常令人惊奇的事情,但我不知道如何使用它们。我很想听到基于它们的解决方案,因为 Firefox 尚不处理 webcodec。请注意,如果在此过程中音频不会丢失,那就太好了。如果我还可以根据要求显示控件,那就太好了。
编辑:我不确定这里发生了什么( …
我正在使用 WebCodecs AudioDecoder来解码 OGG 文件(vorbis 和 opus)。AudioDecoder
配置中的编解码器字符串设置分别为vorbis
和opus
。
我已将容器解析为页面,并且AudioDecoder
几乎已准备好工作。
但是,我无法弄清楚description
它所期望的字段。我已经阅读了Vorbis WebCodecs Registration,但我仍然迷失方向。那是:
let decoder = new AudioDecoder({ ... });
decoder.configure({
description: "", // <----- What do I put here?
codec: "vorbis",
sampleRate: 44100,
numberOfChannels: 2,
});
Run Code Online (Sandbox Code Playgroud)
编辑:我知道它需要有关 OGG 文件结构的关键信息。我不明白的是那里到底有什么。绳子看起来怎么样?它是一个以点分隔的参数字符串吗?
我想生成一个视频。我正在用来MediaRecorder
录制由 生成的曲目MediaStreamTrackGenerator
。
生成每一帧需要一些时间,比如说 1 秒,我想以10
fps 生成视频。
因此,当我创建帧时,我使用timestamp
和duration
来指示帧的实时时间。
const ms = 1_000_000; // 1\xc2\xb5s\nconst fps = 10;\nconst frame = new VideoFrame(await createImageBitmap(canvas), {\n timestamp: (ms * 1) / fps,\n duration: ms / fps,\n});\n
Run Code Online (Sandbox Code Playgroud)\n不幸的是,如果生成每一帧需要 1 秒,尽管指示timestamp
和duration
,视频仍以 1 帧/秒播放,而不是 10 fps。
用于复制的 CodePen:https://codepen.io/AmitMY/pen/OJxgPoG \n(此示例适用于 Chrome。如果您使用 Safari,请更改video/webm
为video/mp4
。)
我尝试过但对我来说不是一个好的解决方案:
\n