Skip to content

Commit

Permalink
Update Embedded Subtitles provider: add forced and ass-only support
Browse files Browse the repository at this point in the history
  • Loading branch information
vitiko98 committed Dec 14, 2021
1 parent f38d03c commit 9b74ad8
Show file tree
Hide file tree
Showing 5 changed files with 73 additions and 12 deletions.
1 change: 1 addition & 0 deletions bazarr/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -192,6 +192,7 @@ def get(self, section, option, raw=False, vars=None):
},
'embeddedsubtitles': {
'include_ass': 'True',
'include_srt': 'True',
},
'subsync': {
'use_subsync': 'False',
Expand Down
1 change: 1 addition & 0 deletions bazarr/get_providers.py
Original file line number Diff line number Diff line change
Expand Up @@ -201,6 +201,7 @@ def get_providers_auth():
},
'embeddedsubtitles': {
'include_ass': settings.embeddedsubtitles.getboolean('include_ass'),
'include_srt': settings.embeddedsubtitles.getboolean('include_srt'),
'cache_dir': os.path.join(args.config_dir, "cache"),
'ffprobe_path': get_binary("ffprobe"),
'ffmpeg_path': get_binary("ffmpeg"),
Expand Down
6 changes: 5 additions & 1 deletion frontend/src/Settings/Providers/list.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,10 +51,14 @@ export const ProviderList: Readonly<ProviderInfo[]> = [
name: "Embedded Subtitles",
description: "Embedded Subtitles from your Media Files",
defaultKey: {
include_srt: true,
include_ass: true,
},
message:
"Warning for cloud users: this provider needs to read the entire file in order to extract subtitles.",
keyNameOverride: {
include_ass: "Convert embedded ASS to SRT",
include_srt: "Include SRT",
include_ass: "Include ASS (will be converted to SRT)",
},
},
{
Expand Down
37 changes: 26 additions & 11 deletions libs/subliminal_patch/providers/embeddedsubtitles.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ def __init__(self, stream, container, matches):
super().__init__(stream.language, stream.disposition.hearing_impaired)
self.stream: FFprobeSubtitleStream = stream
self.container: FFprobeVideoContainer = container
self.forced = stream.disposition.forced
self._matches: set = matches
self.page_link = self.container.path
self.release_info = os.path.basename(self.page_link)
Expand All @@ -55,17 +56,21 @@ class EmbeddedSubtitlesProvider(Provider):
Language.fromalpha2(l) for l in language_converters["alpha2"].codes
}
languages.update(set(Language.rebuild(lang, hi=True) for lang in languages))

# TODO: add forced support
# languages.update(set(Language.rebuild(lang, forced=True) for lang in languages))
languages.update(set(Language.rebuild(lang, forced=True) for lang in languages))

video_types = (Episode, Movie)
subtitle_class = EmbeddedSubtitle

def __init__(
self, include_ass=True, cache_dir=None, ffprobe_path=None, ffmpeg_path=None
self,
include_ass=True,
include_srt=True,
cache_dir=None,
ffprobe_path=None,
ffmpeg_path=None,
):
self._include_ass = include_ass
self._include_srt = include_srt
self._cache_dir = os.path.join(
cache_dir or tempfile.gettempdir(), self.__class__.__name__.lower()
)
Expand All @@ -91,31 +96,41 @@ def query(self, path: str, languages):
video = FFprobeVideoContainer(path)

try:
streams = video.get_subtitles()
streams = filter(_check_allowed_extensions, video.get_subtitles())
except fese.InvalidSource as error:
logger.error("Error trying to get subtitles for %s: %s", video, error)
streams = []

if not streams:
logger.debug("No subtitles found for container: %s", video)

only_forced = all(lang.forced for lang in languages)
also_forced = any(lang.forced for lang in languages)

subtitles = []

for stream in streams:
# Only subrip and ass are currently supported
if stream.codec_name not in ("subrip", "ass"):
logger.debug("Ignoring codec: %s", stream)
if not self._include_ass and stream.extension == "ass":
logger.debug("Ignoring ASS: %s", stream)
continue

if not self._include_ass and stream.codec_name == "ass":
logger.debug("Ignoring ASS subtitle: %s", stream)
if not self._include_srt and stream.extension == "srt":
logger.debug("Ignoring SRT: %s", stream)
continue

if stream.language not in languages:
continue

disposition = stream.disposition
if disposition.generic or disposition.hearing_impaired:

if only_forced and not disposition.forced:
continue

if (
disposition.generic
or disposition.hearing_impaired
or (disposition.forced and also_forced)
):
logger.debug("Appending subtitle: %s", stream)
subtitles.append(EmbeddedSubtitle(stream, video, {"hash"}))
else:
Expand Down
40 changes: 40 additions & 0 deletions tests/subliminal_patch/test_embeddedsubtitles.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,17 @@ def video_multiple_languages():
)


@pytest.fixture
def config(tmpdir):
return {
"include_ass": True,
"include_srt": True,
"cache_dir": tmpdir,
"ffprobe_path": None,
"ffmpeg_path": None,
}


@pytest.fixture
def video_inexistent(tmpdir):
return Movie(
Expand All @@ -46,12 +57,33 @@ def video_inexistent(tmpdir):
)


def test_init(config):
with EmbeddedSubtitlesProvider(**config) as provider:
assert provider is not None


def test_inexistent_video(video_inexistent):
with EmbeddedSubtitlesProvider() as provider:
subtitles = provider.list_subtitles(video_inexistent, {})
assert len(subtitles) == 0


def test_list_subtitles_only_forced(video_single_language):
with EmbeddedSubtitlesProvider() as provider:
language = Language.fromalpha2("en")
language = Language.rebuild(language, forced=True)
subs = provider.list_subtitles(video_single_language, {language})
assert len(subs) == 0


def test_list_subtitles_also_forced(video_single_language):
with EmbeddedSubtitlesProvider() as provider:
language_1 = Language.fromalpha2("en")
language_2 = Language.rebuild(language_1, forced=True)
subs = provider.list_subtitles(video_single_language, {language_1, language_2})
assert any(language_1 == sub.language for sub in subs)


def test_list_subtitles_single_language(video_single_language):
with EmbeddedSubtitlesProvider() as provider:
subs = provider.list_subtitles(
Expand Down Expand Up @@ -81,6 +113,14 @@ def test_list_subtitles_wo_ass(video_single_language):
assert not subs


def test_list_subtitles_wo_srt(video_multiple_languages):
with EmbeddedSubtitlesProvider(include_srt=False) as provider:
subs = provider.list_subtitles(
video_multiple_languages, {Language.fromalpha2("en")}
)
assert not subs


def test_download_subtitle_multiple(video_multiple_languages):
with EmbeddedSubtitlesProvider() as provider:
languages = {Language.fromalpha2(code) for code in ("en", "it", "fr")} | {
Expand Down

0 comments on commit 9b74ad8

Please sign in to comment.