inc stream management
This commit is contained in:
272
bin/ffx.py
272
bin/ffx.py
@@ -618,16 +618,6 @@ def convert(ctx,
|
||||
targetFilenameTokens = [sourceFileBasename]
|
||||
|
||||
|
||||
# SSD -> TSD -> MSO
|
||||
#
|
||||
# src file [vtt files] -> SSD
|
||||
#
|
||||
# in opts, checks -> TSD
|
||||
#
|
||||
# jellyfin -> MSO
|
||||
#
|
||||
# TSD - SSD, MSO -> out opts
|
||||
|
||||
# Load source stream descriptor
|
||||
try:
|
||||
###
|
||||
@@ -638,28 +628,6 @@ def convert(ctx,
|
||||
click.echo(f"File with path {sourcePath} does not contain any audiovisual data, skipping ...")
|
||||
continue
|
||||
|
||||
# # Ensure disposition and tags keys for every stream
|
||||
# for substreamIndex in range(len(sourceStreamDescriptor[STREAM_TYPE_AUDIO])):
|
||||
# if not 'disposition' in sourceStreamDescriptor[STREAM_TYPE_AUDIO][substreamIndex].keys():
|
||||
# sourceStreamDescriptor[STREAM_TYPE_AUDIO][substreamIndex]['disposition'] = {}
|
||||
# if not 'default' in sourceStreamDescriptor[STREAM_TYPE_AUDIO][substreamIndex]['disposition'].keys():
|
||||
# sourceStreamDescriptor[STREAM_TYPE_AUDIO][substreamIndex]['disposition']['default'] = 0
|
||||
# if not 'forced' in sourceStreamDescriptor[STREAM_TYPE_AUDIO][substreamIndex]['disposition'].keys():
|
||||
# sourceStreamDescriptor[STREAM_TYPE_AUDIO][substreamIndex]['disposition']['forced'] = 0
|
||||
# for substreamIndex in range(len(sourceStreamDescriptor[STREAM_TYPE_AUDIO])):
|
||||
# if not 'tags' in sourceStreamDescriptor[STREAM_TYPE_AUDIO][substreamIndex].keys():
|
||||
# sourceStreamDescriptor[STREAM_TYPE_AUDIO][substreamIndex]['tags'] = {}
|
||||
# for substreamIndex in range(len(sourceStreamDescriptor[STREAM_TYPE_SUBTITLE])):
|
||||
# if not 'disposition' in sourceStreamDescriptor[STREAM_TYPE_SUBTITLE][substreamIndex].keys():
|
||||
# sourceStreamDescriptor[STREAM_TYPE_SUBTITLE][substreamIndex]['disposition'] = {}
|
||||
# if not 'default' in sourceStreamDescriptor[STREAM_TYPE_SUBTITLE][substreamIndex]['disposition'].keys():
|
||||
# sourceStreamDescriptor[STREAM_TYPE_SUBTITLE][substreamIndex]['disposition']['default'] = 0
|
||||
# if not 'forced' in sourceStreamDescriptor[STREAM_TYPE_SUBTITLE][substreamIndex]['disposition'].keys():
|
||||
# sourceStreamDescriptor[STREAM_TYPE_SUBTITLE][substreamIndex]['disposition']['forced'] = 0
|
||||
# for substreamIndex in range(len(sourceStreamDescriptor[STREAM_TYPE_SUBTITLE])):
|
||||
# if not 'tags' in sourceStreamDescriptor[STREAM_TYPE_SUBTITLE][substreamIndex].keys():
|
||||
# sourceStreamDescriptor[STREAM_TYPE_SUBTITLE][substreamIndex]['tags'] = {}
|
||||
|
||||
###
|
||||
targetStreamDescriptor = sourceStreamDescriptor.copy()
|
||||
###
|
||||
@@ -705,27 +673,6 @@ def convert(ctx,
|
||||
targetStreamDescriptor[STREAM_TYPE_SUBTITLE][substreamIndex]['disposition']['forded'] = 1 if substreamIndex == forcedSubtitle else 0
|
||||
|
||||
|
||||
|
||||
## Process input opts
|
||||
|
||||
# # Source stream descriptors
|
||||
# audioStreams = targetStreamDescriptor[STREAM_TYPE_AUDIO]
|
||||
# subtitleStreams = targetStreamDescriptor[STREAM_TYPE_SUBTITLE]
|
||||
#
|
||||
# # Set language and title in source stream descriptors if given per command line option
|
||||
# for streamIndex in range(len(audioStreams)):
|
||||
# if streamIndex <= len(audioLanguages) - 1:
|
||||
# audioStreams[streamIndex]['tags']['language'] = audioLanguages[streamIndex]
|
||||
# if streamIndex <= len(audioTitles) - 1:
|
||||
# audioStreams[streamIndex]['tags']['title'] = audioTitles[streamIndex]
|
||||
#
|
||||
# for streamIndex in range(len(subtitleStreams)):
|
||||
# if streamIndex <= len(subtitleLanguages) - 1:
|
||||
# subtitleStreams[streamIndex]['tags']['language'] = subtitleLanguages[streamIndex]
|
||||
# if streamIndex <= len(subtitleTitles) - 1:
|
||||
# subtitleStreams[streamIndex]['tags']['title'] = subtitleTitles[streamIndex]
|
||||
|
||||
|
||||
# Set language and title in source stream descriptors if given per command line option
|
||||
for streamIndex in range(len(targetStreamDescriptor[STREAM_TYPE_AUDIO])):
|
||||
if streamIndex <= len(audioLanguages) - 1:
|
||||
@@ -740,6 +687,7 @@ def convert(ctx,
|
||||
targetStreamDescriptor[STREAM_TYPE_SUBTITLE][streamIndex]['tags']['title'] = subtitleTitles[streamIndex]
|
||||
|
||||
|
||||
|
||||
click.echo('\nTarget streams:')
|
||||
for aStream in targetStreamDescriptor[STREAM_TYPE_AUDIO]:
|
||||
click.echo(f"audio stream {aStream['sub_index']} lang={aStream['tags']['language']} title={aStream['tags']['title']} default={aStream['disposition']['default']} forced={aStream['disposition']['forced']}")
|
||||
@@ -747,6 +695,7 @@ def convert(ctx,
|
||||
click.echo(f"subtitle stream {sStream['sub_index']} lang={sStream['tags']['language']} title={sStream['tags']['title']} default={sStream['disposition']['default']} forced={sStream['disposition']['forced']}")
|
||||
|
||||
|
||||
# Find source stream order
|
||||
audioStreamSourceOrder = list(range(len(sourceStreamDescriptor[STREAM_TYPE_AUDIO])))
|
||||
subtitleStreamSourceOrder = list(range(len(sourceStreamDescriptor[STREAM_TYPE_SUBTITLE])))
|
||||
|
||||
@@ -761,35 +710,66 @@ def convert(ctx,
|
||||
subtitleStreamSourceOrder = getModifiedStreamOrder(len(sourceStreamDescriptor[STREAM_TYPE_SUBTITLE]), defaultTargetSubtitleStreams[0]['sub_index'])
|
||||
|
||||
|
||||
|
||||
mappingVideoTokens = ['-map', '0:v:0']
|
||||
|
||||
mappingTokens = mappingVideoTokens.copy()
|
||||
dispositionTokens = []
|
||||
|
||||
audioTokens = []
|
||||
|
||||
|
||||
audioMetadataTokens = []
|
||||
for audioStreamIndex in range(len(sourceStreamDescriptor[STREAM_TYPE_AUDIO])):
|
||||
|
||||
sourceAudioStreamIndex = audioStreamSourceOrder[audioStreamIndex]
|
||||
sourceAudioStream = sourceStreamDescriptor[STREAM_TYPE_AUDIO][sourceAudioStreamIndex]
|
||||
|
||||
# Create mapping and ffmpeg options for audio streams
|
||||
# mappingTokens += ['-map', f"0:a:{sourceAudioStreamIndex['src_sub_index']}"]
|
||||
mappingTokens += ['-map', f"0:a:{sourceAudioStreamIndex}"]
|
||||
|
||||
# audioTokens += generateAudioTokens(context, sourceAudioStream['src_sub_index'], sourceAudioStream['layout'])
|
||||
audioTokens += generateAudioTokens(context, sourceAudioStreamIndex, sourceAudioStream['audio_layout'])
|
||||
|
||||
if sourceStreamDescriptor[STREAM_TYPE_AUDIO][audioStreamIndex]['tags']['language'] != targetStreamDescriptor[STREAM_TYPE_AUDIO][audioStreamIndex]['tags']['language']:
|
||||
audioMetadataTokens += [f"-metadata:s:a:{audioStreamIndex}", f"language={targetStreamDescriptor[STREAM_TYPE_AUDIO][audioStreamIndex]['tags']['language']}"]
|
||||
|
||||
if sourceStreamDescriptor[STREAM_TYPE_AUDIO][audioStreamIndex]['tags']['title'] != targetStreamDescriptor[STREAM_TYPE_AUDIO][audioStreamIndex]['tags']['title']:
|
||||
audioMetadataTokens += [f"-metadata:s:a:{audioStreamIndex}", f"title={targetStreamDescriptor[STREAM_TYPE_AUDIO][audioStreamIndex]['tags']['title']}"]
|
||||
|
||||
|
||||
|
||||
|
||||
click.echo(f"Audio stream source order {audioStreamSourceOrder}")
|
||||
click.echo(f"Subtitle stream source order {subtitleStreamSourceOrder}")
|
||||
|
||||
continue
|
||||
|
||||
|
||||
commandTokens = COMMAND_TOKENS + ['-i', sourcePath]
|
||||
|
||||
subtitleFileTokens = []
|
||||
matchingSubtitles = []
|
||||
if context['import_subtitles']:
|
||||
subtitleMetadataTokens = []
|
||||
|
||||
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 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 defaultSubtitle != -1 and jellyfin:
|
||||
matchingSubtitles = getReorderedSubstreams(mSubtitles, defaultSubtitle)
|
||||
else:
|
||||
matchingSubtitles = mSubtitles
|
||||
# matchingSubtitles = []
|
||||
# if context['import_subtitles']:
|
||||
#
|
||||
# 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 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 defaultSubtitle != -1 and jellyfin:
|
||||
# matchingSubtitles = getReorderedSubstreams(mSubtitles, defaultSubtitle)
|
||||
# else:
|
||||
# matchingSubtitles = mSubtitles
|
||||
|
||||
|
||||
|
||||
@@ -798,93 +778,71 @@ def convert(ctx,
|
||||
click.echo(f"\nRunning job {job_index} file={sourcePath} q={q}")
|
||||
job_index += 1
|
||||
|
||||
mappingVideoTokens = ['-map', '0:v:0']
|
||||
|
||||
mappingTokens = mappingVideoTokens.copy()
|
||||
dispositionTokens = []
|
||||
# # Reorder audio stream descriptors and create disposition options if default is given per command line option
|
||||
# if defaultAudio == -1:
|
||||
# sourceAudioStreams = audioStreams
|
||||
# else:
|
||||
# for streamIndex in range(len(audioStreams)):
|
||||
# audioStreams[streamIndex]['disposition']['default'] = 1 if streamIndex == defaultAudio else 0
|
||||
#
|
||||
# sourceAudioStreams = getReorderedSubstreams(audioStreams, defaultAudio) if jellyfin else audioStreams
|
||||
#
|
||||
# dispositionTokens += generateDispositionTokens(sourceAudioStreams)
|
||||
#
|
||||
# # Set forced tag in subtitle descriptor if given per command line option
|
||||
# if forcedSubtitle != -1:
|
||||
# for streamIndex in range(len(subtitleStreams)):
|
||||
# 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 defaultSubtitle == -1:
|
||||
# sourceSubtitleStreams = subtitleStreams
|
||||
# else:
|
||||
# for streamIndex in range(len(subtitleStreams)):
|
||||
# subtitleStreams[streamIndex]['disposition']['default'] = 1 if streamIndex == defaultSubtitle else 0
|
||||
#
|
||||
# sourceSubtitleStreams = getReorderedSubstreams(subtitleStreams, defaultSubtitle) if jellyfin else subtitleStreams
|
||||
#
|
||||
# dispositionTokens += generateDispositionTokens(sourceSubtitleStreams)
|
||||
#
|
||||
|
||||
audioTokens = []
|
||||
|
||||
|
||||
# Reorder audio stream descriptors and create disposition options if default is given per command line option
|
||||
if defaultAudio == -1:
|
||||
sourceAudioStreams = audioStreams
|
||||
else:
|
||||
for streamIndex in range(len(audioStreams)):
|
||||
audioStreams[streamIndex]['disposition']['default'] = 1 if streamIndex == defaultAudio else 0
|
||||
|
||||
sourceAudioStreams = getReorderedSubstreams(audioStreams, defaultAudio) if jellyfin else audioStreams
|
||||
# # Create mapping and ffmpeg options for subtitle streams
|
||||
|
||||
dispositionTokens += generateDispositionTokens(sourceAudioStreams)
|
||||
|
||||
# Set forced tag in subtitle descriptor if given per command line option
|
||||
if forcedSubtitle != -1:
|
||||
for streamIndex in range(len(subtitleStreams)):
|
||||
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 defaultSubtitle == -1:
|
||||
sourceSubtitleStreams = subtitleStreams
|
||||
else:
|
||||
for streamIndex in range(len(subtitleStreams)):
|
||||
subtitleStreams[streamIndex]['disposition']['default'] = 1 if streamIndex == defaultSubtitle else 0
|
||||
|
||||
sourceSubtitleStreams = getReorderedSubstreams(subtitleStreams, defaultSubtitle) if jellyfin else subtitleStreams
|
||||
|
||||
dispositionTokens += generateDispositionTokens(sourceSubtitleStreams)
|
||||
|
||||
|
||||
audioMetadataTokens = []
|
||||
for audioStreamIndex in range(len(sourceAudioStreams)):
|
||||
|
||||
audioStream = sourceAudioStreams[audioStreamIndex]
|
||||
|
||||
# Create mapping and ffmpeg options for audio streams
|
||||
mappingTokens += ['-map', f"0:a:{audioStream['src_sub_index']}"]
|
||||
audioTokens += generateAudioTokens(context, audioStream['src_sub_index'], audioStream['layout'])
|
||||
|
||||
if 'tags' in audioStream.keys():
|
||||
if 'language' in audioStream['tags'].keys():
|
||||
audioMetadataTokens += [f"-metadata:s:a:{audioStreamIndex}", f"language={audioStream['tags']['language']}"]
|
||||
if 'title' in audioStream['tags'].keys():
|
||||
audioMetadataTokens += [f"-metadata:s:a:{audioStreamIndex}", f"title={audioStream['tags']['title']}"]
|
||||
|
||||
|
||||
# Create mapping and ffmpeg options for subtitle streams
|
||||
subtitleMetadataTokens = []
|
||||
if context['import_subtitles']:
|
||||
|
||||
numMatchingSubtitles = len(matchingSubtitles)
|
||||
|
||||
if jellyfin and defaultSubtitle != -1:
|
||||
subtitleSequence = getModifiedStreamOrder(numMatchingSubtitles, default_subtitle) #!
|
||||
else:
|
||||
subtitleSequence = range(numMatchingSubtitles)
|
||||
|
||||
for fileIndex in range(numMatchingSubtitles):
|
||||
|
||||
# Create mapping for subtitle streams when imported from files
|
||||
mappingTokens += ['-map', f"{subtitleSequence[fileIndex]+1}:s:0"]
|
||||
|
||||
msg = matchingSubtitles[fileIndex]
|
||||
subtitleMetadataTokens += [f"-metadata:s:s:{fileIndex}", f"language={msg['language']}"]
|
||||
if 'title' in matchingSubtitles[fileIndex].keys():
|
||||
subtitleMetadataTokens += [f"-metadata:s:s:{fileIndex}", f"title={matchingSubtitles[fileIndex]['title']}"]
|
||||
|
||||
else:
|
||||
|
||||
for subtitleStreamIndex in range(len(sourceSubtitleStreams)):
|
||||
|
||||
subtitleStream = sourceSubtitleStreams[subtitleStreamIndex]
|
||||
|
||||
# Create mapping for subtitle streams
|
||||
mappingTokens += ['-map', f"s:{subtitleStream['src_sub_index']}"]
|
||||
|
||||
if 'tags' in subtitleStream.keys():
|
||||
if 'language' in subtitleStream['tags'].keys():
|
||||
subtitleMetadataTokens += [f"-metadata:s:s:{subtitleStreamIndex}", f"language={subtitleStream['tags']['language']}"]
|
||||
if 'title' in subtitleStream['tags'].keys():
|
||||
subtitleMetadataTokens += [f"-metadata:s:s:{subtitleStreamIndex}", f"title={subtitleStream['tags']['title']}"]
|
||||
# if context['import_subtitles']:
|
||||
#
|
||||
# numMatchingSubtitles = len(matchingSubtitles)
|
||||
#
|
||||
# if jellyfin and defaultSubtitle != -1:
|
||||
# subtitleSequence = getModifiedStreamOrder(numMatchingSubtitles, default_subtitle) #!
|
||||
# else:
|
||||
# subtitleSequence = range(numMatchingSubtitles)
|
||||
#
|
||||
# for fileIndex in range(numMatchingSubtitles):
|
||||
#
|
||||
# # Create mapping for subtitle streams when imported from files
|
||||
# mappingTokens += ['-map', f"{subtitleSequence[fileIndex]+1}:s:0"]
|
||||
#
|
||||
# msg = matchingSubtitles[fileIndex]
|
||||
# subtitleMetadataTokens += [f"-metadata:s:s:{fileIndex}", f"language={msg['language']}"]
|
||||
# if 'title' in matchingSubtitles[fileIndex].keys():
|
||||
# subtitleMetadataTokens += [f"-metadata:s:s:{fileIndex}", f"title={matchingSubtitles[fileIndex]['title']}"]
|
||||
#
|
||||
# else:
|
||||
#
|
||||
# for subtitleStreamIndex in range(len(sourceSubtitleStreams)):
|
||||
#
|
||||
# subtitleStream = sourceSubtitleStreams[subtitleStreamIndex]
|
||||
#
|
||||
# # Create mapping for subtitle streams
|
||||
# mappingTokens += ['-map', f"s:{subtitleStream['src_sub_index']}"]
|
||||
#
|
||||
# if 'tags' in subtitleStream.keys():
|
||||
# if 'language' in subtitleStream['tags'].keys():
|
||||
# subtitleMetadataTokens += [f"-metadata:s:s:{subtitleStreamIndex}", f"language={subtitleStream['tags']['language']}"]
|
||||
# if 'title' in subtitleStream['tags'].keys():
|
||||
# subtitleMetadataTokens += [f"-metadata:s:s:{subtitleStreamIndex}", f"title={subtitleStream['tags']['title']}"]
|
||||
|
||||
|
||||
# Job specific tokens
|
||||
|
||||
Reference in New Issue
Block a user