OverviewFilesCommitsIssuesDocsReleasesPeers

stremio-vsembed commits / a7b358e

Language codes Jellyfin actually resolves, not ones that merely look right (0.18.1)
0.18.0 shipped `yue` for Cantonese and `zh-Hant` for traditional Chinese. Both are perfectly good language tags. Jellyfin filed the Cantonese track as "Undefined", because neither is in the table doing the lookup -- which is the only thing that matters here. The targets are now read off the server's own /Localization/Cultures rather than reasoned about: pb -> pt-br Portuguese (Brazil) ea -> es-419 Spanish; Latin zt -> zh-tw Chinese (Traditional) (zh-Hant is absent from that table) zc -> zh-hk Chinese (Hong Kong) (yue is absent from that table) `ze` leaves the map entirely: Jellyfin lists it natively as "Chinese (Bilingual)", so mapping it to `zh` was throwing away a distinction the server was ready to make. Measured after a rescan: 32 tracks, none Undefined. Only the zc change alters an outcome -- zh-Hant already resolved, and `ze` resolves to `zho` either way -- but all four now come from the list rather than from what looked reasonable, which is the difference that let the first one through. Found only by looking at the product surface after the ingest. The unit tests passed on the old map and would have gone on passing: they asserted the filenames matched the map, and the map was the thing that was wrong. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
a7b358e052bf52a4681346b21015cc58ecfe295d
by plankatron <fleeky@gmail.com> · 2026-09-05T01:04:43.000Z

Changed files (2) +42 -16

addon.py +23 -8
……@@ -599,7 +599,7 @@ TV_GENRES = [
599599
600600MANIFEST = {
601601 "id": "org.tabertron.vsembed",
602 "version": "0.18.0",
602 "version": "0.18.1",
603603 "name": "Tabertron VsEmbed",
604604 "description": "Self-hosted HLS extractor with TMDB browse + search, played via vidcore",
605605 "types": ["movie", "series"],
……@@ -1797,16 +1797,31 @@ SUBTITLE_TIMEOUT = 25
17971797# nothing against a set this size and is rude to a host doing us a favour.
17981798SUBTITLE_WORKERS = 8
17991799
1800# wyzie speaks OpenSubtitles' codes, and several are not ISO at all. Verified on
1801# 639988 against the endpoint's own `display` field. Anything not listed is
1802# passed through: an unrecognised code still names a distinct file, and dropping
1803# a subtitle because we did not recognise its label is the worse failure.
1800# wyzie speaks OpenSubtitles' codes, and several are not ISO at all.
1801#
1802# The targets are NOT guessed: they are the codes Jellyfin's own
1803# /Localization/Cultures list answers to, checked 2026-09-04 after a first
1804# attempt shipped `yue` and `zh-Hant` and Jellyfin filed the Cantonese track as
1805# "Undefined". Both are perfectly good language tags; they are simply not in the
1806# table doing the lookup, which is the only thing that matters here.
1807#
1808# pb -> pt-br "Portuguese (Brazil)"
1809# ea -> es-419 "Spanish; Latin"
1810# zt -> zh-tw "Chinese (Traditional)" (zh-Hant is NOT in the table)
1811# zc -> zh-hk "Chinese (Hong Kong)" (yue is NOT in the table)
1812#
1813# `ze` is deliberately absent: Jellyfin knows it natively as "Chinese
1814# (Bilingual)", so mapping it to `zh` threw away a distinction the server was
1815# ready to make.
1816#
1817# Anything not listed is passed through: an unrecognised code still names a
1818# distinct file, and dropping a subtitle because we did not recognise its label
1819# is the worse failure.
18041820WYZIE_LANG_MAP = {
18051821 "pb": "pt-BR", # Portuguese (BR)
18061822 "ea": "es-419", # Spanish (LA)
1807 "zt": "zh-Hant", # Chinese (traditional)
1808 "zc": "yue", # Chinese (Cantonese)
1809 "ze": "zh", # Chinese bilingual
1823 "zt": "zh-TW", # Chinese (traditional)
1824 "zc": "zh-HK", # Chinese (Cantonese)
18101825}
18111826
18121827
test_subtitles.py +19 -8
……@@ -114,22 +114,33 @@ def test_the_language_code_is_the_suffix_jellyfin_reads(mp4, fetched):
114114 assert os.path.basename(paths[0]) == "No Other Choice (2025).en.srt"
115115
116116
117def test_opensubtitles_only_codes_are_mapped_to_real_ones(mp4, fetched):
118 """wyzie speaks OpenSubtitles' codes, several of which are not ISO at all.
119 Verified on 639988: pb='Portuguese (BR)', ea='Spanish (LA)',
120 zt='Chinese (traditional)', zc='Chinese (Cantonese)', ze='Chinese bilingual'."""
117def test_opensubtitles_only_codes_are_mapped_to_ones_jellyfin_RESOLVES(mp4, fetched):
118 """The targets are the codes Jellyfin's /Localization/Cultures answers to.
119
120 Not a detail: the first version shipped `yue` and `zh-Hant`, which are
121 perfectly good language tags and are simply absent from that table, so
122 Jellyfin filed the Cantonese track as "Undefined". Measured, not reasoned.
123 """
121124 paths = addon._write_sidecars(mp4, _tracks(
122125 ("pb", "Portuguese (BR)"), ("ea", "Spanish (LA)"),
123126 ("zt", "Chinese (traditional)"), ("zc", "Chinese (Cantonese)")))
124127 names = sorted(os.path.basename(p) for p in paths)
125128 assert names == sorted([
126 "No Other Choice (2025).pt-BR.srt",
127 "No Other Choice (2025).es-419.srt",
128 "No Other Choice (2025).zh-Hant.srt",
129 "No Other Choice (2025).yue.srt",
129 "No Other Choice (2025).pt-BR.srt", # -> Portuguese (Brazil)
130 "No Other Choice (2025).es-419.srt", # -> Spanish; Latin
131 "No Other Choice (2025).zh-TW.srt", # -> Chinese (Traditional)
132 "No Other Choice (2025).zh-HK.srt", # -> Chinese (Hong Kong)
130133 ])
131134
132135
136def test_a_code_jellyfin_already_knows_is_left_alone(mp4, fetched):
137 """`ze` is native to Jellyfin as "Chinese (Bilingual)". Mapping it to `zh`
138 threw away a distinction the server was ready to make -- so the map must not
139 contain it."""
140 paths = addon._write_sidecars(mp4, _tracks(("ze", "Chinese bilingual")))
141 assert os.path.basename(paths[0]) == "No Other Choice (2025).ze.srt"
142
143
133144def test_two_tracks_in_one_language_do_not_overwrite_each_other(mp4, fetched):
134145 paths = addon._write_sidecars(mp4, _tracks(("en", "English"), ("en", "English")))
135146 assert len(set(paths)) == 2, "the second track overwrote the first"