2 tgh5330992 tgh5330992 于 2016.09.07 18:38 提问

ffmpeg合成MP4格式视频 3C

入手ffmpeg大概2周时间,在H264和aac合成MP4文件遇到一个问题,MP4文件使用QQ影音播放没有声音,使用VLC播放有声音,
我在程序里面打印
AVOutputFormat *audio_codec = ofmt_ctx->oformat;
if(audio_codec->audio_codec == AV_CODEC_ID_AAC)
{

printf("TAG----%d---%d--%d\n", st->codec->sample_rate, st->codec->channels,st->codec->sample_fmt);

if(st->codec->codec_id == AV_CODEC_ID_AAC)
printf("aac-------------------\n");
}
else
{

printf("NO AAC\n");
}
显示的格式为aac 采样率为44100 及bit为8,都是正确的,请教下大神这是什么原因造成的?

下面为源码部分 开发环境为ffmpeg3.0.2,linux 折腾了2周 ,还是没有进展

#include

#define __STDC_CONSTANT_MACROS

#include

/*
FIX: H.264 in some container format (FLV, MP4, MKV etc.) need
"h264_mp4toannexb" bitstream filter (BSF)
*Add SPS,PPS in front of IDR frame
*Add start code ("0,0,0,1") in front of NALU
H.264 in some container (MPEG2TS) don't need this BSF.
*/
//'1': Use H.264 Bitstream Filter
#define USE_H264BSF 0

/*
FIX:AAC in some container format (FLV, MP4, MKV etc.) need
"aac_adtstoasc" bitstream filter (BSF)
*/
//'1': Use AAC Bitstream Filter
#define USE_AACBSF 1

