[FFmpeg实战]从音视频数据中分离出音频数据

1,275 阅读1分钟

概述

本文将介绍如何使用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视频