我有一个要从 Windows 文件浏览器上下文菜单 (https://www.howtogeek.com/107965/how-to-add-any-application-shortcut-to-windows-explorers-context-menu/) 调用的 python 脚本
我目前正在调试从非特定上下文(HKEY_CLASSES_ROOT\Directory\Background\shell)使用命令“python”D:\toolbox\mineAudio.py“0”调用它
(注意 python3 在路径上为 python,脚本位于 D:\toolbox\mineAudio.py)
当我从 cmd 调用脚本时,它可以使用该命令按预期工作,并且当我对脚本进行调试修改(将 os.system("pause") 添加到随机行)时,我可以验证它是否正确运行直到它打线meta=cmd(['ffmpeg','-i',target])
(第 46 行)它立即无声地失败(注意 ffmpeg 也在路径上)
编辑:它实际上到达第 15 行 result = subprocess.run(command, stdout=subprocess.PIPE,stderr=subprocess.PIPE,startupinfo=startupinfo)
我无法弄清楚为什么程序在那里失败,因为该行在我测试过上下文菜单以外的脚本的其他任何地方都可以正常工作。
如果您想浏览它,这是完整的脚本
import subprocess
import os
import sys
from sys import argv
from tree import tree
#for command line use:
#mineAudo.py [prompt=1] [dir=cwd]
#first arg prompt will prompt user for dir if 1, otherwise it wont
#second arg is the directory to use, if specified this will override prompt, if not and prompt=0, current working dir is used
def cmd(command):
startupinfo = subprocess.STARTUPINFO()
startupinfo.dwFlags |= subprocess.STARTF_USESHOWWINDOW
startupinfo.wShowWindow = subprocess.SW_HIDE
result = subprocess.run(command, stdout=subprocess.PIPE,stderr=subprocess.PIPE,startupinfo=startupinfo)
return result.stderr.decode("utf-8")
def stripStreams(meta):
i=1;
lines=[]
while i>0 :
i=meta.find("Stream",i+1)
lineEnd=meta.find("\n",i)
lines.append(meta[i:lineEnd])
return lines
def mineAudio(streams):
ret=[]
for stream in streams:
if "Audio:" in stream:
start =stream.find("#")+1
end=stream.find("(",start)
ret.append(stream[start:end])
return ret
def convDir(dirTarget):
targets=tree(dirTarget)
convList(targets,dirTarget)
def convList(targets,dirTarget):
print(targets)
#target="2018-05-31 06-16-39.mp4"
i=0
for target in targets:
i+=1
if(target[target.rfind("."):]==".mp4"):
print("("+str(i)+"/"+str(len(targets))+") starting file "+target)
meta=cmd(['ffmpeg','-i',target])
streams=stripStreams(meta)
streams=mineAudio(streams)
count=0
output=target[target.rfind("/")+1:target.rfind(".")]
file=target[target.rfind("/")+1:]
#print (output)
try:
os.mkdir(dirTarget+"\\"+output)
except:
pass
for s in streams:
print("converting track "+str(count+1)+" of "+str(len(streams)));
count+=1
cmd("ffmpeg -i \""+target+"\" -vn -sn -c:a mp3 -ab 192k -map "+s+" \""+dirTarget+"\\"+output+"\\"+output+" Track "+str(count)+".mp3\"")
print("moving "+target+" to "+dirTarget+"\\"+output+"\\"+file)
os.rename(target,dirTarget+"\\"+output+"\\"+file)
print("Finished file "+target)
else:
print("("+str(i)+"/"+str(len(targets))+") skiping non mp4 file "+target)
def prompt():
while True:
dirTarget=input("input target dir: ")
convDir(dirTarget)
if __name__ == "__main__":
sys.setrecursionlimit(2000)
if len(argv)>2:
if os.path.isdir(argv[2]):
convDir(argv[2])
else:
convList([argv[2]],os.path.dirname(argv[2]))
elif(len(argv)>1):
if int(argv[1])==1:
prompt()
else:
convDir(os.getcwd())
else:
prompt()
os.system("pause")
请注意,我并没有与这个特定的实现结婚,任何具有相同效果的实现(自动从 .mp4 文件中提取 .mp3 轨道)也可以
另外,这是文件树
#Returns the paths of all files in a directory and all sub directories relative to start directory
import os
def tree(directory,target="f"):
paths=[]
for currentDir,dirs,files in os.walk(directory):
if target=="f":
for file in files:
paths.append(currentDir+"/"+file)
if target=="d":
#paths.append(currentDir)
for dir in dirs:
paths.append(currentDir+"/"+dir)
for i in range(len(paths)):
paths[i]=paths[i].replace("\\","/")
return paths
谁能帮我搞定这个工作?
编辑:
这是一个较短的示例代码,它以相同的方式崩溃(尽管仍然使用 ffmpeg)
import subprocess
import os
def cmd(command):
startupinfo = subprocess.STARTUPINFO()
startupinfo.dwFlags |= subprocess.STARTF_USESHOWWINDOW
startupinfo.wShowWindow = subprocess.SW_HIDE
result = subprocess.run(command,stdin=subprocess.DEVNULL, stdout=subprocess.PIPE,stderr=subprocess.PIPE,startupinfo=startupinfo)
return result.stderr.decode("utf-8")
os.system("pause")
out=cmd(['ffmpeg','-i','D:\\ffmpeg test\\test\\2018-05-31 06-16-39\\2018-05-31 06-16-39.mp4'])
print(out)
os.system("pause")
(注意文件是硬编码的,程序输出应该是
)
最佳答案
我设法通过关于创建调用python脚本命令的批处理文件的hackish方式来“解决”问题,但这似乎有点hack,我认为会有更好的方法。
关于仅当从上下文菜单调用时,Python 脚本才会在 subprocess.run() 调用上执行失败,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55083813/