A "Table Driven" version. Uses a single dictionary to define all of the details needed to make the GUI and launch the commandline program

This commit is contained in:
PySimpleGUI 2020-09-12 08:53:40 -04:00
parent bc78af7436
commit 4c2ad59eca
1 changed files with 69 additions and 46 deletions

View File

@ -22,66 +22,89 @@ import sys
NOTE - it has not yet been tested on Linux. It's only been tested on Windows. Hoping to get it 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. tested out on Linux shortly.
KNOWN Problem - filenames with spaces. Working on it. For now, make a temp folder and make sure everything
has no spaces and you'll be fine. YouTube download wasn't working on the video I tried
Copyright 2020 PySimpleGUI.org Copyright 2020 PySimpleGUI.org
""" """
def build_parameter_string(values):
values_to_parm = {'-FILE-' : '--input_file', def FText(text, in_key=None, default=None, tooltip=None, input_size=None, text_size=None):
'-URL-' : '--url', """
'-OUT FILE-' : '--output_file', A "Fixed-sized Text Input". Returns a row with a Text and an Input element.
'-SILENT THRESHOLD-' : '--silent_threshold', """
'-SOUNDED SPEED-' : '--sounded_speed', if input_size is None:
'-SILENT SPEED-' : '--silent_speed', input_size = (20, 1)
'-FRAME MARGIN-' : '--frame_margin', if text_size is None:
'-SAMPLE RATE-' : '--sample_rate', text_size = (20, 1)
'-FRAME RATE-' : '--frame_rate', return [sg.Text(text, size=text_size, justification='r', tooltip=tooltip),
'-FRAME QUALITY-' : '--frame_quality', sg.Input(default_text=default, key=in_key, size=input_size, tooltip=tooltip)]
}
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 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 = [ # This version of the GUI uses this large dictionary to drive 100% of the creation of the
[sg.Text('Jump Cutter', font='Any 20')], # layout that collections the parameters for the command line call. It's really simplistic
FText('Input File', '-FILE-', '', 'the video file you want modified', input_size=(40,1)) + [sg.FileBrowse()], # at the moment with a tuple containing information about each entry.
FText('URL', '-URL-', '', 'A youtube url to download and process', input_size=(40,1)), # The definition of the GUI. Defines:
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()], # PSG Input Key
FText('Silent Threshold', '-SILENT THRESHOLD-', 0.03, # Tuple of items needed to build a line in the layout
"the volume amount that frames' audio needs to surpass to be consider \"sounded\". It ranges from 0 (silence) to 1 (max volume)"), # 0 - The command line's parameter
FText('Sounded Speed', '-SOUNDED SPEED-', 1.00, "the speed that sounded (spoken) frames should be played at. Typically 1."), # 1 - The text to display next to input
FText('Silent Speed', '-SILENT SPEED-', 5.00, "the speed that silent frames should be played at. 999999 for jumpcutting."), # 2 - The default value for the input
FText('Frame Margin', '-FRAME MARGIN-', 1, # 3 - Size of input field (None for default)
"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."), # 4 - Tooltip string
FText('Sample Rate', '-SAMPLE RATE-', '44100', "sample rate of the input and output videos"), # 5 - List of additional elements to include on the same row
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) input_defintion = {
'-FILE-' : ('--input_file', 'Input File', '', (40,1),'the video file you want modified', [sg.FileBrowse()]),
'-URL-' : ('--url','URL (not yet working)', '', (40,1), 'A youtube url to download and process', []),
'-OUT FILE-' : ('--output_file', 'Output File', '', (40,1), "the output file. (optional. if not included, it'll just modify the input file name)", [sg.FileSaveAs()]),
'-SILENT THRESHOLD-' : ('--silent_threshold', 'Silent Threshold', 0.03, None, "the volume amount that frames' audio needs to surpass to be consider \"sounded\". It ranges from 0 (silence) to 1 (max volume)", []),
'-SOUNDED SPEED-' : ('--sounded_speed', 'Sounded Speed', 1.00, None, "the speed that sounded (spoken) frames should be played at. Typically 1.", []),
'-SILENT SPEED-' : ('--silent_speed', 'Silent Speed', 5.00, None, "the speed that silent frames should be played at. 999999 for jumpcutting.", []),
'-FRAME MARGIN-' : ('--frame_margin', 'Frame Margin', 1, None, "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.", []),
'-SAMPLE RATE-' : ('--sample_rate', 'Sample Rate', 44100, None, "sample rate of the input and output videos", []),
'-FRAME RATE-' : ('--frame_rate', 'Frame Rate', 30, None, "frame rate of the input and output videos. optional... I try to find it out myself, but it doesn't always work.", []),
'-FRAME QUALITY-' : ('--frame_quality', 'Frame Quality', 3, None, "quality of frames to be extracted from input video. 1 is highest, 31 is lowest, 3 is the default.", [])
}
# the command that will be invoked with the parameters
command_to_run = r'python .\jumpcutter.py '
# Find longest input descrption
text_len = max([len(input_defintion[key][1]) for key in input_defintion])
# Top part of layout that's not table driven
layout = [[sg.Text('Jump Cutter', font='Any 20')]]
# Computed part of layout that's based on the dictionary of attributes (the table driven part)
for key in input_defintion:
layout_def = input_defintion[key]
line = FText(layout_def[1], in_key=key, default=layout_def[2], tooltip=layout_def[4], input_size=layout_def[3], text_size=(text_len,1))
if layout_def[5] != []:
line += layout_def[5]
layout += [line]
# Bottom part of layout that's not table driven
layout += [[sg.Text('Constructed Command Line:')],
[sg.Text(size=(80,3), key='-COMMAND LINE-', text_color='yellow', font='Courier 8')],
[sg.MLine(size=(80,10), reroute_stdout=True, reroute_stderr=True, reroute_cprint=True, write_only=True, font='Courier 8', autoscroll=True, key='-ML-')],
[sg.Button('Start'), sg.Button('Exit')]]
window = sg.Window('Jump Cutter', layout, finalize=True)
while True: while True:
event, values = window.read() event, values = window.read()
if event in (sg.WIN_CLOSED, 'Exit'): if event in (sg.WIN_CLOSED, 'Exit'):
break break
if event == 'Start': if event == 'Start':
parms = build_parameter_string(values) parms = ''
print('Your parameters = ', parms) for key in values:
runCommand(cmd=r'python .\jumpcutter.py ' + parms, window=window) if key not in input_defintion:
continue
if values[key] != '':
parms += f"{input_defintion[key][0]} {values[key]} "
command = command_to_run + parms
window['-COMMAND LINE-'].update(command)
runCommand(cmd=command, window=window)
sg.cprint('*'*20+'DONE'+'*'*20, background_color='red', text_color='white') sg.cprint('*'*20+'DONE'+'*'*20, background_color='red', text_color='white')
window.close() window.close()