avformat_write_header在ffmepg中无法正常工作

时间:2017-03-23 10:49:23

标签: c ffmpeg video-streaming mp4 video-conversion

我正在使用FFMPEG进行mp4文件创建项目,我试图基于FFMPEG muxing转换视频数据包的流信息,重新编码代码,但转换成文件后报头被损坏。

/ *此代码使用设置流信息* /

AVFormatContext *input_context,*output_context;
    AVDictionary *opt;
   AVStream *out_stream;
   AVCodecContext *newcontext=NULL;
   out_stream= avformat_new_stream(output_context,NULL);
                newcontext = avcodec_alloc_context3(codec);
                newcontext->codec_id=Output_fmt->video_codec;
                newcontext->bit_rate =in_stream->codec->bit_rate;
                newcontext->width    = in_stream->codec->width;
                newcontext->height   = in_stream->codec->height;
                newcontext->timecode_frame_start=in_stream->codec->timecode_frame_start;
                newcontext->gop_size      = in_stream->codec->gop_size;
                newcontext->profile       =  in_stream->codec->profile;
                newcontext->level         =in_stream->codec->level;
                newcontext->pix_fmt       = PIX_FMT_YUV420P;
                newcontext->frame_size=in_stream->codec->frame_size;
                newcontext->sample_fmt=in_stream->codec->sample_fmt;
                newcontext->sample_rate=in_stream->codec->sample_rate;
                 time_base=  (double)in_stream->time_base.num / (double)in_stream->time_base.den;
                 duration= (double)in_stream->duration * time_base * 1000.0;
                if (!out_stream) {
                    fprintf(stderr, "Failed allocating output stream\n");
                    ret = AVERROR_UNKNOWN;
                    return;
                }
               ret = avcodec_copy_context(out_stream->codec,newcontext);
                if (ret < 0) {
                    fprintf(stderr, "Failed to copy context from input to output stream codec context\n");
                    goto end;
                }
                out_stream->codec->codec_tag = 0;
                if (output_context->oformat->flags & AVFMT_GLOBALHEADER)
                    out_stream->codec->flags |= AV_CODEC_FLAG_GLOBAL_HEADER;

使用以下方法更改了标题信息: / *此代码使用设置元数据* /

av_dict_set(&opt, "major_brand", "mp42", 0);
    av_dict_set(&opt, "minor_version","512" , 0);
    av_dict_set(&opt, "compatible_brands","isomiso2avc1mp41",0);
    av_dict_set(&opt, "comment","Hash=855738390",0);
    output_context->metadata = opt;
    ret = avformat_write_header(output_context,NULL);

在终端中使用ffmpeg创建mp4文件检查文件后。像这样得到错误:

/ 此错误消息 /

  

[mpeg4 @ 0x7ff2b9811c00]标题已损坏最后一条消息重复39   次[mov,mp4,m4a,3gp,3g2,mj2 @ 0x7ff2ba800000]解码流0   失败[mov,mp4,m4a,3gp,3g2,mj2 @ 0x7ff2ba800000]找不到编解码器   流0的参数(视频:mpeg4(mp4v / 0x7634706D),无,376   kb / s):未指定大小考虑增加值   &#39; analyzeduration&#39;并且&#39;探测&#39;选项。

1 个答案:

答案 0 :(得分:0)

最简单的方法是下载免费软件十六进制编辑器(针对您的特定O.S)。接下来是使用FFmpeg的桌面(命令行)版本(下载静态版本)

  • 使用命令行FFmpeg将Source转换为MP4( ie: as mp4_ffmpeg.mp4
  • 使用您的代码将Source转换为MP4( ie: as mp4_code.mp4
  • 同时打开mp4_ffmpeg.mp4&amp; mp4_code.mp4并比较字节。工作的应该是mp4_ffmpeg.mp4所以与你的代码产生的字节有什么不同?

要寻找的东西:

  • 所有内容均以ftyp
  • 开头
  • moov是标题,应该在开始时(有时在mdat之后,将所有a / v数据保存在一个块中。将任何mp4的标题移到前面或开头字节然后使用-movflags +faststart例如在命令行中使用:
    ffmpeg -i myfile.avi -movflags +faststart newfile.mp4

  • 在每个单词moovmdat之前,前4个字节是跳过4个字母后的大小(以字节为单位)......这些大小是否正确?

  • 您是否定义了所有MP4原子(元数据部分)?它们与FFmpeg为其MP4转换版本生产的产品相匹配吗?