This commit is contained in:
Fredrik Burmester
2024-10-21 16:05:36 +02:00
parent ba76f2444d
commit 68d32bd0de
3 changed files with 64 additions and 50 deletions

View File

@@ -29,7 +29,13 @@ import { useFocusEffect, useLocalSearchParams } from "expo-router";
import { useAtomValue } from "jotai";
import { debounce } from "lodash";
import React, { useCallback, useMemo, useRef, useState } from "react";
import { Dimensions, Pressable, StatusBar, View } from "react-native";
import {
Dimensions,
Pressable,
StatusBar,
useWindowDimensions,
View,
} from "react-native";
import { useSharedValue } from "react-native-reanimated";
import Video, { OnProgressData, VideoRef } from "react-native-video";
@@ -38,11 +44,10 @@ export default function page() {
const user = useAtomValue(userAtom);
const [settings] = useSettings();
const videoRef = useRef<VideoRef | null>(null);
const windowDimensions = useWindowDimensions();
const firstTime = useRef(true);
const screenDimensions = Dimensions.get("screen");
const [isPlaybackStopped, setIsPlaybackStopped] = useState(false);
const [showControls, setShowControls] = useState(true);
const [ignoreSafeAreas, setIgnoreSafeAreas] = useState(false);
@@ -267,7 +272,7 @@ export default function page() {
}, [play, stop])
);
const { orientation } = useOrientation();
useOrientation();
useOrientationSettings();
useAndroidNavigationBar();
@@ -292,13 +297,18 @@ export default function page() {
</View>
);
if (!stream || !item || !videoSource) return null;
if (!item || !stream)
return (
<View className="w-screen h-screen flex flex-col items-center justify-center bg-black">
<Text className="text-white">Error</Text>
</View>
);
return (
<View
style={{
width: screenDimensions.width,
height: screenDimensions.height,
width: windowDimensions.width,
height: windowDimensions.height,
position: "relative",
}}
className="flex flex-col items-center justify-center"
@@ -318,31 +328,33 @@ export default function page() {
}}
className="absolute z-0 h-full w-full opacity-0"
>
<Video
ref={videoRef}
source={videoSource}
style={{ width: "100%", height: "100%" }}
resizeMode={ignoreSafeAreas ? "cover" : "contain"}
onProgress={onProgress}
onError={() => {}}
onLoad={() => {
if (firstTime.current === true) {
play();
firstTime.current = false;
}
}}
progressUpdateInterval={500}
playWhenInactive={true}
allowsExternalPlayback={true}
playInBackground={true}
pictureInPicture={true}
showNotificationControls={true}
ignoreSilentSwitch="ignore"
fullscreen={false}
onPlaybackStateChanged={(state) => {
setIsPlaying(state.isPlaying);
}}
/>
{videoSource && (
<Video
ref={videoRef}
source={videoSource}
style={{ width: "100%", height: "100%" }}
resizeMode={ignoreSafeAreas ? "cover" : "contain"}
onProgress={onProgress}
onError={() => {}}
onLoad={() => {
if (firstTime.current === true) {
play();
firstTime.current = false;
}
}}
progressUpdateInterval={500}
playWhenInactive={true}
allowsExternalPlayback={true}
playInBackground={true}
pictureInPicture={true}
showNotificationControls={true}
ignoreSilentSwitch="ignore"
fullscreen={false}
onPlaybackStateChanged={(state) => {
setIsPlaying(state.isPlaying);
}}
/>
)}
</Pressable>
<Controls

View File

@@ -16,7 +16,8 @@ import { apiAtom, userAtom } from "@/providers/JellyfinProvider";
import { getBackdropUrl } from "@/utils/jellyfin/image/getBackdropUrl";
import { getStreamUrl } from "@/utils/jellyfin/media/getStreamUrl";
import { writeToLog } from "@/utils/log";
import { msToTicks, ticksToMs } from "@/utils/time";
import native from "@/utils/profiles/native";
import { msToTicks } from "@/utils/time";
import { Api } from "@jellyfin/sdk";
import { BaseItemDto } from "@jellyfin/sdk/lib/generated-client";
import {
@@ -25,7 +26,7 @@ import {
} from "@jellyfin/sdk/lib/utils/api";
import { useQuery } from "@tanstack/react-query";
import * as Haptics from "expo-haptics";
import { useFocusEffect, useLocalSearchParams } from "expo-router";
import { useLocalSearchParams } from "expo-router";
import { useAtomValue } from "jotai";
import React, { useCallback, useMemo, useRef, useState } from "react";
import {
@@ -118,6 +119,7 @@ export default function page() {
maxStreamingBitrate: bitrateValue,
mediaSourceId: mediaSourceId,
subtitleStreamIndex: subtitleIndex,
deviceProfile: native,
});
if (!res) return null;
@@ -230,8 +232,6 @@ export default function page() {
const { currentTime, isPlaying } = data.nativeEvent;
console.log("onProgress", currentTime);
progress.value = currentTime;
const currentTimeInTicks = msToTicks(currentTime);
@@ -249,15 +249,15 @@ export default function page() {
[item?.Id, isPlaying, api, isPlaybackStopped]
);
useFocusEffect(
useCallback(() => {
play();
// useFocusEffect(
// useCallback(() => {
// play();
return () => {
stop();
};
}, [play, stop])
);
// return () => {
// stop();
// };
// }, [play, stop])
// );
useOrientation();
useOrientationSettings();

View File

@@ -90,16 +90,10 @@ export const getStreamUrl = async ({
userId,
maxStreamingBitrate,
startTimeTicks,
enableTranscoding: maxStreamingBitrate ? true : undefined,
autoOpenLiveStream: true,
mediaSourceId,
allowVideoStreamCopy: maxStreamingBitrate ? false : true,
audioStreamIndex,
subtitleStreamIndex,
deInterlace: true,
breakOnNonKeyFrames: false,
copyTimestamps: false,
enableMpegtsM2TsMode: false,
},
}
);
@@ -112,6 +106,10 @@ export const getStreamUrl = async ({
if (item.MediaType === "Video") {
if (mediaSource?.TranscodingUrl) {
console.log(
"Video has transcoding URL:",
`${api.basePath}${mediaSource.TranscodingUrl}`
);
return {
url: `${api.basePath}${mediaSource.TranscodingUrl}`,
sessionId: sessionId,
@@ -120,6 +118,10 @@ export const getStreamUrl = async ({
}
if (mediaSource?.SupportsDirectPlay) {
console.log(
"Video is being direct played:",
`${api.basePath}/Videos/${itemId}/stream.mp4?playSessionId=${sessionData?.PlaySessionId}&mediaSourceId=${mediaSource?.Id}&static=true&subtitleStreamIndex=${subtitleStreamIndex}&audioStreamIndex=${audioStreamIndex}&deviceId=${api.deviceInfo.id}&api_key=${api.accessToken}`
);
return {
url: `${api.basePath}/Videos/${itemId}/stream.mp4?playSessionId=${sessionData?.PlaySessionId}&mediaSourceId=${mediaSource?.Id}&static=true&subtitleStreamIndex=${subtitleStreamIndex}&audioStreamIndex=${audioStreamIndex}&deviceId=${api.deviceInfo.id}&api_key=${api.accessToken}`,
sessionId: sessionId,