|
|
|
@ -366,7 +366,7 @@ def searchSubtitleFiles(dir, prefix):
|
|
|
|
|
|
|
|
|
|
sesl_match = re.compile(SEASON_EPISODE_STREAM_LANGUAGE_MATCH)
|
|
|
|
|
|
|
|
|
|
availableFileSubtitles = []
|
|
|
|
|
availableFileSubtitleDescriptors = []
|
|
|
|
|
for subtitleFilename in os.listdir(dir):
|
|
|
|
|
if subtitleFilename.startswith(prefix) and subtitleFilename.endswith('.' + SUBTITLE_FILE_EXTENSION):
|
|
|
|
|
sesl_result = sesl_match.search(subtitleFilename)
|
|
|
|
@ -381,11 +381,11 @@ def searchSubtitleFiles(dir, prefix):
|
|
|
|
|
subtitleFileDescriptor['stream'] = int(sesl_result.group(3))
|
|
|
|
|
subtitleFileDescriptor['language'] = sesl_result.group(4)
|
|
|
|
|
|
|
|
|
|
availableFileSubtitles.append(subtitleFileDescriptor)
|
|
|
|
|
availableFileSubtitleDescriptors.append(subtitleFileDescriptor)
|
|
|
|
|
|
|
|
|
|
click.echo(f"Found {len(availableFileSubtitles)} subtitles in files\n")
|
|
|
|
|
click.echo(f"Found {len(availableFileSubtitleDescriptors)} subtitles in files\n")
|
|
|
|
|
|
|
|
|
|
return availableFileSubtitles
|
|
|
|
|
return availableFileSubtitleDescriptors
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@click.group()
|
|
|
|
@ -524,10 +524,11 @@ def convert(ctx,
|
|
|
|
|
e_match = re.compile(EPISODE_INDICATOR_MATCH)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
## Conversion parameters
|
|
|
|
|
|
|
|
|
|
# Parse subtitle files
|
|
|
|
|
context['import_subtitles'] = (subtitle_directory and subtitle_prefix)
|
|
|
|
|
availableFileSubtitles = searchSubtitleFiles(subtitle_directory, subtitle_prefix) if context['import_subtitles'] else []
|
|
|
|
|
|
|
|
|
|
availableFileSubtitleDescriptors = searchSubtitleFiles(subtitle_directory, subtitle_prefix) if context['import_subtitles'] else []
|
|
|
|
|
|
|
|
|
|
# Overwrite audio tags if set
|
|
|
|
|
audioLanguages = audio_language
|
|
|
|
@ -537,6 +538,11 @@ def convert(ctx,
|
|
|
|
|
subtitleLanguages = subtitle_language
|
|
|
|
|
subtitleTitles = subtitle_title
|
|
|
|
|
|
|
|
|
|
defaultAudio = default_audio
|
|
|
|
|
defaultSubtitle = default_subtitle
|
|
|
|
|
forcedAudio = forced_audio
|
|
|
|
|
forcedSubtitle = forced_subtitle
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# Process crop parameters
|
|
|
|
|
context['perform_crop'] = (crop != 'none')
|
|
|
|
@ -654,36 +660,36 @@ def convert(ctx,
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#NOTE: It is currently expected that all source file have the same substream pattern, e.g. coming from the same encoder
|
|
|
|
|
defaultAudioStreams = [a for a in sourceStreamDescriptor[STREAM_TYPE_AUDIO] if a['disposition']['default'] == 1]
|
|
|
|
|
if default_audio == -1 and len(defaultAudioStreams) > 1:
|
|
|
|
|
default_audio = click.prompt("More than one default audio stream detected! Please select stream", type=int)
|
|
|
|
|
numDefaultAudioStreams = len([a for a in sourceStreamDescriptor[STREAM_TYPE_AUDIO] if a['disposition']['default'] == 1])
|
|
|
|
|
if defaultAudio == -1 and numDefaultAudioStreams > 1:
|
|
|
|
|
defaultAudio = click.prompt("More than one default audio stream detected! Please select stream", type=int)
|
|
|
|
|
|
|
|
|
|
forcedAudioStreams = [a for a in sourceStreamDescriptor[STREAM_TYPE_AUDIO] if a['disposition']['forced'] == 1]
|
|
|
|
|
if forced_audio == -1 and len(forcedAudioStreams) > 1:
|
|
|
|
|
forced_audio = click.prompt("More than one forced audio stream detected! Please select stream", type=int)
|
|
|
|
|
numForcedAudioStreams = len([a for a in sourceStreamDescriptor[STREAM_TYPE_AUDIO] if a['disposition']['forced'] == 1])
|
|
|
|
|
if forcedAudio == -1 and numForcedAudioStreams > 1:
|
|
|
|
|
forcedAudio = click.prompt("More than one forced audio stream detected! Please select stream", type=int)
|
|
|
|
|
|
|
|
|
|
defaultSubtitleStreams = [s for s in sourceStreamDescriptor[STREAM_TYPE_SUBTITLE] if s['disposition']['default'] == 1]
|
|
|
|
|
if default_subtitle == -1 and len(defaultSubtitleStreams) > 1:
|
|
|
|
|
default_subtitle = click.prompt("More than one default subtitle stream detected! Please select stream", type=int)
|
|
|
|
|
numDefaultSubtitleStreams = len([s for s in sourceStreamDescriptor[STREAM_TYPE_SUBTITLE] if s['disposition']['default'] == 1])
|
|
|
|
|
if defaultSubtitle == -1 and numDefaultSubtitleStreams > 1:
|
|
|
|
|
defaultSubtitle = click.prompt("More than one default subtitle stream detected! Please select stream", type=int)
|
|
|
|
|
|
|
|
|
|
forcedSubtitleStreams = [s for s in sourceStreamDescriptor[STREAM_TYPE_SUBTITLE] if s['disposition']['forced'] == 1]
|
|
|
|
|
if forced_subtitle == -1 and len(forcedSubtitleStreams) > 1:
|
|
|
|
|
forced_subtitle = click.prompt("More than one forced subtitle stream detected! Please select stream", type=int)
|
|
|
|
|
numForcedSubtitleStreams = len([s for s in sourceStreamDescriptor[STREAM_TYPE_SUBTITLE] if s['disposition']['forced'] == 1])
|
|
|
|
|
if forcedSubtitle == -1 and numForcedSubtitleStreams > 1:
|
|
|
|
|
forcedSubtitle = click.prompt("More than one forced subtitle stream detected! Please select stream", type=int)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#Fix multiple default/forced tags
|
|
|
|
|
if default_audio != -1:
|
|
|
|
|
if defaultAudio != -1:
|
|
|
|
|
for substreamIndex in range(len(targetStreamDescriptor[STREAM_TYPE_AUDIO])):
|
|
|
|
|
targetStreamDescriptor[STREAM_TYPE_AUDIO][substreamIndex]['disposition']['default'] = 1 if substreamIndex == default_audio else 0
|
|
|
|
|
if forced_audio != -1:
|
|
|
|
|
targetStreamDescriptor[STREAM_TYPE_AUDIO][substreamIndex]['disposition']['default'] = 1 if substreamIndex == defaultAudio else 0
|
|
|
|
|
if forcedAudio != -1:
|
|
|
|
|
for substreamIndex in range(len(targetStreamDescriptor[STREAM_TYPE_AUDIO])):
|
|
|
|
|
targetStreamDescriptor[STREAM_TYPE_AUDIO][substreamIndex]['disposition']['forced'] = 1 if substreamIndex == forced_audio else 0
|
|
|
|
|
if default_subtitle != -1:
|
|
|
|
|
targetStreamDescriptor[STREAM_TYPE_AUDIO][substreamIndex]['disposition']['forced'] = 1 if substreamIndex == forcedAudio else 0
|
|
|
|
|
if defaultSubtitle != -1:
|
|
|
|
|
for substreamIndex in range(len(targetStreamDescriptor[STREAM_TYPE_SUBTITLE])):
|
|
|
|
|
targetStreamDescriptor[STREAM_TYPE_SUBTITLE][substreamIndex]['disposition']['default'] = 1 if substreamIndex == default_subtitle else 0
|
|
|
|
|
if forced_subtitle != -1:
|
|
|
|
|
targetStreamDescriptor[STREAM_TYPE_SUBTITLE][substreamIndex]['disposition']['default'] = 1 if substreamIndex == defaultSubtitle else 0
|
|
|
|
|
if forcedSubtitle != -1:
|
|
|
|
|
for substreamIndex in range(len(targetStreamDescriptor[STREAM_TYPE_SUBTITLE])):
|
|
|
|
|
targetStreamDescriptor[STREAM_TYPE_SUBTITLE][substreamIndex]['disposition']['forded'] = 1 if substreamIndex == forced_subtitle else 0
|
|
|
|
|
targetStreamDescriptor[STREAM_TYPE_SUBTITLE][substreamIndex]['disposition']['forded'] = 1 if substreamIndex == forcedSubtitle else 0
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
click.echo('Target streans:')
|
|
|
|
@ -701,21 +707,21 @@ def convert(ctx,
|
|
|
|
|
matchingSubtitles = []
|
|
|
|
|
if context['import_subtitles']:
|
|
|
|
|
|
|
|
|
|
subtitles = [a for a in availableFileSubtitles if a['season'] == season and a['episode'] == episode]
|
|
|
|
|
subtitles = [a for a in availableFileSubtitleDescriptors if a['season'] == season and a['episode'] == episode]
|
|
|
|
|
mSubtitles = sorted(subtitles, key=lambda d: d['stream'])
|
|
|
|
|
|
|
|
|
|
for sfd in mSubtitles:
|
|
|
|
|
subtitleFileTokens += ['-i', sfd['path']]
|
|
|
|
|
|
|
|
|
|
for streamIndex in range(len(mSubtitles)):
|
|
|
|
|
mSubtitles[streamIndex]['forced'] = 1 if forced_subtitle != -1 and streamIndex == forced_subtitle else 0
|
|
|
|
|
mSubtitles[streamIndex]['default'] = 1 if default_subtitle != -1 and streamIndex == default_subtitle else 0
|
|
|
|
|
mSubtitles[streamIndex]['forced'] = 1 if forcedSubtitle != -1 and streamIndex == forcedSubtitle else 0
|
|
|
|
|
mSubtitles[streamIndex]['default'] = 1 if defaultSubtitle != -1 and streamIndex == defaultSubtitle else 0
|
|
|
|
|
|
|
|
|
|
if streamIndex <= len(subtitleTitles) -1:
|
|
|
|
|
mSubtitles[streamIndex]['title'] = subtitleTitles[streamIndex]
|
|
|
|
|
|
|
|
|
|
if default_subtitle != -1 and jellyfin:
|
|
|
|
|
matchingSubtitles = getReorderedSubstreams(mSubtitles, default_subtitle)
|
|
|
|
|
if defaultSubtitle != -1 and jellyfin:
|
|
|
|
|
matchingSubtitles = getReorderedSubstreams(mSubtitles, defaultSubtitle)
|
|
|
|
|
else:
|
|
|
|
|
matchingSubtitles = mSubtitles
|
|
|
|
|
|
|
|
|
@ -757,29 +763,29 @@ def convert(ctx,
|
|
|
|
|
subtitleStreams[streamIndex]['tags']['title'] = subtitleTitles[streamIndex]
|
|
|
|
|
|
|
|
|
|
# Reorder audio stream descriptors and create disposition options if default is given per command line option
|
|
|
|
|
if default_audio == -1:
|
|
|
|
|
if defaultAudio == -1:
|
|
|
|
|
sourceAudioStreams = audioStreams
|
|
|
|
|
else:
|
|
|
|
|
for streamIndex in range(len(audioStreams)):
|
|
|
|
|
audioStreams[streamIndex]['disposition']['default'] = 1 if streamIndex == default_audio else 0
|
|
|
|
|
audioStreams[streamIndex]['disposition']['default'] = 1 if streamIndex == defaultAudio else 0
|
|
|
|
|
|
|
|
|
|
sourceAudioStreams = getReorderedSubstreams(audioStreams, default_audio) if jellyfin else audioStreams
|
|
|
|
|
sourceAudioStreams = getReorderedSubstreams(audioStreams, defaultAudio) if jellyfin else audioStreams
|
|
|
|
|
|
|
|
|
|
dispositionTokens += generateDispositionTokens(sourceAudioStreams)
|
|
|
|
|
|
|
|
|
|
# Set forced tag in subtitle descriptor if given per command line option
|
|
|
|
|
if forced_subtitle != -1:
|
|
|
|
|
if forcedSubtitle != -1:
|
|
|
|
|
for streamIndex in range(len(subtitleStreams)):
|
|
|
|
|
subtitleStreams[streamIndex]['disposition']['forced'] = 1 if streamIndex == forced_subtitle else 0
|
|
|
|
|
subtitleStreams[streamIndex]['disposition']['forced'] = 1 if streamIndex == forcedSubtitle else 0
|
|
|
|
|
|
|
|
|
|
# Reorder subtitle stream descriptors and create disposition options if default is given per command line option
|
|
|
|
|
if default_subtitle == -1:
|
|
|
|
|
if defaultSubtitle == -1:
|
|
|
|
|
sourceSubtitleStreams = subtitleStreams
|
|
|
|
|
else:
|
|
|
|
|
for streamIndex in range(len(subtitleStreams)):
|
|
|
|
|
subtitleStreams[streamIndex]['disposition']['default'] = 1 if streamIndex == default_subtitle else 0
|
|
|
|
|
subtitleStreams[streamIndex]['disposition']['default'] = 1 if streamIndex == defaultSubtitle else 0
|
|
|
|
|
|
|
|
|
|
sourceSubtitleStreams = getReorderedSubstreams(subtitleStreams, default_subtitle) if jellyfin else subtitleStreams
|
|
|
|
|
sourceSubtitleStreams = getReorderedSubstreams(subtitleStreams, defaultSubtitle) if jellyfin else subtitleStreams
|
|
|
|
|
|
|
|
|
|
dispositionTokens += generateDispositionTokens(sourceSubtitleStreams)
|
|
|
|
|
|
|
|
|
@ -806,7 +812,7 @@ def convert(ctx,
|
|
|
|
|
|
|
|
|
|
numMatchingSubtitles = len(matchingSubtitles)
|
|
|
|
|
|
|
|
|
|
if jellyfin and default_subtitle != -1:
|
|
|
|
|
if jellyfin and defaultSubtitle != -1:
|
|
|
|
|
subtitleSequence = getModifiedStreamOrder(numMatchingSubtitles, default_subtitle)
|
|
|
|
|
else:
|
|
|
|
|
subtitleSequence = range(numMatchingSubtitles)
|
|
|
|
|