mirror of
https://github.com/streamyfin/streamyfin.git
synced 2025-08-20 18:37:18 +02:00
fix: trying to fix playback issues
This commit is contained in:
@@ -105,6 +105,29 @@ export const CurrentlyPlayingBar: React.FC = () => {
|
||||
[currentlyPlaying?.item, api]
|
||||
);
|
||||
|
||||
const videoSource = useMemo(() => {
|
||||
if (!api || !currentlyPlaying || !backdropUrl) return null;
|
||||
return {
|
||||
uri: currentlyPlaying.url,
|
||||
isNetwork: true,
|
||||
startPosition,
|
||||
headers: getAuthHeaders(api),
|
||||
metadata: {
|
||||
artist: currentlyPlaying.item?.AlbumArtist
|
||||
? currentlyPlaying.item?.AlbumArtist
|
||||
: undefined,
|
||||
title: currentlyPlaying.item?.Name || "Unknown",
|
||||
description: currentlyPlaying.item?.Overview
|
||||
? currentlyPlaying.item?.Overview
|
||||
: undefined,
|
||||
imageUri: backdropUrl,
|
||||
subtitle: currentlyPlaying.item?.Album
|
||||
? currentlyPlaying.item?.Album
|
||||
: undefined,
|
||||
},
|
||||
};
|
||||
}, [currentlyPlaying, startPosition, api, backdropUrl]);
|
||||
|
||||
if (!api || !currentlyPlaying) return null;
|
||||
|
||||
return (
|
||||
@@ -139,7 +162,7 @@ export const CurrentlyPlayingBar: React.FC = () => {
|
||||
}
|
||||
`}
|
||||
>
|
||||
{currentlyPlaying?.url && (
|
||||
{videoSource && (
|
||||
<Video
|
||||
ref={videoRef}
|
||||
allowsExternalPlayback
|
||||
@@ -164,44 +187,26 @@ export const CurrentlyPlayingBar: React.FC = () => {
|
||||
subtitleStyle={{
|
||||
fontSize: 16,
|
||||
}}
|
||||
source={{
|
||||
uri: currentlyPlaying.url,
|
||||
isNetwork: true,
|
||||
startPosition,
|
||||
headers: getAuthHeaders(api),
|
||||
metadata: {
|
||||
artist: currentlyPlaying.item?.AlbumArtist
|
||||
? currentlyPlaying.item?.AlbumArtist
|
||||
: undefined,
|
||||
title: currentlyPlaying.item?.Name
|
||||
? currentlyPlaying.item?.Name
|
||||
: "Unknown",
|
||||
description: currentlyPlaying.item?.Overview
|
||||
? currentlyPlaying.item?.Overview
|
||||
: undefined,
|
||||
imageUri: backdropUrl ? backdropUrl : undefined,
|
||||
subtitle: currentlyPlaying.item?.Album
|
||||
? currentlyPlaying.item?.Album
|
||||
: undefined,
|
||||
},
|
||||
}}
|
||||
source={videoSource}
|
||||
onRestoreUserInterfaceForPictureInPictureStop={() => {
|
||||
setTimeout(() => {
|
||||
presentFullscreenPlayer();
|
||||
}, 300);
|
||||
}}
|
||||
onBuffer={(e) =>
|
||||
e.isBuffering ? console.log("Buffering...") : null
|
||||
}
|
||||
onFullscreenPlayerDidDismiss={() => {}}
|
||||
onFullscreenPlayerDidPresent={() => {}}
|
||||
onPlaybackStateChanged={(e) => {
|
||||
setIsPlaying(e.isPlaying);
|
||||
console.log("onPlaybackStateChanged ~", e.isPlaying);
|
||||
if (e.isPlaying === true) {
|
||||
playVideo(false);
|
||||
} else if (e.isPlaying === false) {
|
||||
pauseVideo(false);
|
||||
}
|
||||
}}
|
||||
onVolumeChange={(e) => {
|
||||
setVolume(e.volume);
|
||||
}}
|
||||
progressUpdateInterval={2000}
|
||||
progressUpdateInterval={4000}
|
||||
onError={(e) => {
|
||||
console.log(e);
|
||||
writeToLog(
|
||||
|
||||
10
package.json
10
package.json
@@ -30,15 +30,15 @@
|
||||
"@types/lodash": "^4.17.7",
|
||||
"@types/uuid": "^10.0.0",
|
||||
"axios": "^1.7.3",
|
||||
"expo": "~51.0.28",
|
||||
"expo": "~51.0.31",
|
||||
"expo-blur": "~13.0.2",
|
||||
"expo-build-properties": "~0.12.5",
|
||||
"expo-constants": "~16.0.2",
|
||||
"expo-dev-client": "~4.0.23",
|
||||
"expo-dev-client": "~4.0.25",
|
||||
"expo-device": "~6.0.2",
|
||||
"expo-font": "~12.0.9",
|
||||
"expo-haptics": "~13.0.1",
|
||||
"expo-image": "~1.12.14",
|
||||
"expo-image": "~1.12.15",
|
||||
"expo-keep-awake": "~13.0.2",
|
||||
"expo-linking": "~6.3.1",
|
||||
"expo-navigation-bar": "~3.0.7",
|
||||
@@ -48,7 +48,7 @@
|
||||
"expo-splash-screen": "~0.27.5",
|
||||
"expo-status-bar": "~1.12.1",
|
||||
"expo-system-ui": "~3.0.7",
|
||||
"expo-updates": "~0.25.22",
|
||||
"expo-updates": "~0.25.24",
|
||||
"expo-web-browser": "~13.0.3",
|
||||
"ffmpeg-kit-react-native": "^6.0.2",
|
||||
"jotai": "^2.9.1",
|
||||
@@ -72,7 +72,7 @@
|
||||
"react-native-svg": "15.2.0",
|
||||
"react-native-url-polyfill": "^2.0.0",
|
||||
"react-native-uuid": "^2.0.2",
|
||||
"react-native-video": "^6.4.3",
|
||||
"react-native-video": "^6.4.5",
|
||||
"react-native-web": "~0.19.10",
|
||||
"tailwindcss": "3.3.2",
|
||||
"use-debounce": "^10.0.3",
|
||||
|
||||
@@ -13,6 +13,7 @@ import { useSettings } from "@/utils/atoms/settings";
|
||||
import { getDeviceId } from "@/utils/device";
|
||||
import { reportPlaybackProgress } from "@/utils/jellyfin/playstate/reportPlaybackProgress";
|
||||
import { reportPlaybackStopped } from "@/utils/jellyfin/playstate/reportPlaybackStopped";
|
||||
import { postCapabilities } from "@/utils/jellyfin/session/capabilities";
|
||||
import {
|
||||
BaseItemDto,
|
||||
PlaybackInfoResponse,
|
||||
@@ -20,11 +21,10 @@ import {
|
||||
import { getMediaInfoApi } from "@jellyfin/sdk/lib/utils/api";
|
||||
import * as Linking from "expo-linking";
|
||||
import { useAtom } from "jotai";
|
||||
import { debounce } from "lodash";
|
||||
import { Alert, Platform } from "react-native";
|
||||
import { OnProgressData, type VideoRef } from "react-native-video";
|
||||
import { apiAtom, userAtom } from "./JellyfinProvider";
|
||||
import { postCapabilities } from "@/utils/jellyfin/session/capabilities";
|
||||
import { debounce } from "lodash";
|
||||
|
||||
type CurrentlyPlayingState = {
|
||||
url: string;
|
||||
@@ -38,8 +38,8 @@ interface PlaybackContextType {
|
||||
isPlaying: boolean;
|
||||
isFullscreen: boolean;
|
||||
progressTicks: number | null;
|
||||
playVideo: () => void;
|
||||
pauseVideo: () => void;
|
||||
playVideo: (triggerRef?: boolean) => void;
|
||||
pauseVideo: (triggerRef?: boolean) => void;
|
||||
stopPlayback: () => void;
|
||||
presentFullscreenPlayer: () => void;
|
||||
dismissFullscreenPlayer: () => void;
|
||||
@@ -133,22 +133,12 @@ export const PlaybackProvider: React.FC<{ children: ReactNode }> = ({
|
||||
[settings, user, api]
|
||||
);
|
||||
|
||||
// Define control methods
|
||||
const playVideo = useCallback(() => {
|
||||
const playVideo = useCallback(
|
||||
(triggerRef: boolean = true) => {
|
||||
if (triggerRef) {
|
||||
videoRef.current?.resume();
|
||||
setIsPlaying(true);
|
||||
reportPlaybackProgress({
|
||||
api,
|
||||
itemId: currentlyPlaying?.item.Id,
|
||||
positionTicks: progressTicks ? progressTicks : 0,
|
||||
sessionId: session?.PlaySessionId,
|
||||
IsPaused: true,
|
||||
});
|
||||
}, [api, currentlyPlaying?.item.Id, session?.PlaySessionId, progressTicks]);
|
||||
|
||||
const pauseVideo = useCallback(() => {
|
||||
videoRef.current?.pause();
|
||||
setIsPlaying(false);
|
||||
}
|
||||
_setIsPlaying(true);
|
||||
reportPlaybackProgress({
|
||||
api,
|
||||
itemId: currentlyPlaying?.item.Id,
|
||||
@@ -156,7 +146,26 @@ export const PlaybackProvider: React.FC<{ children: ReactNode }> = ({
|
||||
sessionId: session?.PlaySessionId,
|
||||
IsPaused: false,
|
||||
});
|
||||
}, [session?.PlaySessionId, currentlyPlaying?.item.Id, progressTicks]);
|
||||
},
|
||||
[api, currentlyPlaying?.item.Id, session?.PlaySessionId, progressTicks]
|
||||
);
|
||||
|
||||
const pauseVideo = useCallback(
|
||||
(triggerRef: boolean = true) => {
|
||||
if (triggerRef) {
|
||||
videoRef.current?.pause();
|
||||
}
|
||||
_setIsPlaying(false);
|
||||
reportPlaybackProgress({
|
||||
api,
|
||||
itemId: currentlyPlaying?.item.Id,
|
||||
positionTicks: progressTicks ? progressTicks : 0,
|
||||
sessionId: session?.PlaySessionId,
|
||||
IsPaused: true,
|
||||
});
|
||||
},
|
||||
[session?.PlaySessionId, currentlyPlaying?.item.Id, progressTicks]
|
||||
);
|
||||
|
||||
const stopPlayback = useCallback(async () => {
|
||||
await reportPlaybackStopped({
|
||||
@@ -166,17 +175,23 @@ export const PlaybackProvider: React.FC<{ children: ReactNode }> = ({
|
||||
positionTicks: progressTicks ? progressTicks : 0,
|
||||
});
|
||||
setCurrentlyPlayingState(null);
|
||||
}, [currentlyPlaying, session, progressTicks]);
|
||||
}, [currentlyPlaying?.item.Id, session?.PlaySessionId, progressTicks, api]);
|
||||
|
||||
const setIsPlaying = useCallback(
|
||||
debounce((value: boolean) => {
|
||||
_setIsPlaying(value);
|
||||
}, 100),
|
||||
}, 500),
|
||||
[]
|
||||
);
|
||||
|
||||
const onProgress = useCallback(
|
||||
const _onProgress = useCallback(
|
||||
({ currentTime }: OnProgressData) => {
|
||||
if (
|
||||
!session?.PlaySessionId ||
|
||||
!currentlyPlaying?.item.Id ||
|
||||
currentTime === 0
|
||||
)
|
||||
return;
|
||||
const ticks = currentTime * 10000000;
|
||||
setProgressTicks(ticks);
|
||||
reportPlaybackProgress({
|
||||
@@ -187,7 +202,14 @@ export const PlaybackProvider: React.FC<{ children: ReactNode }> = ({
|
||||
IsPaused: !isPlaying,
|
||||
});
|
||||
},
|
||||
[session?.PlaySessionId, currentlyPlaying?.item.Id, isPlaying]
|
||||
[session?.PlaySessionId, currentlyPlaying?.item.Id, isPlaying, api]
|
||||
);
|
||||
|
||||
const onProgress = useCallback(
|
||||
debounce((e: OnProgressData) => {
|
||||
_onProgress(e);
|
||||
}, 1000),
|
||||
[_onProgress]
|
||||
);
|
||||
|
||||
const presentFullscreenPlayer = useCallback(() => {
|
||||
|
||||
@@ -24,12 +24,6 @@ export const reportPlaybackProgress = async ({
|
||||
IsPaused = false,
|
||||
}: ReportPlaybackProgressParams): Promise<void> => {
|
||||
if (!api || !sessionId || !itemId || !positionTicks) {
|
||||
console.error(
|
||||
"Missing required parameter",
|
||||
sessionId,
|
||||
itemId,
|
||||
positionTicks
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user