如何在视频的第一帧之前放置静止图像?

时间:2014-06-08 01:56:07

标签: image video ffmpeg splash poster

当我通过FFMpeg对视频进行编码时,我想在第一个视频帧之前放置一个jpg图像,因为当我将视频嵌入带有“video”html5标签的网页时,它会将第一张图片显示为初始图像。或者,我想将图像编码为1帧视频并将其连接到我的编码视频。我不想使用“video”html5元素的“poster”属性。

2 个答案:

答案 0 :(得分:10)

您可以使用concat过滤器来执行此操作。确切的命令取决于您希望启动画面的时长。我很确定你不想要1帧的闪屏,大概是1/25到1/30秒,视视频而定;)

答案

首先,您需要获取视频的帧速率。尝试ffmpeg -i INPUT并找到tbr值。 E.g。

$ ffmpeg -i a.mkv
ffmpeg version N-62860-g9173602 Copyright (c) 2000-2014 the FFmpeg developers
  built on Apr 30 2014 21:42:15 with gcc 4.8 (Ubuntu 4.8.2-19ubuntu1)
[...]
Input #0, matroska,webm, from 'a.mkv':
  Metadata:
    ENCODER         : Lavf55.37.101
  Duration: 00:00:10.08, start: 0.080000, bitrate: 23 kb/s
    Stream #0:0: Video: h264 (High 4:4:4 Predictive), yuv444p, 320x240 [SAR 1:1 DAR 4:3], 25 fps, 25 tbr, 1k tbn, 50 tbc (default)
At least one output file must be specified

在上面的示例中,它显示了25 tbr。记住这个号码。

其次,您需要将图像与视频连接起来。试试这个命令:

ffmpeg -loop 1 -framerate FPS -t SECONDS -i IMAGE \
       -t SECONDS -f lavfi -i aevalsrc=0 \
       -i INPUTVIDEO \
       -filter_complex '[0:0] [1:0] [2:0] [2:1] concat=n=2:v=1:a=1' \
       [OPTIONS] OUTPUT

如果您的视频没有音频,请尝试以下操作:

ffmpeg -loop 1 -framerate FPS -t SECONDS -i IMAGE \
       -i INPUTVIDEO \
       -filter_complex '[0:0] [1:0] concat=n=2:v=1:a=0' \
       [OPTIONS] OUTPUT

FPS = tbr值来自第1步

SECONDS =希望图像显示的持续时间。

IMAGE =图片名称

INPUTVIDEO =原始视频名称

[OPTIONS] =可选编码参数(例如-vcodec libx264-b:a 160k

OUTPUT =输出视频文件名

这是如何工作的?

让我们拆分我使用的命令行:

-loop 1 -framerate FPS -t SECONDS -i IMAGE:这基本上意味着:打开图片,然后循环播放图像,使其成为SECONDS秒的视频,每秒FPS帧。您需要它与输入视频具有相同FPS的原因是因为我们稍后将使用的concat过滤器对其有限制。

-t SECONDS -f lavfi -i aevalsrc=0:这意味着:为SECONDS生成静音(0表示静音)。你需要沉默来填补飞溅图像的时间。如果原始视频没有音频,则不需要这样做。

-i INPUTVIDEO:打开视频本身。

-filter_complex '[0:0] [1:0] [2:0] [2:1] concat=n=2:v=1:a=1':这是最好的部分。打开文件0流0(图像 - 视频),文件1流0(静音音频),文件2流0和1(真实输入音频和视频),并concat将它们组合在一起。选项nva表示有2个段,1个输出视频和1个输出音频。

[OPTIONS] OUTPUT:这只是意味着将视频编码为输出文件名。如果您使用的是HTML5流式传输,那么您可能希望将-c:v libx264 -crf 23 -c:a libfdk_aac (or -c:a libfaac) -b:a 128k用于H.264视频和AAC音频。

更多信息

答案 1 :(得分:0)

上面的答案对我有用,但就我而言,它花费了太多时间执行(也许是因为它重新编码了整个视频)。我找到了另一个更快的解决方案。基本思想是:

  1. 创建仅包含图片的“视频”。
  2. 将以上视频与原始视频连接起来,而无需重新编码。

创建仅包含图片的视频:

ffmpeg -loop 1 -framerate 30 -i image.jpg -c:v libx264 -t 3 -pix_fmt yuv420p image.mp4

请注意-framerate 30选项。它必须与主视频相同。同样,图像应与主视频具有相同的尺寸。 -t 3以秒为单位指定视频的长度。

将视频转换为MPEG-2传输流

根据ffmpeg官方文档,只能使用concat协议将某些文件连接起来,其中包括MPEG-2传输流。由于我们有2个MP4视频,因此可以将它们无损地转换为MPEG-2 TS:

ffmpeg -i image.mp4 -c copy -bsf:v h264_mp4toannexb -f mpegts image.ts

以及主要视频:

ffmpeg -i video.mp4 -c copy -bsf:v h264_mp4toannexb -f mpegts video.ts

串联MPEG-2 TS文件

现在使用以下命令来连接上述中间文件:

ffmpeg -i "concat:image.ts|video.ts" -c copy -bsf:a aac_adtstoasc output.mp4

尽管有4个命令要运行,但结合起来它们仍然比重新编码整个视频要快得多。