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

NetMatrix 2012-07-27 03:05:20

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

...全文
1319 5 打赏 收藏 转发到动态 举报
写回复
用AI写文章
5 条回复
切换为时间正序
请发表友善的回复…
发表回复
baidu_25293573 2015-01-13
  • 打赏
  • 举报
回复
大虾,你用的是哪个版本的ffmpeg,我在官网下的2011-06-03的,调试时打开音频编码器失败啊。
GFDSAGHFDASH 2013-10-09
  • 打赏
  • 举报
回复
oAcc = avcodec_alloc_context(); oAcc = audio_st->codec;这里是不是有问题哦,改成audio_st->codec=oAcc;试一下
NetMatrix 2012-07-27
  • 打赏
  • 举报
回复
不是我写的代码,在一个网站上看到的,稍微修改下拿来用了,但是音频部分还有点问题
南气子水 2012-07-27
  • 打赏
  • 举报
回复
楼主代码写的不错。
音频的解码可能有问题,不是很清楚,帮楼主顶下

69,371

社区成员

发帖
与我相关
我的任务
社区描述
C语言相关问题讨论
社区管理员
  • C语言
  • 花神庙码农
  • 架构师李肯
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