int main(int argc, char* argv[])
{
AVOutputFormat *ofmt = NULL;
//Input AVFormatContext and Output AVFormatContext
AVFormatContext *ifmt_ctx_v = NULL, *ifmt_ctx_a = NULL,*ofmt_ctx = NULL;
AVPacket pkt;
int ret, i;
int videoindex_v=-1,videoindex_out=-1;
int audioindex_a=-1,audioindex_out=-1;
int frame_index=0;
int64_t cur_pts_v=0,cur_pts_a=0;

//const char *in_filename_v = "cuc_ieschool.ts";//Input file URL
const char *in_filename_v = "22.h264";
//const char *in_filename_a = "cuc_ieschool.mp3";
//const char *in_filename_a = "gowest.m4a";
const char *in_filename_a = "22.aac";
//const char *in_filename_a = "huoyuanjia.mp3";

const char *out_filename = "22.mp4";//Output file URL
av_register_all();
//Input
#if 1
if ((ret = avformat_open_input(&ifmt_ctx_v, in_filename_v, 0, 0)) < 0) {
printf( "Could not open input file.");
goto end;
}
if ((ret = avformat_find_stream_info(ifmt_ctx_v, 0)) < 0) {
printf( "Failed to retrieve input stream information");
goto end;
}
#endif
if ((ret = avformat_open_input(&ifmt_ctx_a, in_filename_a, 0, 0)) < 0) {
printf( "Could not open input file.");
goto end;
}
if ((ret = avformat_find_stream_info(ifmt_ctx_a, 0)) < 0) {
printf( "Failed to retrieve input stream information");
goto end;
}
printf("===========Input Information==========\n");
av_dump_format(ifmt_ctx_v, 0, in_filename_v, 0);
av_dump_format(ifmt_ctx_a, 0, in_filename_a, 0);
printf("======================================\n");
//Output
avformat_alloc_output_context2(&ofmt_ctx, NULL, NULL, out_filename);
if (!ofmt_ctx) {
printf( "Could not create output context\n");
ret = AVERROR_UNKNOWN;
goto end;
}
ofmt_ctx->oformat->video_codec = AV_CODEC_ID_H264;
ofmt_ctx->oformat->audio_codec = AV_CODEC_ID_AAC;
ofmt = ofmt_ctx->oformat;
#if 1
for (i = 0; i < ifmt_ctx_v->nb_streams; i++) {
//Create output AVStream according to input AVStream
if(ifmt_ctx_v->streams[i]->codec->codec_type==AVMEDIA_TYPE_VIDEO){
AVStream *in_stream = ifmt_ctx_v->streams[i];
AVStream *out_stream = avformat_new_stream(ofmt_ctx, in_stream->codec->codec);
videoindex_v=i;
if (!out_stream) {
printf( "Failed allocating output stream\n");
ret = AVERROR_UNKNOWN;
goto end;
}
videoindex_out=out_stream->index;
//Copy the settings of AVCodecContext
if (avcodec_copy_context(out_stream->codec, in_stream->codec) < 0) {
printf( "Failed to copy context from input to output stream codec context\n");
goto end;
}
out_stream->codec->codec_tag = 0;
if (ofmt_ctx->oformat->flags & AVFMT_GLOBALHEADER)
out_stream->codec->flags |= CODEC_FLAG_GLOBAL_HEADER;
break;
}
}
#endif
for (i = 0; i < ifmt_ctx_a->nb_streams; i++) {
//Create output AVStream according to input AVStream
if(ifmt_ctx_a->streams[i]->codec->codec_type==AVMEDIA_TYPE_AUDIO){
AVStream *in_stream = ifmt_ctx_a->streams[i];
AVStream *out_stream = avformat_new_stream(ofmt_ctx, in_stream->codec->codec);
// add_stream(OutputStream * ost, AVFormatContext * oc, AVCodec * * codec, enum AVCodecID codec_id)
audioindex_a=i;
if (!out_stream) {
printf( "Failed allocating output stream\n");
ret = AVERROR_UNKNOWN;
goto end;
}
audioindex_out=out_stream->index;
//Copy the settings of AVCodecContext
if (avcodec_copy_context(out_stream->codec, in_stream->codec) < 0) {
printf( "Failed to copy context from input to output stream codec context\n");
goto end;
}
out_stream->codec->codec_tag = 0;
if (ofmt_ctx->oformat->flags & AVFMT_GLOBALHEADER)
out_stream->codec->flags |= CODEC_FLAG_GLOBAL_HEADER;

break;
}
}

printf("==========Output Information==========\n");
av_dump_format(ofmt_ctx, 0, out_filename, 1);
printf("======================================\n");
//Open output file
if (!(ofmt->flags & AVFMT_NOFILE)) {
if (avio_open(&ofmt_ctx->pb, out_filename, AVIO_FLAG_WRITE) < 0) {
printf( "Could not open output file '%s'", out_filename);
goto end;
}
}
//Write file header
if (avformat_write_header(ofmt_ctx, NULL) < 0) {
printf( "Error occurred when opening output file\n");
goto end;
}

//FIX
#if USE_H264BSF
AVBitStreamFilterContext* h264bsfc = av_bitstream_filter_init("h264_mp4toannexb");
#endif
#if USE_AACBSF
AVBitStreamFilterContext* aacbsfc = av_bitstream_filter_init("aac_adtstoasc");
#endif

while (1) {
AVFormatContext *ifmt_ctx;
int stream_index=0;
AVStream *in_stream, *out_stream;

//Get an AVPacket
#if 1
if(av_compare_ts(cur_pts_v,ifmt_ctx_v->streams[videoindex_v]->time_base,cur_pts_a,ifmt_ctx_a->streams[audioindex_a]->time_base) <= 0){
ifmt_ctx=ifmt_ctx_v;
stream_index=videoindex_out;

if(av_read_frame(ifmt_ctx, &pkt) >= 0){
do{
in_stream = ifmt_ctx->streams[pkt.stream_index];
out_stream = ofmt_ctx->streams[stream_index];

if(pkt.stream_index==videoindex_v){
//FIX:No PTS (Example: Raw H.264)
//Simple Write PTS
if(pkt.pts==AV_NOPTS_VALUE){
//Write PTS
AVRational time_base1=in_stream->time_base;
//Duration between 2 frames (us)
int64_t calc_duration=(double)AV_TIME_BASE/av_q2d(in_stream->r_frame_rate);
//Parameters
pkt.pts=(double)(frame_index*calc_duration)/(double)(av_q2d(time_base1)*AV_TIME_BASE);
pkt.dts=pkt.pts;
pkt.duration=(double)calc_duration/(double)(av_q2d(time_base1)*AV_TIME_BASE);
frame_index++;
}

cur_pts_v=pkt.pts;
break;
}
}while(av_read_frame(ifmt_ctx, &pkt) >= 0);
}else{
break;
}
}else
#endif
{
ifmt_ctx=ifmt_ctx_a;
stream_index=audioindex_out;
if(av_read_frame(ifmt_ctx, &pkt) >= 0){
do{
in_stream = ifmt_ctx->streams[pkt.stream_index];
out_stream = ofmt_ctx->streams[stream_index];

if(pkt.stream_index==audioindex_a){

//FIX:No PTS
//Simple Write PTS
if(pkt.pts==AV_NOPTS_VALUE){
//Write PTS
AVRational time_base1=in_stream->time_base;
//Duration between 2 frames (us)
int64_t calc_duration=(double)AV_TIME_BASE/av_q2d(in_stream->r_frame_rate);
//Parameters
pkt.pts=(double)(frame_index*calc_duration)/(double)(av_q2d(time_base1)*AV_TIME_BASE);
pkt.dts=pkt.pts;
pkt.duration=(double)calc_duration/(double)(av_q2d(time_base1)*AV_TIME_BASE);
frame_index++;
}
cur_pts_a=pkt.pts;

break;
}
}while(av_read_frame(ifmt_ctx, &pkt) >= 0);
}else{
break;
}

}

//FIX:Bitstream Filter
#if USE_H264BSF
av_bitstream_filter_filter(h264bsfc, in_stream->codec, NULL, &pkt.data, &pkt.size, pkt.data, pkt.size, 0);
#endif
#if USE_AACBSF
av_bitstream_filter_filter(aacbsfc, out_stream->codec, NULL, &pkt.data, &pkt.size, pkt.data, pkt.size, 0);
#endif

//Convert PTS/DTS
pkt.pts = av_rescale_q_rnd(pkt.pts, in_stream->time_base, out_stream->time_base, (enum AVRounding)(AV_ROUND_NEAR_INF|AV_ROUND_PASS_MINMAX));
pkt.dts = av_rescale_q_rnd(pkt.dts, in_stream->time_base, out_stream->time_base, (enum AVRounding)(AV_ROUND_NEAR_INF|AV_ROUND_PASS_MINMAX));
pkt.duration = av_rescale_q(pkt.duration, in_stream->time_base, out_stream->time_base);
pkt.pos = -1;
pkt.stream_index=stream_index;

printf("Write 1 Packet. size:%5d\tpts:%lld\n",pkt.size,pkt.pts);
//Write
if (av_interleaved_write_frame(ofmt_ctx, &pkt) < 0) {
printf( "Error muxing packet\n");
break;
}
av_free_packet(&pkt);

}
//Write file trailer
av_write_trailer(ofmt_ctx);

#if USE_H264BSF
av_bitstream_filter_close(h264bsfc);
#endif
#if USE_AACBSF
av_bitstream_filter_close(aacbsfc);
#endif

end:
avformat_close_input(&ifmt_ctx_v);
avformat_close_input(&ifmt_ctx_a);
/* close output */
if (ofmt_ctx && !(ofmt->flags & AVFMT_NOFILE))
avio_close(ofmt_ctx->pb);
avformat_free_context(ofmt_ctx);
if (ret < 0 && ret != AVERROR_EOF) {
printf( "Error occurred.\n");
return -1;
}
return 0;
}

