FFmpeg Visual Studio开发(四):音频解码

本文详细指导如何使用FFmpeg解码音频帧,包括获取多媒体上下文、音频流、选择并打开音频解码器,以及逐帧解码并输出pcm原始数据。适合初学者理解音频处理的基本流程。

上一篇文章我们学习了如何通过FFmpeg解码视频帧,本篇文章我们来学习如何解码音频帧。文章分段讲解视频解码的各个步骤,接着会贴上完整代码,最后进行测试。

准备工作

在开始学习前,我们先准备一个文件夹(Res),在里面放置一个视频文件(video.mp4)和一个音频文件(audio.mp3),时长为1分钟左右即可。
在这里插入图片描述
当然,对于没有学过 FFprobeFFplay 的朋友,强烈建议先学习一下它们的常用命令。这两个工具可以用来测试我们的音视频文件。

音频解码的步骤如下。
1.打开文件获取多媒体文件上下文
2.获取音频流
3.打开音频解码器
4.循环读取封装帧
    4.1.解码音频帧
    4.2.输出pcm原始数据

获取多媒体文件上下文

	...
	AVFormatContext *avFormatContext = NULL;

	//打开文件流,读取头信息
	int ret = avformat_open_input(&avFormatContext, inputFilePath, NULL, NULL);

	if (ret < 0){
   
   //文件打开失败
		char buff[1024];
		//把具体错误信息写入buff
		av_strerror(ret, buff, sizeof(buff)-1);
		cout << "can't open file" << endl;
		cout << buff << endl;
		//释放AVFormatContext的内存
		avformat_close_input(&avFormatContext);
		return -1;
	}
	...

获取音频流

获取音频流的方式和获取视频流的方式是一样的,都是通过下标来获取的。

	...
	//获取音频流
	int audioIndex = av_find_best_stream(avFormatContext, AVMEDIA_TYPE_AUDIO, -1, -1, NULL, 0);
	if (audioIndex < 0){
   
   
		cout << av_get_media_type_string(AVMEDIA_TYPE_AUDIO) << endl;
		//释放AVFormatContext的内存
		avformat_close_input(&avFormatContext);
		return -1;
	}

	//根据audioIndex获取音频流
	AVStream *audioStream = avFormatContext->streams[audioIndex];
	...

打开音频解码器

static int openAudioCodec(int audioStreamIndex,
	AVCodecContext **avCodecContext, AVFormatContext *avFormatContext,char *outputFilePath){
   
   
	
	AVStream *avStream;
	AVCodec *avCodec = NULL;
	AVDictionary *opts = NULL;
	
	if (av_find_best_stream(avFormatContext, AVMEDIA_TYPE_AUDIO, -1, -1, NULL, 0) < 0) {
   
   
		cout << "can't find audio stream" << endl;
		return -1;
	}
	else {
   
   
		avStream = avFormatContext->streams[audioStreamIndex];

		//寻找音频解码器
		avCodec = avcodec_find_decoder(avStream->codecpar->codec_id);
		if (avCodec == NULL) {
   
   
			cout << "can't find audio codec" << endl;
			return -1;
		}

		//获取音频解码器上下文
		*avCodecContext = avcodec_alloc_context3(avCodec);

		if (*avCodecContext == NULL) {
   
   
			cout << "can't alloc audio codec context" << endl;
			return -1;
		}

		//根据音频输入流填写音频解码器上下文
		if (avcodec_parameters_to_context(*avCodecContext, avStream->codecpar) < 0) {
   
   
			cout << "can't copy input stream params" << endl;
			return -1;
		
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值