Signature, Tags cleaning, Bugfixes, Refactoring
This commit is contained in:
24
bin/ffx.py
24
bin/ffx.py
@@ -21,8 +21,11 @@ from ffx.track_disposition import TrackDisposition
|
|||||||
from ffx.process import executeProcess
|
from ffx.process import executeProcess
|
||||||
from ffx.helper import filterFilename
|
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
|
# 0.1.1
|
||||||
# Bugfixes, TMBD identify shows
|
# Bugfixes, TMBD identify shows
|
||||||
@@ -32,6 +35,9 @@ VERSION='0.2.0'
|
|||||||
# Subtitle file imports
|
# Subtitle file imports
|
||||||
# 0.2.0
|
# 0.2.0
|
||||||
# Tests, Config-File
|
# Tests, Config-File
|
||||||
|
# 0.2.1
|
||||||
|
# Signature, Tags cleaning, Bugfixes, Refactoring
|
||||||
|
|
||||||
|
|
||||||
@click.group()
|
@click.group()
|
||||||
@click.pass_context
|
@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('-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('-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=FfxController.DEFAULT_AV1_PRESET, help=f"Quality preset to be used with AV1 encoder (default: {FfxController.DEFAULT_AV1_PRESET})")
|
@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('-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=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('--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=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('--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-directory', type=str, default='', help='Load subtitles from here')
|
||||||
@click.option('--subtitle-prefix', type=str, default='', help='Subtitle filename prefix')
|
@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-prompt", is_flag=True, default=False)
|
||||||
@click.option("--no-signature", 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,
|
def convert(ctx,
|
||||||
paths,
|
paths,
|
||||||
@@ -329,7 +336,8 @@ def convert(ctx,
|
|||||||
no_pattern,
|
no_pattern,
|
||||||
dont_pass_dispositions,
|
dont_pass_dispositions,
|
||||||
no_prompt,
|
no_prompt,
|
||||||
no_signature):
|
no_signature,
|
||||||
|
keep_mkvmerge_metadata):
|
||||||
"""Batch conversion of audiovideo files in format suitable for web playback, e.g. jellyfin
|
"""Batch conversion of audiovideo files in format suitable for web playback, e.g. jellyfin
|
||||||
|
|
||||||
Files found under PATHS will be converted according to parameters.
|
Files found under PATHS will be converted according to parameters.
|
||||||
@@ -348,6 +356,8 @@ def convert(ctx,
|
|||||||
context['use_pattern'] = not no_pattern
|
context['use_pattern'] = not no_pattern
|
||||||
context['no_prompt'] = no_prompt
|
context['no_prompt'] = no_prompt
|
||||||
context['no_signature'] = no_signature
|
context['no_signature'] = no_signature
|
||||||
|
context['keep_mkvmerge_metadata'] = keep_mkvmerge_metadata
|
||||||
|
|
||||||
|
|
||||||
context['import_subtitles'] = (subtitle_directory and subtitle_prefix)
|
context['import_subtitles'] = (subtitle_directory and subtitle_prefix)
|
||||||
if context['import_subtitles']:
|
if context['import_subtitles']:
|
||||||
|
|||||||
10
bin/ffx/constants.py
Normal file
10
bin/ffx/constants.py
Normal file
@@ -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
|
||||||
@@ -10,6 +10,10 @@ from ffx.video_encoder import VideoEncoder
|
|||||||
from ffx.process import executeProcess
|
from ffx.process import executeProcess
|
||||||
from ffx.track_disposition import TrackDisposition
|
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():
|
class FfxController():
|
||||||
|
|
||||||
COMMAND_TOKENS = ['ffmpeg', '-y']
|
COMMAND_TOKENS = ['ffmpeg', '-y']
|
||||||
@@ -19,19 +23,9 @@ class FfxController():
|
|||||||
|
|
||||||
DEFAULT_VIDEO_ENCODER = VideoEncoder.VP9.label()
|
DEFAULT_VIDEO_ENCODER = VideoEncoder.VP9.label()
|
||||||
|
|
||||||
DEFAULT_QUALITY = 23
|
|
||||||
DEFAULT_AV1_PRESET = 5
|
|
||||||
|
|
||||||
DEFAULT_FILE_FORMAT = 'webm'
|
DEFAULT_FILE_FORMAT = 'webm'
|
||||||
DEFAULT_FILE_EXTENSION = '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',
|
MKVMERGE_METADATA_KEYS = ['BPS',
|
||||||
'NUMBER_OF_FRAMES',
|
'NUMBER_OF_FRAMES',
|
||||||
'NUMBER_OF_BYTES',
|
'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'
|
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,
|
def __init__(self,
|
||||||
context : dict,
|
context : dict,
|
||||||
@@ -98,8 +92,8 @@ class FfxController():
|
|||||||
cropStart = int(self.__context['crop_start'])
|
cropStart = int(self.__context['crop_start'])
|
||||||
cropLength = int(self.__context['crop_length'])
|
cropLength = int(self.__context['crop_length'])
|
||||||
else:
|
else:
|
||||||
cropStart = FfxController.DEFAULT_CROP_START
|
cropStart = DEFAULT_CROP_START
|
||||||
cropLength = FfxController.DEFAULT_CROP_LENGTH
|
cropLength = DEFAULT_CROP_LENGTH
|
||||||
|
|
||||||
return ['-ss', str(cropStart), '-t', str(cropLength)]
|
return ['-ss', str(cropStart), '-t', str(cropLength)]
|
||||||
|
|
||||||
@@ -227,14 +221,24 @@ class FfxController():
|
|||||||
metadataTokens += [f"-metadata:g",
|
metadataTokens += [f"-metadata:g",
|
||||||
f"{tagKey}={tagValue}"]
|
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
|
#HINT: With current ffmpeg version track metadata tags are not passed to the outfile
|
||||||
for td in self.__targetMediaDescriptor.getAllTrackDescriptors():
|
for td in self.__targetMediaDescriptor.getAllTrackDescriptors():
|
||||||
|
|
||||||
for tagKey, tagValue in td.getTags().items():
|
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}"]
|
f"{tagKey}={tagValue}"]
|
||||||
|
|
||||||
|
if removeMkvmergeMetadata:
|
||||||
|
for mmKey in FfxController.MKVMERGE_METADATA_KEYS:
|
||||||
|
metadataTokens += [f"-metadata:s:{typeIndicator}:{subIndex}",
|
||||||
|
f"{mmKey}="]
|
||||||
|
|
||||||
return metadataTokens
|
return metadataTokens
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user