初始化vorbis/opus格式AudioDecoder时description字段如何填写
WebCodecs AudioDecoder 解码OGG时description字段传值说明
description字段不接受点分隔的参数字符串,必须传入对应音频编码的私有配置二进制数据(ArrayBuffer/AllowSharedBufferSource类型),Vorbis和Opus两种编码的传值格式不同,所需数据都可以在解析OGG容器层时直接拿到,不需要自行生成参数。
Vorbis编码传值规则
- 先从OGG流中提取出Vorbis的三个纯头部包载荷(剔除OGG页头、校验、段表等容器层数据),按顺序分别是:标识头(identification header)、注释头(comment header)、设置头(setup header)
- 按以下规则拼接成最终的二进制缓冲:
- 首字节写入固定值
0x02 - 依次写入三个头部包的长度,每个长度用小端序32位无符号整数存储,单值占4字节
- 按顺序拼接三个头部包的完整二进制内容,不做截断或修改
- 首字节写入固定值
Opus编码传值规则
- 从OGG流中提取第一个Opus头部包(固定以
OpusHead字符串开头的标识头)的完整纯载荷,直接传入即可,不需要拼接其他头部包,也不需要加额外前缀。 - 同样需要剔除OGG容器层的封装信息,只保留Opus头部本身的二进制内容。
配置示例(Vorbis)
let decoder = new AudioDecoder({ // 自行实现output、error回调逻辑 }); // 以下三个变量为OGG解析阶段拿到的三个Vorbis头包ArrayBuffer const vorbisIdHeader = null; const vorbisCommentHeader = null; const vorbisSetupHeader = null; // 按规则拼接description二进制 const totalLen = 1 + 3*4 + vorbisIdHeader.byteLength + vorbisCommentHeader.byteLength + vorbisSetupHeader.byteLength; const descBuffer = new ArrayBuffer(totalLen); const dataView = new DataView(descBuffer); let offset = 0; dataView.setUint8(offset, 0x02); offset += 1; dataView.setUint32(offset, vorbisIdHeader.byteLength, true); offset += 4; dataView.setUint32(offset, vorbisCommentHeader.byteLength, true); offset += 4; dataView.setUint32(offset, vorbisSetupHeader.byteLength, true); offset += 4; new Uint8Array(descBuffer, offset).set(new Uint8Array(vorbisIdHeader)); offset += vorbisIdHeader.byteLength; new Uint8Array(descBuffer, offset).set(new Uint8Array(vorbisCommentHeader)); offset += vorbisCommentHeader.byteLength; new Uint8Array(descBuffer, offset).set(new Uint8Array(vorbisSetupHeader)); decoder.configure({ description: descBuffer, codec: "vorbis", sampleRate: 44100, numberOfChannels: 2, });
常见踩坑:不要给
description传入任何字符串类型值,所有WebCodecs要求的编解码器私有配置均为二进制缓冲类型,传入字符串会直接触发配置类型错误。
内容的提问来源于stack exchange,提问作者John Weisz
相关产品推荐
相关产品推荐

