• 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("打开文件失败
    ");
    	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!
    ");
    	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
    ");
    			   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();//关闭文件
    
  • 相关阅读:
    实例告诉你如何把 if-else 重构成高质量代码!
    Java8 快速实现List转map 、分组、过滤等操作
    大学四年Java学习路线规划,所有私藏资料我都贡献出来了!
    Redis面试题汇总(附答案),面试突击专用
    代码优化大盘点:35 个 Java 代码优化魔鬼细节
    ES6+Webpack+Babel基本环境搭建
    抽象类和接口的异同及实例解析
    .NET ORM 哪家强
    Asp.Net 高性能ORM框架 SqlSugar.ORM 2.8
    ASP.NET 让无码编程不在是梦 -.NET通用平台、通用权限、易扩展、多语言、多平台架构框架
  • 原文地址:https://www.cnblogs.com/welen/p/3666075.html
Copyright © 2020-2023  润新知