ffmpeg解码音频流

//初始化、注册编解码器
avcodec_init();
av_register_all();
avformat_network_init();

//选取测试文件
char* FileName="test.mp4";
string strFileName(FileName);
WavMaker test(AudioName.c_str());//初始化wav对象

//尝试打开测试文件
AVFormatContext *pFormatCtx; 
if(av_open_input_file(&pFormatCtx, FileName, NULL, 0, NULL) !=0 )
{
	printf("打开文件失败\n");
	return -1;
}
dump_format(pFormatCtx, 0, NULL, NULL);//打印相关参数

//寻找流信息,获取格式上下文信息
int err = av_find_stream_info(pFormatCtx);
if(err < 0)
{
	printf("查看流信息失败");
	return 0;
}

//找到所有的音频流和视频流
vector<int> v_video_index;
vector<int> v_audio_index;
for(int i = 0;i<pFormatCtx->nb_streams;i++)
{
	if(pFormatCtx->streams[i]->codec->codec_type==AVMEDIA_TYPE_AUDIO)
	{ 
		v_audio_index.push_back(i);
	}
	if(pFormatCtx->streams[i]->codec->codec_type==AVMEDIA_TYPE_VIDEO)
	{
		v_video_index.push_back(i);
	}
}

//取第一条音频流,作为测试
AVCodecContext *pAVCodecCtx = pFormatCtx->streams[v_audio_index[0]]->codec;
AVCodec  *pAVCodec = avcodec_find_decoder(pAVCodecCtx->codec_id);//找到相应的解码器
if(!pAVCodec)
{
	printf("Unsupported codec!\n");
	return -1;
} 
avcodec_open(pAVCodecCtx,pAVCodec); //获取编码器上下文信息
  
//初始化包
AVPacket packet;
av_init_packet(&packet);
packet.data = NULL;
packet.size = 0;
int16_t * outbuf = new int16_t[AVCODEC_MAX_AUDIO_FRAME_SIZE * 2];  //解码完一帧pcm缓冲区

//输出wav文件名
int index1 = strFileName.rfind('.');
string AudioName = strFileName.substr( 0, index1) + ".wav";
WavMaker test(AudioName.c_str());

int count = 0;
while(av_read_frame(pFormatCtx,&packet)>=0)//读取包
{          

	if(packet.stream_index==v_audio_index[0])//只解码第一条音频流
	{  
		uint8_t  *pktdata = packet.data;
		int      pktsize = packet.size;
		while (pktsize > 0)
		{  
			 int times=0;
			 int out_size =AVCODEC_MAX_AUDIO_FRAME_SIZE*2; 
			 int len = avcodec_decode_audio3(pAVCodecCtx, (short *)outbuf, &out_size, &packet);
			 if (len < 0)
			 {
			   fprintf(stderr, "Error while decoding\n");
			   break;
			 }
			 if (out_size > 0)
			 {   
			   test.writebody((uint8_t*)outbuf,out_size); //解码后的数据写入文件    
			   break; 
			 }
			 pktsize -= len;
			 pktdata += len;                
		}
	}
	av_free_packet(&packet);//释放packet
}

test.writeheader(pAVCodecCtx->channels,pAVCodecCtx->sample_rate);//写wav头
test.closeFile();//关闭文件

 

转载于:https://www.cnblogs.com/welen/p/3666075.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值