有没有办法 运行 子进程在 Python 的后台打开 window?

Is there a way to run a subprocess that opens a window in the background in Python?

我正在尝试使用 subprocess 在 Python 中调用 ffplay。调用 ffplay 时,它会打开带有视频的 window 并向控制台输出信息,直到 window 关闭。我想在视频继续播放时 抓取 输出和 return 到 Python 脚本(即不关闭 window) .

目前,我有:

# some code
subprocess.call(['ffplay', 'video.mp4'])
# some more code

如何更改此代码以保持 window 启动并将进程输出发送到后台以继续执行 Python 脚本?

提前致谢!

我想 Popen 就是您要找的。

这是一个代码示例:

import subprocess
import time

process = subprocess.Popen(['ffplay', '-hide_banner', '-nostats', '-autoexit', 'video.mp4'])

for i in range(10):
    time.sleep(1)
    print('Continue running ' + str(i))

process.wait()

subprocess.Popen新开一个子进程,子进程在后台执行
Python 脚本在 subprocess.Popen 之后继续 运行ning。

您可以等待子流程完成,或终止它(或让它 运行)。


抓取 stdoutstderr 输出的示例(将 FFplay 输出读入 Python 的内存)。

import subprocess
import time

process = subprocess.Popen(['ffplay', '-autoexit', '-t', '1', 'video.mp4'], stdout=subprocess.PIPE, stderr=subprocess.PIPE)

stdout, stderr = process.communicate()

process.wait()

print('stdout = ' + stdout.decode('utf-8'))
print('stderr = ' + stderr.decode('utf-8'))

在执行其他操作的同时“在飞行中”读取 FFplay 统计信息需要一个线程。
在 Windows 中,我们似乎需要从 stderr.
逐字节读取 readline() 不工作,因为 FFplay 输出行以 LF (\r) 字符结尾。

这是一个代码示例:

import subprocess
import threading

# Read from stderr pipe - "draining the stderr pipe"
def drain_pipe(a_process):
    output_txt = b''
    while a_process.poll() is None:
        try:
            # Read one byte at a time, it's the only way it works in Windows, because lines ends with just \r.
            a_char = a_process.stderr.read(1)
            output_txt += a_char
            if a_char == b'\r':  # Look for line feed character.
                print(output_txt.decode('utf-8'))
                output_txt = b''
        except:
            break  # Exception may be raised because the pipe closes asynchronous

process = subprocess.Popen(['ffplay', '-stats', '-autoexit', 'video.mp4'], stderr=subprocess.PIPE)

stderr_thread = threading.Thread(target=drain_pipe, args=(process,))  # Create a thread for reading from stderr
stderr_thread.start()  # Start thread

# some more code...

process.wait()
stderr_thread.join()  # Join thread

编辑

试试这个,

p = subprocess.Popen(['ffplay', 'sample-mp4-file.mp4', '-autoexit'],
                     stdout=subprocess.PIPE,
                     stderr=subprocess.PIPE,
                     universal_newlines=True) # This flag converts carriage return chars to new lines

while p.poll() is None:          # While the process p is still running
    line = p.stderr.readline()
    print(line)

我的输出:

ffplay version 4.2.4-1ubuntu0.1 Copyright (c) 2003-2020 the FFmpeg developers

  built with gcc 9 (Ubuntu 9.3.0-10ubuntu2)

  configuration: --prefix=/usr --extra-version=1ubuntu0.1 --toolchain=hardened --libdir=/usr/lib/x86_64-linux-gnu --incdir=/usr/include/x86_64-linux-gnu --arch=amd64 --enable-gpl --disable-stripping --enable-avresample --disable-filter=resample --enable-avisynth --enable-gnutls --enable-ladspa --enable-libaom --enable-libass --enable-libbluray --enable-libbs2b --enable-libcaca --enable-libcdio --enable-libcodec2 --enable-libflite --enable-libfontconfig --enable-libfreetype --enable-libfribidi --enable-libgme --enable-libgsm --enable-libjack --enable-libmp3lame --enable-libmysofa --enable-libopenjpeg --enable-libopenmpt --enable-libopus --enable-libpulse --enable-librsvg --enable-librubberband --enable-libshine --enable-libsnappy --enable-libsoxr --enable-libspeex --enable-libssh --enable-libtheora --enable-libtwolame --enable-libvidstab --enable-libvorbis --enable-libvpx --enable-libwavpack --enable-libwebp --enable-libx265 --enable-libxml2 --enable-libxvid --enable-libzmq --enable-libzvbi --enable-lv2 --enable-omx --enable-openal --enable-opencl --enable-opengl --enable-sdl2 --enable-libdc1394 --enable-libdrm --enable-libiec61883 --enable-nvenc --enable-chromaprint --enable-frei0r --enable-libx264 --enable-shared

  libavutil      56. 31.100 / 56. 31.100

  libavcodec     58. 54.100 / 58. 54.100

  libavformat    58. 29.100 / 58. 29.100

  libavdevice    58.  8.100 / 58.  8.100

  libavfilter     7. 57.100 /  7. 57.100

  libavresample   4.  0.  0 /  4.  0.  0

  libswscale      5.  5.100 /  5.  5.100

  libswresample   3.  5.100 /  3.  5.100

  libpostproc    55.  5.100 / 55.  5.100

    nan    :  0.000 fd=   0 aq=    0KB vq=    0KB sq=    0B f=0/0   

