无需查找即可写入的音频文件格式

Posted

技术标签:

【中文标题】无需查找即可写入的音频文件格式【英文标题】:Audio file format that can be written without seeking 【发布时间】:2012-01-12 07:39:13 【问题描述】:

我想将音频数据写入标准输出,最好使用 libsndfile。当我将 WAV 输出到 /dev/stdout 时,我设法编写了标题,但随后出现错误

Error : could not open file : /dev/stdout
System error : Illegal seek.

我假设这与http://www.mega-nerd.com/libsndfile/FAQ.html#Q017 有关,某些文件格式无法在没有搜索的情况下写入。但是,当我尝试输出 SF_FORMAT_AU | SF_FORMAT_PCM_16 相反,我仍然得到同样的非法搜索错误。

有没有什么音频文件格式可以完全不用搜索就能写出来的?

我正在使用 Linux。

编辑:这可能很明显,但 RAW 格式有效(无需搜索)。不幸的是,我需要一种包含采样率等元信息的格式。

【问题讨论】:

我认为你必须向我们展示你编写的代码。 【参考方案1】:

您应该阅读完该常见问题解答...您提供给我们的链接包含所有答案。

但是,至少有一种文件格式 (AU) 专门设计用于写入管道。

所以使用 AU 而不是 WAV。

还要确保使用sf_open_fd 打开SNDFILE 对象,并且不是 sf_open_virtual(或sf_open):

SNDFILE* sf_open_fd      (int fd, int mode, SF_INFO *sfinfo, int close_desc) ;
SNDFILE* sf_open_virtual (SF_VIRTUAL_IO *sfvirtual, int mode, SF_INFO *sfinfo,
                          void *user_data) ;

如果你使用sf_open_fd,那么libsndfile会使用fstat来判断文件描述符是管道还是普通文件。如果您使用sf_open_virtualsf_open,它将假定该文件是可查找的。这似乎是 libsndfile 中的一个缺陷,但无论如何您都应该使用sf_open_fd

脚注:不要打开/dev/stdout来获取标准输出;它已经打开了,无需再次打开它。使用文件描述符STDOUT_FILENO

【讨论】:

如何打开 SNDFILE?【参考方案2】:

结束输出“无限”wav 标头,然后在音频持续时写入原始 PCM 数据。不是很有效,但大多数玩家似乎都明白了。

wav 标题在这里,如果有人想要的话:https://gist.github.com/1428176

【讨论】:

我仍然想知道您是如何使用 libsndfile 打开文件的,因为在我检查 libsndfile 源代码时,如果您将sf_open_fd 与 AU 一起使用,则永远不会返回该错误... 我使用的是 sf_open("/dev/stdout", SFM_WRITE, SF_FORMAT_AU | SF_FORMAT_PCM_16) 那行不通。使用sf_open_fd(STDOUT_FILENO, ...)。 Libsndfile 只检查带有文件描述符的管道,而不是路径。【参考方案3】:

您可以写入临时文件(可能在 /tmp 中),让 libsnd 寻求修改临时文件的 .wav(RIFF) 标头,然后在 libsnd 关闭文件后,将临时文件输出到标准输出。

【讨论】:

以上是关于无需查找即可写入的音频文件格式的主要内容,如果未能解决你的问题,请参考以下文章

如何将图形的输出写入 WAV 或 AIF 格式的外部音频文件?

将.3gp文件写入.wav格式python Flask服务器

在音频文件集合中查找指定的音频模式

无需登录即可以 JSON 格式获取 Google Drive 文件夹的内容

如何在 WASAPICaptureSharedEventDriven 中保存原始格式的音频文件

无需导出即可获取音频文件大小