ffmpeg - libavformat 在编码时生成没有大小的 flv 文件

标签 ffmpeg libavcodec libavformat

我正在使用 libavcodec 和 libavformat 对视频进行编码。我使用 libx264 作为编解码器,使用 flv 作为容器。我选择 flv 是因为我希望能够在视频编码时播放和剪切视频片段,而 flv 应该支持这种行为。

当我尝试在 ffmpeg 仍在编码的情况下使用 ffmpeg 剪切视频的一部分(前 5 秒)时,ffmpeg 会产生错误:

$# ffmpeg -i file.flv -t 00:00:05.000 -c copy test.mp4
[flv @ 0x67ecb00] Could not find codec parameters for stream 0 (Video: h264, none, 2000 kb/s): unspecified size

如果我等到文件完成编码并运行相同的 ffmpeg 命令,则没有错误。实际上,ffprobe 为视频显示了以下内容:
Video: h264 (High), yuv420p, 640x480, 2000 kb/s, 25 fps, 25 tbr, 1k tbn, 50 tbc

当我尝试这样做时,该文件的长度肯定超过 5 秒。

我用来执行此操作的代码很大程度上基于 libavformat 中的 muxing.c 示例。这是一个精简版:
AVOutputFormat *container_format;
AVFormatContext *container_format_context;
AVStream *video_stream;
char *path = "/home/user/temp.flv";

/* allocate the output media context */
avformat_alloc_output_context2(&container_format_context, NULL, NULL, path);
container_format = container_format_context->oformat;

AVCodec* codec = NULL;
/* Pull codec based on name */
codec = avcodec_find_encoder_by_name("libx264");

/*create stream */
video_stream = NULL;
video_stream = avformat_new_stream(container_format_context, codec);

video_stream->id = container_format_context->nb_streams - 1;

video_stream->codec->bit_rate = bitrate;
video_stream->codec->width = 640;
video_stream->codec->height = 480;
video_stream->codec->gop_size = 10;
video_stream->codec->qmax = 31;
video_stream->codec->qmin = 2;
video_stream->codec->pix_fmt = AV_PIX_FMT_YUV420P;
video_stream->codec->time_base = (AVRational) { 1, 25 };

AVCodecContext *avcodec_context = video_stream->codec;

if (container_format_context->oformat->flags & AVFMT_GLOBALHEADER) {
    avcodec_context->flags |= CODEC_FLAG_GLOBAL_HEADER;
}

/* open codec */
guacenc_open_avcodec(avcodec_context, codec, NULL, video_stream);

/* Allocate corresponding frame */
AVFrame* frame = av_frame_alloc();

/* Copy necessary data for frame from avcodec_context */
frame->format = avcodec_context->pix_fmt;
frame->width = avcodec_context->width;
frame->height = avcodec_context->height;

if (!(container_format->flags & AVFMT_NOFILE)) {
    avio_open(&container_format_context->pb, path, AVIO_FLAG_WRITE);
}

avformat_write_header(container_format_context, NULL);

如何将大小信息放在 flv 文件的前面,以便在编码的同时对其进行修剪?

最佳答案

这似乎是 libavformat 的问题。我使用的是 2.8,它显示了这个问题。我针对 3.4 编译,问题不再发生。所以我将在我的应用程序中使用 3.4 来解决这个问题。

我不知道何时将修复提交给 libavformat,但我认为它可能至少已经开始通过此提交进行修复:https://git.ffmpeg.org/gitweb/ffmpeg.git/commitdiff/5702416c57afb2bb062eb69d60fc42c31c91b674

关于ffmpeg - libavformat 在编码时生成没有大小的 flv 文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50517300/

相关文章:

ffmpeg - 为什么在使用 Java JNA 编码声音文件时出现提示音?

audio - 如何确定编解码器/容器组合是否与 FFmpeg 兼容?

ffmpeg - 你如何在 libavformat 中设置 muxer 选项?

ios - mobile-ffmpeg-https (4.3.1) POD 安装失败

ffmpeg - 用 FFmpeg 录制未知帧率的视频

iphone - 转换视频时保持纵横比? - ffmpeg

ffmpeg - 每次我尝试运行代码时,AVI INFO 都会使 Octave GUI 崩溃

ffmpeg - 当编解码器使用 p 帧时,av_seek_frame 会中断 avcodec_decode_video2

c++ - 调用 avformat_find_stream_info 会阻止简单 PNG 图像的解码?

video - FFMPEG:为编解码器定义上下文是强制性的吗?