444d2eb733
Move language normalization out of jellyfin.ts into its own module so non-Jellyfin services (ffmpeg, radarr, sonarr, analyzer) no longer depend on the Jellyfin service file. jellyfin.ts re-exports normalizeLanguage for backward compatibility. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
41 lines
1.8 KiB
TypeScript
41 lines
1.8 KiB
TypeScript
// ISO 639-1 (2-letter) → ISO 639-2/B (3-letter)
|
|
const ISO_1_TO_2: Record<string, string> = {
|
|
en: "eng", de: "deu", es: "spa", fr: "fra", it: "ita", pt: "por",
|
|
ja: "jpn", ko: "kor", zh: "zho", ar: "ara", ru: "rus", nl: "nld",
|
|
sv: "swe", no: "nor", da: "dan", fi: "fin", pl: "pol", tr: "tur",
|
|
th: "tha", hi: "hin", hu: "hun", cs: "ces", ro: "ron", el: "ell",
|
|
he: "heb", fa: "fas", uk: "ukr", id: "ind", ca: "cat", nb: "nob",
|
|
nn: "nno", is: "isl", hr: "hrv", sk: "slk", bg: "bul", sr: "srp",
|
|
sl: "slv", lv: "lav", lt: "lit", et: "est", vi: "vie", ms: "msa",
|
|
ta: "tam", te: "tel",
|
|
};
|
|
|
|
// ISO 639-2/T → ISO 639-2/B normalization + common aliases
|
|
const LANG_ALIASES: Record<string, string> = {
|
|
ger: "deu", chi: "zho", fre: "fra", dut: "nld", gre: "ell",
|
|
heb: "heb", per: "fas", rum: "ron", may: "msa", tib: "bod",
|
|
bur: "mya", cze: "ces", slo: "slk", geo: "kat", ice: "isl",
|
|
arm: "hye", baq: "eus", alb: "sqi", mac: "mkd", wel: "cym",
|
|
};
|
|
|
|
export function normalizeLanguage(lang: string): string {
|
|
const lower = lang.toLowerCase().trim();
|
|
if (ISO_1_TO_2[lower]) return ISO_1_TO_2[lower];
|
|
return LANG_ALIASES[lower] ?? lower;
|
|
}
|
|
|
|
const DUB_TITLE_HINTS = /(dub|dubb|synchro|commentary|director)/i;
|
|
|
|
/**
|
|
* Guess original language from audio streams by looking at the default track.
|
|
* Heuristic: prefer the default audio track, skip dubs/commentary, fall back to first.
|
|
*/
|
|
export function guessOriginalLanguage(
|
|
audioStreams: { language: string | null; title: string | null; isDefault: number }[],
|
|
): string | null {
|
|
if (audioStreams.length === 0) return null;
|
|
const notDub = (s: { title: string | null }) => !s.title || !DUB_TITLE_HINTS.test(s.title);
|
|
const pick = audioStreams.find((s) => s.isDefault && notDub(s)) ?? audioStreams.find(notDub) ?? audioStreams[0];
|
|
return pick.language ? normalizeLanguage(pick.language) : null;
|
|
}
|