繁体   English   中英

如何在使用子进程时设置 output 文件。同时打开和隐藏 cmd window?

[英]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.

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