使用 FFMPEG 将可搜索的 AAC 音频流写入 MP4 文件

Write seekable AAC audio stream into MP4 file with FFMPEG

我正在尝试使用 FFMPEG 库将 AAC 音频流写入 mp4 文件。我正在使用直接写入套接字的自定义 IO 上下文,因此我必须设置 ioContext->seekable = 0。为了完成这项工作,我必须在编写 header.

时添加 "movflags" empty_moovfrag_keyframe

将输出写入套接字另一端的文件后,我可以在 VLC 或 Windows 媒体播放器中播放该文件。但是,寻找文件中的特定位置在两个播放器中都无法正常工作。 WMP 也不显示总持续时间,VLC 仅在到达音频结尾时短暂闪烁。

有没有办法在 muxing 时添加更多元数据,以便播放器能够将文件视为未写入流?通过套接字的传输不会突然中断,所以我可以在文件末尾写入元数据。我也提前知道总持续时间,所以如果可能的话,我可以将它添加到文件的 header 中。我不能使用 faststart 标志,因为这需要在写入套接字之前输出到可搜索文件。

更新: 我了解到我可以在 AVFormatContext 中设置持续时间,我可以在 [=17] 中设置 nb_framesavg_frame_rate =].但是,它不能解决我的问题。当我设置 codecContext 标志 AV_CODEC_FLAG_QSCALE 时,VLC 似乎能够估计总时间。但是,求还是不行。

如果您想要一个可搜索的 MP4 文件,请确保它肯定具有元数据,因为这是 MPEG 解码器处理搜索的必要条件(MP4 元数据列出了每个 AAC 帧字节的起始位置。
这意味着失去 -movflags empty_moov & frag_keyframe 因为它们增加了问题。

考虑:

  • 您不需要 frag_keyframe,因为所有音频帧都被归类为关键帧。
  • 不要强制empty_moov,因为如果没有元数据,MP4 解码器将无法搜索。 (FFmpeg 将在碎片模式下处理元数据)。

this excellent guide 在流媒体上的引述:

Writing a fragmented file has the advantage that the file is decodable even if the writing is interrupted (while a normal MOV/MP4 is undecodable if it is not properly finished), and it requires less memory when writing very long files (since writing normal MOV/MP4 files stores info about every single packet in memory until the file is closed). The downside is that it is less compatible with other applications.

您可以尝试的选项是:

  • frag_duration [num] 创建 num 毫秒长的片段。
  • frag_size [num] 创建最多包含 num 字节大小的有效负载的片段。