PySimpleGUI/UserCreatedPrograms/jumpcutter/jumpcutter_gui.py

110 lines
5.3 KiB
Python
Raw Normal View History

2020-09-11 10:49:22 +00:00
import PySimpleGUI as sg
import subprocess
import sys
"""
Jumpcutter GUI
This is a front-end GUI for a command line tool named jumpcutter.
jumpcutter is a command line based tool written by Carykh. You'll find the repo here:
https://github.com/carykh/jumpcutter
The design of this GUI was made in a way that should not have required any changes to the
jumpcutter.py file. However, there appears to be a bug in the original code. The sample rate
argument was specified as a float, but this later causes a crash in the program, so a single
change was made to line 68, changing the parameter from a float to an int. You can get around
this change by not specifying a default value in this GUI. Rather than specifying 44100, leave it blank
which will cause the parameter to be skipped.
This kind of GUI can be applied to a large number of other commandline programs.
NOTE - it has not yet been tested on Linux. It's only been tested on Windows. Hoping to get it
tested out on Linux shortly.
Copyright 2020 PySimpleGUI.org
"""
def build_parameter_string(values):
values_to_parm = {'-FILE-' : '--input_file',
'-URL-' : '--url',
'-OUT FILE-' : '--output_file',
'-SILENT THRESHOLD-' : '--silent_threshold',
'-SOUNDED SPEED-' : '--sounded_speed',
'-SILENT SPEED-' : '--silent_speed',
'-FRAME MARGIN-' : '--frame_margin',
'-SAMPLE RATE-' : '--sample_rate',
'-FRAME RATE-' : '--frame_rate',
'-FRAME QUALITY-' : '--frame_quality',
}
parms = ''
for key in values:
if key not in values_to_parm:
continue
if values[key] != '':
parms += f"{values_to_parm[key]} {values[key]} "
return(parms)
def main():
def FText(text, in_key=None, default=None, tooltip=None, input_size=(20,1)):
"""
A "Fixed-sized Text Input". Returns a row with a Text and an Input element.
"""
return [sg.Text(text, size=(20, 1), justification='r', tooltip=tooltip), sg.Input(default_text=default, key=in_key, size=input_size)]
layout = [
[sg.Text('Jump Cutter', font='Any 20')],
FText('Input File', '-FILE-', '', 'the video file you want modified', input_size=(40,1)) + [sg.FileBrowse()],
FText('URL', '-URL-', '', 'A youtube url to download and process', input_size=(40,1)),
FText('Output File', '-OUT FILE-', '', "the output file. (optional. if not included, it'll just modify the input file name)", input_size=(40,1)) + [sg.FileSaveAs()],
FText('Silent Threshold', '-SILENT THRESHOLD-', 0.03,
"the volume amount that frames' audio needs to surpass to be consider \"sounded\". It ranges from 0 (silence) to 1 (max volume)"),
FText('Sounded Speed', '-SOUNDED SPEED-', 1.00, "the speed that sounded (spoken) frames should be played at. Typically 1."),
FText('Silent Speed', '-SILENT SPEED-', 5.00, "the speed that silent frames should be played at. 999999 for jumpcutting."),
FText('Frame Margin', '-FRAME MARGIN-', 1,
"some silent frames adjacent to sounded frames are included to provide context. How many frames on either the side of speech should be included? That's this variable."),
FText('Sample Rate', '-SAMPLE RATE-', '44100', "sample rate of the input and output videos"),
FText('Frame Rate', '-FRAME RATE-', 30,
"frame rate of the input and output videos. optional... I try to find it out myself, but it doesn't always work."),
FText('Frame Quality', '-FRAME QUALITY-', 3, "quality of frames to be extracted from input video. 1 is highest, 31 is lowest, 3 is the default."),
[sg.MLine(size=(90,10), reroute_stdout=True, reroute_stderr=True, reroute_cprint=True, write_only=True, font='Courier 10', autoscroll=True, key='-ML-')],
[sg.Button('Start'), sg.Button('Exit')],
]
window = sg.Window('Jump Cutter', layout)
while True:
event, values = window.read()
if event in (sg.WIN_CLOSED, 'Exit'):
break
if event == 'Start':
parms = build_parameter_string(values)
print('Your parameters = ', parms)
runCommand(cmd=r'python .\jumpcutter.py ' + parms, window=window)
sg.cprint('*'*20+'DONE'+'*'*20, background_color='red', text_color='white')
window.close()
def runCommand(cmd, timeout=None, window=None):
""" run shell command
@param cmd: command to execute
@param timeout: timeout for command execution
@param window: the PySimpleGUI window that the output is going to (needed to do refresh on)
@return: (return code from command, command output)
"""
p = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
output = ''
for line in p.stdout:
line = line.decode(errors='replace' if (sys.version_info) < (3, 5) else 'backslashreplace').rstrip()
output += line
print(line)
window.refresh() if window else None # yes, a 1-line if, so shoot me
retval = p.wait(timeout)
return (retval, output)
if __name__ == '__main__':
# sg.theme('Dark Grey 11')
main()