FFmpeg开发->PCM转AAC存入本地

流程图,demo会在文末给出

在这里插入图片描述

ffmpeg初始化大体差不多,说些注意的地方
  1. 创建封装格式上下文与推流不太一样可以根据输出路径推测格式(关键代码)
 	//初始化封装格式上下文
    audioFormatContext = avformat_alloc_context();
    if (audioFormatContext == NULL) return -1;
    //根据本地路径后缀推测输出文件格式
    audioFormatContext->oformat = av_guess_format(NULL, path, NULL);
    //打开输出上下文
    if (avio_open(&audioFormatContext->pb, path, AVIO_FLAG_READ_WRITE) < 0) return -1;
  1. 编码器参数的设置,这里以单通道8000的采样率举例(关键代码)
	//因为我用的是fdk-aac所以不需要重采样的问题如果用ffmpeg自带的则需要重采样
 	audioCodecCxt->sample_fmt = AV_SAMPLE_FMT_S16; //采样格式
    audioCodecCxt->bit_rate = 96000; //码率
    audioCodecCxt->sample_rate = 8000; //采样率
    audioCodecCxt->channel_layout = AV_CH_LAYOUT_MONO; //通道类型
    audioCodecCxt->channels = 1; //通道数
    audioCodecCxt->sample_fmt = audioCodec->sample_fmts[0]; //编码器所支持的第一种采样格式
    audioStream->time_base = (AVRational) {1, audioCodecCxt->sample_rate}; //音频流时间基
  1. 原始数据AVFrame的分配,以及把麦克风数据赋值给AVFrame(关键代码)
	//分配音频原始数据AVFrame
    audioFrame = av_frame_alloc();
    //设置参数
    audioFrame->nb_samples = audioCodecCxt->frame_size; //样本数
    audioFrame->format = audioCodecCxt->sample_fmt; //音频采样格式
    //获取缓冲区大小
    int audioBufferSize = av_samples_get_buffer_size(NULL,
                                                     audioCodecCxt->channels,
                                                     audioCodecCxt->frame_size,
                                                     audioCodecCxt->sample_fmt,
                                                     1);
    //创建缓冲区
    audioBuffer = (uint8_t *) av_malloc(audioBufferSize);
    avcodec_fill_audio_frame(audioFrame,
                             audioCodecCxt->channels,
                             audioCodecCxt->sample_fmt,
                             (const uint8_t *) audioBuffer,
                             audioBufferSize,
                             1);
    //初始化编码后数据储存结构体
    audioPacket = (AVPacket *) av_malloc(audioBufferSize);
  1. FIFO的使用关键代码(他可以把音频帧的大小设置为符合编码的大小)
	//初始化音频fifo
	av_audio_fifo_alloc(audioCodecCxt->sample_fmt, audioCodecCxt->channels,
	                                    audioFrame->nb_samples);
	//存数据
	av_audio_fifo_write(audioFifo, reinterpret_cast<void **>(audioFrame),
	                            audioFrame->nb_samples)
	//取数据
	av_audio_fifo_read(audioFifo, reinterpret_cast<void **>(audioFrame),
	                               audioFrame->nb_samples) 
  1. 开始编码(关键代码)
	//设置pts
	audioFrame->pts = audioPts;
	//编码
	avcodec_send_frame(audioCodecCxt, audioFrame)
	//获取编码数据
	avcodec_receive_packet(audioCodecCxt, audioPacket)
	//更新帧流序号
	audioPacket->stream_index = audioStream->index;
	//转换时间基
	av_packet_rescale_ts(audioPacket, audioCodecCxt->time_base, audioStream->time_base);
	//写入本地文件
	av_write_frame(audioFormatContext, audioPacket)
	//释放packet缓存
	av_packet_unref(audioPacket)
	//计算pts
	audioPts += audioFrame->nb_samples;
	//编码结束后记得写入文件未***
	av_write_trailer(audioFormatContext);
  1. 释放资源
 if (audioPacket != nullptr){
        av_packet_free(&audioPacket);
    }
    if (audioFrame != nullptr){
        av_frame_free(&audioFrame);
    }
    if (audioBuffer != nullptr){
        av_free(audioBuffer);
    }
    if (audioFifo != nullptr){
        av_audio_fifo_free(audioFifo);
    }
    if (audioCodecCxt != nullptr){
        avcodec_free_context(&audioCodecCxt);
    }
    if (audioFormatContext != nullptr){
        avformat_free_context(audioFormatContext);
    }

扫码领源码

在这里插入图片描述

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值