概要
对MP4文件解封装,分离出AAC音频文件,保存到本地路径下。
整体架构流程
- 打开媒体文件(.mp4文件) avformat_open_input
- 获取码流信息 avformat_find_stream_info
- 获取音频流 av_find_best_stream
- 初始化packet(开始读取) av_init_packet
- 读取packet数据 av_read_frame
- 释放packet资源 av_packet_unref
- 关闭媒体文件 avformat_close_input
代码
const char* infilename = "/home/16THDD/xieyingbo/xieyingbo/big_buck_bunny.mp4";
const char* outfilename = "/home/16THDD/xieyingbo/xieyingbo/out.aac";
//1.打开媒体文件(.mp4文件) avformat_open_input
av_register_all();
AVFormatContext *pFormatCtx = NULL;
int ret = avformat_open_input(&pFormatCtx, infilename, NULL, NULL);
if(ret != 0)
{
qDebug() << "open url error.";
return;
}
//2.获取码流信息 avformat_find_stream_info
/*int avformat_find_stream_info(AVFormatContext *ic, AVDictionary **options);*/
ret = avformat_find_stream_info(pFormatCtx, NULL);
if(ret < 0)
{
qDebug() << "find stream failed.";
avformat_close_input(&pFormatCtx);
return;
}
//3.获取音频流 av_find_best_stream
/*int av_find_best_stream(AVFormatContext *ic, enum AVMediaType type, int wanted_stream_nb,
int related_stream, AVCodec **decoder_ret, int flags);*/
int audioIndex = av_find_best_stream(pFormatCtx, AVMEDIA_TYPE_AUDIO, -1, -1, NULL, 0);
if(audioIndex < 0)
{
qDebug() << "find best stream failed";
avformat_close_input(&pFormatCtx);
return;
}
else
{
qDebug() << "audioIndex = " << audioIndex;
}
//4.初始化packet(开始读取)av_init_packet
/*void av_init_packet(AVPacket *pkt);*/
AVPacket packet;
av_init_packet(&packet);
//5.读取packet数据 av_read_frame
/*int av_read_frame(AVFormatContext *s, AVPacket *pkt);*/
FILE *dst_fp = fopen(outfilename, "wb");
if(dst_fp == NULL)
{
qDebug() << "open output file error";
avformat_close_input(&pFormatCtx);
return;
}
while(av_read_frame(pFormatCtx, &packet) >= 0)
{
if(packet.stream_index == audioIndex) //如果是音频数据
{
ret = fwrite(packet.data, 1, packet.size, dst_fp);
if(ret != packet.size)
{
qDebug() << "write file error";
fclose(dst_fp);
avformat_close_input(&pFormatCtx);
return;
}
}
//6.释放packet资源 av_packet_unref
av_packet_unref(&packet);
}
//7.关闭媒体文件 avformat_close_input
if(pFormatCtx)
{
avformat_close_input(&pFormatCtx);
}
if(dst_fp)
{
fclose(dst_fp);
}
return;
小结
可以使用ffplay对分理出的音频文件进行播放。