使用 FFMPEG 在 MP4 末尾添加单帧

J. *_*ull 9 video command-line ffmpeg

我编写了一些图像采集软件,当我采集这些图像时,我想将最后一个图像添加到视频文件的末尾(到目前为止采集的所有图像的延时)。这将提供所有图像的视频视图。

然而,我正在努力尝试添加单帧。我已经生成了延时罚款。我这样做的方式是等待收集到 10 张图像,然后生成延时图像。我用来生成要添加帧的延时的命令是:

-帧速率 40 -start_number N -i DSC_%05d.JPG -c:V libx264 -r 30 输出.mp4

我尝试了几种不同的方法,所有方法都几乎有效,但没有一个完全按照需要工作。这是我尝试过的,使用什么命令以及输出是什么:

用于将 JPG 连接到 MP4 的 Concat Demuxer
包含用于连接的文件列表的文本文件如下所示:

文件“B00334_1.mp4”
文件“test_image.jpg”
持续时间 10

我用来尝试加入文件的命令是:

ffmpeg -f concat -i concat.txt -c 复制输出文件.mp4

此尝试的输出是一个未损坏的视频(得分!),但它仅显示第一个视频,并且不显示新帧的任何迹象,尤其是在指定的 10 秒内。(我不希望它在那里停留 10 秒,比如 0.1,但是我使用 10 秒只是为了让我可以很容易地看到何时成功)。

将 JPG 转换为 MP4,然后 Concat Demuxer
所以我想;也许它需要第二个视频而不是图像,所以我将创建一个短的、帧长的视频并将其附加到延时的末尾。

用于从 JPG 创建 MP4 的命令:

fmpeg -loop 1 -i test_image.jpg -r -t 5 test_video.mp4

这会生成很好的视频,我得到一个 5 秒长的视频,显示静止图像。该视频不加载缩略图,我不确定这是否意味着什么。现在 concat.txt 文件如下所示:

文件“B00334_1.mp4”
文件“text_video.mp4”

运行相同的命令来调用第一个示例中显示的文本文件后,我得到第一个文件的输出(延时)+串联视频的时间(成功!?)。然而,一旦到达视频中应该显示图像的位置,它只会显示延时拍摄的最后一帧,并且会在第二个视频的 5 秒内向下出现故障。基本上根本不显示第二个视频,无论第二个视频是最后一帧多久,都会出现故障。

将 JPG 和 MP4 转换为 .ts,然后连接回 MP4
用于尝试将 JPG 转换为 TS 文件的命令:

ffmpeg -y -i test_image.jpg -c copy -bsf:v h264_mp4toannexb -f mpegtsmedium1.ts

此操作失败并返回输出: Codec 'mjpeg' (8) is not supported by the bitstream filter 'h264_mp4toannexb'. Supported codecs are: h264 (28)
将编解码器更改为显然支持的 h264 也不会影响结果。

将 JPG 转换为 MP4,然后转换为 .ts,然后连接
从 MP4 创建两个 TS 文件就可以了,使用与之前相同的命令ffmpeg -y -i input.jpg -c copy -bsf:v h264_mp4toannexb -f mpegts output.ts。新制作的文件也按其应有的方式显示,从图像创建的 ts 文件仅显示图像,视频显示视频。现在有了这两个新的 TS 文件,我应该能够将它们连接在一起,对吗?

我尝试用concat protocolFFMPEG的功能将这些文件连接起来。使用这个命令:

ffmpeg -y -i 'concat:medium1.ts|medium2.ts' -c 复制 -bsf:a aac_adtstoasc 输出.mp4

现在这将视频连接在一起!时间会附加到末尾,如果跳到最后几秒,您会看到新添加的图像。但是,如果您让视频播放,一旦播放第二个视频,媒体播放器就会崩溃。


非常感谢任何帮助和/或想法,我可以根据需要提供更多信息。谢谢阅读。

编辑:来自 Mulvya 答案的输出日志:

[mov,mp4,m4a,3gp,3g2,mj2 @ 000000000255c0a0] Auto-inserting h264_mp4toannexb bitstream filter
Input #0, concat, from 'concat.txt':
  Duration: N/A, start: 0.000000, bitrate: 44807 kb/s
    Stream #0:0(und): Video: h264 (High 4:2:2) (avc1 / 0x31637661), yuvj422p(pc), 2896x1944, 44807 kb/s, 30 fps, 30 tbr, 15360 tbn, 60 tbc
    Metadata:
      handler_name    : VideoHandler
Output #0, mp4, to 'merged.mp4':
  Metadata:
    encoder         : Lavf57.66.102
    Stream #0:0(und): Video: h264 (High 4:2:2) ([33][0][0][0] / 0x0021), yuvj422p(pc), 2896x1944, q=2-31, 44807 kb/s, 30 fps, 30 tbr, 15360 tbn, 15360 tbc
    Metadata:
      handler_name    : VideoHandler
Stream mapping:
  Stream #0:0 -> #0:0 (copy)
Press [q] to stop, [?] for help
[mov,mp4,m4a,3gp,3g2,mj2 @ 0000000002564840] Auto-inserting h264_mp4toannexb 
bitstream filter
frame=   60 fps=0.0 q=-1.0 Lsize=    5564kB time=00:00:01.90 
bitrate=23990.6kbits/s speed=30.6x
video:5563kB audio:0kB subtitle:0kB other streams:0kB global headers:0kB muxing overhead: 0.024155%
Run Code Online (Sandbox Code Playgroud)

Gya*_*yan 4

对于在 VLC 或 ffplay 中播放,以下内容对我有用:

ffmpeg -framerate 40 -i DSC_%05d.JPG -c:v libx264 -x264opts stitchable -r 30 main.mp4
Run Code Online (Sandbox Code Playgroud)

ffmpeg -framerate 40 -loop 1 -i latest.JPG -c:v libx264 -x264opts stitchable -t 1 -r 30 appendix.mp4
Run Code Online (Sandbox Code Playgroud)

file main.mp4
file appendix.mp4
Run Code Online (Sandbox Code Playgroud)

ffmpeg -f concat -i list.txt -c copy merged.mp4
Run Code Online (Sandbox Code Playgroud)

如果分辨率不同,VLC 将中断播放以切换上下文。