我使用 FFmpeg 从 Xvfb 显示器进行视频屏幕捕获。
目前我使用以下命令调用它:
ffmpeg -y -r 15 -g 600 -s 1280x1024x24 -f x11grab -i :100 -vcodec libx264 /tmp/video.mov
当我从大约 5 个 Xvfb 会话录制视频时,我的 CPU 使用率非常高,因此出现延迟。此外,每个 ffmpeg 进程的内存使用量约为 300 MB。
在进行视频屏幕捕获时,我应该使用 ffmpeg 的哪些参数来最大限度地减少计算机资源的使用(特别是 CPU 和内存)?
答案1
1. 首先制作无损 RGB 输出
ffmpeg -y -framerate 25 -video_size 1280x1024 -f x11grab -i :0.0 -c:v libx264rgb \
-crf 0 -preset ultrafast temp.mp4
输入是 RGB,因此使用编码器 libx264rgb 将避免使用普通 libx264 时可能发生的 RGB 到 YUV 转换速度缓慢的问题。
这使用最快的 x264 编码预设:超快。
-crf 0
由于使用了,因此输出将是无损的。
2.然后重新编码
第一个命令的输出将会非常大,并且大多数笨拙的播放器无法处理 RGB H.264,因此您可以对其进行重新编码:
ffmpeg -i temp.mp4 -c:v libx264 -crf 23 -preset medium -vf format=yuv420p out.mp4
您可以尝试使用该
-crf
值来控制输出质量。主观上合理的范围是 18-28,其中 18 在视觉上无损或几乎无损。默认值为 23。使用您有耐心的最慢预设:
ultrafast
,,,,,,,,,。默认为superfast
。veryfast
faster
fast
medium
slow
slower
veryslow
medium
我添加了
-vf format=yuv420p
此设置以确保输出可与 QuickTime 和 Windows Media Player 等哑播放器配合使用。如果您要将其上传到 YouTube 或仅在 VLC、mpv、MPlayer 或任何其他基于 FFmpeg 的播放器上播放,则可以省略此设置。
另请参阅
答案2
最好集中精力使用不同的 ffmpeg 选项,以使用更少的资源的方式实现相同的结果。也就是说,如果您确实需要使用 ffmpeg 完成某项特定任务,并且它使用了太多资源,那么还是有办法使用更少的资源的。
ffmpeg
您可以降低CPU 进程的优先级:
- 终端方法:使用
nice
命令改变进程的优先级:nice -n 8 ffmpeg -y -r 15 -g 600 -s 1280x1024x24 -f x11grab -i :100 -vcodec libx264 /tmp/video.mov
在Linux中,优先级数字(nice
命令格式为nice -n <priority> <command>
)的范围是-20到20。整数越大,优先级越高。降低优先级为;中性为 0。如果您使用我给您的命令并将其设置为 8,则 CPU 将为该进程提供更少的时间,这看起来就像更少的“权力”。如果这个数字太高或太低,当然,您可以更改它。 - GUI 方法:不建议这样做,因为这样会降低您对确切数字的控制力,并且不会在进程开始时立即生效。但是,这样做更容易理解。在
ffmpeg
运行时,打开系统监视器。向下滚动到名为的进程ffmpeg
,左键单击以选择它,右键单击它,然后将优先级设置为“低”或“非常低”。
如果你也担心内存使用情况,我们知道不可能告诉进程只占用这么多内存并继续运行。内核会自动控制进程的内存分配。有一种方法可以限制进程,即timeout
脚本,这样当某个进程及其子进程占用过多内存(由您设置的限制)时,它们就会被安全终止并显示通知。但是,如果某个进程只被分配了一定数量的内存(例如由内核分配),并且它请求了超出其能力的内存,则该进程将崩溃。
您需要了解的一些有用信息:
- Cgroups - https://www.kernel.org/doc/Documentation/cgroups/cgroups.txt
- 内核的内存控制器 - https://www.kernel.org/doc/Documentation/cgroups/memory.txt
利用 Cgroups 的知识,你可以做很多有趣的事情,比如控制交换性一个过程。
答案3
-re(输入)以原始帧速率读取输入。主要用于模拟抓取设备或实时输入流(例如从文件读取时)。不应与实际抓取设备或实时输入流一起使用(这可能会导致数据包丢失)。默认情况下,ffmpeg 会尝试尽快读取输入。此选项将减慢输入的读取速度至输入的原始帧速率。它对于实时输出(例如实时流)很有用。