mirror of
https://github.com/streamyfin/streamyfin.git
synced 2026-04-17 14:31:58 +01:00
done
This commit is contained in:
@@ -28,7 +28,7 @@ import { useHaptic } from "@/hooks/useHaptic";
|
||||
import { useIntroSkipper } from "@/hooks/useIntroSkipper";
|
||||
import { usePlaybackManager } from "@/hooks/usePlaybackManager";
|
||||
import { useTrickplay } from "@/hooks/useTrickplay";
|
||||
import type { MpvPlayerViewRef, SubtitleTrack } from "@/modules";
|
||||
import type { AudioTrack, MpvPlayerViewRef, SubtitleTrack } from "@/modules";
|
||||
import { DownloadedItem } from "@/providers/Downloads/types";
|
||||
import { useSettings } from "@/utils/atoms/settings";
|
||||
import { getDefaultPlaySettings } from "@/utils/jellyfin/getDefaultPlaySettings";
|
||||
@@ -71,8 +71,10 @@ interface Props {
|
||||
getSubtitleTracks?:
|
||||
| (() => Promise<SubtitleTrack[] | null>)
|
||||
| (() => SubtitleTrack[]);
|
||||
getAudioTracks?: (() => Promise<AudioTrack[] | null>) | (() => AudioTrack[]);
|
||||
setSubtitleURL?: (url: string, customName: string) => void;
|
||||
setSubtitleTrack?: (index: number) => void;
|
||||
setAudioTrack?: (index: number) => void;
|
||||
setVideoAspectRatio?: (aspectRatio: string | null) => Promise<void>;
|
||||
setVideoScaleFactor?: (scaleFactor: number) => Promise<void>;
|
||||
aspectRatio?: AspectRatio;
|
||||
@@ -100,8 +102,10 @@ export const Controls: FC<Props> = ({
|
||||
mediaSource,
|
||||
isVideoLoaded,
|
||||
getSubtitleTracks,
|
||||
getAudioTracks,
|
||||
setSubtitleURL,
|
||||
setSubtitleTrack,
|
||||
setAudioTrack,
|
||||
setVideoAspectRatio,
|
||||
setVideoScaleFactor,
|
||||
aspectRatio = "default",
|
||||
@@ -501,7 +505,9 @@ export const Controls: FC<Props> = ({
|
||||
previousItem={previousItem}
|
||||
nextItem={nextItem}
|
||||
getSubtitleTracks={getSubtitleTracks}
|
||||
getAudioTracks={getAudioTracks}
|
||||
setSubtitleTrack={setSubtitleTrack}
|
||||
setAudioTrack={setAudioTrack}
|
||||
setSubtitleURL={setSubtitleURL}
|
||||
aspectRatio={aspectRatio}
|
||||
scaleFactor={scaleFactor}
|
||||
|
||||
@@ -35,7 +35,9 @@ interface HeaderControlsProps {
|
||||
previousItem?: BaseItemDto | null;
|
||||
nextItem?: BaseItemDto | null;
|
||||
getSubtitleTracks?: (() => Promise<any[] | null>) | (() => any[]);
|
||||
getAudioTracks?: (() => Promise<any[] | null>) | (() => any[]);
|
||||
setSubtitleTrack?: (index: number) => void;
|
||||
setAudioTrack?: (index: number) => void;
|
||||
setSubtitleURL?: (url: string, customName: string) => void;
|
||||
aspectRatio?: AspectRatio;
|
||||
scaleFactor?: ScaleFactor;
|
||||
@@ -57,7 +59,9 @@ export const HeaderControls: FC<HeaderControlsProps> = ({
|
||||
previousItem,
|
||||
nextItem,
|
||||
getSubtitleTracks,
|
||||
getAudioTracks,
|
||||
setSubtitleTrack,
|
||||
setAudioTrack,
|
||||
setSubtitleURL,
|
||||
aspectRatio = "default",
|
||||
scaleFactor = 1.0,
|
||||
@@ -111,7 +115,9 @@ export const HeaderControls: FC<HeaderControlsProps> = ({
|
||||
{!Platform.isTV && (!offline || !mediaSource?.TranscodingUrl) && (
|
||||
<VideoProvider
|
||||
getSubtitleTracks={getSubtitleTracks}
|
||||
getAudioTracks={getAudioTracks}
|
||||
setSubtitleTrack={setSubtitleTrack}
|
||||
setAudioTrack={setAudioTrack}
|
||||
setSubtitleURL={setSubtitleURL}
|
||||
>
|
||||
<View pointerEvents='auto'>
|
||||
|
||||
@@ -9,12 +9,13 @@ import {
|
||||
useMemo,
|
||||
useState,
|
||||
} from "react";
|
||||
import type { SubtitleTrack } from "@/modules";
|
||||
import type { AudioTrack, SubtitleTrack } from "@/modules";
|
||||
import type { Track } from "../types";
|
||||
import { useControlContext } from "./ControlContext";
|
||||
|
||||
interface VideoContextProps {
|
||||
subtitleTracks: Track[] | null;
|
||||
audioTracks: Track[] | null;
|
||||
setSubtitleTrack: ((index: number) => void) | undefined;
|
||||
setSubtitleURL: ((url: string, customName: string) => void) | undefined;
|
||||
}
|
||||
@@ -27,21 +28,29 @@ interface VideoProviderProps {
|
||||
| (() => Promise<SubtitleTrack[] | null>)
|
||||
| (() => SubtitleTrack[])
|
||||
| undefined;
|
||||
getAudioTracks:
|
||||
| (() => Promise<AudioTrack[] | null>)
|
||||
| (() => AudioTrack[])
|
||||
| undefined;
|
||||
setSubtitleTrack: ((index: number) => void) | undefined;
|
||||
setAudioTrack: ((index: number) => void) | undefined;
|
||||
setSubtitleURL: ((url: string, customName: string) => void) | undefined;
|
||||
}
|
||||
|
||||
/**
|
||||
* Video context provider for managing subtitle tracks.
|
||||
s * Video context provider for managing subtitle and audio tracks.
|
||||
* MPV player is used for all playback.
|
||||
*/
|
||||
export const VideoProvider: React.FC<VideoProviderProps> = ({
|
||||
children,
|
||||
getSubtitleTracks,
|
||||
getAudioTracks,
|
||||
setSubtitleTrack,
|
||||
setAudioTrack,
|
||||
setSubtitleURL,
|
||||
}) => {
|
||||
const [subtitleTracks, setSubtitleTracks] = useState<Track[] | null>(null);
|
||||
const [audioTracks, setAudioTracks] = useState<Track[] | null>(null);
|
||||
|
||||
const ControlContext = useControlContext();
|
||||
const isVideoLoaded = ControlContext?.isVideoLoaded;
|
||||
@@ -122,6 +131,7 @@ export const VideoProvider: React.FC<VideoProviderProps> = ({
|
||||
let subtitleData: SubtitleTrack[] | null = null;
|
||||
try {
|
||||
subtitleData = await getSubtitleTracks();
|
||||
console.log("subtitleData", subtitleData);
|
||||
} catch (error) {
|
||||
console.log("[VideoContext] Failed to get subtitle tracks:", error);
|
||||
return;
|
||||
@@ -169,10 +179,49 @@ export const VideoProvider: React.FC<VideoProviderProps> = ({
|
||||
fetchTracks();
|
||||
}, [isVideoLoaded, getSubtitleTracks]);
|
||||
|
||||
// Fetch audio tracks
|
||||
useEffect(() => {
|
||||
const fetchAudioTracks = async () => {
|
||||
if (getAudioTracks) {
|
||||
let audioData: AudioTrack[] | null = null;
|
||||
try {
|
||||
audioData = await getAudioTracks();
|
||||
console.log("audioData", audioData);
|
||||
} catch (error) {
|
||||
console.log("[VideoContext] Failed to get audio tracks:", error);
|
||||
return;
|
||||
}
|
||||
|
||||
const allAudio =
|
||||
mediaSource?.MediaStreams?.filter((s) => s.Type === "Audio") || [];
|
||||
|
||||
let embedAudioIndex = 0;
|
||||
const processedAudio: Track[] = allAudio?.map((audio) => {
|
||||
const mpvIndex = audioData?.at(embedAudioIndex)?.id ?? 1;
|
||||
embedAudioIndex++;
|
||||
return {
|
||||
name: audio.DisplayTitle || "Undefined Audio",
|
||||
index: audio.Index ?? -1,
|
||||
setTrack: () => {
|
||||
setAudioTrack?.(mpvIndex);
|
||||
router.setParams({
|
||||
audioIndex: audio.Index?.toString() ?? "0",
|
||||
});
|
||||
},
|
||||
};
|
||||
});
|
||||
|
||||
setAudioTracks(processedAudio);
|
||||
}
|
||||
};
|
||||
fetchAudioTracks();
|
||||
}, [isVideoLoaded, getAudioTracks]);
|
||||
|
||||
return (
|
||||
<VideoContext.Provider
|
||||
value={{
|
||||
subtitleTracks,
|
||||
audioTracks,
|
||||
setSubtitleTrack,
|
||||
setSubtitleURL,
|
||||
}}
|
||||
|
||||
Reference in New Issue
Block a user