1

由于显然无法通过 ID3 标签或文件扩展名告诉 iTunes 或 iOS MP3 包含有声读物(或电台播放),我想将它们重新组合成带有文件扩展名的MPEG-4 Part 14.m4b容器(无需转换,即转码或将音频流重新编码为 AAC)并设置正确的媒体类型标签(stik= 2 Audiobook)。

$ ffmpeg -hide_banner -y \
         -i "infile.mp3" -codec copy -map 0 \
         "outfile.m4b"

从输出文件名自动检测预期格式时,FFmpeg(撰写本文时版本为 4.2.1)切换其-f ipod兼容模式为.m4a.m4b,这意味着它显然不会接受 MP4 容器中的 MPEG 1/2 第 3 层音频:

[ipod @ 00000223bd927e40]
在流 #0 中找不到编解码器 mp3 的标记,容器中当前不支持编解码器 无法
为输出文件 #0 写入标头(编解码器参数不正确?):参数无效

我可以覆盖它(或者在使用之后更改文件扩展名"outfile.mp4"):

$ ffmpeg -hide_banner -y \
         -i "infile.mp3" -codec copy -map 0 -f mp4 \
         "outfile.m4b"

转换和 FFprobe 所需的时间接近于零,这让我确信重新混合是成功的:

Stream #0:0(und): Audio: mp3 (mp4a / 0x6134706D), 48000 Hz, stereo, fltp, 160 kb/s (default)

不过,自定义 ID3v2 标记字段和没有已知 MP4 同源的标记字段已被删除。我想保存它们!

-map_metadata如果可能的话,我该怎么做?

如何使用-metadata添加必要的标签字段 (atom: stik) 将文件标记为有声读物 - 更笼统地说:
如何使用 FFmpeg 添加手动指定的元数据标签字段(例如 MP4 atom 或 box)?

$ ffmpeg -hide_banner -y \
         -i "infile.mp3" -codec copy -map 0 -f mp4 \
         -metadata:s:a:0 language=deu \
         -metadata stik=2
         "outfile.m4b"

FFmpeg 文档

  • -metadata[:metadata_specifier] key=value (output,per-metadata)
    设置元数据键/值对。
  • -map_metadata[:metadata_spec_out] infile[:metadata_spec_in] (output,per-metadata)
    从 infile 设置下一个输出文件的元数据信息。请注意,这些是文件索引(从零开始),而不是文件名。可选的 metadata_spec_in/out 参数指定要复制的元数据。元数据说明符可以具有以下形式:
    • g
      全局元数据,即适用于整个文件的元数据
    • s[:stream_spec]
      每个流元数据。stream_spec 是流说明符,如流说明符一章中所述。在输入元数据说明符中,复制第一个匹配流。在输出元数据说明符中,所有匹配的流都被复制到。
    • c:chapter_index
      每章元数据。chapter_index 是从零开始的章节索引。
    • p:program_index
      每个程序的元数据。program_index 是从零开始的节目索引。

如果省略元数据说明符,则默认为全局。

默认情况下,全局元数据从第一个输入文件复制,每个流和每个章节的元数据与流/章节一起复制。通过创建相关类型的任何映射来禁用这些默认映射。负文件索引可用于创建仅禁用自动复制的虚拟映射。

附言

  • 苹果似乎没有正式文件stikMPMediaType略有不同。相反的指针将不胜感激。
  • 理想情况下,我想自动添加*.mp3子目录中的所有文件,按字母顺序排序(共享相同的编码器设置)作为单个.mp4容器中的章节,但这可能值得一个单独的问题。
4

0 回答 0