From 91128944c6218ddde40335b23be6405ec70d0018 Mon Sep 17 00:00:00 2001 From: lance chant <13349722+lancechant@users.noreply.github.com> Date: Fri, 9 Jan 2026 10:17:35 +0200 Subject: [PATCH] fix: fixing an issue where offline playback wasn't working/tracking when back online (#1239) Signed-off-by: Lance Chant <13349722+lancechant@users.noreply.github.com> Co-authored-by: retardgerman <78982850+retardgerman@users.noreply.github.com> --- app/(auth)/player/direct-player.tsx | 69 ++++++++++++++++------------- 1 file changed, 39 insertions(+), 30 deletions(-) diff --git a/app/(auth)/player/direct-player.tsx b/app/(auth)/player/direct-player.tsx index 2c4d11f2..40ccc834 100644 --- a/app/(auth)/player/direct-player.tsx +++ b/app/(auth)/player/direct-player.tsx @@ -3,7 +3,6 @@ import { type MediaSourceInfo, PlaybackOrder, PlaybackProgressInfo, - PlaybackStartInfo, RepeatMode, } from "@jellyfin/sdk/lib/generated-client"; import { @@ -351,9 +350,12 @@ export default function page() { useEffect(() => { if (!stream || !api || offline) return; const reportPlaybackStart = async () => { - await getPlaystateApi(api).reportPlaybackStart({ - playbackStartInfo: currentPlayStateInfo() as PlaybackStartInfo, - }); + const progressInfo = currentPlayStateInfo(); + if (progressInfo) { + await getPlaystateApi(api).reportPlaybackStart({ + playbackStartInfo: progressInfo, + }); + } }; reportPlaybackStart(); }, [stream, api, offline]); @@ -363,14 +365,16 @@ export default function page() { setIsPlaying(!isPlaying); if (isPlaying) { await videoRef.current?.pause(); - playbackManager.reportPlaybackProgress( - currentPlayStateInfo() as PlaybackProgressInfo, - ); + const progressInfo = currentPlayStateInfo(); + if (progressInfo) { + playbackManager.reportPlaybackProgress(progressInfo); + } } else { videoRef.current?.play(); + const progressInfo = currentPlayStateInfo(); if (!offline && api) { await getPlaystateApi(api).reportPlaybackStart({ - playbackStartInfo: currentPlayStateInfo() as PlaybackStartInfo, + playbackStartInfo: progressInfo, }); } } @@ -415,22 +419,24 @@ export default function page() { }; }, [navigation, stop]); - const currentPlayStateInfo = useCallback(() => { + const currentPlayStateInfo = useCallback((): + | PlaybackProgressInfo + | undefined => { if (!stream || !item?.Id) return; return { - itemId: item.Id, - audioStreamIndex: audioIndex ? audioIndex : undefined, - subtitleStreamIndex: subtitleIndex ? subtitleIndex : undefined, - mediaSourceId: mediaSourceId, - positionTicks: msToTicks(progress.get()), - isPaused: !isPlaying, - playMethod: stream?.url.includes("m3u8") ? "Transcode" : "DirectStream", - playSessionId: stream.sessionId, - isMuted: isMuted, - canSeek: true, - repeatMode: RepeatMode.RepeatNone, - playbackOrder: PlaybackOrder.Default, + ItemId: item.Id, + AudioStreamIndex: audioIndex ? audioIndex : undefined, + SubtitleStreamIndex: subtitleIndex ? subtitleIndex : undefined, + MediaSourceId: mediaSourceId, + PositionTicks: msToTicks(progress.get()), + IsPaused: !isPlaying, + PlayMethod: stream?.url.includes("m3u8") ? "Transcode" : "DirectStream", + PlaySessionId: stream.sessionId, + IsMuted: isMuted, + CanSeek: true, + RepeatMode: RepeatMode.RepeatNone, + PlaybackOrder: PlaybackOrder.Default, }; }, [ stream, @@ -539,9 +545,10 @@ export default function page() { if (!item?.Id) return; - playbackManager.reportPlaybackProgress( - currentPlayStateInfo() as PlaybackProgressInfo, - ); + const progressInfo = currentPlayStateInfo(); + if (progressInfo) { + playbackManager.reportPlaybackProgress(progressInfo); + } }, [ item?.Id, @@ -932,9 +939,10 @@ export default function page() { setHasPlaybackStarted(true); setTracksReady(true); // VLC tracks are ready when playback starts if (item?.Id) { - playbackManager.reportPlaybackProgress( - currentPlayStateInfo() as PlaybackProgressInfo, - ); + const progressInfo = currentPlayStateInfo(); + if (progressInfo) { + playbackManager.reportPlaybackProgress(progressInfo); + } } if (!Platform.isTV) await activateKeepAwakeAsync(); return; @@ -943,9 +951,10 @@ export default function page() { if (state === "Paused") { setIsPlaying(false); if (item?.Id) { - playbackManager.reportPlaybackProgress( - currentPlayStateInfo() as PlaybackProgressInfo, - ); + const progressInfo = currentPlayStateInfo(); + if (progressInfo) { + playbackManager.reportPlaybackProgress(progressInfo); + } } if (!Platform.isTV) await deactivateKeepAwake(); return;