WebCodecs > VideoEncoder:从编码帧创建视频

互联网 行业动态 更新时间:2024-06-13 00:19:06

Mac*_*iej 9

VideoEncoderWebCodecs API 中的其他类和其他类为您提供了将图像编码为视频流中的帧的方法,但是编码只是创建可播放多媒体文件的第一步。像这样的文件可能包含多个流 - 例如,当您有一个带声音的视频时,它已经至少有一个视频和一个音频流,所以总共有两个。您需要额外的容器格式来存储流,这样您就不必在单独的文件中发送流。要从任意数量的流(甚至只是一个)创建容器文件,您需要一个多路复用器(简称 muxer)。可以在此Stack Overflow 答案中找到对该主题的良好摘要,但要引用重要部分:

创建多媒体文件时,您使用编码器算法对视频和音频数据进行编码,然后使用复用器将流放在一起放入文件(容器)中。为了播放文件,解复用器将流分离并将它们馈送到解码器以获取视频和音频数据。 Codec 是 coder/decoder 的意思,是一个独立于容器格式的概念。许多容器格式可以容纳许多不同类型的格式(AVI 和 QuickTime/MOV 非常通用)。其他格式仅限于一种或两种媒体类型。

你可能会想“我只有一​​个流,我真的需要一个容器吗?” 但多媒体播放器希望接收到的数据(从文件读取的数据或通过网络流式传输的数据)采用容器格式。即使您只有一个视频流,您仍然需要将其打包到一个容器中以便他们识别它。

将字节缓冲区加入一大块数据将不起作用:

const blob = new Blob(chunks, {type: 'video/webm; codecs=vp8'});

在这里,您尝试将所有块粘合在一起并告诉浏览器将其解释为 WebM 视频(视频/webm MIME 类型),但它不能这样做,因为它的格式不正确。这反过来又是错误的根源。为了使其工作,您必须将相关元数据附加到您的块(通常格式化为具有特定格式的二进制数据缓冲区,具体格式取决于容器的类型以及编解码器)并将其传递给复用器。如果您使用旨在处理原始视频流(例如,来自 WebCodecs API 的视频流)的多路复用库,那么它可能会为您处理元数据。作为程序员,您很可能不必手动处理此问题,但是如果您想了解更多有关整个过程的信息,那么我建议您阅读以各种容器格式存在的元数据(例如,此答案下方的 VC.Ones 评论) .

遗憾的是,muxers 似乎目前还不是 WebCodecs API 的一部分。API官方仓库中的示例使用该函数作为编码器输出回调:muxAndSend()

const videoEncoder = new VideoEncoder({
  output: muxAndSend,
  error: onEncoderError,
});

在上面的代码中我们可以看到这个函数需要由程序员提供(原始注释):

// The app provides a way to serialize/containerize encoded media and upload it.
// The browser provides the app byte arrays defined by a codec such as vp8 or opus
// (not in a media container such as mp4 or webm).
function muxAndSend(encodedChunk) { ... };

这是一个关于向浏览器添加多路复用支持的讨论的链接,这里是官方 repo 中跟踪此功能的一个问题。截至目前,似乎没有针对您的问题的内置解决方案。

要解决它,您可以使用第三方库,例如mux.js或类似的库(这里是他们的“基本用法”示例的链接,可能会对您有所帮助)。或者,该项目声称使用VideoEncoder编码数据创建 WebM 容器。他们演示的描述摘录似乎正是您想要实现的(除了使用网络摄像头作为VideoFrame源,而不是画布):

当您单击“开始”按钮时,浏览器会要求您授予捕获相机和麦克风的权限。然后将来自每个的数据传递给两个独立的工作人员,这些工作人员使用 WebCodecs 浏览器 API 将视频编码为 VP9,将音频编码为 Opus。

来自每个工作人员的编码视频和音频被传递到第三个工作人员,该工作人员将其混合成 WebM 格式。

我无法为您提供代码示例,因为我自己没有使用过任何提到的库,但我相信在了解编码器和复用器之间的关系之后,您应该能够自己解决问题。

编辑: 我找到了另一个可以帮助你的图书馆。根据他们的自述文件:

支持什么:

MP4 视频复用(获取已经编码的 H264 帧并将它们包装在 MP4 容器中) 通过 WebCodecs 进行 MP4/H264 编码和复用

我在网上找到的许多库和资源似乎都是基于 WASM 的,通常用 C 或其他编译为本机机器代码的语言实现。这可能是因为存在处理各种媒体格式的大型库(首先想到的是ffmpeg ),这就是它们的编写方式。JS 库通常被编写为与所述本机代码的绑定避免重新发明轮子。此外,我认为性能也可能是一个因素。

免责声明:虽然您在代码示例中使用 video/webm 作为 MIME 类型,但您没有明确说明您希望输出的文件格式是什么,所以我允许自己参考一些产生其他格式的库。

我会赞成,因为他需要关键帧数据的容器格式是正确的。错误/缺失的是 **(1)** **muxing** 需要这些基于 WASM 的代码(可以在纯 Javascript 中完成)。它们在 C 中实现不是为了速度,而是因为它们使用预先存在的 C 代码(如 FFmpeg 或类似代码)来增强它们的能力。WebCodecs **完全**是为了在编码时取代对这些 WASM 变通方法的需求。 (3认同) **(2)** 在混合任何内容之前,他的原始关键帧需要其格式的元数据。例如:**VP8** 关键帧需要一个 VP8 或 **webP** 标头才能混合到 webM 中。要制作一个,他只需要创建一个包含 20 个值(字节)的数组,然后在这 20 个值之后复制/粘贴 blob 自己的数组值。_Eg:_ `52 49 46 46 AA AA AA AA 57 45 42 50 56 50 38 20 BB BB BB BB` 是您将四个值 **0xAA** 替换为 **12 + SIZE** 的关键帧字节(如32 位整数)和四个 **0xBB** 只是关键帧的 **SIZE**。大小表示数组的长度。此时数据现在被混合到 webP 中。 (2认同) **(3)** 类似的设置也可用于 H.264 关键帧。为此,您需要大约 40 个字节用于 **SPS** 和 **PPS** 等,任何 MP4 多路复用器都希望在 H264 流中存在这些字节。SPS 将包含像帧宽度/高度这样的数字,这些数字在创建时会传输到 MP4 标头。WebCodecs 不生成 SPS 和 PPS(在 JS 中,您可以根据画布大小等编写自己的 Array 值)......所以这就是缺少的,注意 Asker 仍然需要准备原始关键帧数据**也带有* * 它是包含之前的预期元数据(_eg:_ **webP 标头** 或 **H.264 标头**)。 (2认同)

更多推荐

视频,amp,WebCodecs,VideoEncoder,gt

本文发布于:2023-04-20 20:29:17,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/hyzx/1d01085a72893f088dd8c38ba4b10b5c.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:视频   amp   WebCodecs   VideoEncoder   gt

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!