ffmpeg抽取音频AAC

2020-04-02 18:40:13 浏览数 (1)

在我的视频课中为了讲解对多媒体文件进行复用和解复用,我特别举了一个例子,就是将一个MP4文件中的音频 AAC 抽取出来。但有很多同学产生的疑问,不断的在群里问我:“为什么使用你代码中例子抽取出来的不能播放呀?”

我在群里给大家耐心的说明了一下 AAC分为 HE-AAC 和 LC-AAC...,由于写的代码只是一个例子,并没有适配所有的情况,所以只对HE-AAC有效,而对于 LC-AAC,需要手动修改一下。

但没过两天当有新的小伙伴加入的时候,我又要重新解释一遍,自己真的很无语呀!感觉刨了个“坑”,自己掉下去了。

两种实现方式

对于从多媒体文件中抽取出 AAC音频有两种实现方式。一种是我在视频课中举的例子,取出一个个音频包,然后在每个音频包前边手动的加 ADTS Header写成一个文件。这种方式对大家要求比较高,也就是要了解 ADTS Header里边的细节,这样才能写出来。

另一种就比较简单了,就是使用 ffmpeg API 直接创建一个 AAC 文件,在 ffmpeg库内部会自己查找到对应的多媒体格式帮你做好 ADTS Header,并最终写好AAC 文件。所以你只需要调API就好了,其它对你完全透明。

接下来我们就看看该如何实现它。

具体实现

对于第二种方法的实现非常的简单,几步就可以完成:

  • 调用 av_guess_format 让ffmpeg帮你找到一个合适的文件格式。
  • 调用 avformat_new_stream 为输出文件创建一个新流。
  • 调用 avio_open 打开新创建的文件。
  • 调用 avformat_write_header 写文件头。
  • 调用 av_interleaved_write_frame 写文件内容。
  • 调用 av_write_trailer 写文件尾。
  • 调用 avio_close 关闭文件。

具体的代码我已经上传到课程的代码库上了。

遇到的问题

需要注意的点,在将抽取出的音频包写入到输出文件之前,要重新计算它的时间戳,也就是将原来时间基的时间戳修改为输出流时间基的时间戳。这一步非常关键,否则在播放该 AAC文件时出错。

小结

通过上面的例子在家可以看到,其实使用ffmpeg帮我们完成了很多的事情,如果是我们自己去写就要了解各种音视频规范,而ffmpeg已经将这些细节帮我们封装好了,我们只需要调用相关的 API即可。

但如我们想深入的了解音视频时,最终还是要学那些规范的,不过好的方面是ffmpeg是开源的,我们可以扒开它的代码一窥里面的内容。

0 人点赞