diff --git a/bin/ffx.py b/bin/ffx.py index 0f12f24..6585bb6 100755 --- a/bin/ffx.py +++ b/bin/ffx.py @@ -21,8 +21,11 @@ from ffx.track_disposition import TrackDisposition from ffx.process import executeProcess from ffx.helper import filterFilename +from ffx.constants import DEFAULT_QUALITY, DEFAULT_AV1_PRESET +from ffx.constants import DEFAULT_STEREO_BANDWIDTH, DEFAULT_AC3_BANDWIDTH, DEFAULT_DTS_BANDWIDTH, DEFAULT_7_1_BANDWIDTH -VERSION='0.2.0' + +VERSION='0.2.1' # 0.1.1 # Bugfixes, TMBD identify shows @@ -32,6 +35,9 @@ VERSION='0.2.0' # Subtitle file imports # 0.2.0 # Tests, Config-File +# 0.2.1 +# Signature, Tags cleaning, Bugfixes, Refactoring + @click.group() @click.pass_context @@ -258,12 +264,12 @@ def checkUniqueDispositions(context, mediaDescriptor: MediaDescriptor): @click.option('-v', '--video-encoder', type=str, default=FfxController.DEFAULT_VIDEO_ENCODER, help=f"Target video encoder (vp9 or av1) default: {FfxController.DEFAULT_VIDEO_ENCODER}") -@click.option('-q', '--quality', type=str, default=FfxController.DEFAULT_QUALITY, help=f"Quality settings to be used with VP9 encoder (default: {FfxController.DEFAULT_QUALITY})") -@click.option('-p', '--preset', type=str, default=FfxController.DEFAULT_AV1_PRESET, help=f"Quality preset to be used with AV1 encoder (default: {FfxController.DEFAULT_AV1_PRESET})") +@click.option('-q', '--quality', type=str, default=DEFAULT_QUALITY, help=f"Quality settings to be used with VP9 encoder (default: {DEFAULT_QUALITY})") +@click.option('-p', '--preset', type=str, default=DEFAULT_AV1_PRESET, help=f"Quality preset to be used with AV1 encoder (default: {DEFAULT_AV1_PRESET})") -@click.option('-a', '--stereo-bitrate', type=int, default=FfxController.DEFAULT_STEREO_BANDWIDTH, help=f"Bitrate in kbit/s to be used to encode stereo audio streams (default: {FfxController.DEFAULT_STEREO_BANDWIDTH})") -@click.option('--ac3', type=int, default=FfxController.DEFAULT_AC3_BANDWIDTH, help=f"Bitrate in kbit/s to be used to encode 5.1 audio streams (default: {FfxController.DEFAULT_AC3_BANDWIDTH})") -@click.option('--dts', type=int, default=FfxController.DEFAULT_DTS_BANDWIDTH, help=f"Bitrate in kbit/s to be used to encode 6.1 audio streams (default: {FfxController.DEFAULT_DTS_BANDWIDTH})") +@click.option('-a', '--stereo-bitrate', type=int, default=DEFAULT_STEREO_BANDWIDTH, help=f"Bitrate in kbit/s to be used to encode stereo audio streams (default: {DEFAULT_STEREO_BANDWIDTH})") +@click.option('--ac3', type=int, default=DEFAULT_AC3_BANDWIDTH, help=f"Bitrate in kbit/s to be used to encode 5.1 audio streams (default: {DEFAULT_AC3_BANDWIDTH})") +@click.option('--dts', type=int, default=DEFAULT_DTS_BANDWIDTH, help=f"Bitrate in kbit/s to be used to encode 6.1 audio streams (default: {DEFAULT_DTS_BANDWIDTH})") @click.option('--subtitle-directory', type=str, default='', help='Load subtitles from here') @click.option('--subtitle-prefix', type=str, default='', help='Subtitle filename prefix') @@ -297,6 +303,7 @@ def checkUniqueDispositions(context, mediaDescriptor: MediaDescriptor): @click.option("--no-prompt", is_flag=True, default=False) @click.option("--no-signature", is_flag=True, default=False) +@click.option("--keep-mkvmerge-metadata", is_flag=True, default=False) def convert(ctx, paths, @@ -329,7 +336,8 @@ def convert(ctx, no_pattern, dont_pass_dispositions, no_prompt, - no_signature): + no_signature, + keep_mkvmerge_metadata): """Batch conversion of audiovideo files in format suitable for web playback, e.g. jellyfin Files found under PATHS will be converted according to parameters. @@ -348,7 +356,9 @@ def convert(ctx, context['use_pattern'] = not no_pattern context['no_prompt'] = no_prompt context['no_signature'] = no_signature - + context['keep_mkvmerge_metadata'] = keep_mkvmerge_metadata + + context['import_subtitles'] = (subtitle_directory and subtitle_prefix) if context['import_subtitles']: context['subtitle_directory'] = subtitle_directory diff --git a/bin/ffx/constants.py b/bin/ffx/constants.py new file mode 100644 index 0000000..b4a755c --- /dev/null +++ b/bin/ffx/constants.py @@ -0,0 +1,10 @@ +DEFAULT_QUALITY = 32 +DEFAULT_AV1_PRESET = 5 + +DEFAULT_STEREO_BANDWIDTH = "112" +DEFAULT_AC3_BANDWIDTH = "256" +DEFAULT_DTS_BANDWIDTH = "320" +DEFAULT_7_1_BANDWIDTH = "384" + +DEFAULT_CROP_START = 60 +DEFAULT_CROP_LENGTH = 180 diff --git a/bin/ffx/ffx_controller.py b/bin/ffx/ffx_controller.py index 6132507..f5e2f2f 100644 --- a/bin/ffx/ffx_controller.py +++ b/bin/ffx/ffx_controller.py @@ -10,6 +10,10 @@ from ffx.video_encoder import VideoEncoder from ffx.process import executeProcess from ffx.track_disposition import TrackDisposition +from ffx.constants import DEFAULT_QUALITY, DEFAULT_AV1_PRESET +from ffx.constants import DEFAULT_CROP_START, DEFAULT_CROP_LENGTH + + class FfxController(): COMMAND_TOKENS = ['ffmpeg', '-y'] @@ -19,19 +23,9 @@ class FfxController(): DEFAULT_VIDEO_ENCODER = VideoEncoder.VP9.label() - DEFAULT_QUALITY = 23 - DEFAULT_AV1_PRESET = 5 - DEFAULT_FILE_FORMAT = 'webm' DEFAULT_FILE_EXTENSION = 'webm' - DEFAULT_STEREO_BANDWIDTH = "128" - DEFAULT_AC3_BANDWIDTH = "256" - DEFAULT_DTS_BANDWIDTH = "320" - - DEFAULT_CROP_START = 60 - DEFAULT_CROP_LENGTH = 180 - MKVMERGE_METADATA_KEYS = ['BPS', 'NUMBER_OF_FRAMES', 'NUMBER_OF_BYTES', @@ -43,7 +37,7 @@ class FfxController(): CHANNEL_MAP_5_1 = 'FL-FL|FR-FR|FC-FC|LFE-LFE|SL-BL|SR-BR:5.1' - SIGNATURE_TAGS = {'EDITED_WITH': 'FFX'} + SIGNATURE_TAGS = {'RECODED_WITH': 'FFX'} def __init__(self, context : dict, @@ -98,8 +92,8 @@ class FfxController(): cropStart = int(self.__context['crop_start']) cropLength = int(self.__context['crop_length']) else: - cropStart = FfxController.DEFAULT_CROP_START - cropLength = FfxController.DEFAULT_CROP_LENGTH + cropStart = DEFAULT_CROP_START + cropLength = DEFAULT_CROP_LENGTH return ['-ss', str(cropStart), '-t', str(cropLength)] @@ -227,14 +221,24 @@ class FfxController(): metadataTokens += [f"-metadata:g", f"{tagKey}={tagValue}"] + removeMkvmergeMetadata = (not 'keep_mkvmerge_metadata' in self.__context.keys() + or not self.__context['keep_mkvmerge_metadata']) + #HINT: With current ffmpeg version track metadata tags are not passed to the outfile for td in self.__targetMediaDescriptor.getAllTrackDescriptors(): for tagKey, tagValue in td.getTags().items(): - metadataTokens += [f"-metadata:s:{td.getType().indicator()}:{td.getSubIndex()}", + typeIndicator = td.getType().indicator() + subIndex = td.getSubIndex() + metadataTokens += [f"-metadata:s:{typeIndicator}:{subIndex}", f"{tagKey}={tagValue}"] + if removeMkvmergeMetadata: + for mmKey in FfxController.MKVMERGE_METADATA_KEYS: + metadataTokens += [f"-metadata:s:{typeIndicator}:{subIndex}", + f"{mmKey}="] + return metadataTokens