【发布时间】:2021-03-17 01:31:38
【问题描述】:
我正在尝试暂停 FFmpeg 在 非 shell 子进程中的编码(这对于它如何在更大的程序中发挥作用很重要)。这可以通过单独按键盘上的“暂停/中断”键来完成,我正在尝试将其发送到 Popen。
命令本身必须是跨平台兼容的,所以我不能以任何方式包装它,但我可以根据需要发送信号或运行特定于平台的函数。
我查看了how to send a "Ctrl+Break" to a subprocess via pid or handler,它建议发送一个信号,但这引发了“ValueError: Unsupported signal: 21”
from subprocess import Popen, PIPE
import signal
if __name__ == '__main__':
command = "ffmpeg.exe -y -i example_video.mkv -map 0:v -c:v libx265 -preset slow -crf 18 output.mkv"
proc = Popen(command, stdin=PIPE, shell=False)
try:
proc.send_signal(signal.SIGBREAK)
finally:
proc.wait()
然后尝试使用 GenerateConsoleCtrlEvent 创建 Ctrl+Break 事件,如此处所述https://docs.microsoft.com/en-us/windows/console/generateconsolectrlevent
from subprocess import Popen, PIPE
import ctypes
if __name__ == '__main__':
command = "ffmpeg.exe -y -i example_video.mkv -map 0:v -c:v libx265 -preset slow -crf 18 output.mkv"
proc = Popen(command, stdin=PIPE, shell=False)
try:
ctypes.windll.kernel32.GenerateConsoleCtrlEvent(1, proc.pid)
finally:
proc.wait()
我尝试过psutil 暂停功能,但即使在“暂停”时,它也会使 CPU 负载保持在很高的水平。
即使它不能与整个程序一起工作,我至少尝试过设置creationflags=CREATE_NEW_PROCESS_GROUP,这使得 SIGBREAK 不会出错,但也不会暂停它。因为 Ctrl-Break 事件将完全停止编码而不是暂停它。
【问题讨论】:
-
有什么解决办法吗?我一直在努力解决这个问题。
-
我认为发送
c到stdin 会导致显示命令菜单,效果是一样的。也许proc.stdin.write(b'c');proc.stdin.flush()然后只是发送一个输入到标准输入简历?我认为这可能行得通? -
@sytech Pressing
c确实会暂停它以等待过滤器输入,并且可以跨平台工作,但存在导致一个 CPU 保持峰值的相同问题。而在 powershell 中使用pause按钮或在 linux 上使用kill -STOP可以让它们全部释放。然而,这可能是最好的答案,我只是在寻找不可能的答案。 -
@CasualDemon 在我的机器中,
psutil工作正常,并且在进程暂停时没有使用 CPU。在 Windows 中,PsSuspend 也可以使用。我测试的方式是在暂停和恢复之间添加sleep(60)。
标签: python ffmpeg subprocess signals popen