mirror of
https://github.com/p-stream/p-stream.git
synced 2026-05-21 17:02:06 +00:00
update skips!
This commit is contained in:
parent
02a179b1d8
commit
5b32daac60
2 changed files with 66 additions and 5 deletions
|
|
@ -8,17 +8,52 @@ import { usePreferencesStore } from "@/stores/preferences";
|
||||||
import { getTurnstileToken } from "@/utils/turnstile";
|
import { getTurnstileToken } from "@/utils/turnstile";
|
||||||
|
|
||||||
// Thanks Nemo for this API
|
// Thanks Nemo for this API
|
||||||
|
const THE_INTRO_DB_BASE_URL = "https://api.theintrodb.org";
|
||||||
const FED_SKIPS_BASE_URL = "https://fed-skips.pstream.mov";
|
const FED_SKIPS_BASE_URL = "https://fed-skips.pstream.mov";
|
||||||
// const VELORA_BASE_URL = "https://veloratv.ru/api/intro-end/confirmed";
|
// const VELORA_BASE_URL = "https://veloratv.ru/api/intro-end/confirmed";
|
||||||
const INTRODB_BASE_URL = "https://api.introdb.app/intro";
|
const INTRODB_BASE_URL = "https://api.introdb.app/intro";
|
||||||
const MAX_RETRIES = 3;
|
const MAX_RETRIES = 3;
|
||||||
|
|
||||||
|
// Track the source of the current skip time (for analytics filtering)
|
||||||
|
let currentSkipTimeSource: "fed-skips" | "introdb" | "theintrodb" | null = null;
|
||||||
|
|
||||||
|
export function useSkipTimeSource(): typeof currentSkipTimeSource {
|
||||||
|
return currentSkipTimeSource;
|
||||||
|
}
|
||||||
|
|
||||||
export function useSkipTime() {
|
export function useSkipTime() {
|
||||||
const { playerMeta: meta } = usePlayerMeta();
|
const { playerMeta: meta } = usePlayerMeta();
|
||||||
const [skiptime, setSkiptime] = useState<number | null>(null);
|
const [skiptime, setSkiptime] = useState<number | null>(null);
|
||||||
const febboxKey = usePreferencesStore((s) => s.febboxKey);
|
const febboxKey = usePreferencesStore((s) => s.febboxKey);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
const fetchTheIntroDBTime = async (): Promise<number | null> => {
|
||||||
|
if (!meta?.imdbId) return null;
|
||||||
|
|
||||||
|
try {
|
||||||
|
let apiUrl = `${THE_INTRO_DB_BASE_URL}?imdb_id=${meta.imdbId}`;
|
||||||
|
if (
|
||||||
|
meta.type !== "movie" &&
|
||||||
|
meta.season?.number &&
|
||||||
|
meta.episode?.number
|
||||||
|
) {
|
||||||
|
apiUrl += `&season=${meta.season.number}&episode=${meta.episode.number}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
const data = await proxiedFetch(apiUrl);
|
||||||
|
|
||||||
|
if (data && typeof data.end_ms === "number") {
|
||||||
|
// Convert milliseconds to seconds
|
||||||
|
return Math.floor(data.end_ms / 1000);
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
} catch (error) {
|
||||||
|
console.error("Error fetching TIDB time:", error);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
// const fetchVeloraSkipTime = async (): Promise<number | null> => {
|
// const fetchVeloraSkipTime = async (): Promise<number | null> => {
|
||||||
// if (!meta?.tmdbId) return null;
|
// if (!meta?.tmdbId) return null;
|
||||||
|
|
||||||
|
|
@ -105,17 +140,33 @@ export function useSkipTime() {
|
||||||
};
|
};
|
||||||
|
|
||||||
const fetchSkipTime = async (): Promise<void> => {
|
const fetchSkipTime = async (): Promise<void> => {
|
||||||
|
// Reset source
|
||||||
|
currentSkipTimeSource = null;
|
||||||
|
|
||||||
// If user has febbox key, prioritize Fed-skips (better quality)
|
// If user has febbox key, prioritize Fed-skips (better quality)
|
||||||
if (febboxKey) {
|
// Note: Fed-skips only supports TV shows, not movies
|
||||||
|
if (febboxKey && meta?.type !== "movie") {
|
||||||
const fedSkipsTime = await fetchFedSkipsTime();
|
const fedSkipsTime = await fetchFedSkipsTime();
|
||||||
if (fedSkipsTime !== null) {
|
if (fedSkipsTime !== null) {
|
||||||
|
currentSkipTimeSource = "fed-skips";
|
||||||
setSkiptime(fedSkipsTime);
|
setSkiptime(fedSkipsTime);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Fall back to IntroDB API (available to all users)
|
// Try TheIntroDB API (supports both movies and TV shows)
|
||||||
|
const theIntroDBTime = await fetchTheIntroDBTime();
|
||||||
|
if (theIntroDBTime !== null) {
|
||||||
|
currentSkipTimeSource = "theintrodb";
|
||||||
|
setSkiptime(theIntroDBTime);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fall back to IntroDB API (TV shows only, available to all users)
|
||||||
const introDBTime = await fetchIntroDBTime();
|
const introDBTime = await fetchIntroDBTime();
|
||||||
|
if (introDBTime !== null) {
|
||||||
|
currentSkipTimeSource = "introdb";
|
||||||
|
}
|
||||||
setSkiptime(introDBTime);
|
setSkiptime(introDBTime);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
import { useCallback, useEffect, useRef, useState } from "react";
|
import { useCallback, useEffect, useRef, useState } from "react";
|
||||||
|
|
||||||
|
import { useSkipTimeSource } from "@/components/player/hooks/useSkipTime";
|
||||||
import { useSkipTracking } from "@/components/player/hooks/useSkipTracking";
|
import { useSkipTracking } from "@/components/player/hooks/useSkipTracking";
|
||||||
import { usePlayerStore } from "@/stores/player/store";
|
import { usePlayerStore } from "@/stores/player/store";
|
||||||
|
|
||||||
|
|
@ -18,6 +19,7 @@ interface PendingSkip {
|
||||||
startTime: number;
|
startTime: number;
|
||||||
endTime: number;
|
endTime: number;
|
||||||
hasBackwardMovement: boolean;
|
hasBackwardMovement: boolean;
|
||||||
|
skipTimeSource: "fed-skips" | "introdb" | "theintrodb" | null;
|
||||||
timer: ReturnType<typeof setTimeout>;
|
timer: ReturnType<typeof setTimeout>;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -31,6 +33,7 @@ export function SkipTracker() {
|
||||||
const meta = usePlayerStore((s) => s.meta);
|
const meta = usePlayerStore((s) => s.meta);
|
||||||
const progress = usePlayerStore((s) => s.progress);
|
const progress = usePlayerStore((s) => s.progress);
|
||||||
const turnstileToken = "";
|
const turnstileToken = "";
|
||||||
|
const skipTimeSource = useSkipTimeSource();
|
||||||
|
|
||||||
const sendSkipAnalytics = useCallback(
|
const sendSkipAnalytics = useCallback(
|
||||||
async (skip: SkipEvent, adjustedConfidence: number) => {
|
async (skip: SkipEvent, adjustedConfidence: number) => {
|
||||||
|
|
@ -71,8 +74,14 @@ export function SkipTracker() {
|
||||||
? Math.max(0.1, pendingSkip.originalConfidence * 0.5) // Reduce confidence by half if adjusted
|
? Math.max(0.1, pendingSkip.originalConfidence * 0.5) // Reduce confidence by half if adjusted
|
||||||
: pendingSkip.originalConfidence;
|
: pendingSkip.originalConfidence;
|
||||||
|
|
||||||
// Send analytics
|
// Only send analytics if skip time came from fed-skips or introdb (not theintrodb)
|
||||||
sendSkipAnalytics(pendingSkip.skip, adjustedConfidence);
|
if (
|
||||||
|
pendingSkip.skipTimeSource === "fed-skips" ||
|
||||||
|
pendingSkip.skipTimeSource === "introdb"
|
||||||
|
) {
|
||||||
|
// Send analytics
|
||||||
|
sendSkipAnalytics(pendingSkip.skip, adjustedConfidence);
|
||||||
|
}
|
||||||
|
|
||||||
// Remove from pending
|
// Remove from pending
|
||||||
return prev.filter((p) => p.skip.timestamp !== skip.timestamp);
|
return prev.filter((p) => p.skip.timestamp !== skip.timestamp);
|
||||||
|
|
@ -85,10 +94,11 @@ export function SkipTracker() {
|
||||||
startTime: skip.startTime,
|
startTime: skip.startTime,
|
||||||
endTime: skip.endTime,
|
endTime: skip.endTime,
|
||||||
hasBackwardMovement: false,
|
hasBackwardMovement: false,
|
||||||
|
skipTimeSource,
|
||||||
timer,
|
timer,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
[sendSkipAnalytics],
|
[sendSkipAnalytics, skipTimeSource],
|
||||||
);
|
);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue