This commit is contained in:
Fredrik Burmester
2024-10-16 08:50:22 +02:00
parent 04e31e8628
commit 6a4fe83fbb

View File

@@ -9,26 +9,19 @@ import {
ProgressUpdatePayload, ProgressUpdatePayload,
VlcPlayerViewRef, VlcPlayerViewRef,
} from "@/modules/vlc-player/src/VlcPlayer.types"; } from "@/modules/vlc-player/src/VlcPlayer.types";
import { apiAtom, userAtom } from "@/providers/JellyfinProvider"; import { apiAtom } from "@/providers/JellyfinProvider";
import { import {
PlaybackType, PlaybackType,
usePlaySettings, usePlaySettings,
} from "@/providers/PlaySettingsProvider"; } from "@/providers/PlaySettingsProvider";
import { getBackdropUrl } from "@/utils/jellyfin/image/getBackdropUrl"; import { getBackdropUrl } from "@/utils/jellyfin/image/getBackdropUrl";
import { getAuthHeaders } from "@/utils/jellyfin/jellyfin"; import { msToTicks, ticksToMs } from "@/utils/time";
import { ticksToMs, ticksToSeconds } from "@/utils/time";
import { Api } from "@jellyfin/sdk"; import { Api } from "@jellyfin/sdk";
import { getPlaystateApi } from "@jellyfin/sdk/lib/utils/api"; import { getPlaystateApi } from "@jellyfin/sdk/lib/utils/api";
import * as Haptics from "expo-haptics"; import * as Haptics from "expo-haptics";
import { useFocusEffect } from "expo-router"; import { useFocusEffect } from "expo-router";
import { useAtomValue } from "jotai"; import { useAtomValue } from "jotai";
import React, { import React, { useCallback, useMemo, useRef, useState } from "react";
useCallback,
useEffect,
useMemo,
useRef,
useState,
} from "react";
import { Dimensions, Pressable, StatusBar, View } from "react-native"; import { Dimensions, Pressable, StatusBar, View } from "react-native";
import { useSharedValue } from "react-native-reanimated"; import { useSharedValue } from "react-native-reanimated";
@@ -37,8 +30,8 @@ export default function page() {
usePlaySettings(); usePlaySettings();
const api = useAtomValue(apiAtom); const api = useAtomValue(apiAtom);
const videoRef = useRef<VlcPlayerViewRef>(null); const videoRef = useRef<VlcPlayerViewRef>(null);
const poster = usePoster(playSettings, api); // const poster = usePoster(playSettings, api);
const videoSource = useVideoSource(playSettings, api, poster, playUrl); // const user = useAtomValue(userAtom);
const screenDimensions = Dimensions.get("screen"); const screenDimensions = Dimensions.get("screen");
@@ -47,24 +40,13 @@ export default function page() {
const [ignoreSafeAreas, setIgnoreSafeAreas] = useState(false); const [ignoreSafeAreas, setIgnoreSafeAreas] = useState(false);
const [isPlaying, setIsPlaying] = useState(false); const [isPlaying, setIsPlaying] = useState(false);
const [isBuffering, setIsBuffering] = useState(true); const [isBuffering, setIsBuffering] = useState(true);
const [isVideoLoaded, setIsVideoLoaded] = useState(false);
const progress = useSharedValue(0); const progress = useSharedValue(0);
const isSeeking = useSharedValue(false); const isSeeking = useSharedValue(false);
const cacheProgress = useSharedValue(0); const cacheProgress = useSharedValue(0);
const user = useAtomValue(userAtom);
const [playbackState, setPlaybackState] = useState< if (!playSettings || !playUrl || !api || !playSettings.item || !mediaSource)
PlaybackStatePayload["nativeEvent"] | null
>(null);
if (
!playSettings ||
!playUrl ||
!api ||
!videoSource ||
!playSettings.item ||
!mediaSource
)
return null; return null;
const togglePlay = useCallback( const togglePlay = useCallback(
@@ -150,33 +132,26 @@ export default function page() {
async (data: ProgressUpdatePayload) => { async (data: ProgressUpdatePayload) => {
if (isSeeking.value === true) return; if (isSeeking.value === true) return;
if (isPlaybackStopped === true) return; if (isPlaybackStopped === true) return;
if (!playSettings.item?.Id) return;
const { currentTime, duration, isBuffering, isPlaying } = const { currentTime, isPlaying } = data.nativeEvent;
data.nativeEvent;
setIsBuffering(isBuffering); const currentTimeInTicks = msToTicks(currentTime);
progress.value = currentTime; await getPlaystateApi(api).onPlaybackProgress({
itemId: playSettings.item.Id,
// cacheProgress.value = secondsToTicks(data.playableDuration); audioStreamIndex: playSettings.audioIndex
// setIsBuffering(data.playableDuration === 0); ? playSettings.audioIndex
: undefined,
// if (!playSettings?.item?.Id || data.currentTime === 0) return; subtitleStreamIndex: playSettings.subtitleIndex
? playSettings.subtitleIndex
// await getPlaystateApi(api).onPlaybackProgress({ : undefined,
// itemId: playSettings.item.Id, mediaSourceId: playSettings.mediaSource?.Id!,
// audioStreamIndex: playSettings.audioIndex positionTicks: Math.floor(currentTimeInTicks),
// ? playSettings.audioIndex isPaused: !isPlaying,
// : undefined, playMethod: playUrl.includes("m3u8") ? "Transcode" : "DirectStream",
// subtitleStreamIndex: playSettings.subtitleIndex playSessionId: playSessionId ? playSessionId : undefined,
// ? playSettings.subtitleIndex });
// : undefined,
// mediaSourceId: playSettings.mediaSource?.Id!,
// positionTicks: Math.round(ticks),
// isPaused: !isPlaying,
// playMethod: playUrl.includes("m3u8") ? "Transcode" : "DirectStream",
// playSessionId: playSessionId ? playSessionId : undefined,
// });
}, },
[playSettings?.item.Id, isPlaying, api, isPlaybackStopped] [playSettings?.item.Id, isPlaying, api, isPlaybackStopped]
); );
@@ -191,7 +166,7 @@ export default function page() {
}, [play, stop]) }, [play, stop])
); );
const { orientation } = useOrientation(); useOrientation();
useOrientationSettings(); useOrientationSettings();
useAndroidNavigationBar(); useAndroidNavigationBar();
@@ -203,7 +178,7 @@ export default function page() {
}); });
const onPlaybackStateChanged = (e: PlaybackStatePayload) => { const onPlaybackStateChanged = (e: PlaybackStatePayload) => {
const { target, state, isBuffering, isPlaying } = e.nativeEvent; const { state, isBuffering, isPlaying } = e.nativeEvent;
if (state === "Playing") { if (state === "Playing") {
setIsPlaying(true); setIsPlaying(true);
@@ -221,18 +196,8 @@ export default function page() {
} else if (isBuffering) { } else if (isBuffering) {
setIsBuffering(true); setIsBuffering(true);
} }
setPlaybackState(e.nativeEvent);
}; };
useEffect(() => {
return () => {
stop();
};
}, []);
const [isVideoLoaded, setIsVideoLoaded] = useState(false);
return ( return (
<View <View
style={{ style={{
@@ -321,38 +286,3 @@ export function usePoster(
return poster ?? undefined; return poster ?? undefined;
} }
export function useVideoSource(
playSettings: PlaybackType | null,
api: Api | null,
poster: string | undefined,
playUrl?: string | null
) {
const videoSource = useMemo(() => {
if (!playSettings || !api || !playUrl) {
return null;
}
const startPosition = playSettings.item?.UserData?.PlaybackPositionTicks
? Math.round(
ticksToSeconds(playSettings.item.UserData.PlaybackPositionTicks)
)
: 0;
return {
uri: playUrl,
isNetwork: true,
startPosition,
headers: getAuthHeaders(api),
metadata: {
artist: playSettings.item?.AlbumArtist ?? undefined,
title: playSettings.item?.Name || "Unknown",
description: playSettings.item?.Overview ?? undefined,
imageUri: poster,
subtitle: playSettings.item?.Album ?? undefined,
},
};
}, [playSettings, api, poster]);
return videoSource;
}