【问题标题】:Create a video from JPG without have all pictures at begining with ffmpeg从 JPG 创建一个视频,没有以 ffmpeg 开头的所有图片
【发布时间】:2021-10-13 00:16:14
【问题描述】:

我有一个可以创建一些屏幕截图的游戏,我想将它们转换为 mp4 视频。所以我有下一个命令:

ffmpeg -framerate 15 -i %06d.png -s hd1080 -vcodec libx264 -r 30 timelapse.mp4

但是我的游戏持续了8小时,所以,在自动压缩图片后,我有超过9To的图片。所以我想在图片生成结束之前启动ffmpeg进程,所以我想让ffmpeg等下一张图片消化一下。

我该怎么做?

【问题讨论】:

  • 我认为使用命令行是不可能的,但使用 Python 脚本很简单。建议的解决方案将帧写入 FFmpeg 标准输入管道,如 here 所述。如果你不懂 Python,也可以用其他编程语言来实现。
  • 我承认我不喜欢python,因为它对生态来说是一场大灾难,但感谢image2pipe和“-i-”!!!我会试试的,我会在接下来的几天里发布解决方案:D
  • @Chklang 你需要澄清:... (1) I have a game which can create some screenshots是你做游戏还是修改源代码还要运行像FFmpeg这样的外部进程? (2) 听起来您需要运行 FFmpeg 作为进程,以便在可用时将图像作为视频帧发送...您知道任何也可以使用 std in/out的编程语言> 关于外部计划?如果您有本地主机服务器,PHP 可以做到这一点。 (3) 你说“...但是我的游戏持续8小时”那么它多久保存一次图片?这是自动的还是仅当您按下按钮时?
  • 对不起@Rotem,你已经给出了最好的解决方案,但不是作为“答案”,只是作为“评论”,所以我不能给你赏金:/

标签: video ffmpeg jpeg


【解决方案1】:

关于第一个解决方案的 stackoverflow 社区和 Rotem。

解决方案是使用 FFmpeg 管道(通过标准输入/输出)。
其中-f image2pipe 设置预期输入的格式,-i - 开始监视管道中的一些传入媒体数据。

我将 Java 用于标准 I/O 部分,但任何具有该功能的编程语言都可以应用相同的解决方案。

我在 Github 上创建了一个存储库来执行此操作:https://github.com/Chklang/ffmpeg-digester

而且执行起来非常简单:

java -jar ffmpeg-digester.jar --ffmpeg ffmpeg.exe --input ./pictures --output myVideo.mkv --codec libx264

(使用“--help”/“-h”的一些集成帮助)

使用这个程序,我在两天内从每个 25-35Mo 的 74.000 张图片中生成了一个 h265 视频,51 分钟,54Go,8k 分辨率。

结果:https://youtu.be/Iqsq7irgUEQ

【讨论】:

    【解决方案2】:

    批量处理

    如果您在游戏结束后绝对不需要视频,请尝试批处理。

    使用您的新图片定期创建视频,可能每 5 到 30 分钟一次。然后在准备好后合并所有视频。在 ffmpeg 中连接一堆相同格式的视频无需重新编码非常快。

    This answer 对 ffmpeg 中合并视频的方法有一个很好的概述。

    在您的情况下,您可以在创建每个视频剪辑时将输出文件名附加到文本文件中。例如vidlist.txt:

    file '/path/to/clip1.mp4'
    file '/path/to/clip2.mp4'
    file '/path/to/clip3.mp4'
    

    然后使用命令:

    ffmpeg -f concat -safe 0 -i vidlist.txt -c copy output.mp4

    一个缺点是您在创建最终视频的同时有效地增加了磁盘空间的使用量。您仍然可以在合并后立即删除所有剪辑,最终使用相同数量的空间。或者,您可以随时将每个视频剪辑连接到主剪辑,而不是等到结束。不需要额外的空间。

    您还可以使用一个脚本将图像通过管道传输到 ffmpeg,该脚本会在 8 小时内提供偶尔的输入。但根据游戏结束后您需要视频的速度(管道脚本脚本可能需要几秒钟,而批处理脚本可能需要一分钟左右),批处理和组合可能是一个更简单的解决方案。

    如果它在与游戏相同的硬件上运行,则恒定脚本方法可能仍然更好,因为 cpu 使用率应保持低于批处理每几分钟创建的峰值,尽管可以通过限制线程在一定程度上缓解这种情况对于 ffmpeg。

    【讨论】:

    • 我想您可以在每个视频剪辑完成时将它们连接到主视频上,而不是等到最后并将所有内容连接起来,避免在编译时可能需要大量额外的结尾。我不相信多次连接有任何缺点,因为没有重新编码。编辑答案以包含此内容。
    【解决方案3】:

    这是一个脚本,它将生成旋转向导的图片流用于测试

    i=0; (while true; do convert magick:logo -rotate $i $i.jpg; i=`expr $i + 1`; sleep 1; done )
    

    (编辑:注意转换是 ImageMagick 的一部分。) 所以启动它来模拟图像处理,然后在另一个终端启动它来生成视频

    (while true; do \
        ls *.jpg | \
        sort -n | # All images sorted numerically \ 
        ( while read im; do # For each image \ 
            convert $im -resize 800x600\! RGBA:-; # Convert each image, output it to stdout
            rm $im; # Then delete
        done); 
        sleep 1; 
    done ) | # Then pipe all raw images to ffmpeg \ 
    ffmpeg -y -f rawvideo -pix_fmt argb -s 800x600 -r 25 -i - out_vid.avi
    

    重要的部分是 resize 以确保它完全适合 ffmpeg 的大小,以及 RGBA:- 以确保它是原始未压缩流。它将输出 25fps 的视频,但这与生成图片的速率无关。

    脚本在 bash 中运行,但等效的东西在任何现代操作系统的 shell 中都可以正常运行。

    它会在处理 jpg 图像时清除它们,因此只要您有足够的处理能力,它就会将磁盘空间保持在最终视频大小以下。

    有关 ffmpeg 方面的更多信息,请点击此处:is it possible to send ffmpeg images by using pipe?。 (我只是接受了这个答案并添加了实时图像处理。)

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-02-06
      • 1970-01-01
      • 1970-01-01
      • 2013-04-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多