生成原始PCM数据
#include <stdio.h>
#include <stdlib.h>
#include <libavcodec/avcodec.h>
#include <libavformat/avformat.h>
#include <libavutil/avutil.h>
#include <libswscale/swscale.h>
#include <libswresample/swresample.h>
int main(){
char* fileName = "./jichi.mp4";
char* outFile = "./jichi.pcm";
AVFormatContext* avf_cxt = NULL;
av_register_all();
int ret = avformat_open_input(&avf_cxt,fileName,NULL,NULL);
if(ret < 0){
printf("文件地址错误 %s \n",fileName);
return -1;
}
ret = avformat_find_stream_info(avf_cxt,NULL);
if(ret < 0){
printf("不能获取到文件多媒体信息 %s \n",fileName);
goto _end;
}
av_dump_format(avf_cxt,0,fileName,0);
int audio_index = -1;
for(int i = 0; i < avf_cxt->nb_streams;i++){
if( avf_cxt->streams[i]->codec->codec_type == AVMEDIA_TYPE_AUDIO){
audio_index = i;
break;
}
}
if(audio_index == -1){
printf("没有找到文件中的音频流 \n");
goto _end;
}
AVCodecContext *avc_cxt = avf_cxt->streams[audio_index]->codec;
AVCodec *avcodec = avcodec_find_decoder(avc_cxt->codec_id);
if(avcodec == NULL){
printf("不能得到音频的解码器 \n");
goto _end;
}
ret = avcodec_open2(avc_cxt,avcodec,NULL);
if(ret < 0){
printf("不能打开解码器");
goto _end;
}
AVPacket *avp = av_packet_alloc();
AVFrame *avf = av_frame_alloc();
SwrContext* swr_cxt = swr_alloc();
enum AVSampleFormat in_sample_fmt = avc_cxt->sample_fmt;
enum AVSampleFormat out_sample_fmt = AV_SAMPLE_FMT_S16;
int in_sample_rate = avc_cxt->sample_rate;
int out_sample_rate = 44100;
uint64_t in_ch_layout = avc_cxt->channel_layout;
uint64_t out_ch_layout = AV_CH_LAYOUT_MONO;
swr_alloc_set_opts(swr_cxt,out_ch_layout,out_sample_fmt,out_sample_rate,in_ch_layout,in_sample_fmt,in_sample_rate,0,NULL);
swr_init(swr_cxt);
int out_channel_nb = av_get_channel_layout_nb_channels(out_ch_layout);
uint8_t *out_buf = (uint8_t*)av_malloc(2*44100);
FILE *fb_out = fopen(outFile,"wb+");
int got_frame, frame_count = 0;
while(av_read_frame(avf_cxt,avp) >= 0){
if(avp->stream_index == audio_index){
ret = avcodec_decode_audio4(avc_cxt,avf,&got_frame,avp);
if(ret < 0){
av_log(NULL,AV_LOG_INFO,"解码完成 \n");
}
if(got_frame != 0){
swr_convert(swr_cxt , &out_buf , 2 * 44100 , avf->data , avf->nb_samples);
int out_buf_size = av_samples_get_buffer_size(NULL,out_channel_nb,avf->nb_samples,out_sample_fmt,1);
fwrite(out_buf,1,out_buf_size,fb_out);
}
}
av_free_packet(avp);
}
_end:
fclose(fb_out);
av_frame_free(&avf);
av_free(out_buf);
swr_free(&swr_cxt);
avcodec_close(avc_cxt);
avformat_free_context(avf_cxt);
return 0;
}