我使用Python运行FFMPEG命令subprocess.Popen(ffmpeg_cmd)
我的项目需要暂停/恢复 ffmpeg 作业一段时间。

为此,我使用process.suspend()psutilsprocess.resume()

但是,当我恢复该过程时,FFMPEG 会要求我输入一些输入:

Enter command: <target>|all <time>|-1 <command>[ <argument>]

我发现-nosdtin在我的 ffmpeg 命令中添加标志可以避免这个问题。

但是现在,由于 stdin 已被禁用,我不知道如何停止该过程。

我试过:

process.send_signal(subprocess.signal.CTRL_C_EVENT) // with no effect
process.terminate() // ends the process but loses the job done


最佳答案
2

不要添加-nosdtin,避免shell=True在打开 FFmpeg 子进程时使用。

Python 代码示例:

import subprocess as sp
import shlex
import psutil
from time import sleep

# Open FFmpeg subprocess with opened stdin pipe (generate synthetic pattern for testing):
process = sp.Popen(shlex.split('ffmpeg -hide_banner -y -re -f lavfi -i testsrc=size=384x216:rate=1 -c:v libx264 -pix_fmt yuv420p test.mp4'), stdin=sp.PIPE)
ps_process = psutil.Process(pid=process.pid)  # Pass the PID of FFmpeg subprocess to PsUtil.

sleep(3)  # Wait 3 seconds for testing ("recored 3 seconds")
ps_process.suspend()  # Suspend FFmpeg process for 3 seconds
sleep(3)  # Wait 3 seconds
ps_process.resume()  # Resume FFmpeg process.
sleep(3)
ps_process.suspend()
sleep(3)
ps_process.resume()

# Close FFmpeg gracefully:
process.stdin.write(b'q')  # Simulate user pressing q key for gracefully closing FFmpeg.
process.communicate()
process.wait()

在 Linux 中,当使用:时process = sp.Popen(shlex.split('ffmpeg ...'), stdin=sp.PIPE, shell=True),我收到以下消息usage: ffmpeg [options] [[infile options] -i infile]... {[outfile options] outfile}...Use -h to get full help or, even better, run 'man ffmpeg'

我不确定 psutils 库在这里是否有用,但我确实有一个使用标准库的脚本,它会向 ffmpeg 命令生成的进程组发送 SIGSTOP 和 SIGCONT 信号:

#!/usr/bin/env python3

import subprocess
import time
import os

ffmpeg_cmd = "ffmpeg -i /tmp/in.mp4 -vcodec libx264 /tmp/out.mp4"

process = subprocess.Popen(
        ffmpeg_cmd,
        shell=True,
        preexec_fn=os.setsid,
        stdout= open(os.devnull, 'w'),
        stderr=subprocess.STDOUT)

while True:
    os.killpg(os.getpgid(process.pid), subprocess.signal.SIGSTOP)
    print("asleep")
    time.sleep(10)
    os.killpg(os.getpgid(process.pid), subprocess.signal.SIGCONT)
    print("awake")
    time.sleep(5)

示例输出为:

$ ./test.py 
asleep
awake
asleep
awake
asleep
Traceback (most recent call last):
  File "/home/preston/superuser/1856303/./test.py", line 19, in <module>
    time.sleep(10)
KeyboardInterrupt
$ 

您可以在资源监视器中看到工作启动和停止: