diff options
author | Melody Horn <melody@boringcactus.com> | 2020-12-24 04:56:55 -0700 |
---|---|---|
committer | Melody Horn <melody@boringcactus.com> | 2020-12-24 04:56:55 -0700 |
commit | 3364694f14f8a0b92ce70ca608a73966c4043256 (patch) | |
tree | de2a073ad2660b094fdf5152cfae353578eb488e /output.py | |
parent | 940e8754bc13f9f601c5f3db58e4a1ab7d05e2ea (diff) | |
download | vidslice-3364694f14f8a0b92ce70ca608a73966c4043256.tar.gz vidslice-3364694f14f8a0b92ce70ca608a73966c4043256.zip |
switch from wxpython to tkinter
Diffstat (limited to 'output.py')
-rw-r--r-- | output.py | 174 |
1 files changed, 95 insertions, 79 deletions
@@ -1,87 +1,100 @@ import os import subprocess import threading - -import wx +from tkinter import * +from tkinter import filedialog +from tkinter import ttk from options import FFmpegOptions -class OutputPanel(wx.Panel): - def __init__(self, *args, get_ffmpeg_args=lambda: FFmpegOptions([], []), **kw): - super(OutputPanel, self).__init__(*args, **kw) +class OutputPanel(ttk.LabelFrame): + def __init__(self, *args, get_ffmpeg_args=lambda: FFmpegOptions([], []), get_frame_count=lambda: 0, **kw): + super(OutputPanel, self).__init__(*args, text='Output', **kw) self.update_listeners = [] self.input_path = None self.get_ffmpeg_args = get_ffmpeg_args + self.get_frame_count = get_frame_count + + ttk.Label(self, text="File").grid(column=0, row=0, sticky=W) + self.file_text = StringVar(self) + ttk.Entry(self, textvariable=self.file_text, width=30).grid(column=1, row=0, columnspan=2, sticky=(E, W)) + self.columnconfigure(1, weight=1) + self.columnconfigure(2, weight=1) + self.file_text.trace_add("write", self.handle_file_changed) + ttk.Button(self, text="Browse", command=self.handle_file_browse_pressed).grid(column=3, row=0, sticky=E) + + self.silence = BooleanVar(self) + ttk.Checkbutton(self, text="Silence", variable=self.silence, onvalue=True, offvalue=False + ).grid(column=0, row=1, columnspan=2, sticky=W) + self.deepfry = BooleanVar(self) + ttk.Checkbutton(self, text="Compress beyond recognition", variable=self.deepfry, onvalue=True, offvalue=False + ).grid(column=2, row=1, columnspan=2, sticky=W) + + run_button = ttk.Button(self, text="Run", command=self.handle_run_pressed) + run_button.grid(column=0, row=2, sticky=(E, W)) + run_preview_button = ttk.Button(self, text="Run & Preview", command=self.handle_run_preview_pressed) + run_preview_button.grid(column=1, row=2, columnspan=2, sticky=(E, W)) + run_quit_button = ttk.Button(self, text="Run & Quit", command=self.handle_run_quit_pressed) + run_quit_button.grid(column=3, row=2, sticky=(E, W)) + + self.progress = ttk.Progressbar(self, orient=HORIZONTAL, mode='determinate') + self.progress.grid(column=0, row=3, columnspan=4, sticky=(N, S, E, W)) + + self.logs = StringVar(self) + logs_widget = ttk.Label(self, textvariable=self.logs, font="TkFixedFont", + justify='left') + logs_widget.grid(column=0, row=4, columnspan=4, sticky=(N, S, E, W)) + self.rowconfigure(4, weight=1) + + for child in self.winfo_children(): + child.grid_configure(padx=2, pady=2) + + self.enable(False) + + def enable(self, enabled, run_enabled=None): + if run_enabled is None: + run_enabled = enabled + state = 'disabled' + if enabled: + state = '!' + state + run_state = 'disabled' + if run_enabled: + run_state = '!' + run_state + self.state([state]) + for child in self.winfo_children(): + if 'text' in child.configure() and child['text'].startswith('Run'): + child.state([run_state]) + else: + child.state([state]) - root_sizer = wx.StaticBoxSizer(wx.VERTICAL, self, label="Output") - self.SetSizer(root_sizer) - - file_panel = wx.Panel(self) - root_sizer.Add(file_panel, flag=wx.EXPAND, border=5) - file_sizer = wx.BoxSizer(wx.HORIZONTAL) - file_panel.SetSizer(file_sizer) - file_sizer.Add(wx.StaticText(file_panel, label="File"), flag=wx.EXPAND, border=5) - self.file_text = wx.TextCtrl(file_panel) - self.file_text.Bind(wx.EVT_TEXT, self.handle_file_changed) - file_sizer.Add(self.file_text, proportion=1, flag=wx.EXPAND, border=5) - self.file_browse_button = wx.Button(file_panel, label="Browse") - self.file_browse_button.Bind(wx.EVT_BUTTON, self.handle_file_browse_pressed) - file_sizer.Add(self.file_browse_button, flag=wx.EXPAND, border=5) - - options_panel = wx.Panel(self) - root_sizer.Add(options_panel, flag=wx.EXPAND, border=5) - options_sizer = wx.BoxSizer(wx.HORIZONTAL) - options_panel.SetSizer(options_sizer) - self.silence = wx.CheckBox(options_panel, label="Silence") - options_sizer.Add(self.silence, proportion=1, flag=wx.EXPAND, border=5) - self.deepfry = wx.CheckBox(options_panel, label="Compress beyond recognition") - options_sizer.Add(self.deepfry, proportion=1, flag=wx.EXPAND, border=5) - - self.run_panel = wx.Panel(self) - root_sizer.Add(self.run_panel, flag=wx.EXPAND, border=5) - run_sizer = wx.BoxSizer(wx.HORIZONTAL) - self.run_panel.SetSizer(run_sizer) - run_button = wx.Button(self.run_panel, label="Run") - run_button.Bind(wx.EVT_BUTTON, self.handle_run_pressed) - run_sizer.Add(run_button, proportion=1, flag=wx.EXPAND, border=5) - run_preview_button = wx.Button(self.run_panel, label="Run && Preview") - run_preview_button.Bind(wx.EVT_BUTTON, self.handle_run_preview_pressed) - run_sizer.Add(run_preview_button, proportion=1, flag=wx.EXPAND, border=5) - run_quit_button = wx.Button(self.run_panel, label="Run && Quit") - run_quit_button.Bind(wx.EVT_BUTTON, self.handle_run_quit_pressed) - run_sizer.Add(run_quit_button, proportion=1, flag=wx.EXPAND, border=5) - self.run_panel.Disable() - - self.logs = wx.TextCtrl(self, style=wx.TE_MULTILINE | wx.TE_READONLY) - root_sizer.Add(self.logs, proportion=1, flag=wx.EXPAND, border=5) - - self.Disable() - - def handle_file_changed(self, _): - path = self.file_text.GetValue() + def handle_file_changed(self, *args): + path = self.file_text.get() (folder, name) = os.path.split(path) try: os.stat(folder) - self.run_panel.Enable() + self.enable(True) except FileNotFoundError: - self.run_panel.Disable() + self.enable(True, False) - def handle_file_browse_pressed(self, _): - dialog = wx.FileDialog(self, style=wx.FD_SAVE | wx.FD_OVERWRITE_PROMPT) - if dialog.ShowModal() == wx.ID_OK: - self.file_text.SetValue(dialog.GetPath()) + def handle_file_browse_pressed(self, *args): + filename = filedialog.asksaveasfilename(parent=self) + if filename != '': + self.file_text.set(filename) - def handle_run_pressed(self, _, callback=lambda _: None): - self.logs.Clear() - self.run_panel.Disable() + def handle_run_pressed(self, *args, callback=lambda _: None): + self.logs.set('') + self.progress['value'] = 0 + self.enable(False) real_args = self.get_ffmpeg_args() + self.progress['maximum'] = float(self.get_frame_count()) + print(self.get_frame_count()) input_args = real_args.input output_args = real_args.output - output_path = self.file_text.GetValue() + output_path = self.file_text.get() (folder, name) = os.path.split(output_path) (name, ext) = os.path.splitext(name) - if self.silence.GetValue(): + if self.silence.get(): output_args += ['-an'] if ext == '.gif': filter_before = '[0:v] ' @@ -95,12 +108,14 @@ class OutputPanel(wx.Panel): output_args[i:i + 2] = [] break output_args += ['-filter_complex', filter_before + filter_during + filter_after] - if self.deepfry.GetValue(): + if self.deepfry.get(): if ext == '.mp3': output_args += ['-q:a', '9'] else: output_args += ['-q:a', '0.1', '-crf', '51'] - args = ['ffmpeg', '-hide_banner', '-y'] + input_args + ['-i', self.input_path] + output_args + [output_path] + args = ['ffmpeg', '-hide_banner', '-v', 'warning', '-stats', '-y'] + input_args + ['-i', + self.input_path] + output_args + [ + output_path] print(args) def run(): @@ -110,35 +125,36 @@ class OutputPanel(wx.Panel): while proc.poll() is None: out_data = proc.stdout.readline() if out_data != '': - wx.CallAfter(lambda: self.add_log(out_data)) - wx.CallAfter(lambda: self.run_panel.Enable()) - wx.CallAfter(lambda: callback(proc.returncode)) + progress_data = re.match(r'^frame=\s*(\d+)', out_data) + print(out_data, end='') + if progress_data is not None: + self.progress['value'] = float(progress_data.group(1)) + else: + self.logs.set(self.logs.get() + out_data) + self.enable(True) + callback(proc.returncode) threading.Thread(target=run).start() - def handle_run_preview_pressed(self, _event): + def handle_run_preview_pressed(self, *args): def preview(code): if code == 0: - out_file = self.file_text.GetValue() + out_file = self.file_text.get() subprocess.Popen(['ffplay', '-autoexit', out_file], creationflags=subprocess.CREATE_NO_WINDOW) - self.handle_run_pressed(_event, callback=preview) + self.handle_run_pressed(*args, callback=preview) - def handle_run_quit_pressed(self, _event): + def handle_run_quit_pressed(self, *args): def quit(code): if code == 0: - parent = self.GetTopLevelParent() - parent.Close(True) + toplevel = self.winfo_toplevel() + toplevel.destroy() - self.handle_run_pressed(_event, callback=quit) + self.handle_run_pressed(*args, callback=quit) def set_input_path(self, path, data): + self.enable(data is not None) if data is None: self.input_path = None - self.Disable() else: self.input_path = path - self.Enable() - - def add_log(self, data): - self.logs.AppendText(data) |