decon/inc stream parsing

click
Maveno 1 year ago
parent 5ed97e0b9b
commit 8ad50fd881

@ -209,30 +209,29 @@ def getStreamDescriptor(filename):
for subStream in streamData: for subStream in streamData:
s = subStream.copy() if not 'disposition' in subStream.keys():
subStream['disposition'] = {}
#Defaulting to undefined if tag not defined for stream if not 'default' in subStream['disposition'].keys():
if 'tags' in subStream.keys() and 'language' in subStream['tags'].keys(): subStream['disposition']['default'] = 0
s['language'] = subStream['tags']['language'] if not 'forced' in subStream['disposition'].keys():
else: subStream['disposition']['forced'] = 0
s['language'] = 'undefined' if not 'tags' in subStream.keys():
subStream['tags'] = {}
#Defaulting to undefined if tag not defined for stream if not 'language' in subStream['tags'].keys():
if 'tags' in subStream.keys() and 'title' in subStream['tags'].keys(): subStream['tags']['language'] = 'undefined'
s['title'] = subStream['tags']['title'] if not 'title' in subStream['tags'].keys():
else: subStream['tags']['title'] = 'undefined'
s['title'] = 'undefined'
if subStream['codec_type'] == STREAM_TYPE_AUDIO: if subStream['codec_type'] == STREAM_TYPE_AUDIO:
if 'channel_layout' in subStream.keys(): if 'channel_layout' in subStream.keys():
s['layout'] = subStream['channel_layout'] subStream['audio_layout'] = subStream['channel_layout']
elif subStream['channels'] == 6: elif subStream['channels'] == 6:
s['layout'] = STREAM_LAYOUT_6CH subStream['audio_layout'] = STREAM_LAYOUT_6CH
else: else:
s['layout'] = 'undefined' subStream['audio_layout'] = 'undefined'
descriptor[s['codec_type']].append(s) descriptor[subStream['codec_type']].append(subStream)
descriptor[s['codec_type']][-1]['src_sub_index'] = len(descriptor[s['codec_type']]) - 1 descriptor[subStream['codec_type']][-1]['sub_index'] = len(descriptor[subStream['codec_type']]) - 1
return descriptor return descriptor
@ -247,13 +246,13 @@ def getModifiedStreamOrder(length, last):
return seq return seq
def getReorderedSubstreams(subDescriptor, last): # def getReorderedSubstreams(subDescriptor, last):
numSubStreams = len(subDescriptor) # numSubStreams = len(subDescriptor)
modifiedOrder = getModifiedStreamOrder(numSubStreams, last) # modifiedOrder = getModifiedStreamOrder(numSubStreams, last)
reorderedDescriptor = [] # reorderedDescriptor = []
for streamIndex in range(numSubStreams): # for streamIndex in range(numSubStreams):
reorderedDescriptor.append(subDescriptor[modifiedOrder[streamIndex]]) # reorderedDescriptor.append(subDescriptor[modifiedOrder[streamIndex]])
return reorderedDescriptor # return reorderedDescriptor
def generateAV1Tokens(q, p): def generateAV1Tokens(q, p):
@ -619,46 +618,61 @@ def convert(ctx,
targetFilenameTokens = [sourceFileBasename] 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: try:
###
sourceStreamDescriptor = getStreamDescriptor(sourcePath) sourceStreamDescriptor = getStreamDescriptor(sourcePath)
###
# 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()
except Exception: except Exception:
click.echo(f"File with path {sourcePath} does not contain any audiovisual data, skipping ...") click.echo(f"File with path {sourcePath} does not contain any audiovisual data, skipping ...")
continue continue
# # Ensure disposition and tags keys for every stream
click.echo('Source streans:') # 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()
###
click.echo('\nSource streams:')
for aStream in sourceStreamDescriptor[STREAM_TYPE_AUDIO]: for aStream in sourceStreamDescriptor[STREAM_TYPE_AUDIO]:
click.echo(f"audio stream {aStream['src_sub_index']} lang={aStream['language']} title={aStream['title']} default={aStream['disposition']['default']} forced={aStream['disposition']['forced']}") click.echo(f"audio stream {aStream['sub_index']} lang={aStream['tags']['language']} title={aStream['tags']['title']} default={aStream['disposition']['default']} forced={aStream['disposition']['forced']}")
for sStream in sourceStreamDescriptor[STREAM_TYPE_SUBTITLE]: for sStream in sourceStreamDescriptor[STREAM_TYPE_SUBTITLE]:
click.echo(f"subtitle stream {sStream['src_sub_index']} lang={sStream['language']} title={sStream['title']} default={sStream['disposition']['default']} forced={sStream['disposition']['forced']}") click.echo(f"subtitle stream {sStream['sub_index']} lang={sStream['tags']['language']} title={sStream['tags']['title']} default={sStream['disposition']['default']} forced={sStream['disposition']['forced']}")
# Check for multiple default or forced dispositions if not set by user input or database requirements
#NOTE: It is currently expected that all source file have the same substream pattern, e.g. coming from the same encoder #NOTE: It is currently expected that all source file have the same substream pattern, e.g. coming from the same encoder
numDefaultAudioStreams = len([a for a in sourceStreamDescriptor[STREAM_TYPE_AUDIO] if a['disposition']['default'] == 1]) numDefaultAudioStreams = len([a for a in sourceStreamDescriptor[STREAM_TYPE_AUDIO] if a['disposition']['default'] == 1])
if defaultAudio == -1 and numDefaultAudioStreams > 1: if defaultAudio == -1 and numDefaultAudioStreams > 1:
@ -676,7 +690,6 @@ def convert(ctx,
if forcedSubtitle == -1 and numForcedSubtitleStreams > 1: if forcedSubtitle == -1 and numForcedSubtitleStreams > 1:
forcedSubtitle = click.prompt("More than one forced subtitle stream detected! Please select stream", type=int) forcedSubtitle = click.prompt("More than one forced subtitle stream detected! Please select stream", type=int)
#Fix multiple default/forced tags #Fix multiple default/forced tags
if defaultAudio != -1: if defaultAudio != -1:
for substreamIndex in range(len(targetStreamDescriptor[STREAM_TYPE_AUDIO])): for substreamIndex in range(len(targetStreamDescriptor[STREAM_TYPE_AUDIO])):
@ -692,14 +705,50 @@ def convert(ctx,
targetStreamDescriptor[STREAM_TYPE_SUBTITLE][substreamIndex]['disposition']['forded'] = 1 if substreamIndex == forcedSubtitle else 0 targetStreamDescriptor[STREAM_TYPE_SUBTITLE][substreamIndex]['disposition']['forded'] = 1 if substreamIndex == forcedSubtitle else 0
click.echo('Target streans:')
for aStream in targetStreamDescriptor[STREAM_TYPE_AUDIO]:
click.echo(f"audio stream {aStream['src_sub_index']} lang={aStream['language']} title={aStream['title']} default={aStream['disposition']['default']} forced={aStream['disposition']['forced']}")
for sStream in targetStreamDescriptor[STREAM_TYPE_SUBTITLE]: ## Process input opts
click.echo(f"subtitle stream {sStream['src_sub_index']} lang={sStream['language']} title={sStream['title']} default={sStream['disposition']['default']} forced={sStream['disposition']['forced']}")
# # 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:
targetStreamDescriptor[STREAM_TYPE_AUDIO][streamIndex]['tags']['language'] = audioLanguages[streamIndex]
if streamIndex <= len(audioTitles) - 1:
targetStreamDescriptor[STREAM_TYPE_AUDIO][streamIndex]['tags']['title'] = audioTitles[streamIndex]
for streamIndex in range(len(targetStreamDescriptor[STREAM_TYPE_SUBTITLE])):
if streamIndex <= len(subtitleLanguages) - 1:
targetStreamDescriptor[STREAM_TYPE_SUBTITLE][streamIndex]['tags']['language'] = subtitleLanguages[streamIndex]
if streamIndex <= len(subtitleTitles) - 1:
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']}")
for sStream in targetStreamDescriptor[STREAM_TYPE_SUBTITLE]:
click.echo(f"subtitle stream {sStream['sub_index']} lang={sStream['tags']['language']} title={sStream['tags']['title']} default={sStream['disposition']['default']} forced={sStream['disposition']['forced']}")
continue
commandTokens = COMMAND_TOKENS + ['-i', sourcePath] commandTokens = COMMAND_TOKENS + ['-i', sourcePath]
@ -739,28 +788,6 @@ def convert(ctx,
audioTokens = [] audioTokens = []
# Source stream descriptors
audioStreams = sourceStreamDescriptor[STREAM_TYPE_AUDIO]
subtitleStreams = sourceStreamDescriptor[STREAM_TYPE_SUBTITLE]
# Set language and title in source stream descriptors if given per command line option
for streamIndex in range(len(audioStreams)):
if 'tags' not in audioStreams[streamIndex].keys():
audioStreams[streamIndex]['tags'] = {}
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 'tags' not in subtitleStreams[streamIndex].keys():
subtitleStreams[streamIndex]['tags'] = {}
if streamIndex <= len(subtitleLanguages) - 1:
subtitleStreams[streamIndex]['tags']['language'] = subtitleLanguages[streamIndex]
if streamIndex <= len(subtitleTitles) - 1:
subtitleStreams[streamIndex]['tags']['title'] = subtitleTitles[streamIndex]
# Reorder audio stream descriptors and create disposition options if default is given per command line option # Reorder audio stream descriptors and create disposition options if default is given per command line option
if defaultAudio == -1: if defaultAudio == -1:
@ -813,7 +840,7 @@ def convert(ctx,
numMatchingSubtitles = len(matchingSubtitles) numMatchingSubtitles = len(matchingSubtitles)
if jellyfin and defaultSubtitle != -1: if jellyfin and defaultSubtitle != -1:
subtitleSequence = getModifiedStreamOrder(numMatchingSubtitles, default_subtitle) subtitleSequence = getModifiedStreamOrder(numMatchingSubtitles, default_subtitle) #!
else: else:
subtitleSequence = range(numMatchingSubtitles) subtitleSequence = range(numMatchingSubtitles)

Loading…
Cancel
Save