FFMPEG H264 每帧自定义覆盖

FFMPEG H264 with custom overlay per frame

我们有一个流作为单独的 H264 帧存储在云 (Amazon S3) 中。帧存储为 framexxxxxx.264,编号不是从 0 开始,而是从某个更大的数字开始,比如 1000(所以,frame001000.264

目标是创建一个 mp4 剪辑,它要么是延时摄影,要么只是为了检查和其他检查而更快(更快,将大约 3 小时的视频压缩到 < 20 分钟),这也需要我们叠加帧数(文件名)在框架本身

起初我只是通过从 S3 中拉出关键帧(i 帧?对编解码器和其他东西来说还是相当新)并在其上覆盖文件名并另存为 png(可能不需要,但这就是我所做的)使用(此命令在 python 脚本中使用)

ffmpeg -y -i {h264_name} -vf \"scale=1920:-1, 
drawtext=fontfile=/usr/share/fonts/truetype/ubuntu-font-family/Ubuntu-B.ttf:fontsize=34:text={txt}:fontcolor=white:x=50:y=50:bordercolor=black:borderw=2\" 
-c:a copy -pix_fmt yuv420p {basename}.png

在此之后,我通过使用 python 将编号最低的帧转换为 0.png 并递增来合并所有帧(因此它将是连续的,因为我只使用了关键帧,这些数字最初不是' t 顺序)和 运行

ffmpeg -y -f image2 -i %d.png -r {self.params.fps} -vcodec libx264 -crf {self.params.crf} -pix_fmt yuv420p {out_file}

效果很好,但关键帧之间的差异太长,无法进行适当检查

现在回答问题

因为我知道不是关键帧的帧(p帧?)不能被ffmpeg单独使用,覆盖文件名并将其转换为png(或保留为h264,同样的事情)的方法获胜不起作用,或者至少,我找不到一种方法让它起作用,也许有一种方法可以指定帧的关键帧?如何覆盖文件名(而不是显示的帧编号 here例如)

另外,是否可以在关键帧之间跳过一些 p 帧? (所以如果一个关键帧是每 30 帧,我们将取一个关键帧,一个 15 帧后的帧,然后是另一个关键帧)

我考虑过使用 ffmpeg 的管道选项在下载文件时将其与文件一起提供给它,但我不确定是否可以通过这种方式指定 drawtext

此外,如果有另一种选择可以实现这一点(起初我正在转换为 png,使用 python 和 OpenCV 添加文件名,然后将 png 合并为 mp4,但后来我发现 drawtext 可以在一个命令中完成,所以我使用了它)

我最终使用了 https://github.com/DaWelter/h264decoder 而不是直接使用 ffmpeg。

它有一个非常简单的界面,我只是调用

decoder = h264decoder.H264Decoder()
# For each file, in order call
framedatas = decoder.decode(data_in)
for framedata in framedatas:
    (frame, w, h, ls) = framedata
    self.process_frame(frame, path) # Using OpenCV to manipulate, resize, add the overlay, etc.

然后将输出数据通过管道传输到 ffmpeg 中以组合生成 MP4 文件