我正在尝试使用FFMPEG库将AAC音频流写入mp4文件。我正在使用直接写入套接字的自定义IO上下文,因此我必须设置ioContext->seekable = 0
。为了完成这项工作,我必须在编写标题时添加“movflags”empty_moov
和frag_keyframe
。
将输出写入套接字另一端的文件后,我可以在VLC或Windows Media Player中播放该文件。但是,寻找文件中的特定位置在两个玩家中都不能正常工作。 WMP也没有显示总持续时间,VLC仅在到达音频结束时很快闪烁。
有没有办法在多路复用时添加更多元数据,以便玩家能够将文件看作是不是作为流写入?通过套接字传输不会突然中断,因此我可以在文件末尾写入元数据。我也提前知道总持续时间,所以如果可能的话我可以将它添加到文件的标题中。我不能使用faststart
标志,因为这需要在写入套接字之前输出到可搜索文件。
更新:我了解到我可以在AVFormatContext
中设置持续时间,并且可以在nb_frames
中设置avg_frame_rate
和AVStream
。但是,它并没有解决我的问题。当我设置codecContext标志AV_CODEC_FLAG_QSCALE
时,VLC似乎能够估计总时间。但是,寻求仍然无效。
答案 0 :(得分:2)
如果你想要一个可搜索的MP4文件,请确保它肯定有元数据,因为MPEG解码器处理搜索是必要的(MP4元数据列出了每个AAC帧的字节的开始位置。
这意味着失去-movflags empty_moov & frag_keyframe
,因为它们会增加问题。
考虑一下:
frag_keyframe
,因为所有音频帧都被归类为关键帧。empty_moov
,因为如果没有元数据,MP4解码器无法搜索。 (FFmpeg将在碎片模式下处理元数据)。关于流媒体的 this excellent guide 的引用:
编写碎片文件的优点是文件可解码 即使写入被中断(正常的MOV / MP4是 如果没有正确完成则不可解码,并且需要更少 写入非常长的文件时的内存(自写入正常的MOV / MP4以来) files存储有关内存中每个数据包的信息,直到文件为止 关闭了)。缺点是它是
less compatible with other applications
。
您可以尝试的选项是:
frag_duration [num]
创建num
毫秒长的片段。frag_size [num]
创建最多包含num
字节大小的有效负载的片段。