diff --git a/components/video-player/controls/DropdownView.tsx b/components/video-player/controls/DropdownView.tsx index 44cd7e20..a83b8bec 100644 --- a/components/video-player/controls/DropdownView.tsx +++ b/components/video-player/controls/DropdownView.tsx @@ -1,14 +1,17 @@ - -import React, { useCallback, useMemo } from 'react'; -import { View, TouchableOpacity } from 'react-native'; -import { Ionicons } from '@expo/vector-icons'; +import React, { useCallback, useMemo } from "react"; +import { View, TouchableOpacity } from "react-native"; +import { Ionicons } from "@expo/vector-icons"; import * as DropdownMenu from "zeego/dropdown-menu"; -import { useControlContext } from './contexts/ControlContext'; -import { useVideoContext } from './contexts/VideoContext'; -import { EmbeddedSubtitle, ExternalSubtitle, TranscodedSubtitle } from './types'; -import { useAtomValue } from 'jotai'; -import { apiAtom } from '@/providers/JellyfinProvider'; -import { useLocalSearchParams, useRouter } from 'expo-router'; +import { useControlContext } from "./contexts/ControlContext"; +import { useVideoContext } from "./contexts/VideoContext"; +import { + EmbeddedSubtitle, + ExternalSubtitle, + TranscodedSubtitle, +} from "./types"; +import { useAtomValue } from "jotai"; +import { apiAtom } from "@/providers/JellyfinProvider"; +import { useLocalSearchParams, useRouter } from "expo-router"; interface DropdownViewProps { showControls: boolean; @@ -23,7 +26,13 @@ const DropdownView: React.FC = ({ showControls }) => { const isVideoLoaded = ControlContext?.isVideoLoaded; const videoContext = useVideoContext(); - const { subtitleTracks, audioTracks, setSubtitleURL, setSubtitleTrack, setAudioTrack } = videoContext; + const { + subtitleTracks, + audioTracks, + setSubtitleURL, + setSubtitleTrack, + setAudioTrack, + } = videoContext; const allSubtitleTracksForDirectPlay = useMemo(() => { if (mediaSource?.TranscodingUrl) return null; @@ -52,6 +61,13 @@ const DropdownView: React.FC = ({ showControls }) => { )[]; }, [item, isVideoLoaded, subtitleTracks, mediaSource?.MediaStreams]); + // const audioForTranscodingStream = mediaSource?.MediaStreams?.filter( + // (x) => x.Type === "Audio" + // ).map((x) => ({ + // name: x.DisplayTitle!, + // index: x.Index!, + // })); + // Only used for transcoding streams. const { subtitleIndex: subtitleIndexStr, @@ -66,29 +82,33 @@ const DropdownView: React.FC = ({ showControls }) => { }>(); // Either its on a text subtitle or its on not on any subtitle therefore it should show all the embedded HLS subtitles. - const isOnTextSubtitle = mediaSource?.MediaStreams?.find((x) => x.Index === parseInt(subtitleIndexStr) - && x.IsTextSubtitleStream) - || subtitleIndexStr === "-1"; - + const isOnTextSubtitle = + mediaSource?.MediaStreams?.find( + (x) => x.Index === parseInt(subtitleIndexStr) && x.IsTextSubtitleStream + ) || subtitleIndexStr === "-1"; // TODO: Add support for text sorting subtitles renaming. const allSubtitleTracksForTranscodingStream = useMemo(() => { - const allSubs = mediaSource?.MediaStreams?.filter((x) => x.Type === "Subtitle") ?? []; + const allSubs = + mediaSource?.MediaStreams?.filter((x) => x.Type === "Subtitle") ?? []; if (isOnTextSubtitle) { const textSubtitles = - subtitleTracks - ?.map((s) => ({ + subtitleTracks?.map((s) => ({ name: s.name, index: s.index, IsTextSubtitleStream: true, })) || []; - const imageSubtitles = - allSubs.filter((x) => !x.IsTextSubtitleStream).map((x) => ( - { name: x.DisplayTitle!, - index: x.Index!, - IsTextSubtitleStream: x.IsTextSubtitleStream - } as TranscodedSubtitle)); + const imageSubtitles = allSubs + .filter((x) => !x.IsTextSubtitleStream) + .map( + (x) => + ({ + name: x.DisplayTitle!, + index: x.Index!, + IsTextSubtitleStream: x.IsTextSubtitleStream, + } as TranscodedSubtitle) + ); return [...textSubtitles, ...imageSubtitles]; } @@ -96,33 +116,32 @@ const DropdownView: React.FC = ({ showControls }) => { const transcodedSubtitle: TranscodedSubtitle[] = allSubs.map((x) => ({ name: x.DisplayTitle!, index: x.Index!, - IsTextSubtitleStream: x.IsTextSubtitleStream! + IsTextSubtitleStream: x.IsTextSubtitleStream!, })); return transcodedSubtitle; - }, [item, isVideoLoaded, subtitleTracks, mediaSource?.MediaStreams]); - const ChangeTranscodingSubtitle = useCallback((subtitleIndex: number) => { - const queryParams = new URLSearchParams({ - itemId: item.Id ?? "", // Ensure itemId is a string - audioIndex: audioIndex?.toString() ?? "", - subtitleIndex: subtitleIndex?.toString() ?? "", - mediaSourceId: mediaSource?.Id ?? "", // Ensure mediaSourceId is a string - bitrateValue: bitrateValue, - }).toString(); - - // @ts-expect-error - router.replace(`player/player?${queryParams}`); - }, [mediaSource]); - - + const ChangeTranscodingSubtitle = useCallback( + (subtitleIndex: number) => { + const queryParams = new URLSearchParams({ + itemId: item.Id ?? "", // Ensure itemId is a string + audioIndex: audioIndex?.toString() ?? "", + subtitleIndex: subtitleIndex?.toString() ?? "", + mediaSourceId: mediaSource?.Id ?? "", // Ensure mediaSourceId is a string + bitrateValue: bitrateValue, + }).toString(); + // @ts-expect-error + router.replace(`player/player?${queryParams}`); + }, + [mediaSource] + ); return ( = ({ showControls }) => { loop={true} sideOffset={10} > - {!mediaSource?.TranscodingUrl && allSubtitleTracksForDirectPlay?.map((sub, idx: number) => ( - { - if ("deliveryUrl" in sub && sub.deliveryUrl) { - setSubtitleURL && - setSubtitleURL( - api?.basePath + sub.deliveryUrl, - sub.name + {!mediaSource?.TranscodingUrl && + allSubtitleTracksForDirectPlay?.map((sub, idx: number) => ( + { + if ("deliveryUrl" in sub && sub.deliveryUrl) { + setSubtitleURL && + setSubtitleURL( + api?.basePath + sub.deliveryUrl, + sub.name + ); + + console.log( + "Set external subtitle: ", + api?.basePath + sub.deliveryUrl ); + } else { + console.log("Set sub index: ", sub.index); + setSubtitleTrack && setSubtitleTrack(sub.index); + } - console.log("Set external subtitle: ", api?.basePath + sub.deliveryUrl); - } else { - console.log("Set sub index: ", sub.index); - setSubtitleTrack && setSubtitleTrack(sub.index); - } + console.log("Subtitle: ", sub); + }} + > + + + {sub.name} + + + ))} + {mediaSource?.TranscodingUrl && + allSubtitleTracksForTranscodingStream?.map( + (sub, idx: number) => ( + { + if (subtitleIndexStr === sub.index.toString()) return; - console.log("Subtitle: ", sub); - }} - > - - - {sub.name} - - - ))} - {mediaSource?.TranscodingUrl && allSubtitleTracksForTranscodingStream?.map((sub, idx: number) => ( - { - if (subtitleIndexStr === sub.index.toString()) return; - - if (sub.IsTextSubtitleStream && isOnTextSubtitle) { - setSubtitleTrack && setSubtitleTrack(sub.index); - return; - } - ChangeTranscodingSubtitle(sub.index); - }} - > - - - {sub.name} - - - ))} + if (sub.IsTextSubtitleStream && isOnTextSubtitle) { + setSubtitleTrack && setSubtitleTrack(sub.index); + return; + } + ChangeTranscodingSubtitle(sub.index); + }} + > + + + {sub.name} + + + ) + )} @@ -233,4 +261,4 @@ const DropdownView: React.FC = ({ showControls }) => { ); }; -export default DropdownView; \ No newline at end of file +export default DropdownView;