为“vorbis”和“opus”初始化一个 AudioDecoder,需要描述 - 它到底是什么?

Joh*_*isz 7 javascript oggvorbis webcodecs

我正在使用 WebCodecs AudioDecoder来解码 OGG 文件(vorbis 和 opus)。AudioDecoder配置中的编解码器字符串设置分别为vorbisopus

我已将容器解析为页面,并且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 文件结构的关键信息。我不明白的是那里到底有什么。绳子看起来怎么样?它是一个以点分隔的参数字符串吗?

Ale*_*s99 5

https://www.w3.org/TR/webcodecs-vorbis-codec-registration/#audiodecoderconfig-description

AudioDecoderConfig.description是必须的。假设它采用 Xiph 额外数据格式,如[OGG-FRAMING]中所述。该格式由page_segments字段、segment_table字段、三个 Vorbis 头数据包组成,依次为标识头、注释头和设置头,如[VORBIS]的 4.2 节中所述。

https://www.w3.org/TR/webcodecs-opus-codec-registration/#audiodecoderconfig-description

AudioDecoderConfig.description可以选择设置为标识标头,如[OPUS-IN-OGG]的第 5.1 节中所述。

如果AudioDecoderConfig.description已设置,则假定比特流已格式化ogg

如果AudioDecoderConfig.description尚未设置,则假定比特流已格式化opus

如果您想要很好地解释 OGG/Opus 标头的结构,[OPUS-IN-OGG]非常有启发性。

OGG/Vorbis 标头有点模糊,没有关于 Xiph 额外数据是什么的文档,因此只能相信 W3 文档的结构,并与字段上的 OGG/Vorbis 文档进行比较([ OGG-框架])。

本质上,您需要为解码器提供您正在解码的文件的相关二进制数据标头,如ArrayBufferTypedArrayDataView。您可以从正在解码的二进制文件内容中获取此信息。

不幸的是,要获取这些数据,您可能需要解析底层 OGG 容器的格式。WebCodecs API 旨在用于低级使用,即用于处理编解码器,而不是容器本身。请参阅此 GitHub 问题,其中有人遇到了有关描述的类似问题,并被告知自己解析容器。解析容器超出了此 API 的范围。

也许您可以使用外部 OGG 解析库,或者选择更高级别的音频处理类,例如 WebAudio API 或 WebAssembly 库?

更新:

为了澄清描述中应包含哪些内容,描述字段直接传递到extradataChromium 中的 FFmpeg。

文档规定,对于OGG/Opus,应将描述设置为第0页的内容,即标识标头(二进制)。

对于 OGG/Vorbis,文档非常糟糕,而且相当模糊。 我将检查 FFmpeg 源代码。它似乎是标识标头,后面是设置标头(作为第三个标头,因此非可选注释标头将位于中间)

因此,总结一下描述字段中应该包含的内容,您应该放置相关编解码器标头的二进制内容。对于 OGG/Opus,您将提供第一页的二进制内容(标识标头) 对于 OGG/Vorbis,您将提供前三个数据包的二进制内容(标识标头、注释标头和设置标头)。

该文档建议codec-parser提供标题数据为OpusHeader.dataVorbisHeader.{data,comments,setup}

尝试将 Vorbis 的三者连接在一起,看看是否有效。(请注意,注释和设置不会与数据同时初始化)

// opus
let desc = hdr.data;

// vorbis
let desc = new Uint8Array(hdr.data.length + hdr.comments.length + hdr.setup.length);
desc.set(hdr.data);
desc.set(hdr.comments, hdr.data.length);
desc.set(hdr.setup, hdr.data.length + hdr.comments.length);
Run Code Online (Sandbox Code Playgroud)