ffmpeg实现转码一个普通视频文件为视频mpeg4,音频mp3的

    • http://www.roarsoft.net/a/Media/Codec/201009/10193.html
    • #include <avcodec.h> 
    • #include <avformat.h> 
    • #include <stdio.h> 
    • #include <avutil.h> 
    • #include <stdio.h> 
    • #include <stdlib.h> 
    • #include <string.h> 
    •  
    • main(int argc,char **argv) 
    • {    
    •   const char *input_file_name="/root/movies/ddh1.mpg"; 
    •   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<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); 
    •   }//打开该音频解码器 
    • //下面为输出文件处理部分 
    •     const char *output_file_name="/root/123.avi"; 
    •     AVOutputFormat *fmt; 
    •     AVFormatContext *oc; 
    •     AVCodecContext *oVcc,*oAcc; 
    •     AVCodec *oVc,*oAc; 
    •     AVStream *video_st,*audio_st; 
    •     AVFrame *oVFrame,*oAFrame; 
    •     double video_pts; 
    •     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; 
    •     pstrcpy(oc->filename,sizeof(oc->filename),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_MPEG4; 
    •     oVcc->codec_type=CODEC_TYPE_VIDEO; 
    •     oVcc->bit_rate=2500000; 
    •     oVcc->width=704; 
    •     oVcc->height=480; 
    •     oVcc->time_base=vCodecCtx->time_base; 
    •     oVcc->gop_size=vCodecCtx->gop_size; 
    •     //oVcc->pix_fmt=vCodecCtx->pix_fmt; 
    •     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; 
    •     audio_st=av_new_stream(oc,oc->nb_streams); 
    •     if(!audio_st) 
    •     { 
    • printf("could not alloc audio stream\n"); 
    •            exit(0); 
    •     }   
    •     avcodec_get_context_defaults2(audio_st->codec,CODEC_TYPE_AUDIO); 
    •     oAcc=avcodec_alloc_context(); 
    •     oAcc=audio_st->codec; 
    •     oAcc->codec_id=CODEC_ID_MP3; 
    •     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_MPEG4); 
    •     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_MP3); 
    •     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(url_exist(output_file_name)) 
    •     { 
    • printf("file %s exist,please select other\n",output_file_name); 
    •        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,*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=400000; 
    •   video_outbuf= (unsigned char *) malloc(video_outbuf_size); 
    •   audio_outbuf_size = 10000; 
    •   audio_outbuf = av_malloc(audio_outbuf_size); 
    •   int flag;int frameFinished;int len;int frame_index=0,ret; 
    • 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)                                        
  1. pkt.flags |= PKT_FLAG_KEY;                                         
  2. pkt.flags = packet.flags;                       
  3. pkt.stream_index= video_st->index;                                                
  4. pkt.data= video_outbuf;                                                          
  5. pkt.size= out_size;                                              
  6. ret=av_write_frame(oc, &pkt);                                        
  7.              frame_index++; 
  8.          } 
  9.          else 
  10.              ret=av_write_frame(oc, &packet);  
  11. if(ret!=0) 
  12. printf("while write video frame error\n"); 
  13. exit(0); 
  14.       else if(packet.stream_index==audioindex) 
  15.       { 
  16. len=packet.size; 
  17. ptr=packet.data; 
  18. int ret=0; 
  19. while(len>0) 
  20. out_buf=NULL; 
  21. out_size=0; 
  22. if(&packet) 
  23. samples=av_fast_realloc(samples,&samples_size,
  24. FFMAX(packet.size*sizeof(*samples),
  25. AVCODEC_MAX_AUDIO_FRAME_SIZE)); 
  26. out_size=samples_size; 
  27. ret=avcodec_decode_audio(aCodecCtx,samples,&out_size,ptr,len);
  28. if(ret<0) 
  29. printf("while decode audio failure\n"); 
  30. exit(0); 
  31. fflush(stdout); 
  32. ptr+=ret; 
  33. len-=ret; 
  34. if(out_size<=0)  continue; 
  35. out_buf=(uint8_t *)samples; 
  36. AVPacket pkt; 
  37. av_init_packet(&pkt); 
  38. pkt.size= avcodec_encode_audio(oAcc, audio_outbuf, audio_outbuf_size, out_buf); 
  39. pkt.pts= av_rescale_q(oAcc->coded_frame->pts, oAcc->time_base, audio_st->time_base); 
  40. pkt.flags |= PKT_FLAG_KEY; 
  41. pkt.stream_index= audioindex; 
  42. pkt.data= audio_outbuf; 
  43. if (av_write_frame(oc, &pkt) != 0)  
  44. fprintf(stderr, "Error while writing audio frame\n"); 
  45. exit(1); 
  46. }  
  47. av_free_packet(&packet); 
  48. }  
  49. av_write_trailer(oc); 
  50. for(i = 0; i < oc->nb_streams; i++)  
  51. {             
  52.   av_freep(&oc->streams[i]->codec);                        
  53.   av_freep(&oc->streams[i]);                            
  54. url_fclose(oc); 
  55. av_free(oc); 
  56. av_free(oVFrame); 
  57. av_free(out_buf); 
  58. avcodec_close(vCodecCtx); 
  59. avcodec_close(aCodecCtx); 
  60. av_close_input_file(ic); 
  61. }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值