概述
本文将介绍如何使用FFmpeg从现有的音视频数据中分离出音频数据
用到的FFmpeg方法
/*
初始化一个数据包结构体,我们从多媒体文件中读取的数据就是放着这个packet中,然后通过操作packet获取里面的音/视频数据
*/
av_init_packet()
/*
从多媒体文件中找到最好的数据流
*/
av_find_best_stream()
/*
av_read_frame():获取到这路流中的数据包
av_packet_unref():释放资源,防止内存泄漏
*/
av_read_frame()/av_packet_unref()
代码
/* 步骤: ①确定要读取的MP4文件路径和要输出的aac文件路径 ②读多媒体文件信息 ③获取想要处理的流 ④从流中获取到想要的音频数据,并输出到aac文件 */
- (void)handleGetAudioFromMedia {
int ret;
// 音频index
int audio_index;
int len;
// 输入的MP4文件路径(改成你具体的文件路径)
char * src = "/Users/xxx/built.mp4";
// 输出的aac文件路径(改成你要输出的文件路径)
char * dst = "/Users/xxx/test.aac";
// 数据包
AVPacket pkt;
// 上下文结构体
AVFormatContext *fmt_ctx = NULL;
// 设置log级别
av_log_set_level(AV_LOG_INFO);
// 注册各种编解码器、多媒体协议
av_register_all();
// 打开一个多媒体文件
ret = avformat_open_input(&fmt_ctx, src, NULL, NULL);
// 如果打开多媒体文件失败了打印日志
if (ret < 0) {
av_log(NULL, AV_LOG_ERROR, "can not open file: %s\n",av_err2str(ret));
}
// 创建一个新的保存acc的文件
FILE * dst_fd = fopen(dst, "wb");
if (!dst_fd) {
av_log(NULL, AV_LOG_ERROR, "can not open file!");
// 关闭多媒体文件
avformat_close_input(&fmt_ctx);
}
// 打印多媒体详细信息
av_dump_format(fmt_ctx, 0, src, 0);
// 获取想要处理的流(参数:1上下文,2想要处理的多媒体文件的类型)
ret = av_find_best_stream(fmt_ctx, AVMEDIA_TYPE_AUDIO, -1, -1, NULL, 0);
if (ret < 0) {
av_log(NULL, AV_LOG_ERROR, "can not open find best stream!");
// 关闭多媒体文件
avformat_close_input(&fmt_ctx);
// 关闭输出文件
fclose(dst_fd);
}
// 初始化音频index
audio_index = ret;
// 初始化数据包
av_init_packet(&pkt);
// 读取数据包
while (av_read_frame(fmt_ctx, &pkt) >= 0) {
if (pkt.stream_index == audio_index) {
// 输出到我们的aac文件中
len = fwrite(pkt.data, 1, pkt.size, dst_fd);
if (len != pkt.size) {
av_log(NULL, AV_LOG_ERROR, "获取的流数据长度不对");
}
}
av_packet_unref(&pkt);
}
// 关闭多媒体文件
avformat_close_input(&fmt_ctx);
if (dst_fd) {
fclose(dst_fd);
}
}
运行结果
参考文献:
慕课网李超FFmpeg视频