click-textual
Javanaut 12 months ago
parent a082058ce2
commit fe1ed57758

@ -339,7 +339,7 @@ def convert(ctx,
click.echo(f"Input mapping tokens: {targetMediaDescriptor.getInputMappingTokens()}") click.echo(f"Input mapping tokens: {targetMediaDescriptor.getInputMappingTokens()}")
fc = FfxController(currentMediaDescriptor, targetMediaDescriptor) fc = FfxController(context, currentMediaDescriptor, targetMediaDescriptor)
mappingTokens = fc.generateMetadataTokens() mappingTokens = fc.generateMetadataTokens()
click.echo(f"Metadata Tokens: {mappingTokens}") click.echo(f"Metadata Tokens: {mappingTokens}")

@ -13,7 +13,7 @@ class AudioLayout(Enum):
LAYOUT_UNDEFINED = {"layout": "undefined", "index": 0} LAYOUT_UNDEFINED = {"layout": "undefined", "index": 0}
def layout(self): def label(self):
"""Returns the layout as string""" """Returns the layout as string"""
return self.value['layout'] return self.value['layout']
@ -21,6 +21,12 @@ class AudioLayout(Enum):
"""Returns the layout as string""" """Returns the layout as string"""
return self.value['layout'] return self.value['layout']
@staticmethod
def fromIndex(index : int):
try:
return [a for a in AudioLayout if a.index() == int(index)][0]
except:
return AudioLayout.LAYOUT_UNDEFINED
def identify(self, streamObj): def identify(self, streamObj):

@ -4,6 +4,7 @@ from ffx.media_descriptor import MediaDescriptor
from ffx.helper import DIFF_ADDED_KEY, DIFF_REMOVED_KEY, DIFF_CHANGED_KEY from ffx.helper import DIFF_ADDED_KEY, DIFF_REMOVED_KEY, DIFF_CHANGED_KEY
from ffx.track_descriptor import TrackDescriptor from ffx.track_descriptor import TrackDescriptor
from ffx.model.track import Track from ffx.model.track import Track
from ffx.audio_layout import AudioLayout
class FfxController(): class FfxController():
@ -37,8 +38,12 @@ class FfxController():
INPUT_FILE_EXTENSIONS = ['mkv', 'mp4', 'avi', 'flv', 'webm'] INPUT_FILE_EXTENSIONS = ['mkv', 'mp4', 'avi', 'flv', 'webm']
def __init__(self, sourceMediaDescriptor : MediaDescriptor, targetMediaDescriptor : MediaDescriptor): def __init__(self,
context : dict,
sourceMediaDescriptor : MediaDescriptor,
targetMediaDescriptor : MediaDescriptor):
self.__context = context
self.__sourceMediaDescriptor = sourceMediaDescriptor self.__sourceMediaDescriptor = sourceMediaDescriptor
self.__targetMediaDescriptor = targetMediaDescriptor self.__targetMediaDescriptor = targetMediaDescriptor
@ -99,49 +104,49 @@ class FfxController():
return ['-f', format, f"{filepath}.{ext}"] return ['-f', format, f"{filepath}.{ext}"]
def generateAudioEncodingTokens(self, context, index, layout): def generateAudioEncodingTokens(self, subIndex : int, layout : AudioLayout):
"""Generates ffmpeg options for one output audio stream including channel remapping, codec and bitrate""" """Generates ffmpeg options for one output audio stream including channel remapping, codec and bitrate"""
pass pass
#
# if layout == STREAM_LAYOUT_6_1: if layout == AudioLayout.LAYOUT_6_1:
# return [f"-c:a:{index}", return [f"-c:a:{subIndex}",
# 'libopus', 'libopus',
# f"-filter:a:{index}", f"-filter:a:{subIndex}",
# 'channelmap=channel_layout=6.1', 'channelmap=channel_layout=6.1',
# f"-b:a:{index}", f"-b:a:{subIndex}",
# context['bitrates']['dts']] self.__context['bitrates']['dts']]
#
# elif layout == STREAM_LAYOUT_5_1: elif layout == AudioLayout.LAYOUT_5_1:
# return [f"-c:a:{index}", return [f"-c:a:{subIndex}",
# 'libopus', 'libopus',
# f"-filter:a:{index}", f"-filter:a:{subIndex}",
# "channelmap=FL-FL|FR-FR|FC-FC|LFE-LFE|SL-BL|SR-BR:5.1", "channelmap=FL-FL|FR-FR|FC-FC|LFE-LFE|SL-BL|SR-BR:5.1",
# f"-b:a:{index}", f"-b:a:{subIndex}",
# context['bitrates']['ac3']] self.__context['bitrates']['ac3']]
#
# elif layout == STREAM_LAYOUT_STEREO: elif layout == AudioLayout.LAYOUT_STEREO:
# return [f"-c:a:{index}", return [f"-c:a:{subIndex}",
# 'libopus', 'libopus',
# f"-b:a:{index}", f"-b:a:{subIndex}",
# context['bitrates']['stereo']] self.__context['bitrates']['stereo']]
#
# elif layout == STREAM_LAYOUT_6CH: elif layout == AudioLayout.LAYOUT_6CH:
# return [f"-c:a:{index}", return [f"-c:a:{subIndex}",
# 'libopus', 'libopus',
# f"-filter:a:{index}", f"-filter:a:{subIndex}",
# "channelmap=FL-FL|FR-FR|FC-FC|LFE-LFE|SL-BL|SR-BR:5.1", "channelmap=FL-FL|FR-FR|FC-FC|LFE-LFE|SL-BL|SR-BR:5.1",
# f"-b:a:{index}", f"-b:a:{subIndex}",
# context['bitrates']['ac3']] self.__context['bitrates']['ac3']]
# else: else:
# return [] return []
def generateClearTokens(self, streams): # def generateClearTokens(self, streams):
clearTokens = [] # clearTokens = []
for s in streams: # for s in streams:
for k in FfxController.MKVMERGE_METADATA_KEYS: # for k in FfxController.MKVMERGE_METADATA_KEYS:
clearTokens += [f"-metadata:s:{s['type'][0]}:{s['sub_index']}", f"{k}="] # clearTokens += [f"-metadata:s:{s['type'][0]}:{s['sub_index']}", f"{k}="]
return clearTokens # return clearTokens

@ -191,7 +191,9 @@ class MediaDescriptor():
#HINT: Some tags differ per file, for example creation_time, so these are removed before diff #HINT: Some tags differ per file, for example creation_time, so these are removed before diff
for emt in MediaDescriptor.EXCLUDED_MEDIA_TAGS: for emt in MediaDescriptor.EXCLUDED_MEDIA_TAGS:
if emt in tags.keys():
del tags[emt] del tags[emt]
if emt in vsTags.keys():
del vsTags[emt] del vsTags[emt]
tagsDiff = dictDiff(vsTags, tags) tagsDiff = dictDiff(vsTags, tags)
@ -218,12 +220,12 @@ class MediaDescriptor():
for tp in range(maxNumOfTracks): for tp in range(maxNumOfTracks):
# if self.__jellyfinOrder: # inspect/update funktionier nur so
# vsTrackIndex = tracks[tp].getSourceIndex() if self.__jellyfinOrder:
# else:
# vsTrackIndex = tp
vsTrackIndex = tracks[tp].getSourceIndex() vsTrackIndex = tracks[tp].getSourceIndex()
else:
vsTrackIndex = tp
# vsTrackIndex = tracks[tp].getSourceIndex()
# Will trigger if tracks are missing in file # Will trigger if tracks are missing in file
if tp > (numVsTracks - 1): if tp > (numVsTracks - 1):

@ -507,6 +507,8 @@ class MediaDetailsScreen(Screen):
if DIFF_REMOVED_KEY in self.__mediaDifferences[MediaDescriptor.TRACKS_KEY].keys(): if DIFF_REMOVED_KEY in self.__mediaDifferences[MediaDescriptor.TRACKS_KEY].keys():
for removedTrackIndex, removedTrack in self.__mediaDifferences[MediaDescriptor.TRACKS_KEY][DIFF_REMOVED_KEY].items(): for removedTrackIndex, removedTrack in self.__mediaDifferences[MediaDescriptor.TRACKS_KEY][DIFF_REMOVED_KEY].items():
# Track per inspect/update hinzufügen
self.__tc.addTrack(removedTrack, patternId = self.__currentPattern.getId()) self.__tc.addTrack(removedTrack, patternId = self.__currentPattern.getId())
if DIFF_CHANGED_KEY in self.__mediaDifferences[MediaDescriptor.TRACKS_KEY].keys(): if DIFF_CHANGED_KEY in self.__mediaDifferences[MediaDescriptor.TRACKS_KEY].keys():

@ -11,6 +11,8 @@ from ffx.iso_language import IsoLanguage
from ffx.track_disposition import TrackDisposition from ffx.track_disposition import TrackDisposition
from ffx.track_descriptor import TrackDescriptor from ffx.track_descriptor import TrackDescriptor
from ffx.audio_layout import AudioLayout
import click import click
class Track(Base): class Track(Base):
@ -40,9 +42,10 @@ class Track(Base):
track_tags = relationship('TrackTag', back_populates='track', cascade="all, delete", lazy="joined") track_tags = relationship('TrackTag', back_populates='track', cascade="all, delete", lazy="joined")
disposition_flags = Column(Integer) disposition_flags = Column(Integer)
audio_layout = Column(Integer)
def __init__(self, **kwargs): def __init__(self, **kwargs):
@ -57,7 +60,7 @@ class Track(Base):
@classmethod @classmethod
def fromStreamObj(cls, streamObj, patternId): def fromFfprobeStreamObj(cls, streamObj, patternId):
"""{ """{
'index': 4, 'index': 4,
'codec_name': 'hdmv_pgs_subtitle', 'codec_name': 'hdmv_pgs_subtitle',
@ -124,14 +127,15 @@ class Track(Base):
""" """
trackType = streamObj['codec_type'] trackType = streamObj[TrackDescriptor.FFPROBE_CODEC_TYPE_KEY]
if trackType in [t.label() for t in TrackType]: if trackType in [t.label() for t in TrackType]:
# sub_index = int(subIndex),
return cls(pattern_id = patternId, return cls(pattern_id = patternId,
track_type = trackType, track_type = trackType,
disposition_flags = sum([2**t.index() for (k,v) in streamObj['disposition'].items() if v and (t := TrackDisposition.find(k)) is not None])) disposition_flags = sum([2**t.index() for (k,v) in streamObj[TrackDescriptor.FFPROBE_DISPOSITION_KEY].items()
if v and (t := TrackDisposition.find(k)) is not None]),
audio_layout = AudioLayout.identify(streamObj))
else: else:
return None return None
@ -163,6 +167,9 @@ class Track(Base):
def getDispositionSet(self): def getDispositionSet(self):
return TrackDisposition.toSet(self.disposition_flags) return TrackDisposition.toSet(self.disposition_flags)
def getAudioLayout(self):
return AudioLayout.fromIndex(self.audio_layout)
def getTags(self): def getTags(self):
return {str(t.key):str(t.value) for t in self.track_tags} return {str(t.key):str(t.value) for t in self.track_tags}
@ -194,4 +201,6 @@ class Track(Base):
kwargs[TrackDescriptor.DISPOSITION_SET_KEY] = self.getDispositionSet() kwargs[TrackDescriptor.DISPOSITION_SET_KEY] = self.getDispositionSet()
kwargs[TrackDescriptor.TAGS_KEY] = self.getTags() kwargs[TrackDescriptor.TAGS_KEY] = self.getTags()
kwargs[TrackDescriptor.AUDIO_LAYOUT_KEY] = self.getAudioLayout()
return TrackDescriptor(**kwargs) return TrackDescriptor(**kwargs)

@ -138,7 +138,7 @@ class PatternDetailsScreen(Screen):
row = (td.getIndex(), row = (td.getIndex(),
trackType.label(), trackType.label(),
typeCounter[trackType], typeCounter[trackType],
" ", td.getAudioLayout().label(),
td.getLanguage().label(), td.getLanguage().label(),
td.getTitle(), td.getTitle(),
'Yes' if TrackDisposition.DEFAULT in dispoSet else 'No', 'Yes' if TrackDisposition.DEFAULT in dispoSet else 'No',

@ -82,16 +82,16 @@ class ShowDetailsScreen(Screen):
self.show_obj = self.__sc.getShowDesciptor(showId) if showId is not None else {} self.show_obj = self.__sc.getShowDesciptor(showId) if showId is not None else {}
def loadPatterns(self, show_id): def loadPatterns(self, show_id : int):
try: try:
s = self.Session() s = self.Session()
q = s.query(Pattern).filter(Pattern.show_id == int(show_id)) q = s.query(Pattern).filter(Pattern.show_id == int(show_id))
return [{'id': int(p.id), 'pattern': p.pattern} for p in q.all()] return [{'id': int(p.id), 'pattern': str(p.pattern)} for p in q.all()]
except Exception as ex: except Exception as ex:
click.ClickException(f"loadPatterns(): {repr(ex)}") raise click.ClickException(f"ShowDetailsScreen.loadPatterns(): {repr(ex)}")
finally: finally:
s.close() s.close()
@ -109,7 +109,11 @@ class ShowDetailsScreen(Screen):
self.query_one("#indicator_season_digits_input", Input).value = str(self.show_obj['indicator_season_digits']) self.query_one("#indicator_season_digits_input", Input).value = str(self.show_obj['indicator_season_digits'])
self.query_one("#indicator_episode_digits_input", Input).value = str(self.show_obj['indicator_episode_digits']) self.query_one("#indicator_episode_digits_input", Input).value = str(self.show_obj['indicator_episode_digits'])
for pattern in self.loadPatterns(int(self.show_obj['id'])): showId = int(self.show_obj['id'])
#raise click.ClickException(f"show_id {showId}")
patternList = self.loadPatterns(showId)
# raise click.ClickException(f"patternList {patternList}")
for pattern in patternList:
row = (pattern['pattern'],) row = (pattern['pattern'],)
self.patternTable.add_row(*map(str, row)) self.patternTable.add_row(*map(str, row))

@ -23,6 +23,7 @@ class TrackDescriptor():
FFPROBE_INDEX_KEY = 'index' FFPROBE_INDEX_KEY = 'index'
FFPROBE_DISPOSITION_KEY = 'disposition' FFPROBE_DISPOSITION_KEY = 'disposition'
FFPROBE_TAGS_KEY = 'tags' FFPROBE_TAGS_KEY = 'tags'
FFPROBE_CODEC_TYPE_KEY = 'codec_type'
def __init__(self, **kwargs): def __init__(self, **kwargs):

@ -348,6 +348,7 @@ class TrackDetailsScreen(Screen):
if self.__isNew: if self.__isNew:
# Track per Screen hinzufügen
self.__tc.addTrack(trackDescriptor) self.__tc.addTrack(trackDescriptor)
self.dismiss(trackDescriptor) self.dismiss(trackDescriptor)
@ -355,6 +356,7 @@ class TrackDetailsScreen(Screen):
track = self.__tc.getTrack(self.__pattern.getId(), self.__index) track = self.__tc.getTrack(self.__pattern.getId(), self.__index)
# Track per details screen updaten
if self.__tc.updateTrack(track.getId(), trackDescriptor): if self.__tc.updateTrack(track.getId(), trackDescriptor):
self.dismiss(trackDescriptor) self.dismiss(trackDescriptor)

Loading…
Cancel
Save