update skips!

This commit is contained in:
Pas 2026-01-12 13:05:45 -07:00
parent 02a179b1d8
commit 5b32daac60
2 changed files with 66 additions and 5 deletions

View file

@ -8,17 +8,52 @@ import { usePreferencesStore } from "@/stores/preferences";
import { getTurnstileToken } from "@/utils/turnstile";
// 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 VELORA_BASE_URL = "https://veloratv.ru/api/intro-end/confirmed";
const INTRODB_BASE_URL = "https://api.introdb.app/intro";
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() {
const { playerMeta: meta } = usePlayerMeta();
const [skiptime, setSkiptime] = useState<number | null>(null);
const febboxKey = usePreferencesStore((s) => s.febboxKey);
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> => {
// if (!meta?.tmdbId) return null;
@ -105,17 +140,33 @@ export function useSkipTime() {
};
const fetchSkipTime = async (): Promise<void> => {
// Reset source
currentSkipTimeSource = null;
// 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();
if (fedSkipsTime !== null) {
currentSkipTimeSource = "fed-skips";
setSkiptime(fedSkipsTime);
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();
if (introDBTime !== null) {
currentSkipTimeSource = "introdb";
}
setSkiptime(introDBTime);
};

View file

@ -1,5 +1,6 @@
import { useCallback, useEffect, useRef, useState } from "react";
import { useSkipTimeSource } from "@/components/player/hooks/useSkipTime";
import { useSkipTracking } from "@/components/player/hooks/useSkipTracking";
import { usePlayerStore } from "@/stores/player/store";
@ -18,6 +19,7 @@ interface PendingSkip {
startTime: number;
endTime: number;
hasBackwardMovement: boolean;
skipTimeSource: "fed-skips" | "introdb" | "theintrodb" | null;
timer: ReturnType<typeof setTimeout>;
}
@ -31,6 +33,7 @@ export function SkipTracker() {
const meta = usePlayerStore((s) => s.meta);
const progress = usePlayerStore((s) => s.progress);
const turnstileToken = "";
const skipTimeSource = useSkipTimeSource();
const sendSkipAnalytics = useCallback(
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
: pendingSkip.originalConfidence;
// Send analytics
sendSkipAnalytics(pendingSkip.skip, adjustedConfidence);
// Only send analytics if skip time came from fed-skips or introdb (not theintrodb)
if (
pendingSkip.skipTimeSource === "fed-skips" ||
pendingSkip.skipTimeSource === "introdb"
) {
// Send analytics
sendSkipAnalytics(pendingSkip.skip, adjustedConfidence);
}
// Remove from pending
return prev.filter((p) => p.skip.timestamp !== skip.timestamp);
@ -85,10 +94,11 @@ export function SkipTracker() {
startTime: skip.startTime,
endTime: skip.endTime,
hasBackwardMovement: false,
skipTimeSource,
timer,
};
},
[sendSkipAnalytics],
[sendSkipAnalytics, skipTimeSource],
);
useEffect(() => {