如何减少 cpu ffmpeg 的使用?
how to reduce cpu usage of ffmpeg?
嗨,我正在将 hls 流重新流式传输为 hls 流
SETLOCAL
:loop
ffmpeg -thread_queue_size 32768 -i "http://xx/636.m3u8" -f hls -hls_time 5 -hls_list_size 5 -hls_allow_cache 0 -hls_flags delete_segments -segment_list_flags +live -hls_base_url "../ts/" -hls_segment_filename "C:\nginx\html\ts\lig-%random%%random%-%%3d.svgz" -y "C:\nginx\html\hls\lig1.m3u8" > log.txt
goto loop
但它使用了 cpu 的 %15-20 我必须在同一台服务器上制作 16 个流,但我不能。
我不能像只下载 .ts 文件克隆 m3u8 那样进行配置吗?
默认情况下,FFmpeg 会尝试重新编码输入,即使您不使用任何编码相关参数也是如此。
如果你只想按原样复制流,你应该尝试 streamcopy 函数:
-c:v copy -c:a copy
通过复制传入的流,您可以完全跳过编码过程。
因此您的命令将如下所示:
ffmpeg -thread_queue_size 32768 -i "http://xx/636.m3u8" -f hls -c:v copy -c:a copy -hls_time 5 -hls_list_size 5 -hls_allow_cache 0 -hls_flags delete_segments -segment_list_flags +live -hls_base_url "../ts/" -hls_segment_filename "C:\nginx\html\ts\lig-%random%%random%-%%3d.svgz" -y "C:\nginx\html\hls\lig1.m3u8" > log.txt
(不过不确定它是否有效。)
当你需要re-encode传入流时,你应该考虑在命令中添加一些编码参数。
默认情况下,ffmpeg 尝试匹配源参数和质量,这在实时应用程序中并不总是最佳的。
"veryfast, superfast and ultrafast" h264 预设是获得一些性能提升的良好开端。
-c:v h264 -preset:v ultrafast
您还可以 fiddle 使用 CRF(恒定速率因子)编码、更高的比特率等
关于 H264 编码的更多信息:https://trac.ffmpeg.org/wiki/Encode/H.264
-re (input)
以原始帧速率读取输入。主要用于模拟抓取设备或实时输入流(例如,从文件中读取时)。不应与实际抓取设备或实时输入流一起使用(可能导致数据包丢失)。
默认情况下,FFmpeg 会尝试尽可能快地读取输入。此选项会将输入的读取速度减慢到输入的本机帧速率。它对实时输出很有用(例如直播)。
虽然这个问题已经被认为已经回答了,但我认为它缺少一个不涉及调整命令参数但可以与其他工具或命令一起使用而不仅仅是 FFmpeg 的答案。
CPUlimit 工具正是为此目的而设计的,它不仅适用于 FFmpeg,而且适用于任何其他 CPU 您想要减少此资源利用率的密集型进程。
CPUlimit 最重要的参数是 -l
,它允许您指定允许进程使用的 CPU 百分比(作为其上限)。
还请注意,这个限制取决于CPUs/Cores/Threads机器的数量,例如,如果机器有8CPUs,CPU限制-l
有效值范围从 0 到 800(0 是无用的,当然,800 表示完全不限制进程,因为 800% 表示所有机器处理能力)。
使用 8 CPUs 机器一半容量的示例:
cpulimit -l 400 ffmpeg ...
希望这对这个特定问题以及未来的类似需求有所帮助。
更新:2020/04/19
原来的 CPUlimit 项目似乎已经转移到 github,现在由用户 denji
here 维护。我要离开原来的 link 因为新项目必须编译并且不提供二进制下载。
此外,关于原始问题,如果您试图限制 bash 脚本(或任何分叉子进程的脚本),请确保添加选项 -i
或 --include-children
并指定脚本的位置(如果它不在 PATH 中)。
示例更新:
cpulimit -l 400 -i ./script.sh
嗨,我正在将 hls 流重新流式传输为 hls 流
SETLOCAL
:loop
ffmpeg -thread_queue_size 32768 -i "http://xx/636.m3u8" -f hls -hls_time 5 -hls_list_size 5 -hls_allow_cache 0 -hls_flags delete_segments -segment_list_flags +live -hls_base_url "../ts/" -hls_segment_filename "C:\nginx\html\ts\lig-%random%%random%-%%3d.svgz" -y "C:\nginx\html\hls\lig1.m3u8" > log.txt
goto loop
但它使用了 cpu 的 %15-20 我必须在同一台服务器上制作 16 个流,但我不能。
我不能像只下载 .ts 文件克隆 m3u8 那样进行配置吗?
默认情况下,FFmpeg 会尝试重新编码输入,即使您不使用任何编码相关参数也是如此。
如果你只想按原样复制流,你应该尝试 streamcopy 函数:
-c:v copy -c:a copy
通过复制传入的流,您可以完全跳过编码过程。
因此您的命令将如下所示:
ffmpeg -thread_queue_size 32768 -i "http://xx/636.m3u8" -f hls -c:v copy -c:a copy -hls_time 5 -hls_list_size 5 -hls_allow_cache 0 -hls_flags delete_segments -segment_list_flags +live -hls_base_url "../ts/" -hls_segment_filename "C:\nginx\html\ts\lig-%random%%random%-%%3d.svgz" -y "C:\nginx\html\hls\lig1.m3u8" > log.txt
(不过不确定它是否有效。)
当你需要re-encode传入流时,你应该考虑在命令中添加一些编码参数。
默认情况下,ffmpeg 尝试匹配源参数和质量,这在实时应用程序中并不总是最佳的。
"veryfast, superfast and ultrafast" h264 预设是获得一些性能提升的良好开端。
-c:v h264 -preset:v ultrafast
您还可以 fiddle 使用 CRF(恒定速率因子)编码、更高的比特率等
关于 H264 编码的更多信息:https://trac.ffmpeg.org/wiki/Encode/H.264
-re (input)
以原始帧速率读取输入。主要用于模拟抓取设备或实时输入流(例如,从文件中读取时)。不应与实际抓取设备或实时输入流一起使用(可能导致数据包丢失)。
默认情况下,FFmpeg 会尝试尽可能快地读取输入。此选项会将输入的读取速度减慢到输入的本机帧速率。它对实时输出很有用(例如直播)。
虽然这个问题已经被认为已经回答了,但我认为它缺少一个不涉及调整命令参数但可以与其他工具或命令一起使用而不仅仅是 FFmpeg 的答案。
CPUlimit 工具正是为此目的而设计的,它不仅适用于 FFmpeg,而且适用于任何其他 CPU 您想要减少此资源利用率的密集型进程。
CPUlimit 最重要的参数是 -l
,它允许您指定允许进程使用的 CPU 百分比(作为其上限)。
还请注意,这个限制取决于CPUs/Cores/Threads机器的数量,例如,如果机器有8CPUs,CPU限制-l
有效值范围从 0 到 800(0 是无用的,当然,800 表示完全不限制进程,因为 800% 表示所有机器处理能力)。
使用 8 CPUs 机器一半容量的示例:
cpulimit -l 400 ffmpeg ...
希望这对这个特定问题以及未来的类似需求有所帮助。
更新:2020/04/19
原来的 CPUlimit 项目似乎已经转移到 github,现在由用户 denji
here 维护。我要离开原来的 link 因为新项目必须编译并且不提供二进制下载。
此外,关于原始问题,如果您试图限制 bash 脚本(或任何分叉子进程的脚本),请确保添加选项 -i
或 --include-children
并指定脚本的位置(如果它不在 PATH 中)。
示例更新:
cpulimit -l 400 -i ./script.sh