mirror of
https://github.com/streamyfin/streamyfin.git
synced 2026-07-06 20:42:55 +01:00
fix(tv): re-negotiate the stream when changing audio track while transcoding
This commit is contained in:
@@ -893,6 +893,22 @@ export default function DirectPlayerPage() {
|
||||
// Check if we're transcoding
|
||||
const isTranscoding = Boolean(stream?.mediaSource?.TranscodingUrl);
|
||||
|
||||
// A transcoded stream only carries the audio track the server encoded
|
||||
// into it — switching requires re-negotiating the stream with the new
|
||||
// index (like the mobile menu's replacePlayer), not an mpv aid change.
|
||||
if (isTranscoding) {
|
||||
const queryParams = new URLSearchParams({
|
||||
itemId: item?.Id ?? "",
|
||||
audioIndex: String(index),
|
||||
subtitleIndex: String(currentSubtitleIndex),
|
||||
mediaSourceId: stream?.mediaSource?.Id ?? "",
|
||||
bitrateValue: bitrateValue?.toString() ?? "",
|
||||
playbackPosition: msToTicks(progress.get()).toString(),
|
||||
}).toString();
|
||||
router.replace(`player/direct-player?${queryParams}` as any);
|
||||
return;
|
||||
}
|
||||
|
||||
// Convert Jellyfin index to MPV track ID
|
||||
const mpvTrackId = getMpvAudioId(
|
||||
stream?.mediaSource,
|
||||
@@ -904,7 +920,14 @@ export default function DirectPlayerPage() {
|
||||
await videoRef.current?.setAudioTrack?.(mpvTrackId);
|
||||
}
|
||||
},
|
||||
[stream?.mediaSource],
|
||||
[
|
||||
stream?.mediaSource,
|
||||
item?.Id,
|
||||
currentSubtitleIndex,
|
||||
bitrateValue,
|
||||
router,
|
||||
progress,
|
||||
],
|
||||
);
|
||||
|
||||
// TV subtitle track change handler
|
||||
|
||||
@@ -4,6 +4,7 @@ import { useCallback, useEffect, useMemo, useRef, useState } from "react";
|
||||
import {
|
||||
Animated,
|
||||
Easing,
|
||||
InteractionManager,
|
||||
ScrollView,
|
||||
StyleSheet,
|
||||
TVFocusGuideView,
|
||||
@@ -75,9 +76,13 @@ export default function TVOptionModal() {
|
||||
}, [isReady]);
|
||||
|
||||
const handleSelect = (value: any) => {
|
||||
modalState?.onSelect(value);
|
||||
// Close FIRST, run the callback after this modal route is dismissed: an
|
||||
// onSelect that navigates (e.g. the transcode audio switch replacing the
|
||||
// player) would otherwise target the MODAL route and be swallowed.
|
||||
const onSelect = modalState?.onSelect;
|
||||
store.set(tvOptionModalAtom, null);
|
||||
router.back();
|
||||
InteractionManager.runAfterInteractions(() => onSelect?.(value));
|
||||
};
|
||||
|
||||
const handleClose = useCallback(() => {
|
||||
|
||||
Reference in New Issue
Block a user