mirror of
https://github.com/streamyfin/streamyfin.git
synced 2026-01-19 09:38:07 +00:00
fix: add Chromecast video progress tracking
This commit is contained in:
@@ -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(
|
||||
() =>
|
||||
|
||||
Reference in New Issue
Block a user