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

ffmpeg 视频格式转换后没有声音,该怎么解决

2013-10-21 
ffmpeg 视频格式转换后没有声音int main(int argc,char **argv){const char *input_file_nameE://testda

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


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


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

热点排行