diff --git a/app/(auth)/play-video.tsx b/app/(auth)/play-video.tsx index 09851ef7..7e8e2d17 100644 --- a/app/(auth)/play-video.tsx +++ b/app/(auth)/play-video.tsx @@ -1,104 +1,191 @@ import { apiAtom, userAtom } from "@/providers/JellyfinProvider"; -import { useSettings } from "@/utils/atoms/settings"; +import { settingsAtom, useSettings } from "@/utils/atoms/settings"; import { getBackdropUrl } from "@/utils/jellyfin/image/getBackdropUrl"; import { getAuthHeaders } from "@/utils/jellyfin/jellyfin"; +import { getStreamUrl } from "@/utils/jellyfin/media/getStreamUrl"; import { Api } from "@jellyfin/sdk"; -import { BaseItemDto } from "@jellyfin/sdk/lib/generated-client"; +import { + BaseItemDto, + MediaSourceInfo, +} from "@jellyfin/sdk/lib/generated-client"; import { useRouter } from "expo-router"; import { atom, useAtom } from "jotai"; -import { useMemo, useRef, useState } from "react"; -import Video, { VideoRef } from "react-native-video"; - -type PlaybackType = { - item: BaseItemDto; - mediaSourceId: string; - subtitleIndex: number; - audioIndex: number; - url: string; - quality: any; -}; - -export const playInfoAtom = atom(null); +import { useCallback, useEffect, useMemo, useRef, useState } from "react"; +import Video, { OnProgressData, VideoRef } from "react-native-video"; +import settings from "./(tabs)/(home)/settings"; +import iosFmp4 from "@/utils/profiles/iosFmp4"; +import native from "@/utils/profiles/native"; +import old from "@/utils/profiles/old"; +import { + PlaybackType, + usePlaySettings, +} from "@/providers/PlaySettingsProvider"; +import { StatusBar, View } from "react-native"; +import React from "react"; +import { Controls } from "@/components/video-player/Controls"; +import { reportPlaybackProgress } from "@/utils/jellyfin/playstate/reportPlaybackProgress"; +import { useSharedValue } from "react-native-reanimated"; +import { secondsToTicks } from "@/utils/secondsToTicks"; export default function page() { - const [playInfo, setPlayInfo] = useAtom(playInfoAtom); + const { playSettings, setPlaySettings, playUrl, reportStopPlayback } = + usePlaySettings(); const [api] = useAtom(apiAtom); const [user] = useAtom(userAtom); const [settings] = useSettings(); const router = useRouter(); const videoRef = useRef(null); - const poster = usePoster(playInfo, api); - const videoSource = useVideoSource(playInfo, api, poster); + const poster = usePoster(playSettings, api); + const videoSource = useVideoSource(playSettings, api, poster, playUrl); const [ignoreSafeArea, setIgnoreSafeArea] = useState(false); + const [isPlaying, setIsPlaying] = useState(false); + const [isBuffering, setIsBuffering] = useState(true); - if (!playInfo || !api || !videoSource) return null; + const progress = useSharedValue(0); + const isSeeking = useSharedValue(false); + const cacheProgress = useSharedValue(0); + + useEffect(() => { + console.log("play-video ~", playUrl); + }); + + if (!playSettings || !playUrl || !api || !videoSource || !playSettings.item) + return null; + + const togglePlay = useCallback( + (ticks: number) => { + if (isPlaying) { + videoRef.current?.pause(); + reportPlaybackProgress({ + api, + itemId: playSettings?.item?.Id, + positionTicks: ticks, + sessionId: undefined, + IsPaused: true, + }); + } else { + videoRef.current?.resume(); + reportPlaybackProgress({ + api, + itemId: playSettings?.item?.Id, + positionTicks: ticks, + sessionId: undefined, + IsPaused: false, + }); + } + }, + [isPlaying, api, playSettings?.item?.Id, videoRef] + ); + + useEffect(() => { + if (!isPlaying) { + togglePlay(playSettings.item?.UserData?.PlaybackPositionTicks || 0); + } + }, [isPlaying]); + + const onProgress = useCallback( + (data: OnProgressData) => { + if (isSeeking.value === true) return; + progress.value = secondsToTicks(data.currentTime); + cacheProgress.value = secondsToTicks(data.playableDuration); + setIsBuffering(data.playableDuration === 0); + + if (!playSettings?.item?.Id || data.currentTime === 0) return; + const ticks = data.currentTime * 10000000; + reportPlaybackProgress({ + api, + itemId: playSettings?.item.Id, + positionTicks: ticks, + sessionId: undefined, + IsPaused: !isPlaying, + }); + }, + [playSettings?.item.Id, isPlaying, api] + ); return ( -