diff --git a/app/(auth)/player/direct-player.tsx b/app/(auth)/player/direct-player.tsx index 3a07fef0..efa854e0 100644 --- a/app/(auth)/player/direct-player.tsx +++ b/app/(auth)/player/direct-player.tsx @@ -531,7 +531,11 @@ export default function page() { subtitleIndex, isTranscoding, ); - const initialAudioId = getMpvAudioId(mediaSource, audioIndex); + const initialAudioId = getMpvAudioId( + mediaSource, + audioIndex, + isTranscoding, + ); // Calculate start position directly here to avoid timing issues const startTicks = playbackPositionFromUrl diff --git a/utils/jellyfin/subtitleUtils.ts b/utils/jellyfin/subtitleUtils.ts index 619e3a39..f20f8521 100644 --- a/utils/jellyfin/subtitleUtils.ts +++ b/utils/jellyfin/subtitleUtils.ts @@ -91,21 +91,32 @@ export const getMpvSubtitleId = ( /** * Calculate the MPV track ID for a given Jellyfin audio index. * - * Audio tracks are simpler - they're always in MPV (no burn-in like image subs). + * For direct play: Audio tracks map to their position in the file (1-based). + * For transcoding: Only ONE audio track exists in the HLS stream (the selected one), + * so we should return 1 or undefined to use the default track. + * * MPV track IDs are 1-based. * * @param mediaSource - The media source containing audio streams * @param jellyfinAudioIndex - The Jellyfin server-side audio index + * @param isTranscoding - Whether the stream is being transcoded * @returns MPV track ID (1-based), or undefined if not found */ export const getMpvAudioId = ( mediaSource: MediaSourceInfo | null | undefined, jellyfinAudioIndex: number | undefined, + isTranscoding: boolean, ): number | undefined => { if (jellyfinAudioIndex === undefined) { return undefined; } + // When transcoding, Jellyfin only includes the selected audio track in the HLS stream. + // So there's only 1 audio track - no need to specify an ID. + if (isTranscoding) { + return undefined; + } + const allAudio = mediaSource?.MediaStreams?.filter((s) => s.Type === "Audio") || [];