Input #0, mov,mp4,m4a,3gp,3g2,mj2, from 'sample-mp4-file.mp4':

  Metadata:

    major_brand     : isom

    minor_version   : 512

    compatible_brands: isomiso2avc1mp41

    creation_time   : 1970-01-01T00:00:00.000000Z

    encoder         : Lavf53.24.2

  Duration: 00:02:05.95, start: 0.000000, bitrate: 669 kb/s

    Stream #0:0(und): Video: h264 (Main) (avc1 / 0x31637661), yuv420p, 320x240 [SAR 1:1 DAR 4:3], 282 kb/s, 15 fps, 15 tbr, 15360 tbn, 30 tbc (default)

    Metadata:

      creation_time   : 1970-01-01T00:00:00.000000Z

      handler_name    : VideoHandler

    Stream #0:1(und): Audio: aac (LC) (mp4a / 0x6134706D), 48000 Hz, 5.1, fltp, 383 kb/s (default)

    Metadata:

      creation_time   : 1970-01-01T00:00:00.000000Z

      handler_name    : SoundHandler

  -0.01 A-V: -0.034 fd=   0 aq=  137KB vq=   93KB sq=    0B f=0/0   

   0.04 A-V: -0.027 fd=   0 aq=  135KB vq=   93KB sq=    0B f=0/0   

   0.07 A-V: -0.024 fd=   0 aq=  137KB vq=   94KB sq=    0B f=0/0   

   0.11 A-V: -0.022 fd=   0 aq=  135KB vq=   94KB sq=    0B f=0/0   

   0.14 A-V: -0.020 fd=   0 aq=  136KB vq=   94KB sq=    0B f=0/0   

   0.18 A-V: -0.020 fd=   0 aq=  136KB vq=   94KB sq=    0B f=0/0   

   0.20 A-V: -0.027 fd=   0 aq=  137KB vq=   92KB sq=    0B f=0/0   

   0.24 A-V: -0.025 fd=   0 aq=  135KB vq=   92KB sq=    0B f=0/0   

   0.27 A-V: -0.023 fd=   0 aq=  136KB vq=   93KB sq=    0B f=0/0   

   0.31 A-V: -0.020 fd=   0 aq=  134KB vq=   93KB sq=    0B f=0/0   

   0.34 A-V: -0.020 fd=   0 aq=  137KB vq=   89KB sq=    0B f=0/0   

   0.37 A-V: -0.028 fd=   0 aq=  135KB vq=   89KB sq=    0B f=0/0   

   0.41 A-V: -0.025 fd=   0 aq=  136KB vq=   89KB sq=    0B f=0/0   

   0.44 A-V: -0.023 fd=   0 aq=  134KB vq=   89KB sq=    0B f=0/0   

   0.48 A-V: -0.020 fd=   0 aq=  135KB vq=   86KB sq=    0B f=0/0   

   0.51 A-V: -0.020 fd=   0 aq=  135KB vq=   86KB sq=    0B f=0/0   

   0.54 A-V: -0.028 fd=   0 aq=  137KB vq=   83KB sq=    0B f=0/0   

   0.57 A-V: -0.025 fd=   0 aq=  134KB vq=   83KB sq=    0B f=0/0   

   0.61 A-V: -0.023 fd=   0 aq=  137KB vq=   82KB sq=    0B f=0/0   

   0.64 A-V: -0.020 fd=   0 aq=  135KB vq=   82KB sq=    0B f=0/0   

   0.68 A-V: -0.020 fd=   0 aq=  138KB vq=   78KB sq=    0B f=0/0   

   0.70 A-V: -0.027 fd=   0 aq=  136KB vq=   78KB sq=    0B f=0/0   

   0.74 A-V: -0.025 fd=   0 aq=  138KB vq=   76KB sq=    0B f=0/0   

   0.77 A-V: -0.022 fd=   0 aq=  136KB vq=   76KB sq=    0B f=0/0   

   0.81 A-V: -0.020 fd=   0 aq=  139KB vq=   73KB sq=    0B f=0/0   

   0.84 A-V: -0.020 fd=   0 aq=  137KB vq=   73KB sq=    0B f=0/0   

   0.87 A-V: -0.027 fd=   0 aq=  138KB vq=   69KB sq=    0B f=0/0   

   0.90 A-V: -0.025 fd=   0 aq=  136KB vq=   69KB sq=    0B f=0/0   

   0.94 A-V: -0.023 fd=   0 aq=  138KB vq=   67KB sq=    0B f=0/0   

   0.97 A-V: -0.023 fd=   0 aq=  138KB vq=   67KB sq=    0B f=0/0   

   1.01 A-V: -0.020 fd=   0 aq=  139KB vq=   64KB sq=    0B f=0/0   

   1.03 A-V: -0.028 fd=   0 aq=  137KB vq=   64KB sq=    0B f=0/0   

   1.07 A-V: -0.025 fd=   0 aq=  138KB vq=   62KB sq=    0B f=0/0   

   1.10 A-V: -0.025 fd=   0 aq=  138KB vq=   62KB sq=    0B f=0/0   

   1.14 A-V: -0.023 fd=   0 aq=  140KB vq=   60KB sq=    0B f=0/0   

   1.17 A-V: -0.020 fd=   0 aq=  138KB vq=   60KB sq=    0B f=0/0   

   1.20 A-V: -0.028 fd=   0 aq=  139KB vq=   57KB sq=    0B f=0/0   

   1.23 A-V: -0.028 fd=   0 aq=  139KB vq=   57KB sq=    0B f=0/0   

   1.27 A-V: -0.025 fd=   0 aq=  140KB vq=   56KB sq=    0B f=0/0   

   1.30 A-V: -0.023 fd=   0 aq=  138KB vq=   56KB sq=    0B f=0/0   

   1.34 A-V: -0.020 fd=   0 aq=  139KB vq=   54KB sq=    0B f=0/0   

我想这就是您要找的。