fix(audio): dedupe language menu by (lang, label)

A video with two audio tracks sharing the same language (common when
an upload was retried before the first attempt finished syncing) used
to show both rows in the player's language picker, leaving the viewer
guessing which one to pick. Dedupe keeps the first occurrence per
(language, label) pair — so legit variants like "en — Original" and
"en — Director's cut" still coexist, but bare duplicates collapse.

Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]>
This commit is contained in:
ghassanandClaude Opus 4.7 committed 2026-10-21 10:20:44 +03:00
1 parent 4581870517
commit 9eb9535c83
1 file changed
+18 -10
+18 -10
View File
@@ -956,16 +956,24 @@ class VideoController extends Controller
: $slideMap['0']; : $slideMap['0'];
$allLangData = \App\Data\Languages::all(); $allLangData = \App\Data\Languages::all();
$audioTracks = $video->audioTracks->map(fn ($t) => [ // Dedupe the language picker by (language + label). A video with two
'id' => $t->id, // tracks sharing the same language (e.g. "ar" uploaded twice while
'language' => $t->language, // retrying) used to list both and leave the viewer guessing. Keeping
'label' => $t->label, // the first occurrence preserves the primary when it exists; using
'flag' => $allLangData[$t->language]['flag'] ?? null, // (lang, label) as the key still lets legit variants coexist (e.g.
'stream_url' => route('videos.audio-track', ['video' => $video, 'track' => $t->id]) . '?v=' . $t->updated_at->timestamp, // "en — Original" and "en — Director's cut").
'title' => $t->title ?? '', $audioTracks = $video->audioTracks
'description' => $t->description ?? '', ->unique(fn ($t) => mb_strtolower((string) $t->language) . '|' . mb_strtolower((string) ($t->label ?? '')))
'dl_url' => route('videos.audio-track', ['video' => $video, 'track' => $t->id]) . '?download=1&v=' . $t->updated_at->timestamp, ->map(fn ($t) => [
])->values()->all(); 'id' => $t->id,
'language' => $t->language,
'label' => $t->label,
'flag' => $allLangData[$t->language]['flag'] ?? null,
'stream_url' => route('videos.audio-track', ['video' => $video, 'track' => $t->id]) . '?v=' . $t->updated_at->timestamp,
'title' => $t->title ?? '',
'description' => $t->description ?? '',
'dl_url' => route('videos.audio-track', ['video' => $video, 'track' => $t->id]) . '?download=1&v=' . $t->updated_at->timestamp,
])->values()->all();
// Synced lyrics embedded inline (no separate request), keyed by track id; "0" = primary. // Synced lyrics embedded inline (no separate request), keyed by track id; "0" = primary.
// Local mirror only — must not block this hot path on NAS I/O. // Local mirror only — must not block this hot path on NAS I/O.