如何从 WAVE 文件中提取 Vorbis 流?

如何从 WAVE 文件中提取 Vorbis 流?

我想将 Vorbis 流移到 ogg 容器中,但 ffmpeg 似乎无法识别该流。

尽管MPlayer播放时给出了以下输出:

打开音频解码器:[acm] Win32/ACM 解码器
加载编解码器 DLL:'vorbis.acm'
在 10000000 处加载 DLL 驱动程序 vorbis.acm
警告!ACM 编解码器报告 srcsize=0
AUDIO:44100 Hz,2 ch,s16le,128.0 kbit/9.07% (比例:16000->176400)
选定的音频编解码器:[vorbisacm] afm:acm (OggVorbis ACM)

ffmpeg:

ffmpeg -i Source.wav -acodec copy Target.ogg
Input #0, wav, from 'Source.wav':
  Duration: 00:02:15.17, bitrate: 128 kb/s
    Stream #0.0: Audio: qg[0][0] / 0x6771, 44100 Hz, 2 channels, 128 kb/s
[ogg @ 00000000003096C0] Unsupported codec id in stream 0
Output #0, ogg, to 'Target.ogg':
  Metadata:
    encoder         : Lavf53.6.0
    Stream #0.0: Audio: qg[0][0] / 0x6771, 44100 Hz, 2 channels, 128 kb/s
Stream mapping:
  Stream #0.0 -> #0.0
Could not write header for output file #0 (incorrect codec parameters ?)

当然这不一定需要通过 ffmpeg 来完成,任何可行的方法都可以......


我已将其中一个文件缩减为 512KB:样本.wav
(为了解决这个问题,更改了波头中的两个块大小字段,嵌入的流被“未经通知”切断)

答案1

WAV 容器基本上只是一个文件头。它不支持 Vorbis 所需的可变长度帧。“OggVorbis ACM”实际上是 Ogg 容器内的 Vorbis(用于提供帧),因此它可以在不支持所需帧的旧版 Windows ACM 音频框架中使用。这也允许它在 WAV 文件中使用,尽管这没有多大意义,因为您可以只保存 .ogg 文件。

ffmpeg 无法实现或识别此非标准“OggVorbis ACM”WAV 编解码器。您可以使用识别此编解码器的程序,例如大胆,或者您可以尝试剥离 WAV 标头以提取里面的 Ogg Vorbis。

有效的 Ogg 流以 开头OggS,这标志着文件中每个 Ogg 页面的开头。在您提供的文件中,第一个 之前有 66 个字节OggS。至少在 Mac/Linux/Unix 上,您可以使用以下命令删除前 66 个字节:

tail -c +67 sample.wav > sample.ogg

在您的文件中,嵌入的 Ogg 实际上包含两个流,似乎是试图将其填充到固定比特率。第二个流有一个未知的编解码器,似乎会让一些播放器感到困惑。例如,Firefox 播放第一个流(忽略第二个流),但 Chrome 在遇到第二个流时会停止。它还违反了其他规范,包括没有 eos(流结束)(可能是因为您没有发布完整的文件)。

如果您提取出第一个比特流(vorbis),它似乎可以正确播放。以下是一些应该能够提取第一个比特流的工具:

最好使用 Audacity 之类的程序读取 WAV 文件并重新编码以确保它不包含任何其他奇怪的东西。

答案2

我也遇到过同样的问题,唯一的不同是我需要处理大量的 Ogg Vorbis WAV 文件。Audacity 无法打开其中的许多文件(目前 Audacity 不支持编解码器 ID 为 6771 的 Ogg Vorbis WAV 文件),更不用说它不能以递归方式批量处理文件(其“应用链”功能仅限于单个目录中的文件)。

我最后写了ogg_wav脚本将 Ogg Vorbis WAV 转换为更可用的格式。该脚本有许多选项和错误处理。它可以将 Ogg Vorbis WAV 转换为未压缩的 WAV(-c选项),或提取主 OGG 流(-e选项,如果没有提供选项,则为默认选项),等等。它会跳过没有 Ogg 流的文件。使用-d选项,它将删除原始 .wav 文件。

这是它在最简单情况下的工作原理:它使用 ogginfo 检查文件是否具有 Ogg 流,检查我们是否具有必要的写入权限,然后查找第一个“OggS”标记并使用 moggsplit 尝试提取 Ogg 流,如果有多个,则假定最大的可播放 Ogg 流是我们想要的。该脚本还可以处理一些更复杂的情况,并且有许多选项,运行ogg_wav -h即可查看所有选项。

下面是一些如何使用它的示例。首先,需要安装脚本:下载 ogg_wav(它需要 Bash shell 并且我只在 Linux 中测试过它),使其可执行(使用chmod +x)并将其放入/usr/local/bin/

要将 Ogg Vorbis WAV 转换为 OGG(可以指定多个文件或使用类似的 shell 通配符*.wav):

ogg_wav ogg-vorbis.wav

上述命令将通过从 WAV 文件中提取最大的可播放 OGG 流来创建 ogg-vorbis.ogg。

对于大量文件,最好使用 GNU parallel。这是将 Ogg Vorbis WAV 递归转换为未压缩的 WAV 的命令(-d如果您想通过将 .wav 扩展名更改为 .bak 来保留原始 WAV 文件的备份,请删除该选项):

find DIRECTORY -type f -iname '*.wav' | parallel ogg_wav -cd '{}'

该脚本将跳过没有 Ogg 流的 WAV 文件,因此即使同一文件夹中有未压缩的 WAV 和 Ogg Vorbis WAV 也可以使用它。

相关内容