读书人

ffmpeg 视频格式变换后没有声音

发布时间: 2012-09-16 17:33:17 作者: rapoo

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后,图像还有,但声音没有了,请问这个问题怎么解决?



[解决办法]
楼主代码写的不错。
音频的解码可能有问题,不是很清楚,帮楼主顶下

读书人网 >C语言

热点推荐