1个回答

devmiao
devmiao   Ds   Rxr 2016.09.07 23:00
tgh5330992
tgh5330992 我使用编译出来的ffmpeg,执行指令./ffmpeg -i 22.264 -i 22.aac 22.mp4,这样合出来的是有声音的,但是我使用相同版本的库和头文件编译上述代码没有声音,现在不能定位原因在哪里,因为现在我使用mp4分析软件查看时有音频的trak的
接近 2 年之前 回复
Csdn user default icon
上传中...
上传图片
插入图片
准确详细的回答,更有利于被提问者采纳,从而获得C币。复制、灌水、广告等回答会被删除,是时候展现真正的技术了!
其他相关推荐
FFMpeg 常用命令格式转换,视频合成
FFmpeg都是命令行的,用起来肯定不方便。但是,这对技术宅应该不成问题。下面,我就罗列一些比较实用的使用方法吧。 FFmpeg的下载与安装 FFmpeg是开源的。但我们不必去下载它的源代码。下载已经编译好的exe/dll即可。可以到http://www.ffmpeg.org/download.html,然后点击“Windows Builds”,再根据你当前的机器是32位还是64位来决
下载视频流M4S并合成MP4
1、使用文件连接命令(windows是type,linux是cat)将所有分段合成一个m4s文件。 2、利用 ffmpeg 进行音视频合成、格式转换
FFmpeg合成h264视频流和aac音频流为mp4
[备份使用,尚未优化代码] #include "MyMuxerToMP4.h" #include #include #include /*  FIX: H.264 in some container format (FLV, MP4, MKV etc.) need  "h264_mp4toannexb" bit
ffmpeg合并mp4视频
ffmpeg -i 1.mp4 -vcodec copy -acodec copy -vbsf h264_mp4toannexb 1.ts   ffmpeg -i 2.mp4 -vcodec copy -acodec copy -vbsf h264_mp4toannexb 2.ts   ffmpeg -i "concat:1.ts|2.ts" -acodec copy -vcodec copy
ffmpeg之多个MP4视频合并一个MP4视频文件(附遇见的bug)
准备材料:两张jpg照片、两个MP3 首先将两张照片和MP3文件合并为两个MP4视频文件。 照片的地址分别为:/home/ffmpeg_data/001.jpg、/home/ffmpeg_data/002.jpg MP3文件地址:/home/ffmpeg_data/001.mp3、/home/ffmpeg_data/002.mp3 在/home/ffmpeg_data/路径下执行:ffmp
ios ffmpeg 保存mp4
废话不说,直接上代码: header写入成功: -(void) init_mp4saving:(AVFormatContext*) pFormatCtx videoStreamin:(int) videoStream savenamein:(NSString *)savename {          i_video_stream=pFormatCtx->streams[video
ffmpeg: 合并/合并多个mp4视频不工作
ffmpeg: 合并/合并多个mp4视频不工作 必须将它们转换为一个易于连接的MPEG格式。 下面是一个我使用的脚本,并调用"ffcat"作为GoPro视频。 它实际上运行几个"ffmpeg -i"命令,这些命令产生 concatenate-able MPEG,它被管道转换成一个ffmpeg命令,然后将它们转换成一个 H.264 mp4文件。 它还将视频大小调整为 720,但你可能
ffmpeg 合并 拼接 mp4视频
今天同事做字幕识别测试,其中360p的视频是直接从CNTV网上下载的,一套好好接的节目被切成9段、10段,为测试带来了一点小的麻烦;   所以今天想着用ffmpeg拼接一下这些视频;   需求如下: 1.mp4 2.mp4 … 封装成 combine.mp4   我对各种封装格式还不是很了解,因为之前被坑过,大概知道mp4封装会在一个地方声明duration,因此,如果从数据层面直接
H264+PCM文件
这里面包含测试需要用到的H264码流和pcm的音频数据,本人测试过这些数据,是ok的,分享给需哟测试数据的朋友们。
ffmpeg将h264和aac合成ts,内存输入输出
在内存中读取h264视频和aac音频,在内存中输出ts AVOutputFormat *ofmt = NULL; //Input AVFormatContext and Output AVFormatContext AVFormatContext *ifmt_ctx_v = NULL, *ifmt_ctx_a = NULL,*ofmt_ctx = NULL; AVPacket pkt;