Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Add support for forced subtitles #208

Merged
merged 4 commits into from
Nov 11, 2024
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions streamer/autodetect.py
Original file line number Diff line number Diff line change
Expand Up @@ -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)
8 changes: 8 additions & 0 deletions streamer/input_configuration.py
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -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.
Expand Down
3 changes: 3 additions & 0 deletions streamer/output_stream.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ def __init__(self,
self.input: Input = input
self.features: Dict[str, str] = {}
self.codec: Union[AudioCodec, VideoCodec, None] = codec
self.forced_subtitle = False;
avelad marked this conversation as resolved.
Show resolved Hide resolved

if self.skip_transcoding:
# If skip_transcoding is specified, let the Packager read from a plain
Expand Down Expand Up @@ -155,6 +156,8 @@ def __init__(self,
super().__init__(MediaType.TEXT, input, codec, pipe_dir,
skip_transcoding, pipe_suffix='.vtt')

self.forced_subtitle = input.forced_subtitle

avelad marked this conversation as resolved.
Show resolved Hide resolved
# The features that will be used to generate the output filename.
self.features = {
'language': input.language,
Expand Down
3 changes: 3 additions & 0 deletions streamer/packager_node.py
Original file line number Diff line number Diff line change
Expand Up @@ -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.type == MediaType.TEXT and stream.forced_subtitle:
avelad marked this conversation as resolved.
Show resolved Hide resolved
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.
Expand Down
3 changes: 3 additions & 0 deletions tests/tests.js
Original file line number Diff line number Diff line change
Expand Up @@ -1091,6 +1091,7 @@ function textTracksTests(manifestUrl, format) {
'name': TEST_DIR + 'Sintel.2010.Arabic.vtt',
'media_type': 'text',
'language': 'ar',
'forced_subtitle': true,
},
],
};
Expand All @@ -1109,6 +1110,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();
});
}

Expand Down
Loading