首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > C语言 >

音频转换后,时间长度从20秒变成了2秒,该如何处理

2012-02-21 
音频转换后,时间长度从20秒变成了2秒最近正在学习ffmpeg,打算从音频转换学起,下边是写的一段转换音频的代

音频转换后,时间长度从20秒变成了2秒
最近正在学习ffmpeg,打算从音频转换学起,下边是写的一段转换音频的代码。
把一个wav的音频转换成mp3后,原来20秒的音频只有2秒了。音频的内容从头到尾都是有的,就是速度变快了,应该是一些帧被抛弃了。
初学ffmpeg,搞了好长时间还是不知道是什么原因,请大家帮忙参谋参谋。这里先谢谢了。

下边是代码:

//   使用的是vc2003
void   CAudio::OnBtnAudioConvert()  
{
//   TODO:   Add   your   control   notification   handler   code   here
CString   str;
GetDlgItem(IDC_EDIT_FILENAME)-> GetWindowText(str);
if   (str== " ")
{
    MessageBox( "请选择一个有效的视频文件。 ",_T( "提示 "),MB_ICONINFORMATION);
    return;
}
AVFormatContext   *pFormatCtx;
        int                           i,   audioStream;
        AVCodecContext     *pCodecCtx;
        AVCodec                   *pCodec;
        AVPacket                 packet;
        int                           frameFinished;
        int                           numBytes;
        const   char   *filename   =str;
/*   must   be   called   before   using   avcodec   lib   */
avcodec_init();
        //   注册所有的格式和编解码器
        av_register_all();

        //   Open   audio   file
        if(av_open_input_file(&pFormatCtx,   filename,   NULL,   0,   NULL)!=0)
{
    m_ListAudioInfo.AddString( "无法打开文件: "+str);
                return   ;  
}
        //   Retrieve   stream   information
        if(av_find_stream_info(pFormatCtx) <0)
        {
    m_ListAudioInfo.AddString( "无法在该文件中找到音频流... ");
                return   ;  
}
        audioStream=-1;
        for(i=0;   i <pFormatCtx-> nb_streams;   i++)
                if(pFormatCtx-> streams-> codec-> codec_type==CODEC_TYPE_AUDIO)
                {
                        audioStream=i;
                        break;
                }
        if(audioStream==-1)
                return;   //   Didn 't   find   a   audio   stream
        //   Get   a   pointer   to   the   codec   context   for   the   audio   stream
        pCodecCtx=pFormatCtx-> streams[audioStream]-> codec;
        //   Find   the   decoder   for   the   audio   stream
        pCodec=avcodec_find_decoder(pCodecCtx-> codec_id);



        if(pCodec==NULL)
                return;   //   Codec   not   found
        //   Open   codec
        if(avcodec_open(pCodecCtx,   pCodec) <0)
                return;   //   Could   not   open   codec
        //   --------------------------   输出文件   -----------------------------
AVFormatContext   *pOutFormatCtx;
AVOutputFormat   *fmt;
AVStream   *audio_st;
char   *outputfile   =   "c:\\light_wave.mp3 ";
//     根据文件名的后缀,猜测文件格式
fmt   =   guess_format(NULL,   outputfile,   NULL);
if   (!fmt)  
        {
                fprintf(stderr,   "Could   not   find   suitable   output   format\n ");
                exit(1);
        }
   
        /*   allocate   the   output   media   context   */
        pOutFormatCtx   =   av_alloc_format_context();
        if   (!pOutFormatCtx)  
        {
                fprintf(stderr,   "Memory   error\n ");
                exit(1);
        }
        pOutFormatCtx-> oformat   =   fmt;

/*   set   the   output   parameters   (must   be   done   even   if   no
              parameters).   */
//AVFormatParameters   ap;
//ap.sample_rate   =;
        //if   (av_set_parameters(oc,   &ap)   <   0)   {    
if   (fmt-> audio_codec!=CODEC_ID_NONE)
      audio_st   =av_new_stream(pOutFormatCtx,fmt-> audio_codec);//add_audio_stream(oc,   fmt-> audio_codec);
        //dump_format(oc,   0,   outputfile,   1);
        avcodec_get_context_defaults(audio_st-> codec);
/******   Open   the   audio   ***********/
        AVCodecContext   *c;
        AVCodec   *codec;
c=avcodec_alloc_context();
        c   =   audio_st-> codec;
c-> codec_id   =pOutFormatCtx-> oformat-> audio_codec;
c-> codec_type   =CODEC_TYPE_AUDIO;
c-> bit_rate   =pCodecCtx-> bit_rate;
c-> sample_rate   =pCodecCtx-> sample_rate;
c-> channels   =pCodecCtx-> channels;
if   (av_set_parameters(pOutFormatCtx,   NULL)   <   0)  
{
                fprintf(stderr,   "Invalid   output   format   parameters\n ");
                exit(1);
        }


        /*   查找音频编码器*/
        codec   =   avcodec_find_encoder(c-> codec_id);
        if   (!codec)   {
                fprintf(stderr,   "codec   not   found\n ");


                exit(1);
        }
        //   打开输出编解码器
        if   (avcodec_open(c,   codec)   <   0)  
        {
                fprintf(stderr,   "could   not   open   codec\n ");
                exit(1);
        }
/******   Open   the   audio   ***********/
        /*   open   the   output   file,   if   needed*/
        if   (!(fmt-> flags   &   AVFMT_NOFILE))  
{
                if   (url_fopen(&pOutFormatCtx-> pb,   outputfile,   URL_WRONLY)   <   0)   {
                        fprintf(stderr,   "Could   not   open   '%s '\n ",   outputfile);
                        exit(1);
                }
        }

/*   写文件头*/
        av_write_header(pOutFormatCtx);
/***   Write   audio   into   file   ******/
AVPacket   pkt;
av_init_packet(&pkt);
av_init_packet(&packet);
numBytes   =   10000;
        short   *buffer   =NULL;//   (short*)   malloc(AVCODEC_MAX_AUDIO_FRAME_SIZE);
uint8_t   *outbuf   =(uint8_t*)   malloc(numBytes);
static   unsigned   int   buffer_size=0;

//     开始逐帧读取音频
        while(av_read_frame(pFormatCtx,   &packet)> =0)
        {
                //   Is   this   a   packet   from   the   audio   stream?
                if(packet.stream_index==audioStream)
                {
      if   (&packet)
        buffer   =(short*)av_fast_realloc(buffer,&buffer_size,FFMAX(packet.size*sizeof(*buffer),AVCODEC_MAX_AUDIO_FRAME_SIZE));
            frameFinished   =buffer_size;
      avcodec_decode_audio(pCodecCtx,   buffer,   &frameFinished,   packet.data,   packet.size);
     
      //   Did   we   get   a   audio   frame?
      if(frameFinished)  
      {
        /*   encode   the   samples   */
        pkt.size=   avcodec_encode_audio(c,   outbuf,   packet.size,   buffer);    
        pkt.pts=   av_rescale_q(c-> coded_frame-> pts,   c-> time_base,   audio_st-> time_base);
        pkt.flags   |=   PKT_FLAG_KEY;
        pkt.stream_index   =audioStream;
        pkt.data=   outbuf;
        /*   write   the   compressed   frame   in   the   media   file   */


        if   (av_write_frame(pOutFormatCtx,   &pkt)   !=   0)  
              {
          fprintf(stderr,   "Error   while   writing   audio   frame\n ");
          exit(1);
        }
      }
                }
                //   Free   the   packet   that   was   allocated   by   av_read_frame
                av_free_packet(&packet);
    av_free_packet(&pkt);
        }

        /*   写文件尾*/
av_write_trailer(pOutFormatCtx);

        for(i   =   0;   i   <   pOutFormatCtx-> nb_streams;   i++)   {
                av_freep(&pOutFormatCtx-> streams-> codec);
                av_freep(&pOutFormatCtx-> streams);
        }
        if   (!(fmt-> flags   &   AVFMT_NOFILE))   {
                /*   close   the   output   file   */
                url_fclose(&pOutFormatCtx-> pb);
        }
        /*   free   the   stream   */
        av_free(pOutFormatCtx);

        //   Close   the   codec
        avcodec_close(pCodecCtx);
        //   Close   the   video   file
        av_close_input_file(pFormatCtx);
}



[解决办法]
我最近也在研究ffmpeg ,你的ar参数有没有设置正确呀。你先看下你的wav的采样频率是多少。然后设置ar参数。
如果你的wav采样为8000 则为-ar 8000 .纯粹支持呵呵!
[解决办法]
查一下pcm流的采样率,要和MP3编码的采样率对得上,如果象你说的是变快了,就是pcm得采样率小于mp3编码需要的pcm流的采样率

比如pcm的采样率是8K,而你mp3编码器设定原始pcm数据流为48K,这样编出来的mp3就短了6倍

热点排行