ffmpeg 视频格式转换后没有声音
- C/C++ code
int main(int argc,char **argv){ const char *input_file_name="E://testdata//94.ts"; const char *output_file_name="E://testdata//94.avi"; av_register_all(); //输入文件处理部分 AVFormatContext *ic; ic=av_alloc_format_context(); //打开输入文件 if(av_open_input_file(&ic,input_file_name,NULL,0,NULL)!=0) { printf("can't open the file %s\n",input_file_name); exit(1); } //取出流信息 if(av_find_stream_info(ic)<0) { printf("can't find suitable codec parameters\n"); exit(1); } //列出输入文件的相关流信息 dump_format(ic,0,input_file_name,0); int i; int videoindex=-1; int audioindex=-1; for(i=0;i<(int)ic->nb_streams;i++) { if(ic->streams[i]->codec->codec_type==CODEC_TYPE_VIDEO) { videoindex=i; } else if(ic->streams[i]->codec->codec_type==CODEC_TYPE_AUDIO) { audioindex=i; } } if(videoindex==-1) { printf("can't find video stream\n"); exit(1); } AVCodecContext *vCodecCtx; vCodecCtx=ic->streams[videoindex]->codec;//取得视频流编码上下文指针 AVCodec *vCodec; //列出输入文件的相关流信息 vCodec=avcodec_find_decoder(vCodecCtx->codec_id); if(vCodec==NULL) { printf("can't find suitable video decoder\n"); exit(1); } //打开该视频解码器 if(avcodec_open(vCodecCtx,vCodec)<0) { printf("can't open the video decoder\n"); exit(1); } if(audioindex==-1) { printf("can't find audio stream\n"); exit(1); } AVCodecContext *aCodecCtx; aCodecCtx=ic->streams[audioindex]->codec; AVCodec *aCodec; //找到合适的音频解码器 aCodec=avcodec_find_decoder(aCodecCtx->codec_id); if(aCodec==NULL) { printf("can't find suitable audio decoder\n"); exit(1); } //打开该音频解码器 if(avcodec_open(aCodecCtx,aCodec)<0) { printf("can't open the audio decoder\n"); exit(1); } //下面为输出文件处理部分 AVOutputFormat *fmt; AVFormatContext *oc; AVCodecContext *oVcc,*oAcc; AVCodec *oVc,*oAc; AVStream *video_st,*audio_st; AVFrame *oVFrame; oVFrame = avcodec_alloc_frame(); //判断是否可以判断输出文件的编码格式 fmt = guess_format(NULL,output_file_name,NULL); if(!fmt) { printf("could not deduce output format from outfile extension\n"); exit(0); } oc = av_alloc_format_context(); if(!oc) { printf("Memory error\n"); exit(0); } oc->oformat = fmt; snprintf(oc->filename,sizeof(oc->filename),"%s",output_file_name); video_st = av_new_stream(oc,0); if(!video_st) { printf("could not alloc video stream\n"); exit(0); } oVcc = avcodec_alloc_context(); oVcc = video_st->codec; oVcc->codec_id = CODEC_ID_H264; oVcc->codec_type = CODEC_TYPE_VIDEO; oVcc->bit_rate = vCodecCtx->bit_rate/2; oVcc->width = vCodecCtx->width; oVcc->height = vCodecCtx->height; oVcc->time_base = vCodecCtx->time_base; oVcc->gop_size = vCodecCtx->gop_size; oVcc->pix_fmt = vCodecCtx->pix_fmt; oVcc->max_b_frames = vCodecCtx->max_b_frames; video_st->r_frame_rate = ic->streams[videoindex]->r_frame_rate;// frame rate audio_st = av_new_stream(oc,1); if(!audio_st) { printf("could not alloc audio stream\n"); exit(0); } avcodec_get_context_defaults2(audio_st->codec,CODEC_TYPE_AUDIO);// do what oAcc = avcodec_alloc_context(); oAcc = audio_st->codec; oAcc->codec_id = CODEC_ID_AAC; oAcc->codec_type = CODEC_TYPE_AUDIO; oAcc->bit_rate = aCodecCtx->bit_rate; oAcc->sample_rate = aCodecCtx->sample_rate; oAcc->channels = 2; if (av_set_parameters(oc, NULL) < 0) { printf( "Invalid output format parameters\n"); exit(0); } //设置必要的输出参数 strcpy(oc->title,ic->title); strcpy(oc->author,ic->author); strcpy(oc->copyright,ic->copyright); strcpy(oc->comment,ic->comment); strcpy(oc->album,ic->album); oc->year = ic->year; oc->track = ic->track; strcpy(oc->genre,ic->genre); dump_format(oc,0,output_file_name,1);//列出输出文件的相关流信息 //找到合适的视频编码器 oVc = avcodec_find_encoder(CODEC_ID_H264); if(!oVc) { printf("can't find suitable video encoder\n"); exit(0); } //打开视频编码器 if(avcodec_open(oVcc,oVc) < 0) { printf("can't open the output video codec\n"); exit(0); } //找到合适的音频编码器 oAc = avcodec_find_encoder(CODEC_ID_AAC); if(!oAc) { printf("can't find suitable audio encoder\n"); exit(0); } //打开音频编码器 if(avcodec_open(oAcc,oAc) < 0) { printf("can't open the output audio codec"); exit(0); } if (!(oc->flags & AVFMT_NOFILE)) { if(url_fopen(&oc->pb,output_file_name,URL_WRONLY)<0) //打开输出文件 { printf("can't open the output file %s\n",output_file_name); exit(0); } } if(!oc->nb_streams) { fprintf(stderr,"output file dose not contain any stream\n"); exit(0); } if(av_write_header(oc)<0) { fprintf(stderr, "Could not write header for output file\n"); exit(1); } AVPacket packet; uint8_t *ptr; int16_t *out_buf; int out_size; static short *samples = NULL; static unsigned int samples_size = 0; uint8_t *video_outbuf,*audio_outbuf; int video_outbuf_size,audio_outbuf_size; video_outbuf_size = 1024000; video_outbuf = (unsigned char *) malloc(video_outbuf_size); audio_outbuf_size = 100000; audio_outbuf = (unsigned char *) malloc(audio_outbuf_size); int frameFinished,len,ret; int frame_index=0; while(av_read_frame(ic,&packet) >= 0)//从输入文件中读取一个包 { if(packet.stream_index == videoindex)//判断是否为当前视频流中的包 { len = avcodec_decode_video(vCodecCtx,oVFrame,&frameFinished,packet.data,packet.size);//若为视频包,解码该视频包 if(len < 0) { printf("Error while decoding\n"); exit(0); } if(frameFinished)//判断视频祯是否读完 { fflush(stdout); oVFrame->pts = av_rescale(frame_index,AV_TIME_BASE*(int64_t)oVcc->time_base.num,oVcc->time_base.den); oVFrame->pict_type = 0; out_size = avcodec_encode_video(oVcc, video_outbuf, video_outbuf_size, oVFrame); if (out_size > 0) { AVPacket pkt; av_init_packet(&pkt); if(oVcc->coded_frame && oVcc->coded_frame->key_frame) pkt.flags |= PKT_FLAG_KEY; pkt.flags = packet.flags; pkt.stream_index = video_st->index; pkt.data = video_outbuf; pkt.size = out_size; ret = av_write_frame(oc, &pkt); } frame_index++; } else { //ret = av_write_frame(oc,&packet); printf("......\n"); } } else if(packet.stream_index == audioindex) { len = packet.size; ptr = packet.data; int ret = 0; while(len > 0) { out_buf = NULL; out_size = 0; if(&packet) samples = (short *)av_fast_realloc(samples,&samples_size,FFMAX(packet.size*sizeof(*samples),AVCODEC_MAX_AUDIO_FRAME_SIZE)); out_size = samples_size; ret = avcodec_decode_audio(aCodecCtx,samples,&out_size,ptr,len);//若为音频包,解码该音频包 if(ret<0) { printf("error while decode audio\n"); exit(0); } fflush(stdout); ptr += ret; len -= ret; if(out_size <= 0) continue; out_buf = samples; AVPacket pkt; av_init_packet(&pkt); pkt.size = avcodec_encode_audio(oAcc, audio_outbuf, audio_outbuf_size, out_buf); pkt.pts = av_rescale_q(oAcc->coded_frame->pts, oAcc->time_base, audio_st->time_base); pkt.flags |= PKT_FLAG_KEY; pkt.stream_index = audioindex; pkt.data = audio_outbuf; if(av_write_frame(oc,&pkt) != 0) { fprintf(stderr,"Error while writing audio frame\n"); exit(1); } } } av_free_packet(&packet); } av_write_trailer(oc); for(i = 0; i < (int)oc->nb_streams; i++) { av_freep(&oc->streams[i]->codec); av_freep(&oc->streams[i]); }// url_fclose(oc); av_free(oc); av_free(oVFrame); av_free(out_buf); avcodec_close(vCodecCtx); avcodec_close(aCodecCtx); av_close_input_file(ic); return 0;}
代码如上,
交TS格式文件转换成AVI后,图像还有,但声音没有了,请问这个问题怎么解决?
[解决办法]
楼主代码写的不错。
音频的解码可能有问题,不是很清楚,帮楼主顶下