[英]How to set output file while using subprocess.Popen and hide cmd window at the same time?
我做了一个简单的应用程序,可以使用 FFMpeg 转换视频文件。 我将 Kivy 用于 UI。 我使用os.system()
执行 ffmpeg 命令,但是在使用此方法时,总是会弹出 cmd window。 因此,我尝试使用 subprocess.Popen subprocess.Popen()
执行 ffmpeg 命令,但我也想将 ffmpeg output 保存到文本文件中。
我试过了,但没有用:
subprocess.Popen(f"ffmpeg -i {path} -acodec {acodec} {output} > output.txt 2>&1", creationflags = 0x08000000, stdout="output.txt")
FFMpeg 转换视频但没有 output.txt 文件。 此代码适用于os.system()
如何在将 output 保存到文本文件时隐藏 cmd window?
我的完整 python 代码:
import os
from signal import SIGINT
import psutil
from time import sleep
from threading import Thread
from kivy.config import Config
Config.set('graphics', 'resizable', False)
Config.set('graphics', 'width', '400')
Config.set('graphics', 'height', '330')
from kivy.app import App
from kivy.uix.widget import Widget
from kivy.core.window import Window
from kivy.uix.popup import Popup
from kivy.properties import ObjectProperty
Window.clearcolor = (1, 1, 1, 1)
desktop = os.path.join(os.path.join(os.path.expanduser('~')), 'Desktop') + "\\"
def cmd(command):
os.system(command)
def getpid(prcs):
for proc in psutil.process_iter():
try:
pinf = proc.as_dict(attrs=["pid", "name"])
if prcs.lower() in pinf["name"].lower():
return pinf["pid"]
except (psutil.NoSuchProcess, psutil.AccessDenied, psutil.ZombieProcess):
return False
return False
# noinspection PyGlobalUndefined
def progress(app, path):
app.root.prgrss_bar.value = 0
app.root.prgrss_lbl.text = "Progress: %0"
if not os.getcwd().endswith("ffmpeg"):
os.chdir("ffmpeg")
inputpath = app.root.label.text
if inputpath.startswith("Choose"):
return
audio = app.root.audio.state
video = app.root.video.state
both = app.root.both.state
global line1
global line2
if video == "down" or both == "down":
command = f"ffprobe -v error -select_streams v:0 -show_entries stream=nb_frames -of default=nokey=1:noprint_wrappers=1 {inputpath} > output2.txt 2>&1"
os.system(command)
ffprobe = open("output2.txt", "r")
frames = int(ffprobe.read())
control = True
while control:
sleep(0.5)
with open(path, "r") as f:
for last_line in f:
pass
line1 = last_line
sleep(0.5)
with open(path, "r") as f:
for last_line in f:
pass
line2 = last_line
if line1 == line2:
app.root.prgrss_bar.value = 100
app.root.prgrss_lbl.text = "Progress: Finished"
control = False
else:
try:
current_frame = int(line2.split("=")[1].split()[0])
percentage = int(current_frame / frames * 100)
text = f"Progress: %{percentage}"
app.root.prgrss_lbl.text = text
app.root.prgrss_bar.value = percentage
if percentage == 100:
control = False
except ValueError or TypeError:
pass
elif audio == "down":
command = f"ffprobe -v error -show_entries format=duration -of default=noprint_wrappers=1:nokey=1 {app.root.label.text} > output2.txt 2>&1"
os.system(command)
ffprobe = open("output2.txt", "r")
duration = round(float(ffprobe.read()), 2)
control = True
while control:
sleep(0.5)
with open(path, "r") as f:
for last_line in f:
pass
line1 = last_line
sleep(0.5)
with open(path, "r") as f:
for last_line in f:
pass
line2 = last_line
if line1 == line2:
app.root.prgrss_bar.value = 100
app.root.prgrss_lbl.text = "Progress: Finished"
control = False
else:
try:
current = line2.split("=")[2].split()[0].split(":")
seconds = round((int(current[0]) * 3600) + (int(current[1]) * 60) + float(current[2]), 2)
percentage = int(seconds / duration * 100)
text = f"Progress: %{percentage}"
app.root.prgrss_lbl.text = text
app.root.prgrss_bar.value = percentage
if percentage == 100:
control = False
except ValueError or TypeError:
pass
class Window(Widget):
@staticmethod
def popup_open():
popup = FolderPopup()
popup.open()
@staticmethod
def exists_open():
popup = Exists()
popup.open()
@staticmethod
def choose_open():
popup = ChooseFormat()
popup.open()
@staticmethod
def path_popup():
popup = ChoosePath()
popup.open()
@staticmethod
def unsupported_audio():
popup = UnsupportedAudio()
popup.open()
@staticmethod
def no_video_format():
popup = NoVideoFormat()
popup.open()
@staticmethod
def no_process():
popup = NoFFMPEGProcess()
popup.open()
def start(self, app):
path = app.root.label.text
if path.startswith("Choose"):
self.path_popup()
return
outname = app.root.outname.text
video_f = app.root.spinner.text
audio_f = app.root.spinner2.text
video = app.root.video.state
audio = app.root.audio.state
both = app.root.both.state
audio_supported = {"MP4": ["AAC", "MP3", "Opus"],
"MKV": ["AAC", "MP3", "Opus"],
"MOV": ["AAC", "MP3"],
"AVI": ["AAC", "MP3"],
"WMV": ["AAC", "MP3"]}
audio_ce = {"AAC": ["aac", ".m4a"],
"MP3": ["libmp3lame", ".mp3"],
"Opus": ["libopus", ".opus"],
"WAV": ["pcm_u8", ".wav"],
"Choose": ["Choose", "Choose"]}
if not os.getcwd().endswith("ffmpeg"):
os.chdir("ffmpeg")
video_ext = video_f.lower()
acodec = audio_ce[audio_f][0]
audio_ext = audio_ce[audio_f][1]
command = ""
if (video == "normal" and audio == "normal" and both == "normal") or (
video_f == "Choose" and audio_f == "Choose"):
self.choose_open()
return
elif video == "down":
if video_f == "Choose":
self.no_video_format()
return
output = f"{desktop}{outname}.{video_ext}"
if not os.path.exists(output):
command += f"ffmpeg -i {path} -an {output} > output.txt 2>&1"
else:
self.exists_open()
return
elif audio == "down":
output = f"{desktop}{outname}{audio_ext}"
if not os.path.exists(output):
command += f"ffmpeg -i {path} -vn -acodec {acodec} {output} > output.txt 2>&1"
else:
self.exists_open()
return
elif both == "down":
if video_f == "Choose":
self.no_video_format()
return
elif audio_f == "Choose":
output = f"{desktop}{outname}.{video_ext}"
if not os.path.exists(output):
command += f"ffmpeg -i {path} {output} > output.txt 2>&1"
else:
self.exists_open()
return
else:
if audio_f not in audio_supported[video_f]:
self.unsupported_audio()
return
else:
output = f"{desktop}{outname}.{video_ext}"
if not os.path.exists(output):
command += f"ffmpeg -i {path} -acodec {acodec} {output} > output.txt 2>&1"
else:
self.exists_open()
return
thrd = Thread(target=cmd, args=(command,))
thrd.start()
print("Thread started.")
def stop(self):
pid = getpid("ffmpeg")
if not pid:
self.no_process()
else:
os.kill(pid, SIGINT)
def test_open(self, app):
if not os.getcwd().endswith("ffmpeg"):
os.chdir("ffmpeg")
video = app.root.label.text
if video.startswith("Choose"):
return self.path_popup()
command = f"ffplay {video}"
os.system(command)
@staticmethod
def check_progress(app):
path = os.getcwd() + r"\output.txt"
chkprgrss = Thread(target=progress, args=(app, path,))
chkprgrss.start()
class FolderPopup(Popup):
dosya = ObjectProperty(None)
desktop = desktop
@staticmethod
def no_path_submit():
popup = NoPathSubmit()
popup.open()
def buton(self, app):
try:
app.root.label.text = self.dosya.selection[0]
self.dismiss()
except:
self.no_path_submit()
class Exists(Popup):
def buton(self):
self.dismiss()
class ChooseFormat(Popup):
def buton(self):
self.dismiss()
class ChoosePath(Popup):
def buton(self):
self.dismiss()
class UnsupportedAudio(Popup):
def buton(self):
self.dismiss()
class NoVideoFormat(Popup):
def buton(self):
self.dismiss()
class NoPathSubmit(Popup):
def buton(self):
self.dismiss()
class NoFFMPEGProcess(Popup):
def buton(self):
self.dismiss()
class GUI(App):
def build(self):
return Window()
if __name__ == "__main__":
GUI().run()
用户发布了答案并删除了,但我根据他/她的答案找到了解决方案。
我使用了这段代码:
with open("output.txt", "w") as output:
subprocess.run( ["ffmpeg", "-i", "video.mp4", "-acodec", "aac", "namnum.mov"], stdout=output, stderr=output, text=True, check=True, creationflags=0x08000000)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.