Add asterisk to filename filter, Signature
This commit is contained in:
105
bin/ffx.py
105
bin/ffx.py
@@ -19,6 +19,7 @@ from ffx.video_encoder import VideoEncoder
|
|||||||
from ffx.track_disposition import TrackDisposition
|
from ffx.track_disposition import TrackDisposition
|
||||||
|
|
||||||
from ffx.process import executeProcess
|
from ffx.process import executeProcess
|
||||||
|
from ffx.helper import filterFilename
|
||||||
|
|
||||||
|
|
||||||
VERSION='0.2.0'
|
VERSION='0.2.0'
|
||||||
@@ -150,8 +151,7 @@ def unmux(ctx,
|
|||||||
subtitles_only):
|
subtitles_only):
|
||||||
|
|
||||||
existingSourcePaths = [p for p in paths if os.path.isfile(p)]
|
existingSourcePaths = [p for p in paths if os.path.isfile(p)]
|
||||||
if ctx.obj['verbosity'] > 0:
|
ctx.obj['logger'].debug(f"\nUnmuxing {len(existingSourcePaths)} files")
|
||||||
click.echo(f"\nUnmuxing {len(existingSourcePaths)} files")
|
|
||||||
|
|
||||||
for sourcePath in existingSourcePaths:
|
for sourcePath in existingSourcePaths:
|
||||||
|
|
||||||
@@ -169,12 +169,10 @@ def unmux(ctx,
|
|||||||
targetIndicator = f"_S{season}E{episode}" if label and season != -1 and episode != -1 else ''
|
targetIndicator = f"_S{season}E{episode}" if label and season != -1 and episode != -1 else ''
|
||||||
|
|
||||||
if label and not targetIndicator:
|
if label and not targetIndicator:
|
||||||
if ctx.obj['verbosity'] > 0:
|
ctx.obj['logger'].warning(f"Skipping file {fp.getFilename()}: Label set but no indicator recognized")
|
||||||
click.echo(f"Skipping file {fp.getFilename()}: Label set but no indicator recognized")
|
|
||||||
continue
|
continue
|
||||||
else:
|
else:
|
||||||
if ctx.obj['verbosity'] > 0:
|
ctx.obj['logger'].debug(f"\nUnmuxing file {fp.getFilename()}\n")
|
||||||
click.echo(f"\nUnmuxing file {fp.getFilename()}\n")
|
|
||||||
|
|
||||||
for trackDescriptor in sourceMediaDescriptor.getAllTrackDescriptors():
|
for trackDescriptor in sourceMediaDescriptor.getAllTrackDescriptors():
|
||||||
|
|
||||||
@@ -187,18 +185,14 @@ def unmux(ctx,
|
|||||||
|
|
||||||
if unmuxSequence:
|
if unmuxSequence:
|
||||||
if not ctx.obj['dry_run']:
|
if not ctx.obj['dry_run']:
|
||||||
if ctx.obj['verbosity'] > 0:
|
ctx.obj['logger'].debug(f"Executing unmuxing sequence: {' '.join(unmuxSequence)}")
|
||||||
click.echo(f"Executing unmuxing sequence: {' '.join(unmuxSequence)}")
|
|
||||||
out, err, rc = executeProcess(unmuxSequence)
|
out, err, rc = executeProcess(unmuxSequence)
|
||||||
if rc:
|
if rc:
|
||||||
if ctx.obj['verbosity'] > 0:
|
ctx.obj['logger'].error(f"Unmuxing of stream {trackDescriptor.getIndex()} failed with error ({rc}) {err}")
|
||||||
click.echo(f"Unmuxing of stream {trackDescriptor.getIndex()} failed with error ({rc}) {err}")
|
|
||||||
else:
|
else:
|
||||||
if ctx.obj['verbosity'] > 0:
|
ctx.obj['logger'].warning(f"Skipping stream with unknown codec {trackDescriptor.getCodec()}")
|
||||||
click.echo(f"Skipping stream with unknown codec {trackDescriptor.getCodec()}")
|
|
||||||
except Exception as ex:
|
except Exception as ex:
|
||||||
if ctx.obj['verbosity'] > 0:
|
ctx.obj['logger'].warning(f"Skipping File {sourcePath} ({ex})")
|
||||||
click.echo(f"Skipping File {sourcePath} ({ex})")
|
|
||||||
|
|
||||||
|
|
||||||
@ffx.command()
|
@ffx.command()
|
||||||
@@ -267,7 +261,7 @@ def checkUniqueDispositions(context, mediaDescriptor: MediaDescriptor):
|
|||||||
@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=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('-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('-s', '--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=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('--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('--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})")
|
||||||
|
|
||||||
@@ -298,8 +292,11 @@ def checkUniqueDispositions(context, mediaDescriptor: MediaDescriptor):
|
|||||||
@click.option("--no-tmdb", is_flag=True, default=False)
|
@click.option("--no-tmdb", is_flag=True, default=False)
|
||||||
@click.option("--no-jellyfin", is_flag=True, default=False)
|
@click.option("--no-jellyfin", is_flag=True, default=False)
|
||||||
@click.option("--no-pattern", is_flag=True, default=False)
|
@click.option("--no-pattern", is_flag=True, default=False)
|
||||||
|
|
||||||
@click.option("--dont-pass-dispositions", is_flag=True, default=False)
|
@click.option("--dont-pass-dispositions", is_flag=True, default=False)
|
||||||
|
|
||||||
@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)
|
||||||
|
|
||||||
def convert(ctx,
|
def convert(ctx,
|
||||||
paths,
|
paths,
|
||||||
@@ -331,7 +328,8 @@ def convert(ctx,
|
|||||||
no_jellyfin,
|
no_jellyfin,
|
||||||
no_pattern,
|
no_pattern,
|
||||||
dont_pass_dispositions,
|
dont_pass_dispositions,
|
||||||
no_prompt):
|
no_prompt,
|
||||||
|
no_signature):
|
||||||
"""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.
|
||||||
@@ -349,29 +347,28 @@ def convert(ctx,
|
|||||||
context['use_tmdb'] = not no_tmdb
|
context['use_tmdb'] = not no_tmdb
|
||||||
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['import_subtitles'] = (subtitle_directory and subtitle_prefix)
|
context['import_subtitles'] = (subtitle_directory and subtitle_prefix)
|
||||||
if context['import_subtitles']:
|
if context['import_subtitles']:
|
||||||
context['subtitle_directory'] = subtitle_directory
|
context['subtitle_directory'] = subtitle_directory
|
||||||
context['subtitle_prefix'] = subtitle_prefix
|
context['subtitle_prefix'] = subtitle_prefix
|
||||||
|
|
||||||
# click.echo(f"\nVideo encoder: {video_encoder}")
|
ctx.obj['logger'].debug(f"\nVideo encoder: {video_encoder}")
|
||||||
|
|
||||||
qualityTokens = quality.split(',')
|
qualityTokens = quality.split(',')
|
||||||
q_list = [q for q in qualityTokens if q.isnumeric()]
|
q_list = [q for q in qualityTokens if q.isnumeric()]
|
||||||
|
|
||||||
if ctx.obj['verbosity'] > 0:
|
ctx.obj['logger'].debug(f"Qualities: {q_list}")
|
||||||
click.echo(f"Qualities: {q_list}")
|
|
||||||
|
|
||||||
context['bitrates'] = {}
|
context['bitrates'] = {}
|
||||||
context['bitrates']['stereo'] = str(stereo_bitrate) if str(stereo_bitrate).endswith('k') else f"{stereo_bitrate}k"
|
context['bitrates']['stereo'] = str(stereo_bitrate) if str(stereo_bitrate).endswith('k') else f"{stereo_bitrate}k"
|
||||||
context['bitrates']['ac3'] = str(ac3) if str(ac3).endswith('k') else f"{ac3}k"
|
context['bitrates']['ac3'] = str(ac3) if str(ac3).endswith('k') else f"{ac3}k"
|
||||||
context['bitrates']['dts'] = str(dts) if str(dts).endswith('k') else f"{dts}k"
|
context['bitrates']['dts'] = str(dts) if str(dts).endswith('k') else f"{dts}k"
|
||||||
|
|
||||||
if ctx.obj['verbosity'] > 0:
|
ctx.obj['logger'].debug(f"Stereo bitrate: {context['bitrates']['stereo']}")
|
||||||
click.echo(f"Stereo bitrate: {context['bitrates']['stereo']}")
|
ctx.obj['logger'].debug(f"AC3 bitrate: {context['bitrates']['ac3']}")
|
||||||
click.echo(f"AC3 bitrate: {context['bitrates']['ac3']}")
|
ctx.obj['logger'].debug(f"DTS bitrate: {context['bitrates']['dts']}")
|
||||||
click.echo(f"DTS bitrate: {context['bitrates']['dts']}")
|
|
||||||
|
|
||||||
|
|
||||||
# Process crop parameters
|
# Process crop parameters
|
||||||
@@ -381,15 +378,14 @@ def convert(ctx,
|
|||||||
if cTokens and len(cTokens) == 2:
|
if cTokens and len(cTokens) == 2:
|
||||||
context['crop_start'] = int(cTokens[0])
|
context['crop_start'] = int(cTokens[0])
|
||||||
context['crop_length'] = int(cTokens[1])
|
context['crop_length'] = int(cTokens[1])
|
||||||
if ctx.obj['verbosity'] > 0:
|
ctx.obj['logger'].debug(f"Crop start={context['crop_start']} length={context['crop_length']}")
|
||||||
click.echo(f"Crop start={context['crop_start']} length={context['crop_length']}")
|
|
||||||
|
|
||||||
|
|
||||||
tc = TmdbController() if context['use_tmdb'] else None
|
tc = TmdbController() if context['use_tmdb'] else None
|
||||||
|
|
||||||
existingSourcePaths = [p for p in paths if os.path.isfile(p) and p.split('.')[-1] in FfxController.INPUT_FILE_EXTENSIONS]
|
existingSourcePaths = [p for p in paths if os.path.isfile(p) and p.split('.')[-1] in FfxController.INPUT_FILE_EXTENSIONS]
|
||||||
if ctx.obj['verbosity'] > 0:
|
ctx.obj['logger'].info(f"\nRunning {len(existingSourcePaths) * len(q_list)} jobs")
|
||||||
click.echo(f"\nRunning {len(existingSourcePaths) * len(q_list)} jobs")
|
|
||||||
jobIndex = 0
|
jobIndex = 0
|
||||||
|
|
||||||
for sourcePath in existingSourcePaths:
|
for sourcePath in existingSourcePaths:
|
||||||
@@ -402,8 +398,7 @@ def convert(ctx,
|
|||||||
sourceFileBasename = '.'.join(sourcePathTokens[:-1])
|
sourceFileBasename = '.'.join(sourcePathTokens[:-1])
|
||||||
sourceFilenameExtension = sourcePathTokens[-1]
|
sourceFilenameExtension = sourcePathTokens[-1]
|
||||||
|
|
||||||
if ctx.obj['verbosity'] > 0:
|
ctx.obj['logger'].info(f"\nProcessing file {sourcePath}")
|
||||||
click.echo(f"\nProcessing file {sourcePath}")
|
|
||||||
|
|
||||||
|
|
||||||
mediaFileProperties = FileProperties(context, sourceFilename)
|
mediaFileProperties = FileProperties(context, sourceFilename)
|
||||||
@@ -412,8 +407,7 @@ def convert(ctx,
|
|||||||
#HINT: This is None if the filename did not match anything in database
|
#HINT: This is None if the filename did not match anything in database
|
||||||
currentPattern = mediaFileProperties.getPattern() if context['use_pattern'] else None
|
currentPattern = mediaFileProperties.getPattern() if context['use_pattern'] else None
|
||||||
|
|
||||||
if ctx.obj['verbosity'] > 0:
|
ctx.obj['logger'].debug(f"Pattern matching: {'No' if currentPattern is None else 'Yes'}")
|
||||||
click.echo(f"Pattern matching: {'No' if currentPattern is None else 'Yes'}")
|
|
||||||
|
|
||||||
# fileBasename = ''
|
# fileBasename = ''
|
||||||
|
|
||||||
@@ -452,13 +446,14 @@ def convert(ctx,
|
|||||||
|
|
||||||
if context['use_tmdb']:
|
if context['use_tmdb']:
|
||||||
|
|
||||||
click.echo(f"Querying TMDB for show_id={currentShowDescriptor.getId()} season={mediaFileProperties.getSeason()} episode{mediaFileProperties.getEpisode()}")
|
ctx.obj['logger'].debug(f"Querying TMDB for show_id={currentShowDescriptor.getId()} season={mediaFileProperties.getSeason()} episode{mediaFileProperties.getEpisode()}")
|
||||||
tmdbEpisodeResult = tc.queryEpisode(currentShowDescriptor.getId(), mediaFileProperties.getSeason(), mediaFileProperties.getEpisode())
|
tmdbEpisodeResult = tc.queryEpisode(currentShowDescriptor.getId(), mediaFileProperties.getSeason(), mediaFileProperties.getEpisode())
|
||||||
click.echo(f"tmdbEpisodeResult={tmdbEpisodeResult}")
|
ctx.obj['logger'].debug(f"tmdbEpisodeResult={tmdbEpisodeResult}")
|
||||||
|
|
||||||
if tmdbEpisodeResult:
|
if tmdbEpisodeResult:
|
||||||
|
filteredEpisodeName = filterFilename(tmdbEpisodeResult['name'])
|
||||||
sourceFileBasename = TmdbController.getEpisodeFileBasename(currentShowDescriptor.getFilenamePrefix(),
|
sourceFileBasename = TmdbController.getEpisodeFileBasename(currentShowDescriptor.getFilenamePrefix(),
|
||||||
tmdbEpisodeResult['name'],
|
filteredEpisodeName,
|
||||||
mediaFileProperties.getSeason(),
|
mediaFileProperties.getSeason(),
|
||||||
mediaFileProperties.getEpisode(),
|
mediaFileProperties.getEpisode(),
|
||||||
currentShowDescriptor.getIndexSeasonDigits(),
|
currentShowDescriptor.getIndexSeasonDigits(),
|
||||||
@@ -474,50 +469,45 @@ def convert(ctx,
|
|||||||
mediaFileProperties.getSeason(),
|
mediaFileProperties.getSeason(),
|
||||||
mediaFileProperties.getEpisode())
|
mediaFileProperties.getEpisode())
|
||||||
|
|
||||||
# raise click.ClickException(f"tmd subindices: {[t.getSubIndex() for t in targetMediaDescriptor.getAllTrackDescriptors()]}")
|
ctx.obj['logger'].debug(f"tmd subindices: {[t.getIndex() for t in targetMediaDescriptor.getAllTrackDescriptors()]} {[t.getSubIndex() for t in targetMediaDescriptor.getAllTrackDescriptors()]} {[t.getDispositionFlag(TrackDisposition.DEFAULT) for t in targetMediaDescriptor.getAllTrackDescriptors()]}")
|
||||||
# click.echo(f"tmd subindices: {[t.getIndex() for t in targetMediaDescriptor.getAllTrackDescriptors()]} {[t.getSubIndex() for t in targetMediaDescriptor.getAllTrackDescriptors()]} {[t.getDispositionFlag(TrackDisposition.DEFAULT) for t in targetMediaDescriptor.getAllTrackDescriptors()]}")
|
|
||||||
|
|
||||||
if context['use_jellyfin']:
|
if context['use_jellyfin']:
|
||||||
# Reorder subtracks in types with default the last, then make subindices flat again
|
# Reorder subtracks in types with default the last, then make subindices flat again
|
||||||
targetMediaDescriptor.applyJellyfinOrder()
|
targetMediaDescriptor.applyJellyfinOrder()
|
||||||
# sourceMediaDescriptor.applyJellyfinOrder()
|
|
||||||
|
|
||||||
# click.echo(f"tmd subindices: {[t.getIndex() for t in targetMediaDescriptor.getAllTrackDescriptors()]} {[t.getSubIndex() for t in targetMediaDescriptor.getAllTrackDescriptors()]} {[t.getDispositionFlag(TrackDisposition.DEFAULT) for t in targetMediaDescriptor.getAllTrackDescriptors()]}")
|
ctx.obj['logger'].debug(f"tmd subindices: {[t.getIndex() for t in targetMediaDescriptor.getAllTrackDescriptors()]} {[t.getSubIndex() for t in targetMediaDescriptor.getAllTrackDescriptors()]} {[t.getDispositionFlag(TrackDisposition.DEFAULT) for t in targetMediaDescriptor.getAllTrackDescriptors()]}")
|
||||||
# raise click.Abort
|
|
||||||
|
|
||||||
if ctx.obj['verbosity'] > 0:
|
ctx.obj['logger'].debug(f"Input mapping tokens (2nd pass): {targetMediaDescriptor.getInputMappingTokens()}")
|
||||||
click.echo(f"Input mapping tokens (2nd pass): {targetMediaDescriptor.getInputMappingTokens()}")
|
|
||||||
|
|
||||||
fc = FfxController(context, targetMediaDescriptor, sourceMediaDescriptor)
|
fc = FfxController(context, targetMediaDescriptor, sourceMediaDescriptor)
|
||||||
|
|
||||||
|
ctx.obj['logger'].debug(f"Season={mediaFileProperties.getSeason()} Episode={mediaFileProperties.getEpisode()}")
|
||||||
|
|
||||||
if ctx.obj['verbosity'] > 0:
|
ctx.obj['logger'].debug(f"fileBasename={sourceFileBasename}")
|
||||||
click.echo(f"Season={mediaFileProperties.getSeason()} Episode={mediaFileProperties.getEpisode()}")
|
|
||||||
|
|
||||||
if ctx.obj['verbosity'] > 0:
|
|
||||||
click.echo(f"fileBasename={sourceFileBasename}")
|
|
||||||
|
|
||||||
|
|
||||||
for q in q_list:
|
for q in q_list:
|
||||||
|
|
||||||
if ctx.obj['verbosity'] > 0:
|
ctx.obj['logger'].debug(f"\nRunning job {jobIndex} file={sourcePath} q={q}")
|
||||||
click.echo(f"\nRunning job {jobIndex} file={sourcePath} q={q}")
|
|
||||||
jobIndex += 1
|
jobIndex += 1
|
||||||
|
|
||||||
extra = ['ffx'] if sourceFilenameExtension == FfxController.DEFAULT_FILE_EXTENSION else []
|
extra = ['ffx'] if sourceFilenameExtension == FfxController.DEFAULT_FILE_EXTENSION else []
|
||||||
|
|
||||||
click.echo(f"label={label if label else 'Falsy'}")
|
ctx.obj['logger'].debug(f"label={label if label else 'Falsy'}")
|
||||||
click.echo(f"sourceFileBasename={sourceFileBasename}")
|
ctx.obj['logger'].debug(f"sourceFileBasename={sourceFileBasename}")
|
||||||
|
|
||||||
targetFilename = (sourceFileBasename if context['use_tmdb']
|
targetFileBasename = mediaFileProperties.assembleTargetFileBasename(label,
|
||||||
else mediaFileProperties.assembleTargetFileBasename(label,
|
q if len(q_list) > 1 else -1,
|
||||||
q if len(q_list) > 1 else -1,
|
extraTokens = extra)
|
||||||
extraTokens = extra))
|
|
||||||
|
#TODO #387
|
||||||
|
targetFilename = ((f"{sourceFileBasename}_q{q}" if len(q_list) > 1 else sourceFileBasename)
|
||||||
|
if context['use_tmdb'] else targetFileBasename)
|
||||||
|
|
||||||
targetPath = os.path.join(output_directory if output_directory else sourceDirectory, targetFilename)
|
targetPath = os.path.join(output_directory if output_directory else sourceDirectory, targetFilename)
|
||||||
|
|
||||||
# media_S01E02_S01E02
|
#TODO: target extension anpassen
|
||||||
click.echo(f"targetPath={targetPath}")
|
ctx.obj['logger'].info(f"Creating file {targetFilename}.webm")
|
||||||
|
|
||||||
fc.runJob(sourcePath,
|
fc.runJob(sourcePath,
|
||||||
targetPath,
|
targetPath,
|
||||||
@@ -529,8 +519,7 @@ def convert(ctx,
|
|||||||
#TODO: click.confirm('Warning! This file is not compliant to the defined source schema! Do you want to continue?', abort=True)
|
#TODO: click.confirm('Warning! This file is not compliant to the defined source schema! Do you want to continue?', abort=True)
|
||||||
|
|
||||||
endTime = time.perf_counter()
|
endTime = time.perf_counter()
|
||||||
if ctx.obj['verbosity'] > 0:
|
ctx.obj['logger'].info(f"\nDONE\nTime elapsed {endTime - startTime}")
|
||||||
click.echo(f"\nDONE\nTime elapsed {endTime - startTime}")
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
|
|||||||
@@ -28,7 +28,6 @@ class AudioLayout(Enum):
|
|||||||
|
|
||||||
return [a for a in AudioLayout if a.value['label'] == str(label)][0]
|
return [a for a in AudioLayout if a.value['label'] == str(label)][0]
|
||||||
except:
|
except:
|
||||||
raise click.ClickException('fromLabel failed')
|
|
||||||
return AudioLayout.LAYOUT_UNDEFINED
|
return AudioLayout.LAYOUT_UNDEFINED
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
@@ -36,7 +35,6 @@ class AudioLayout(Enum):
|
|||||||
try:
|
try:
|
||||||
return [a for a in AudioLayout if a.value['index'] == int(index)][0]
|
return [a for a in AudioLayout if a.value['index'] == int(index)][0]
|
||||||
except:
|
except:
|
||||||
raise click.ClickException('fromIndex failed')
|
|
||||||
return AudioLayout.LAYOUT_UNDEFINED
|
return AudioLayout.LAYOUT_UNDEFINED
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
|
|||||||
@@ -43,6 +43,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'}
|
||||||
|
|
||||||
def __init__(self,
|
def __init__(self,
|
||||||
context : dict,
|
context : dict,
|
||||||
@@ -214,7 +215,15 @@ class FfxController():
|
|||||||
|
|
||||||
metadataTokens = []
|
metadataTokens = []
|
||||||
|
|
||||||
for tagKey, tagValue in self.__targetMediaDescriptor.getTags().items():
|
mediaTags = self.__targetMediaDescriptor.getTags()
|
||||||
|
|
||||||
|
if (not 'no_signature' in self.__context.keys()
|
||||||
|
or not self.__context['no_signature']):
|
||||||
|
outputMediaTags = mediaTags | FfxController.SIGNATURE_TAGS
|
||||||
|
else:
|
||||||
|
outputMediaTags = mediaTags
|
||||||
|
|
||||||
|
for tagKey, tagValue in outputMediaTags.items():
|
||||||
metadataTokens += [f"-metadata:g",
|
metadataTokens += [f"-metadata:g",
|
||||||
f"{tagKey}={tagValue}"]
|
f"{tagKey}={tagValue}"]
|
||||||
|
|
||||||
|
|||||||
@@ -229,7 +229,7 @@ class FileProperties():
|
|||||||
|
|
||||||
# targetFilenameExtension = FfxController.DEFAULT_FILE_EXTENSION if extension is None else str(extension)
|
# targetFilenameExtension = FfxController.DEFAULT_FILE_EXTENSION if extension is None else str(extension)
|
||||||
|
|
||||||
click.echo(f"assembleTargetFileBasename(): label={label} is {'truthy' if label else 'falsy'}")
|
self.__logger.debug(f"assembleTargetFileBasename(): label={label} is {'truthy' if label else 'falsy'}")
|
||||||
|
|
||||||
if label:
|
if label:
|
||||||
|
|
||||||
@@ -256,7 +256,6 @@ class FileProperties():
|
|||||||
|
|
||||||
targetFilename = '_'.join(targetFilenameTokens)
|
targetFilename = '_'.join(targetFilenameTokens)
|
||||||
|
|
||||||
#self.__logger.debug(f"assembleTargetFileBasename(): Target filename: {targetFilename}")
|
self.__logger.debug(f"assembleTargetFileBasename(): Target filename: {targetFilename}")
|
||||||
click.echo(f"assembleTargetFileBasename(): Target filename: {targetFilename}")
|
|
||||||
|
|
||||||
return targetFilename
|
return targetFilename
|
||||||
|
|||||||
@@ -57,5 +57,11 @@ def filterFilename(fileName: str) -> str:
|
|||||||
"""This filter replaces charactes from TMDB responses with characters
|
"""This filter replaces charactes from TMDB responses with characters
|
||||||
less problemating when using in filenames or removes them"""
|
less problemating when using in filenames or removes them"""
|
||||||
|
|
||||||
|
# This appears in TMDB episode names
|
||||||
|
fileName = str(fileName).replace(' (*)', '')
|
||||||
|
fileName = str(fileName).replace('(*)', '')
|
||||||
|
|
||||||
fileName = str(fileName).replace(':', ';')
|
fileName = str(fileName).replace(':', ';')
|
||||||
return fileName
|
fileName = str(fileName).replace('*', '')
|
||||||
|
|
||||||
|
return fileName.strip()
|
||||||
|
|||||||
@@ -102,7 +102,8 @@ class Scenario1(Scenario):
|
|||||||
|
|
||||||
commandSequence += ['convert',
|
commandSequence += ['convert',
|
||||||
mediaFilePath,
|
mediaFilePath,
|
||||||
'--no-prompt']
|
'--no-prompt',
|
||||||
|
'--no-signature']
|
||||||
|
|
||||||
if variantFilenameLabel:
|
if variantFilenameLabel:
|
||||||
commandSequence += ['--label', variantFilenameLabel]
|
commandSequence += ['--label', variantFilenameLabel]
|
||||||
|
|||||||
@@ -94,7 +94,8 @@ class Scenario2(Scenario):
|
|||||||
|
|
||||||
commandSequence += ['convert',
|
commandSequence += ['convert',
|
||||||
mediaFilePath,
|
mediaFilePath,
|
||||||
'--no-prompt']
|
'--no-prompt',
|
||||||
|
'--no-signature']
|
||||||
|
|
||||||
if not testContext['use_jellyfin']:
|
if not testContext['use_jellyfin']:
|
||||||
commandSequence += ['--no-jellyfin']
|
commandSequence += ['--no-jellyfin']
|
||||||
|
|||||||
@@ -180,7 +180,7 @@ class Scenario4(Scenario):
|
|||||||
'convert']
|
'convert']
|
||||||
commandSequence += [tfo['filename'] for tfo in testFileList]
|
commandSequence += [tfo['filename'] for tfo in testFileList]
|
||||||
|
|
||||||
commandSequence += ['--no-prompt']
|
commandSequence += ['--no-prompt', '--no-signature']
|
||||||
|
|
||||||
if not testContext['use_jellyfin']:
|
if not testContext['use_jellyfin']:
|
||||||
commandSequence += ['--no-jellyfin']
|
commandSequence += ['--no-jellyfin']
|
||||||
|
|||||||
Reference in New Issue
Block a user