简体   繁体   English

在python中启动和停止ffmpeg管道

[英]Starting and stopping an ffmpeg pipeline in python

I'm trying to start and stop an ffmpeg pipeline in my Python script. 我正在尝试在我的Python脚本中启动和停止ffmpeg管道。 I can get it to start the pipeline on command, using a subprocess, but it ties up the script, so that it no longer receives commands. 我可以使用一个子进程来使它按命令启动管道,但是它绑定了脚本,因此它不再接收命令。 What do I need to change to keep this from happening? 我需要更改什么才能阻止这种情况发生?

I'm using: 我正在使用:

    pipeline= "ffmpeg -f video4linux2 -video_size 640x480 -framerate 15 -input_format yuyv422 -i /dev/video7 -f alsa  -i hw:0,0 -map 0:0 -map 1:0  -b:v 120k -bufsize 120k -vcodec libx264 -preset ultrafast  -acodec aac -strict -2  -f flv -metadata streamName=myStream tcp://192.168.1.20:6666 "

    p = subprocess.Popen(pipeline, shell=True,
                         stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
    output = p.communicate()[0]

The problem with your code is that p.communicate() reads data until end-of-file is reached. 您的代码的问题在于p.communicate()会读取数据,直到到达文件末尾。 My Idea would be to use the multiprocessing module. 我的想法是使用multiprocessing模块。

Example: 例:

import subprocess
import multiprocessing

def ffmpeg():
    pipeline = 'ffmpeg ...'
    p = subprocess.Popen(pipeline, shell=True, stdout=subprocess.PIPE,
                         stderr=subprocess.PIPE)
    out = p.communicate()[0]

proc = multiprocessing.Process(target=ffmpeg)

This basically moves your code into the function ffmpeg and creates a new process to run it. 基本上,这会将您的代码移到ffmpeg函数中,并创建一个新进程来运行它。

You can now start the process using: proc.start() and terminate it using proc.terminate() . 您现在可以开始使用流程: proc.start()和使用终止它proc.terminate()

For more details have a look at the documentation of multiprocessing . 有关更多详细信息,请参阅多处理文档。

EDIT: 编辑:

multiprocessing is maybe kinda overkill. multiprocessing可能有点过大。 See JF Sebastian's comment. 参见JF Sebastian的评论。

p.communicate() call doesn't return until the process exits and all output is read. 在进程退出并读取所有输出之前,不会返回p.communicate()调用。

To avoid blocking your script, drop the p.communicate() call: 为避免阻塞脚本,请删除p.communicate()调用:

#!/usr/bin/env python3
import shlex
from subprocess import Popen, DEVNULL, STDOUT
# ...
p = Popen(shlex.split(pipeline), stdin=DEVNULL, stdout=DEVNULL, stderr=STDOUT)
# call p.terminate() any time you like, to terminate the ffmpeg process

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM