//初始化、註冊編解碼器 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();//關閉文件