diff --git a/bin/ffx.py b/bin/ffx.py index 3a0ac9c..c531707 100755 --- a/bin/ffx.py +++ b/bin/ffx.py @@ -1,15 +1,37 @@ #! /usr/bin/python3 -import os, sys, subprocess, json +import os, sys, subprocess, json, click + +VERSION='0.1.0' + +DEFAULT_VIDEO_ENCODER = 'vp9' DEFAULT_QUALITY = 23 + DEFAULT_AV1_PRESET = 5 + DEFAULT_STEREO_BANDWIDTH = "128" DEFAULT_AC3_BANDWIDTH = "256" DEFAULT_DTS_BANDWIDTH = "320" +DEFAULT_CROP_START = 60 +DEFAULT_CROP_LENGTH = 180 + TEMP_FILE_NAME = "ffmpeg2pass-0.log" + +MKVMERGE_METADATA_KEYS = ['BPS', + 'NUMBER_OF_FRAMES', + 'NUMBER_OF_BYTES', + '_STATISTICS_WRITING_APP', + '_STATISTICS_WRITING_DATE_UTC', + '_STATISTICS_TAGS'] + + +COMMAND_TOKENS = ['ffmpeg', '-y', '-i'] +NULL_TOKENS = ['-f', 'null', '/dev/null'] + + def executeProcess(commandSequence): process = subprocess.Popen(commandSequence, stdout=subprocess.PIPE, stderr=subprocess.PIPE) @@ -19,31 +41,91 @@ def executeProcess(commandSequence): return output + +#[{'index': 0, 'codec_name': 'vp9', 'codec_long_name': 'Google VP9', 'profile': 'Profile 0', 'codec_type': 'video', 'codec_tag_string': '[0][0][0][0]', 'codec_tag': '0x0000', 'width': 1920, 'height': 1080, 'coded_width': 1920, 'coded_height': 1080, 'closed_captions': 0, 'film_grain': 0, 'has_b_frames': 0, 'sample_aspect_ratio': '1:1', 'display_aspect_ratio': '16:9', 'pix_fmt': 'yuv420p', 'level': -99, 'color_range': 'tv', 'chroma_location': 'left', 'field_order': 'progressive', 'refs': 1, 'r_frame_rate': '24000/1001', 'avg_frame_rate': '24000/1001', 'time_base': '1/1000', 'start_pts': 0, 'start_time': '0.000000', 'disposition': {'default': 1, 'dub': 0, 'original': 0, 'comment': 0, 'lyrics': 0, 'karaoke': 0, 'forced': 0, 'hearing_impaired': 0, 'visual_impaired': 0, 'clean_effects': 0, 'attached_pic': 0, 'timed_thumbnails': 0, 'non_diegetic': 0, 'captions': 0, 'descriptions': 0, 'metadata': 0, 'dependent': 0, 'still_image': 0}, 'tags': {'BPS': '7974017', 'NUMBER_OF_FRAMES': '34382', 'NUMBER_OF_BYTES': '1429358655', '_STATISTICS_WRITING_APP': "mkvmerge v63.0.0 ('Everything') 64-bit", '_STATISTICS_WRITING_DATE_UTC': '2023-10-07 13:59:46', '_STATISTICS_TAGS': 'BPS DURATION NUMBER_OF_FRAMES NUMBER_OF_BYTES', 'ENCODER': 'Lavc61.3.100 libvpx-vp9', 'DURATION': '00:23:54.016000000'}}] +#[{'index': 1, 'codec_name': 'opus', 'codec_long_name': 'Opus (Opus Interactive Audio Codec)', 'codec_type': 'audio', 'codec_tag_string': '[0][0][0][0]', 'codec_tag': '0x0000', 'sample_fmt': 'fltp', 'sample_rate': '48000', 'channels': 2, 'channel_layout': 'stereo', 'bits_per_sample': 0, 'initial_padding': 312, 'r_frame_rate': '0/0', 'avg_frame_rate': '0/0', 'time_base': '1/1000', 'start_pts': -7, 'start_time': '-0.007000', 'extradata_size': 19, 'disposition': {'default': 1, 'dub': 0, 'original': 0, 'comment': 0, 'lyrics': 0, 'karaoke': 0, 'forced': 0, 'hearing_impaired': 0, 'visual_impaired': 0, 'clean_effects': 0, 'attached_pic': 0, 'timed_thumbnails': 0, 'non_diegetic': 0, 'captions': 0, 'descriptions': 0, 'metadata': 0, 'dependent': 0, 'still_image': 0}, 'tags': {'language': 'jpn', 'title': 'Japanisch', 'BPS': '128000', 'NUMBER_OF_FRAMES': '61763', 'NUMBER_OF_BYTES': '22946145', '_STATISTICS_WRITING_APP': "mkvmerge v63.0.0 ('Everything') 64-bit", '_STATISTICS_WRITING_DATE_UTC': '2023-10-07 13:59:46', '_STATISTICS_TAGS': 'BPS DURATION NUMBER_OF_FRAMES NUMBER_OF_BYTES', 'ENCODER': 'Lavc61.3.100 libopus', 'DURATION': '00:23:54.141000000'}}] + +#[{'index': 2, 'codec_name': 'webvtt', 'codec_long_name': 'WebVTT subtitle', 'codec_type': 'subtitle', 'codec_tag_string': '[0][0][0][0]', 'codec_tag': '0x0000', 'r_frame_rate': '0/0', 'avg_frame_rate': '0/0', 'time_base': '1/1000', 'start_pts': -7, 'start_time': '-0.007000', 'duration_ts': 1434141, 'duration': '1434.141000', 'disposition': {'default': 1, 'dub': 0, 'original': 0, 'comment': 0, 'lyrics': 0, 'karaoke': 0, 'forced': 0, 'hearing_impaired': 0, 'visual_impaired': 0, 'clean_effects': 0, 'attached_pic': 0, 'timed_thumbnails': 0, 'non_diegetic': 0, 'captions': 0, 'descriptions': 0, 'metadata': 0, 'dependent': 0, 'still_image': 0}, 'tags': {'language': 'ger', 'title': 'Deutsch [Full]', 'BPS': '118', 'NUMBER_OF_FRAMES': '300', 'NUMBER_OF_BYTES': '21128', '_STATISTICS_WRITING_APP': "mkvmerge v63.0.0 ('Everything') 64-bit", '_STATISTICS_WRITING_DATE_UTC': '2023-10-07 13:59:46', '_STATISTICS_TAGS': 'BPS DURATION NUMBER_OF_FRAMES NUMBER_OF_BYTES', 'ENCODER': 'Lavc61.3.100 webvtt', 'DURATION': '00:23:54.010000000'}}, {'index': 3, 'codec_name': 'webvtt', 'codec_long_name': 'WebVTT subtitle', 'codec_type': 'subtitle', 'codec_tag_string': '[0][0][0][0]', 'codec_tag': '0x0000', 'r_frame_rate': '0/0', 'avg_frame_rate': '0/0', 'time_base': '1/1000', 'start_pts': -7, 'start_time': '-0.007000', 'duration_ts': 1434141, 'duration': '1434.141000', 'disposition': {'default': 0, 'dub': 0, 'original': 0, 'comment': 0, 'lyrics': 0, 'karaoke': 0, 'forced': 0, 'hearing_impaired': 0, 'visual_impaired': 0, 'clean_effects': 0, 'attached_pic': 0, 'timed_thumbnails': 0, 'non_diegetic': 0, 'captions': 0, 'descriptions': 0, 'metadata': 0, 'dependent': 0, 'still_image': 0}, 'tags': {'language': 'eng', 'title': 'Englisch [Full]', 'BPS': '101', 'NUMBER_OF_FRAMES': '276', 'NUMBER_OF_BYTES': '16980', '_STATISTICS_WRITING_APP': "mkvmerge v63.0.0 ('Everything') 64-bit", '_STATISTICS_WRITING_DATE_UTC': '2023-10-07 13:59:46', '_STATISTICS_TAGS': 'BPS DURATION NUMBER_OF_FRAMES NUMBER_OF_BYTES', 'ENCODER': 'Lavc61.3.100 webvtt', 'DURATION': '00:23:53.230000000'}}] + + + +def getStreamDescriptor(filename): + + ffprobeOutput = executeProcess(["ffprobe", + "-show_streams", + "-of", "json", + filename]) + + streamData = json.loads(ffprobeOutput)['streams'] + + descriptor = [] + + for d in [s for s in streamData if s['codec_type'] == 'video']: + descriptor.append({ + 'index': d['index'], + 'type': 'video', + 'codec': d['codec_name'] + }) + + for d in [s for s in streamData if s['codec_type'] == 'audio']: + descriptor.append({ + 'index': d['index'], + 'type': 'audio', + 'codec': d['codec_name'], + 'channels': d['channels'] + }) + + for d in [s for s in streamData if s['codec_type'] == 'subtitle']: + descriptor.append({ + 'index': d['index'], + 'type': 'subtitle', + 'codec': d['codec_name'] + }) + + return descriptor + + + def generateAV1Tokens(q, p): - return ['-c:v:0', - 'libsvtav1', - '-svtav1-params', - f"crf={q}:preset={p}:tune=0:enable-overlays=1:scd=1:scm=0", + return ['-c:v:0', 'libsvtav1', + '-svtav1-params', f"crf={q}:preset={p}:tune=0:enable-overlays=1:scd=1:scm=0", '-pix_fmt', 'yuv420p10le'] def generateVP9Pass1Tokens(q): - return ['-c:v:0', 'libvpx-vp9', '-row-mt', '1', - '-crf', str(q), '-pass', '1', '-speed', '4', - '-frame-parallel', '0', '-g', '9999', '-aq-mode', '0'] + return ['-c:v:0', 'libvpx-vp9', + '-row-mt', '1', + '-crf', str(q), + '-pass', '1', + '-speed', '4', + '-frame-parallel', '0', + '-g', '9999', + '-aq-mode', '0'] def generateVP9Pass2Tokens(q): - return ['-c:v:0', 'libvpx-vp9', '-row-mt', '1', - '-crf', str(q), '-pass', '2', - '-frame-parallel', '0', '-g', '9999', '-aq-mode', '0', - '-auto-alt-ref', '1', '-lag-in-frames', '25'] + return ['-c:v:0', 'libvpx-vp9', + '-row-mt', '1', + '-crf', str(q), + '-pass', '2', + '-frame-parallel', '0', + '-g', '9999', + '-aq-mode', '0', + '-auto-alt-ref', '1', + '-lag-in-frames', '25'] + def generateCropTokens(start, length): return ['-ss', str(start), '-t', str(length)] + +def generateDenoiseTokens(spatial=5, patch=7, research=7, hw=False): + filterName = 'nlmeans_opencl' if hw else 'nlmeans' + return ['-vf', f"{filterName}=s={spatial}:p={patch}:r={research}"] + + def generateOutputTokens(f, q=''): if q: fTokens = f.split('.') @@ -52,186 +134,286 @@ def generateOutputTokens(f, q=''): else: return ['-f', 'webm', f] +# inputFilename = sys.argv[1] +# outputFilename = sys.argv[2] +# +# targetFormat = 'vp9' +# if 'av1' in sys.argv: +# targetFormat = 'av1' +# if 'vp9' in sys.argv: +# targetFormat = 'vp9' +# +# +# qualities = [str(DEFAULT_QUALITY)] +# qualitiesTokens = [q for q in sys.argv if q.startswith('q=')] +# if qualitiesTokens: +# qualitiesString = qualitiesTokens[0].split('=')[1] +# qualities = qualitiesString.split(',') +# +# preset = DEFAULT_AV1_PRESET +# presetTokens = [p for p in sys.argv if p.startswith('p=')] +# if presetTokens: +# preset = int(presetTokens[0].split('=')[1]) +# +# stereoBandwidth = DEFAULT_STEREO_BANDWIDTH +# stereoTokens = [s for s in sys.argv if s.startswith('a=')] +# if stereoTokens: +# stereoBandwidth = str(stereoTokens[0].split('=')[1]) +# if not stereoBandwidth.endswith('k'): +# stereoBandwidth += "k" +# +# ac3Bandwidth = DEFAULT_AC3_BANDWIDTH +# ac3Tokens = [a for a in sys.argv if a.startswith('ac3=')] +# if ac3Tokens: +# ac3Bandwidth = str(ac3Tokens[0].split('=')[1]) +# if not ac3Bandwidth.endswith('k'): +# ac3Bandwidth += "k" +# +# dtsBandwidth = DEFAULT_DTS_BANDWIDTH +# dtsTokens = [d for d in sys.argv if d.startswith('dts=')] +# if dtsTokens: +# dtsBandwidth = str(dtsTokens[0].split('=')[1]) +# if not dtsBandwidth.endswith('k'): +# dtsBandwidth += "k" +# +# cropStart = '' +# cropLength = '' +# cropTokens = [c for c in sys.argv if c.startswith('crop')] +# if cropTokens: +# if '=' in cropTokens[0]: +# cropString = cropTokens[0].split('=')[1] +# cropStart, cropLength = cropString.split(',') +# else: +# cropStart = 60 +# cropLength = 180 +# +# denoiseTokens = [d for d in sys.argv if d.startswith('denoise')] +# + +# for aStream in audioStreams: +# if 'channel_layout' in aStream: +# print(f"audio stream: {aStream['channel_layout']}") #channel_layout +# else: +# print(f"unknown audio stream with {aStream['channels']} channels") #channel_layout + +# +# audioTokens = [] +# audioStreamIndex = 0 +# for aStream in audioStreams: +# +# channels = aStream['channels'] +# +# if 'channel_layout' in aStream.keys(): +# +# channelLayout = aStream['channel_layout'] +# +# if channelLayout == '6.1': +# audioTokens += [f"-c:a:{audioStreamIndex}", +# 'libopus', +# f"-filter:a:{audioStreamIndex}", +# 'channelmap=channel_layout=6.1', +# f"-b:a:{audioStreamIndex}", +# dtsBandwidth] +# +# if channelLayout == '5.1(side)': +# audioTokens += [f"-c:a:{audioStreamIndex}", +# 'libopus', +# f"-filter:a:{audioStreamIndex}", +# "channelmap=FL-FL|FR-FR|FC-FC|LFE-LFE|SL-BL|SR-BR:5.1", +# f"-b:a:{audioStreamIndex}", +# ac3Bandwidth] +# +# if channelLayout == 'stereo': +# audioTokens += [f"-c:a:{audioStreamIndex}", +# 'libopus', +# f"-b:a:{audioStreamIndex}", +# stereoBandwidth] +# else: +# +# if channels == 6: +# audioTokens += [f"-c:a:{audioStreamIndex}", +# 'libopus', +# f"-filter:a:{audioStreamIndex}", +# "channelmap=FL-FL|FR-FR|FC-FC|LFE-LFE|SL-BL|SR-BR:5.1", +# f"-b:a:{audioStreamIndex}", +# ac3Bandwidth] +# +# +# audioStreamIndex += 1 +# +# +# nullTokens = ['-f', 'null', '/dev/null'] + +@click.group() +@click.pass_context +def ffx(ctx): + """FFX""" + pass + + +# Define a subcommand +@ffx.command() +def version(): + click.echo(VERSION) + + +# Another subcommand +@ffx.command() +def help(): + click.echo(f"ffx {VERSION}\n") + click.echo(f"Usage: ffx [input file] [output file] [vp9|av1] [q=[nn[,nn,...]]] [p=nn] [a=nnn[k]] [ac3=nnn[k]] [dts=nnn[k]] [crop]") + + +@click.argument('filename', nargs=1) +@ffx.command() +def streams(filename): + for d in getStreamDescriptor(filename): + click.echo(f"{d['codec']}{' (' + str(d['channels']) + ')' if d['type'] == 'audio' else ''}") + + +@ffx.command() +@click.argument('args', nargs=-1) + +@click.option('-ve', '--video-encoder', type=str, default=DEFAULT_VIDEO_ENCODER, help='Target video encoder (vp9 or av1) default: vp9') + +@click.option('-q', '--quality', type=str, default=DEFAULT_QUALITY, help='Quality settings to be used with VP9 encoder (default: 23)') +@click.option('-p', '--preset', type=str, default=DEFAULT_QUALITY, help='Quality preset to be used with AV1 encoder (default: 5)') + +@click.option('-a', '--stereo-bitrate', type=int, default=DEFAULT_STEREO_BANDWIDTH, help='Bitrate in kbit/s to be used to encode stereo audio streams') +@click.option('-ac3', '--ac3-bitrate', type=int, default=DEFAULT_AC3_BANDWIDTH, help='Bitrate in kbit/s to be used to encode 5.1 audio streams') +@click.option('-dts', '--dts-bitrate', type=int, default=DEFAULT_DTS_BANDWIDTH, help='Bitrate in kbit/s to be used to encode 6.1 audio streams') -inputFilename = sys.argv[1] -outputFilename = sys.argv[2] - -targetFormat = 'vp9' -if 'av1' in sys.argv: - targetFormat = 'av1' -if 'vp9' in sys.argv: - targetFormat = 'vp9' - - -qualities = [str(DEFAULT_QUALITY)] -qualitiesTokens = [q for q in sys.argv if q.startswith('q=')] -if qualitiesTokens: - qualitiesString = qualitiesTokens[0].split('=')[1] - qualities = qualitiesString.split(',') - -preset = DEFAULT_AV1_PRESET -presetTokens = [p for p in sys.argv if p.startswith('p=')] -if presetTokens: - preset = int(presetTokens[0].split('=')[1]) - -stereoBandwidth = DEFAULT_STEREO_BANDWIDTH -stereoTokens = [s for s in sys.argv if s.startswith('a=')] -if stereoTokens: - stereoBandwidth = str(stereoTokens[0].split('=')[1]) -if not stereoBandwidth.endswith('k'): - stereoBandwidth += "k" - -ac3Bandwidth = DEFAULT_AC3_BANDWIDTH -ac3Tokens = [a for a in sys.argv if a.startswith('ac3=')] -if ac3Tokens: - ac3Bandwidth = str(ac3Tokens[0].split('=')[1]) -if not ac3Bandwidth.endswith('k'): - ac3Bandwidth += "k" - -dtsBandwidth = DEFAULT_DTS_BANDWIDTH -dtsTokens = [d for d in sys.argv if d.startswith('dts=')] -if dtsTokens: - dtsBandwidth = str(dtsTokens[0].split('=')[1]) -if not dtsBandwidth.endswith('k'): - dtsBandwidth += "k" - -cropStart = '' -cropLength = '' -cropTokens = [c for c in sys.argv if c.startswith('crop')] -if cropTokens: - if '=' in cropTokens[0]: - cropString = cropTokens[0].split('=')[1] - cropStart, cropLength = cropString.split(',') - else: - cropStart = 60 - cropLength = 180 +@click.option('-ds', '--default-subtitle', type=int, help='Index of default subtitle stream') +@click.option('-da', '--default-audio', type=int, help='Index of default audio stream') +@click.option("--crop", is_flag=False, flag_value="default", default="none") -output = executeProcess(["ffprobe", "-show_streams", "-of", "json" ,inputFilename]) +@click.option("--clear-metadata", is_flag=True, default=False) -streamData = json.loads(output)['streams'] -videoStreams = [s for s in streamData if s['codec_type'] == 'video'] -audioStreams = [s for s in streamData if s['codec_type'] == 'audio'] -subtitleStreams = [s for s in streamData if s['codec_type'] == 'subtitle'] +def convert(args, video_encoder, quality, preset, stereo_bitrate, ac3_bitrate, dts_bitrate, crop, clear_metadata, default_subtitle, default_audio): -for aStream in audioStreams: - if 'channel_layout' in aStream: - print(f"audio stream: {aStream['channel_layout']}") #channel_layout - else: - print(f"unknown audio stream with {aStream['channels']} channels") #channel_layout + if len(args) != 2: + raise click.BadArgumentUsage( + 'Exactly 2 arguments containing the source file path and target file name must be provided\n' + 'Usage: ffx convert source_path target_filename' + ) -commandTokens = ['ffmpeg', '-y', '-i', inputFilename] + sourcePath = args[0] + targetFilename = args[1] + click.echo(f"src: {sourcePath} tgt: {targetFilename}") -mappingTokens = ['-map', 'v:0'] -for a in range(len(audioStreams)): - mappingTokens += ['-map', f"a:{a}"] + click.echo(f"ve={video_encoder}") -for s in range(len(subtitleStreams)): - mappingTokens += ['-map', f"s:{s}"] + q_list = quality.split(',') + click.echo(f"q={q_list}") -audioTokens = [] -audioStreamIndex = 0 -for aStream in audioStreams: - channels = aStream['channels'] - if 'channel_layout' in aStream.keys(): + click.echo(f"a={stereo_bitrate}") + click.echo(f"ac3={ac3_bitrate}") + click.echo(f"dts={dts_bitrate}") - channelLayout = aStream['channel_layout'] - if channelLayout == '6.1': - audioTokens += [f"-c:a:{audioStreamIndex}", - 'libopus', - f"-filter:a:{audioStreamIndex}", - 'channelmap=channel_layout=6.1', - f"-b:a:{audioStreamIndex}", - dtsBandwidth] + performCrop = (crop != 'none') - if channelLayout == '5.1(side)': - audioTokens += [f"-c:a:{audioStreamIndex}", - 'libopus', - f"-filter:a:{audioStreamIndex}", - "channelmap=FL-FL|FR-FR|FC-FC|LFE-LFE|SL-BL|SR-BR:5.1", - f"-b:a:{audioStreamIndex}", - ac3Bandwidth] - if channelLayout == 'stereo': - audioTokens += [f"-c:a:{audioStreamIndex}", - 'libopus', - f"-b:a:{audioStreamIndex}", - stereoBandwidth] - else: + if performCrop: - if channels == 6: - audioTokens += [f"-c:a:{audioStreamIndex}", - 'libopus', - f"-filter:a:{audioStreamIndex}", - "channelmap=FL-FL|FR-FR|FC-FC|LFE-LFE|SL-BL|SR-BR:5.1", - f"-b:a:{audioStreamIndex}", - ac3Bandwidth] + cropTokens = crop.split(',') + if cropTokens and len(cropTokens) == 2: - audioStreamIndex += 1 + cropStart, cropLength = crop.split(',') + else: + cropStart = DEFAULT_CROP_START + cropLength = DEFAULT_CROP_LENGTH + click.echo(f"crop start={cropStart} length={cropLength}") -nullTokens = ['-f', 'null', '/dev/null'] -for quality in qualities: + click.echo(f"\nRunning {len(q_list)} jobs") + + + for q in q_list: - if targetFormat == 'av1': + click.echo(f"\nRunning job q={q}") - commandSequence = commandTokens + mappingTokens + generateAV1Tokens(quality, preset) + audioTokens + streamDescriptor = getStreamDescriptor(sourcePath) - if cropStart: - commandSequence += generateCropTokens(cropStart, cropLength) + commandTokens = ['ffmpeg', '-y', '-i', sourcePath] - if len(qualities) > 1: - commandSequence += generateOutputTokens(outputFilename, quality) - else: - commandSequence += generateOutputTokens(outputFilename) + mappingVideoTokens = ['-map', 'v:0'] + mappingTokens = mappingVideoTokens.copy() - print(f"Command: {' '.join(commandSequence)}") + for a in range(len(audioStreams)): + mappingTokens += ['-map', f"a:{a}"] - executeProcess(commandSequence) + for s in range(len(subtitleStreams)): + mappingTokens += ['-map', f"s:{s}"] - if targetFormat == 'vp9': - commandSequence1 = commandTokens + mappingTokens + generateVP9Pass1Tokens(quality) + if video_encoder == 'av1': + commandSequence = COMMAND_TOKENS #+ mappingTokens + generateAV1Tokens(quality, preset) + audioTokens - if cropStart: - commandSequence1 += generateCropTokens(cropStart, cropLength) + #if cropStart: + # commandSequence += generateCropTokens(cropStart, cropLength) - commandSequence1 += nullTokens + #if len(qualities) > 1: + # commandSequence += generateOutputTokens(outputFilename, quality) + #else: + # commandSequence += generateOutputTokens(outputFilename) + print(f"Command: {' '.join(commandSequence)}") - print(f"Command 1: {' '.join(commandSequence1)}") + executeProcess(commandSequence) - if os.path.exists(TEMP_FILE_NAME): - os.remove(TEMP_FILE_NAME) - executeProcess(commandSequence1) - - commandSequence2 = commandTokens + mappingTokens + generateVP9Pass2Tokens(quality) + audioTokens + if video_encoder == 'vp9': + commandSequence1 = COMMAND_TOKENS #+ mappingVideoTokens + generateVP9Pass1Tokens(quality) - if cropStart: - commandSequence2 += generateCropTokens(cropStart, cropLength) + #if cropStart: + # commandSequence1 += generateCropTokens(cropStart, cropLength) + #commandSequence1 += nullTokens + + print(f"Command 1: {' '.join(commandSequence1)}") + + #if os.path.exists(TEMP_FILE_NAME): + # os.remove(TEMP_FILE_NAME) + + #executeProcess(commandSequence1) + + + commandSequence2 = COMMAND_TOKENS #+ mappingTokens + + #if denoiseTokens: + # commandSequence2 += generateDenoiseTokens() + + #commandSequence2 += generateVP9Pass2Tokens(quality) + audioTokens + + #if cropStart: + # commandSequence2 += generateCropTokens(cropStart, cropLength) + + #if len(qualities) > 1: + # commandSequence2 += generateOutputTokens(outputFilename, quality) + #else: + # commandSequence2 += generateOutputTokens(outputFilename) + + print(f"Command 2: {' '.join(commandSequence2)}") + + #executeProcess(commandSequence2) - if len(qualities) > 1: - commandSequence2 += generateOutputTokens(outputFilename, quality) - else: - commandSequence2 += generateOutputTokens(outputFilename) + click.echo('\nDONE\n') - print(f"Command 2: {' '.join(commandSequence2)}") - - executeProcess(commandSequence2) +if __name__ == '__main__': + ffx()