ff
This commit is contained in:
@@ -1,5 +1,6 @@
|
|||||||
import click
|
import click
|
||||||
|
|
||||||
|
from ffx.iso_language import IsoLanguage
|
||||||
from ffx.media_descriptor import MediaDescriptor
|
from ffx.media_descriptor import MediaDescriptor
|
||||||
from ffx.track_descriptor import TrackDescriptor
|
from ffx.track_descriptor import TrackDescriptor
|
||||||
|
|
||||||
@@ -117,7 +118,11 @@ class MediaDescriptorChangeSet():
|
|||||||
sourceTrackDescriptor: TrackDescriptor = None):
|
sourceTrackDescriptor: TrackDescriptor = None):
|
||||||
|
|
||||||
sourceTrackTags = sourceTrackDescriptor.getTags() if sourceTrackDescriptor is not None else {}
|
sourceTrackTags = sourceTrackDescriptor.getTags() if sourceTrackDescriptor is not None else {}
|
||||||
targetTrackTags = targetTrackDescriptor.getTags() if targetTrackDescriptor is not None else {}
|
targetTrackTags = (
|
||||||
|
self.normalizeTrackTags(targetTrackDescriptor.getTags())
|
||||||
|
if targetTrackDescriptor is not None
|
||||||
|
else {}
|
||||||
|
)
|
||||||
|
|
||||||
trackCompareResult = {}
|
trackCompareResult = {}
|
||||||
|
|
||||||
@@ -142,6 +147,25 @@ class MediaDescriptorChangeSet():
|
|||||||
|
|
||||||
return trackCompareResult
|
return trackCompareResult
|
||||||
|
|
||||||
|
def normalizeTrackTagValue(self, tagKey, tagValue):
|
||||||
|
if tagKey != "language":
|
||||||
|
return tagValue
|
||||||
|
|
||||||
|
if isinstance(tagValue, IsoLanguage):
|
||||||
|
return tagValue.threeLetter()
|
||||||
|
|
||||||
|
trackLanguage = IsoLanguage.findThreeLetter(str(tagValue))
|
||||||
|
if trackLanguage != IsoLanguage.UNDEFINED:
|
||||||
|
return trackLanguage.threeLetter()
|
||||||
|
|
||||||
|
return tagValue
|
||||||
|
|
||||||
|
def normalizeTrackTags(self, trackTags: dict):
|
||||||
|
return {
|
||||||
|
tagKey: self.normalizeTrackTagValue(tagKey, tagValue)
|
||||||
|
for tagKey, tagValue in trackTags.items()
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
def generateDispositionTokens(self):
|
def generateDispositionTokens(self):
|
||||||
"""
|
"""
|
||||||
@@ -243,7 +267,7 @@ class MediaDescriptorChangeSet():
|
|||||||
addedTracks: dict = self.__changeSetObj[MediaDescriptorChangeSet.TRACKS_KEY][DIFF_ADDED_KEY]
|
addedTracks: dict = self.__changeSetObj[MediaDescriptorChangeSet.TRACKS_KEY][DIFF_ADDED_KEY]
|
||||||
trackDescriptor: TrackDescriptor
|
trackDescriptor: TrackDescriptor
|
||||||
for trackDescriptor in addedTracks.values():
|
for trackDescriptor in addedTracks.values():
|
||||||
for tagKey, tagValue in trackDescriptor.getTags().items():
|
for tagKey, tagValue in self.normalizeTrackTags(trackDescriptor.getTags()).items():
|
||||||
if not tagKey in self.__removeTrackKeys:
|
if not tagKey in self.__removeTrackKeys:
|
||||||
metadataTokens += [f"-metadata:s:{trackDescriptor.getType().indicator()}"
|
metadataTokens += [f"-metadata:s:{trackDescriptor.getType().indicator()}"
|
||||||
+ f":{trackDescriptor.getSubIndex()}",
|
+ f":{trackDescriptor.getSubIndex()}",
|
||||||
@@ -267,7 +291,7 @@ class MediaDescriptorChangeSet():
|
|||||||
|
|
||||||
trackDescriptor = self.__targetTrackDescriptorsByIndex[trackIndex]
|
trackDescriptor = self.__targetTrackDescriptorsByIndex[trackIndex]
|
||||||
|
|
||||||
for tagKey, tagValue in outputTrackTags.items():
|
for tagKey, tagValue in self.normalizeTrackTags(outputTrackTags).items():
|
||||||
metadataTokens += [f"-metadata:s:{trackDescriptor.getType().indicator()}"
|
metadataTokens += [f"-metadata:s:{trackDescriptor.getType().indicator()}"
|
||||||
+ f":{trackDescriptor.getSubIndex()}",
|
+ f":{trackDescriptor.getSubIndex()}",
|
||||||
f"{tagKey}={tagValue}"]
|
f"{tagKey}={tagValue}"]
|
||||||
@@ -285,7 +309,7 @@ class MediaDescriptorChangeSet():
|
|||||||
}
|
}
|
||||||
| unchangedTrackTags
|
| unchangedTrackTags
|
||||||
)
|
)
|
||||||
for tagKey, tagValue in preservedTrackTags.items():
|
for tagKey, tagValue in self.normalizeTrackTags(preservedTrackTags).items():
|
||||||
metadataTokens += [f"-metadata:s:{trackDescriptor.getType().indicator()}"
|
metadataTokens += [f"-metadata:s:{trackDescriptor.getType().indicator()}"
|
||||||
+ f":{trackDescriptor.getSubIndex()}",
|
+ f":{trackDescriptor.getSubIndex()}",
|
||||||
f"{tagKey}={tagValue}"]
|
f"{tagKey}={tagValue}"]
|
||||||
|
|||||||
@@ -27,6 +27,64 @@ class StaticConfig:
|
|||||||
|
|
||||||
|
|
||||||
class MediaDescriptorChangeSetTests(unittest.TestCase):
|
class MediaDescriptorChangeSetTests(unittest.TestCase):
|
||||||
|
def test_non_primary_source_language_code_is_normalized_in_changed_track_metadata(self):
|
||||||
|
context = {
|
||||||
|
"logger": get_ffx_logger(),
|
||||||
|
"config": StaticConfig({}),
|
||||||
|
}
|
||||||
|
|
||||||
|
source_track = TrackDescriptor(
|
||||||
|
index=0,
|
||||||
|
source_index=0,
|
||||||
|
sub_index=0,
|
||||||
|
track_type=TrackType.AUDIO,
|
||||||
|
tags={"language": "ger", "title": "German Main"},
|
||||||
|
)
|
||||||
|
target_track = TrackDescriptor(
|
||||||
|
index=0,
|
||||||
|
source_index=0,
|
||||||
|
sub_index=0,
|
||||||
|
track_type=TrackType.AUDIO,
|
||||||
|
tags={"language": "ger", "title": "German Main"},
|
||||||
|
)
|
||||||
|
|
||||||
|
change_set = MediaDescriptorChangeSet(
|
||||||
|
context,
|
||||||
|
MediaDescriptor(track_descriptors=[target_track]),
|
||||||
|
MediaDescriptor(track_descriptors=[source_track]),
|
||||||
|
)
|
||||||
|
|
||||||
|
metadata_tokens = change_set.generateMetadataTokens()
|
||||||
|
|
||||||
|
self.assertIn("-metadata:s:a:0", metadata_tokens)
|
||||||
|
self.assertIn("language=deu", metadata_tokens)
|
||||||
|
self.assertNotIn("language=ger", metadata_tokens)
|
||||||
|
|
||||||
|
def test_target_only_track_language_metadata_uses_primary_code(self):
|
||||||
|
context = {
|
||||||
|
"logger": get_ffx_logger(),
|
||||||
|
"config": StaticConfig({}),
|
||||||
|
}
|
||||||
|
|
||||||
|
target_track = TrackDescriptor(
|
||||||
|
index=0,
|
||||||
|
source_index=0,
|
||||||
|
sub_index=0,
|
||||||
|
track_type=TrackType.AUDIO,
|
||||||
|
tags={"language": "ger", "title": "German Main"},
|
||||||
|
)
|
||||||
|
|
||||||
|
change_set = MediaDescriptorChangeSet(
|
||||||
|
context,
|
||||||
|
MediaDescriptor(track_descriptors=[target_track]),
|
||||||
|
)
|
||||||
|
|
||||||
|
metadata_tokens = change_set.generateMetadataTokens()
|
||||||
|
|
||||||
|
self.assertIn("-metadata:s:a:0", metadata_tokens)
|
||||||
|
self.assertIn("language=deu", metadata_tokens)
|
||||||
|
self.assertNotIn("language=ger", metadata_tokens)
|
||||||
|
|
||||||
def test_external_subtitle_preserves_source_only_tags_except_removed_keys(self):
|
def test_external_subtitle_preserves_source_only_tags_except_removed_keys(self):
|
||||||
context = {
|
context = {
|
||||||
"logger": get_ffx_logger(),
|
"logger": get_ffx_logger(),
|
||||||
@@ -79,6 +137,40 @@ class MediaDescriptorChangeSetTests(unittest.TestCase):
|
|||||||
self.assertNotIn("BPS=remove-me", metadata_tokens)
|
self.assertNotIn("BPS=remove-me", metadata_tokens)
|
||||||
self.assertIn("BPS=", metadata_tokens)
|
self.assertIn("BPS=", metadata_tokens)
|
||||||
|
|
||||||
|
def test_external_subtitle_normalizes_preserved_source_language_metadata(self):
|
||||||
|
context = {
|
||||||
|
"logger": get_ffx_logger(),
|
||||||
|
"config": StaticConfig({}),
|
||||||
|
}
|
||||||
|
|
||||||
|
source_track = TrackDescriptor(
|
||||||
|
index=0,
|
||||||
|
source_index=0,
|
||||||
|
sub_index=0,
|
||||||
|
track_type=TrackType.SUBTITLE,
|
||||||
|
tags={"language": "ger", "title": "German Subtitle"},
|
||||||
|
)
|
||||||
|
target_track = TrackDescriptor(
|
||||||
|
index=0,
|
||||||
|
source_index=0,
|
||||||
|
sub_index=0,
|
||||||
|
track_type=TrackType.SUBTITLE,
|
||||||
|
tags={},
|
||||||
|
external_source_file="/tmp/external-subtitle.vtt",
|
||||||
|
)
|
||||||
|
|
||||||
|
change_set = MediaDescriptorChangeSet(
|
||||||
|
context,
|
||||||
|
MediaDescriptor(track_descriptors=[target_track]),
|
||||||
|
MediaDescriptor(track_descriptors=[source_track]),
|
||||||
|
)
|
||||||
|
|
||||||
|
metadata_tokens = change_set.generateMetadataTokens()
|
||||||
|
|
||||||
|
self.assertIn("-metadata:s:s:0", metadata_tokens)
|
||||||
|
self.assertIn("language=deu", metadata_tokens)
|
||||||
|
self.assertNotIn("language=ger", metadata_tokens)
|
||||||
|
|
||||||
def test_target_only_tracks_still_emit_remove_tokens_for_configured_stream_keys(self):
|
def test_target_only_tracks_still_emit_remove_tokens_for_configured_stream_keys(self):
|
||||||
context = {
|
context = {
|
||||||
"logger": get_ffx_logger(),
|
"logger": get_ffx_logger(),
|
||||||
|
|||||||
Reference in New Issue
Block a user