在 subprocess.Popen 中使用通配符
Using wildcards in subprocess.Popen
我找到了几个解决通过 Popen 传递通配符问题的答案,但我似乎无法让这些解决方案适用于我的特定情况。
我有一个项目,按下按钮时会合并一个音频和视频文件,我需要使用subprocess.Popen来执行我想要的命令:
mergeFile = "ffmpeg -i /home/pi/Video/* -i /home/pi/Audio/test.wav -acodec copy -vcodec copymap 0:v -map 1:a /home/pi/Test/output.mkv"
proc= subprocess.Popen(shlex.split(mergeFiles), shell=True)
我基本上想获取我的视频文件夹中的任何文件(我的项目从摄像机下载视频,每次保存新视频时文件名都会更改)并合并来自单独 "Audio" 文件夹,然后将该文件保存到另一个文件夹。
我已经尝试将 shell 设置为 true,但没有任何效果。
我也不知道 glob 模块在这种情况下会如何帮助我。
这里的问题是shlex.split()
。当与 shell=True
一起使用时,它意味着只有字符串 ffmpeg
被视为脚本,并且命令行的其他组件作为参数传递给该脚本(它从不查看/ 阅读)。
mergeFile = "ffmpeg -i /home/pi/Video/* -i /home/pi/Audio/test.wav -acodec copy -vcodec copymap 0:v -map 1:a /home/pi/Test/output.mkv"
proc = subprocess.Popen(mergeFile, shell=True)
仍然使用 shell=True
的更好实践替代方案(如果您实际上正在参数化目录名称和文件名)可能是:
mergeFile=[
'ffmpeg -i ""/* -i "" -acodec copy -vcodec copymap 0:v -map 1:a ""',
'_', # placeholder for [=11=]
"/home/pi/Video", # directory for -- can use a variable here
"/home/pi/Audio/test.wav",
"/home/pi/Test/output.mkv",
]
subprocess.Popen(mergeFile, shell=True)
...在这种情况下 脚本本身 是常量(并且不能通过文件名或其他参数注入的值改变其含义),但是超出-可以提供波段数据。
更好的方法是完全停止使用 shell=True
。考虑:
import subprocess, glob
mergeFile=[
'ffmpeg', '-i',
] + (glob.glob('/home/pi/Video/*') or ['/home/pi/Video/*']) + [
'-i', '/home/pi/Audio/test.wav',
'-acodec', 'copy',
'-vcodec', 'copymap', '0:v',
'-map', '1:a1',
'/home/pi/Test/output.mkv'
]
subprocess.Popen(mergefile)
如果不存在与 glob 匹配的文件,or ['/home/pi/Video/*']
的存在会导致与 shell 相同的错误消息。显然,您也可以在这种情况下中止。
我找到了几个解决通过 Popen 传递通配符问题的答案,但我似乎无法让这些解决方案适用于我的特定情况。
我有一个项目,按下按钮时会合并一个音频和视频文件,我需要使用subprocess.Popen来执行我想要的命令:
mergeFile = "ffmpeg -i /home/pi/Video/* -i /home/pi/Audio/test.wav -acodec copy -vcodec copymap 0:v -map 1:a /home/pi/Test/output.mkv"
proc= subprocess.Popen(shlex.split(mergeFiles), shell=True)
我基本上想获取我的视频文件夹中的任何文件(我的项目从摄像机下载视频,每次保存新视频时文件名都会更改)并合并来自单独 "Audio" 文件夹,然后将该文件保存到另一个文件夹。
我已经尝试将 shell 设置为 true,但没有任何效果。
我也不知道 glob 模块在这种情况下会如何帮助我。
这里的问题是shlex.split()
。当与 shell=True
一起使用时,它意味着只有字符串 ffmpeg
被视为脚本,并且命令行的其他组件作为参数传递给该脚本(它从不查看/ 阅读)。
mergeFile = "ffmpeg -i /home/pi/Video/* -i /home/pi/Audio/test.wav -acodec copy -vcodec copymap 0:v -map 1:a /home/pi/Test/output.mkv"
proc = subprocess.Popen(mergeFile, shell=True)
仍然使用 shell=True
的更好实践替代方案(如果您实际上正在参数化目录名称和文件名)可能是:
mergeFile=[
'ffmpeg -i ""/* -i "" -acodec copy -vcodec copymap 0:v -map 1:a ""',
'_', # placeholder for [=11=]
"/home/pi/Video", # directory for -- can use a variable here
"/home/pi/Audio/test.wav",
"/home/pi/Test/output.mkv",
]
subprocess.Popen(mergeFile, shell=True)
...在这种情况下 脚本本身 是常量(并且不能通过文件名或其他参数注入的值改变其含义),但是超出-可以提供波段数据。
更好的方法是完全停止使用 shell=True
。考虑:
import subprocess, glob
mergeFile=[
'ffmpeg', '-i',
] + (glob.glob('/home/pi/Video/*') or ['/home/pi/Video/*']) + [
'-i', '/home/pi/Audio/test.wav',
'-acodec', 'copy',
'-vcodec', 'copymap', '0:v',
'-map', '1:a1',
'/home/pi/Test/output.mkv'
]
subprocess.Popen(mergefile)
如果不存在与 glob 匹配的文件,or ['/home/pi/Video/*']
的存在会导致与 shell 相同的错误消息。显然,您也可以在这种情况下中止。