gpt4 book ai didi

Python ffmpeg 子进程永远不会在 Linux 上退出,适用于 Windows

转载 作者:行者123 更新时间:2023-12-04 23:11:16 28 4
gpt4 key购买 nike

我想知道是否有人可以帮助解释发生了什么?
我运行 2 个子进程,1 个用于 ffprobe,1 个用于 ffmpeg。

popen = subprocess.Popen(ffprobecmd, stderr=subprocess.PIPE, shell=True)
popen = subprocess.Popen(ffmpegcmd, shell=True, stdout=subprocess.PIPE)
在 Windows 和 Linux 上,ffprobe 命令都会触发、完成并从 taskmanager/htop 中删除。但只有在 Windows 上,ffmpeg 才会发生同样的情况。在 Linux 上,该命令保留在 htop...
enter image description here
任何人都可以解释发生了什么,如果它很重要,我该如何阻止它发生?
编辑:这里是命令...
ffprobecmd = 'ffprobe' + \
' -user_agent "' + request.headers['User-Agent'] + '"' + \
' -headers "Referer: ' + request.headers['Referer'] + '"' + \
' -timeout "5000000"' + \
' -v error -select_streams v -show_entries stream=height -of default=nw=1:nk=1' + \
' -i "' + request.url + '"'
ffmpegcmd = 'ffmpeg' + \
' -re' + \
' -user_agent "' + r.headers['User-Agent'] + '"' + \
' -headers "Referer: ' + r.headers['Referer'] + '"' + \
' -timeout "10"' + \
' -i "' + r.url + '"' + \
' -c copy' + \
' -f mpegts' + \
' pipe:'
编辑:这是一个行为如所描述的示例......
import flask
from flask import Response
import subprocess

app = flask.Flask(__name__)

@app.route('/', methods=['GET'])
def go():
def stream(ffmpegcmd):
popen = subprocess.Popen(ffmpegcmd, stdout=subprocess.PIPE, shell=True)
try:
for stdout_line in iter(popen.stdout.readline, ""):
yield stdout_line
except GeneratorExit:
raise

url = "https://bitdash-a.akamaihd.net/content/MI201109210084_1/m3u8s/f08e80da-bf1d-4e3d-8899-f0f6155f6efa.m3u8"

ffmpegcmd = 'ffmpeg' + \
' -re' + \
' -timeout "10"' + \
' -i "' + url + '"' + \
' -c copy' + \
' -f mpegts' + \
' pipe:'
return Response(stream(ffmpegcmd))

if __name__ == '__main__':
app.run(host= '0.0.0.0', port=5000)

最佳答案

你有额外的sh由于 shell=True 处理,并且您的 ffmpeg 副本被允许尝试附加到原始终端的标准输入,因为您没有覆盖该文件句柄。要修复这两个问题以及一些安全漏洞,请切换到 shell=False , 设置 stdin=subprocess.DEVNULL , 和(为了阻止僵尸可能被抛在后面,请注意下面的 finally: block ,它调用 popen.poll() 来查看 child 是否退出,popen.terminate() 告诉它在没有退出时退出):

#!/usr/bin/env python

import flask
from flask import Response
import subprocess

app = flask.Flask(__name__)

@app.route('/', methods=['GET'])
def go():
def stream(ffmpegcmd):
popen = subprocess.Popen(ffmpegcmd, stdin=subprocess.DEVNULL, stdout=subprocess.PIPE)
try:
# NOTE: consider reading fixed-sized blocks (4kb at least) at a time
# instead of parsing binary streams into "lines".
for stdout_line in iter(popen.stdout.readline, ""):
yield stdout_line
finally:
if popen.poll() == None:
popen.terminate()
popen.wait() # yes, this can cause things to actually block

url = "https://bitdash-a.akamaihd.net/content/MI201109210084_1/m3u8s/f08e80da-bf1d-4e3d-8899-f0f6155f6efa.m3u8"

ffmpegcmd = [
'ffmpeg',
'-re',
'-timeout', '10',
'-i', url,
'-c', 'copy',
'-f', 'mpegts',
'pipe:'
]
return Response(stream(ffmpegcmd))

if __name__ == '__main__':
app.run(host= '127.0.0.1', port=5000)
请注意,将二进制流解析为一系列行根本不合适。使用 block (并更改响应 header 以便浏览器知道将内容解析为视频)会更合适。

关于Python ffmpeg 子进程永远不会在 Linux 上退出,适用于 Windows,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/67661268/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com