diff --git a/apps/web/src/components/player-defaults.tsx b/apps/web/src/components/player-defaults.tsx index 6a6b4ee5..aa386b5a 100644 --- a/apps/web/src/components/player-defaults.tsx +++ b/apps/web/src/components/player-defaults.tsx @@ -7,7 +7,11 @@ import { useMediaState, useVideoQualityOptions, } from "../lib/vidstack"; -import { includesOriginal, normalizeLanguageTag } from "./player-language"; +import { + hasMultipleLanguageTracks, + includesOriginal, + normalizeLanguageTag, +} from "./player-language"; const QUALITY_OPTIONS = { sort: "descending" } as const; @@ -114,11 +118,14 @@ export function PlayerDefaults({ : (audioOptions.find((option) => option.track.id === preferredDefaultAudioTrackId) ?? audioOptions.find((option) => option.track.id === originalAudioTrackId)); + const hasMultipleLanguages = hasMultipleLanguageTracks(audioOptions); + const missingOriginalByContract = forceOriginal && originalAudioTrackId === null; const missingOriginalByHeuristic = - forceOriginal && originalAudioTrackId === undefined && !match; + forceOriginal && originalAudioTrackId === undefined && hasMultipleLanguages && !match; if ( (missingOriginalByContract || missingOriginalByHeuristic) && + hasMultipleLanguages && !originalMissingNotified.current ) { originalMissingNotified.current = true; diff --git a/apps/web/src/components/player-language.ts b/apps/web/src/components/player-language.ts index 08fc13af..c2608844 100644 --- a/apps/web/src/components/player-language.ts +++ b/apps/web/src/components/player-language.ts @@ -8,3 +8,15 @@ export function includesOriginal(value: string | undefined): boolean { if (!value) return false; return value.toLowerCase().includes("original"); } + +export function hasMultipleLanguageTracks( + options: readonly { track: { language?: string | null } }[], +): boolean { + const languages = new Set(); + for (const option of options) { + const language = normalizeLanguageTag(option.track.language); + if (language) languages.add(language); + if (languages.size > 1) return true; + } + return false; +} diff --git a/apps/web/tests/player-language.test.ts b/apps/web/tests/player-language.test.ts new file mode 100644 index 00000000..4473c184 --- /dev/null +++ b/apps/web/tests/player-language.test.ts @@ -0,0 +1,21 @@ +import { expect, test } from "bun:test"; +import { hasMultipleLanguageTracks } from "../src/components/player-language"; + +test("distinguishes multiple bitrate tracks from multiple languages", () => { + expect( + hasMultipleLanguageTracks([{ track: { language: "fr-FR" } }, { track: { language: "fr-CA" } }]), + ).toBe(false); + expect( + hasMultipleLanguageTracks([{ track: { language: "fr-FR" } }, { track: { language: "en-US" } }]), + ).toBe(true); +}); + +test("ignores missing language tags", () => { + expect( + hasMultipleLanguageTracks([ + { track: { language: "fr-FR" } }, + { track: { language: null } }, + { track: {} }, + ]), + ).toBe(false); +});