fix: add Chromecast video progress tracking

This commit is contained in:
Uruk
2026-01-17 18:34:36 +01:00
parent 36304ad58e
commit 3555ef964e

View File

@@ -1,5 +1,8 @@
import { Feather } from "@expo/vector-icons";
import { useCallback, useEffect } from "react";
import type { PlaybackProgressInfo } from "@jellyfin/sdk/lib/generated-client/models";
import { getPlaystateApi } from "@jellyfin/sdk/lib/utils/api";
import { useAtomValue } from "jotai";
import { useCallback, useEffect, useRef } from "react";
import { Platform } from "react-native";
import { Pressable } from "react-native-gesture-handler";
import GoogleCast, {
@@ -10,6 +13,7 @@ import GoogleCast, {
useMediaStatus,
useRemoteMediaClient,
} from "react-native-google-cast";
import { apiAtom, userAtom } from "@/providers/JellyfinProvider";
import { RoundButton } from "./RoundButton";
export function Chromecast({
@@ -24,6 +28,10 @@ export function Chromecast({
const sessionManager = GoogleCast.getSessionManager();
const discoveryManager = GoogleCast.getDiscoveryManager();
const mediaStatus = useMediaStatus();
const api = useAtomValue(apiAtom);
const user = useAtomValue(userAtom);
const lastReportedProgressRef = useRef(0);
useEffect(() => {
(async () => {
@@ -36,6 +44,53 @@ export function Chromecast({
})();
}, [client, devices, castDevice, sessionManager, discoveryManager]);
// Report video progress to Jellyfin server
useEffect(() => {
if (
!api ||
!user?.Id ||
!mediaStatus ||
!mediaStatus.mediaInfo?.contentId
) {
return;
}
const streamPosition = mediaStatus.streamPosition || 0;
// Report every 10 seconds
if (Math.abs(streamPosition - lastReportedProgressRef.current) < 10) {
return;
}
const contentId = mediaStatus.mediaInfo.contentId;
const positionTicks = Math.floor(streamPosition * 10000000);
const isPaused = mediaStatus.playerState === "paused";
const streamUrl = mediaStatus.mediaInfo.contentUrl || "";
const isTranscoding = streamUrl.includes("m3u8");
const progressInfo: PlaybackProgressInfo = {
ItemId: contentId,
PositionTicks: positionTicks,
IsPaused: isPaused,
PlayMethod: isTranscoding ? "Transcode" : "DirectStream",
PlaySessionId: contentId,
};
getPlaystateApi(api)
.reportPlaybackProgress({ playbackProgressInfo: progressInfo })
.then(() => {
lastReportedProgressRef.current = streamPosition;
})
.catch((error) => {
console.error("Failed to report Chromecast progress:", error);
});
}, [
api,
user?.Id,
mediaStatus?.streamPosition,
mediaStatus?.mediaInfo?.contentId,
]);
// Android requires the cast button to be present for startDiscovery to work
const AndroidCastButton = useCallback(
() =>