Thursday 21 October 2021

Pause a FFmpeg encoding in a Python Popen subprocess on Windows

I am trying to pause an encode of FFmpeg while it is in a non-shell subprocess (This is important to how it plays into a larger program). This can be done by presssing the "Pause / Break" key on the keyboard by itself, and I am trying to send that to Popen.

The command itself must be cross platform compatible, so I cannot wrap it in any way, but I can send signals or run functions that are platform specific as needed.

I looked at how to send a "Ctrl+Break" to a subprocess via pid or handler and it suggested to send a signal, but that raised a "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()

Then attempted to use GenerateConsoleCtrlEvent to create a Ctrl+Break event as described here 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()

I have tried psutil pause feature, but it keeps the CPU load really high even when "paused".

Even though it wouldn't work with the program overall, I have at least tried setting creationflags=CREATE_NEW_PROCESS_GROUP which makes the SIGBREAK not error, but also not pause it. For the Ctrl-Break event will entirely stop the encode instead of pausing it.



from Pause a FFmpeg encoding in a Python Popen subprocess on Windows

No comments:

Post a Comment