From 96ae67a1d657c0cd4d8d1991742cf5f7dd553d29 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=81lvaro=20Velad=20Galv=C3=A1n?= Date: Mon, 11 Nov 2024 19:06:10 +0100 Subject: [PATCH] feat: Add support for forced subtitles (#208) --- streamer/autodetect.py | 10 ++++++++++ streamer/input_configuration.py | 8 ++++++++ streamer/packager_node.py | 3 +++ tests/tests.js | 3 +++ 4 files changed, 24 insertions(+) diff --git a/streamer/autodetect.py b/streamer/autodetect.py index 1cfcb96..0404e04 100644 --- a/streamer/autodetect.py +++ b/streamer/autodetect.py @@ -173,3 +173,13 @@ def get_channel_layout(input: Input) -> Optional[AudioChannelLayoutName]: return bucket.get_key() return None + +def get_forced_subttitle(input: Input) -> bool: + """Returns the forced subtitle value of the input.""" + + forced_subttitle_string = _probe(input, 'disposition=forced') + + if forced_subttitle_string is None: + return False + + return bool(forced_subttitle_string) diff --git a/streamer/input_configuration.py b/streamer/input_configuration.py index 301a351..b34f6b5 100644 --- a/streamer/input_configuration.py +++ b/streamer/input_configuration.py @@ -211,6 +211,12 @@ class Input(configuration.Base): Not supported with media_type of 'text'. """ + forced_subtitle = configuration.Field(bool).cast() + """Indicates that the subtitle is forced. + + Only supported with media_type of 'text'. + """ + def __init__(self, *args) -> None: super().__init__(*args) @@ -264,6 +270,8 @@ def disallow_field(name: str, reason: str) -> None: reason = 'text streams are not supported in input_type "{}"'.format( self.input_type.value) disallow_field('input_type', reason) + if self.forced_subtitle is None: + self.forced_subtitle = autodetect.get_forced_subttitle(self) # These fields are not supported with text, because we don't process or # transcode it. diff --git a/streamer/packager_node.py b/streamer/packager_node.py index e80019b..db18b61 100644 --- a/streamer/packager_node.py +++ b/streamer/packager_node.py @@ -144,6 +144,9 @@ def _setup_stream(self, stream: OutputStream) -> str: if stream.input.drm_label: dict['drm_label'] = stream.input.drm_label + if stream.input.forced_subtitle: + dict['forced_subtitle'] = '1' + # Note: Shaka Packager will not accept 'und' as a language, but Shaka # Player will fill that in if the language metadata is missing from the # manifest/playlist. diff --git a/tests/tests.js b/tests/tests.js index b781d7f..0268c16 100644 --- a/tests/tests.js +++ b/tests/tests.js @@ -1066,6 +1066,7 @@ function textTracksTests(manifestUrl, format) { 'name': TEST_DIR + 'Sintel.2010.Arabic.vtt', 'media_type': 'text', 'language': 'ar', + 'forced_subtitle': true, }, ], }; @@ -1084,6 +1085,8 @@ function textTracksTests(manifestUrl, format) { const languageList = trackList.map(track => track.language); languageList.sort(); expect(languageList).toEqual(['ar', 'en', 'eo', 'es']); + const arTrack = trackList.find(track => track.language == 'ar'); + expect(arTrack.forced).toBeTruthy(); }); }