libavformat создает файлы flv без размера при кодировании - PullRequest
0 голосов
/ 24 мая 2018

Я кодирую видео с помощью libavcodec и libavformat.Я использую libx264 в качестве кодека и flv в качестве контейнера.Я выбрал flv, потому что хотел иметь возможность воспроизводить и вырезать фрагменты видео, пока оно кодируется, и flv должен поддерживать это поведение.

Когда я пытаюсь вырезать часть (первые 5 секунд) видео с помощью ffmpeg, пока оно все еще кодирует, 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 секунд, когда я пытаюсь это сделать.

Код, который я использую для этого,основано на примере muxing.c из libavformat.Вот урезанная версия:

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-файла, чтобы его можно было обрезать, пока он еще кодируется?

1 Ответ

0 голосов
/ 26 мая 2018

Кажется, что это проблема с libavformat.Я использовал 2.8, который показывал эту проблему.Я скомпилировал против 3.4, и проблема больше не происходила.Так что я собираюсь использовать 3.4 в своем приложении, чтобы исправить это.

Я не знаю, когда исправление было зафиксировано в libavformat, но я думаю, что оно могло, по крайней мере, быть исправлено с помощью этого коммита: https://git.ffmpeg.org/gitweb/ffmpeg.git/commitdiff/5702416c57afb2bb062eb69d60fc42c31c91b674

...