如何以编程方式使用ffmpeg快速启动标志

How to use ffmpeg faststart flag programmatically?

本文关键字:启动 标志 ffmpeg 编程 方式使      更新时间:2023-10-16

我尝试使用H264、AAC编解码器和mp4容器转换视频以在Android上播放。视频在非系统播放器中正常播放。但系统播放器显示错误"无法播放此视频"。我发现问题出在moov原子中,它写在文件的末尾。当我使用"-movflags+faststart"ffmeg标志转换视频时,它会正常播放,但当我尝试以编程方式进行转换时,它不会给出任何结果。我使用以下代码:

av_dict_set( &dict, "movflags", "faststart", 0 );
ret = avformat_write_header( ofmt_ctx, &dict );

此代码运行良好:

av_dict_set( &dict, "movflags", "faststart", 0 );
ret = avformat_write_header( ofmt_ctx, &dict );

但问题并没有得到解决。我仍然无法在Android设备上播放转换后的视频。

我认为这个答案已经很晚了,但对于任何可能仍然面临相同问题的人来说:这可能是由于音频/视频AVCodecContext中没有设置AV_CODEC_FLAG_GLOBAL_HEADER造成的。许多指南显示,它需要在AVFormatContext中设置,但在使用avcodec_open2打开它之前,它需要先在AVCodecContext中设置。

if (format_context->oformat->flags & AVFMT_GLOBALHEADER) {
  video_codec_context->flags |= AV_CODEC_FLAG_GLOBAL_HEADER;
}
avcodec_open2(video_codec_context, video_codec, nullptr);

TL;DR

avformat_write_header之前设置AVFormatContexturl字段。

为什么

我今天遇到了同样的问题,在调用av_write_trailer:时发现有一个日志

无法重新打开第二次通过(快速启动)的输出文件

movenc.c的实现中,我们可以看到它需要s->url来重新打开文件:

avio_flush(s->pb);
ret = s->io_open(s, &read_pb, s->url, AVIO_FLAG_READ, NULL);
if (ret < 0) {
    av_log(s, AV_LOG_ERROR, "Unable to re-open %s output file for "
           "the second pass (faststart)n", s->url);
    goto end;
}

也许视频与您的android手机不兼容?尝试使用h264基线配置文件进行转换。