跳到主要内容
AZ Tools

Ogg 容器检查器

Ogg 不是编解码器,而是容器:整个文件是一连串的页,每一页承载某个逻辑流的一个片段。本工具遍历每一页,展示 27 字节页头里真正存放的东西——OggS 捕获模式、版本、标记流起始与流结束以及承接上一页未完成包的头类型标志、64 位颗粒位置、该页所属流的序列号、页序号,以及 CRC32。随后把校验和字段清零,对整页重新计算 CRC,用的是 Ogg 规定的非反转多项式 0x04C11DB7 而不是 zlib 里那个反转的 CRC-32,并把存储值与计算值并排显示。段表是别处不会展示的部分。最多 255 个 lacing 值说明这一页如何切分成包,而恰好等于 255 的值并不结束一个包,它表示这个包延续到下一段;如果它是本页最后一个值,就延续到下一页。带封面的注释头往往因此散布在几十页上,而那些页的颗粒位置都是 -1,因为其中没有任何包结束。接着按序列号把页归并成逻辑流,并解析每个流开头的识别头:Vorbis、Opus、Ogg FLAC、Theora 和 Speex,注释头按它本来的多重映射来读,重复的键原样保留。最后回答播放器不会告诉你的两个问题:这些流是交替排布的复用,还是首尾相连的串接(把两个 Ogg 文件拼起来就是这样);以及每个流是否都有起始页和结束页——下载被截断的文件没有结束页,却照样能播放,只是把时长报错。

使用方法

  1. 把 .ogg、.oga、.ogv、.opus 或 .spx 文件拖进方框。整个文件都会被读取,因为时长藏在最后一页的颗粒位置里。
  2. 先看容器卡片:有几个逻辑流,是复用还是串接,所有页的 CRC 是否都对得上。
  3. 展开每个流的区块查看编解码细节——Vorbis 的声道与采样率、Opus 的预跳过与声道映射、Ogg FLAC 的位深与总采样数——以及厂商字符串和按文件顺序排列的全部注释字段。
  4. 在页表里扫一遍标志位:流首页的 BOS、末页的 EOS,以及从包中间开始的页上的延续标记。
  5. 查看警告。缺失的结束页、对不上的 CRC、页序号的断裂,各自指向文件损坏的一种具体方式。

常见问题

为什么我的 Opus 流一行显示 16 kHz,另一行显示 48 kHz?
因为它们本来就是两回事。OpusHead 里的输入采样率只是记录:它保存了送进编码器的是什么,好让解码器在需要时重采样回去。Opus 自身只有一个内部采样率 48 kHz,颗粒位置也以它为单位计数,所以一段以 16 kHz 录制的一秒音频,最后的颗粒位置大约是 48312 而不是 16000。把输入采样率当成播放采样率是 Opus 上最经典的错误,会让你算出的所有时长按两者之比整体偏离。
颗粒位置是什么?为什么有些页显示 -1?
颗粒位置是编解码器自己的时钟,写在每页末尾:在 Vorbis 和 FLAC 里它是这一页能解出的最后一个采样的编号,在 Opus 里同理但以 48 kHz 采样计并含预跳过,在 Theora 里则是关键帧号与偏移打包成的一个值。当一页里没有任何包结束时,它就是 64 位全 1 的 -1。只要某个包大到跨页就会发生,这不是损坏,而是唯一诚实的取值,因为这一页停在了半路上。
工具说我的文件是串接的,这是什么意思?
串接文件就是两个或更多完整的 Ogg 流首尾相连,各自有自己的序列号、自己的头、自己的起始页和结束页。cat a.ogg b.ogg 得到的正是这种文件,规范也允许。但规范并不能让播放器行为一致:有的会播完整条链,有的播完第一段就停,有的整条都播却只报第一段的时长,还有的进度条会在中途乱掉。如果你想要的是一个连续文件,请重新编码而不是拼接。
有一页 CRC 校验不通过,文件坏了吗?
确实有东西在这一页写好之后被改动了,但不一定是音频。Ogg 的 CRC 覆盖包含页头在内的整页,所以某个标签编辑器就地改了一个字节却没有重算校验和,留下的正是这种痕迹;存储介质翻转的一个比特,或者中断后续传的下载,也会这样。另外要注意它不是 zlib 的 CRC-32:Ogg 用的是多项式 0x04C11DB7,输入输出都不反转、末尾也不取反,并且要把校验和字段置零后计算——这就是为什么直接调用常见库函数的工具会把每一页都判成坏页。
为什么一个包会摊到三十页上?
因为一页最多 255 个段、每段最多 255 字节,上限就是 65025 字节,而带内嵌封面的注释头轻易就会超过。段表用「以 lacing 值 255 结尾」来表达溢出,意思是还没结束;下一页则置上延续标志,从上一页停下的地方接着写。这同时也说明,你不能在任意页边界把一个 Ogg 文件切开还指望两半都能用:以延续标志开头的页,开头处并没有一个完整的包。
这里显示的时长和我的播放器不一样,哪个对?
先看流结束标志。本页用能找到的最后一页的颗粒位置计算时长,Opus 还要减去预跳过;如果那个流没有结束页,说明文件被截断了,两个数字都没多大意义,你的播放器可能是在按比特率外推。串接文件在这里会把各段时长相加,而很多播放器只报第一段。至于 Opus,忘记减去预跳过会让每个文件都长出大约 6.5 毫秒,在歌曲上看不出来,在节拍轨上一眼就能发现。

相关工具