add granite subtitle source

This commit is contained in:
Pas 2025-12-01 15:35:32 -07:00
parent d527446eb4
commit b875bc93aa
2 changed files with 77 additions and 0 deletions

View file

@ -134,6 +134,7 @@ export function CaptionOption(props: {
"bg-blue-500": props.subtitleSource.includes("wyzie"),
"bg-orange-500": props.subtitleSource === "opensubs",
"bg-purple-500": props.subtitleSource === "febbox",
"bg-green-500": props.subtitleSource === "granite",
},
)}
>

View file

@ -284,6 +284,77 @@ export async function scrapeFebboxCaptions(
}
}
export async function scrapeVdrkCaptions(
tmdbId: string | number,
season?: number,
episode?: number,
): Promise<CaptionListItem[]> {
try {
const tmdbIdNum =
typeof tmdbId === "string" ? parseInt(tmdbId, 10) : tmdbId;
let url: string;
if (season && episode) {
// For TV shows: https://sub.vdrk.site/v1/tv/{tmdb_id}/{season}/{episode}
url = `https://sub.vdrk.site/v1/tv/${tmdbIdNum}/${season}/${episode}`;
} else {
// For movies: https://sub.vdrk.site/v1/movie/{tmdb_id}
url = `https://sub.vdrk.site/v1/movie/${tmdbIdNum}`;
}
console.log("Searching VDRK subtitles with URL:", url);
const response = await fetch(url);
if (!response.ok) {
throw new Error(`VDRK API returned ${response.status}`);
}
const data = await response.json();
// Check if response is an array
if (!Array.isArray(data)) {
console.log("Invalid VDRK response format");
return [];
}
const vdrkCaptions: CaptionListItem[] = [];
for (const subtitle of data) {
if (subtitle.file && subtitle.label) {
// Parse label to extract language and hearing impaired info
const label = subtitle.label;
const isHearingImpaired = label.includes(" Hi") || label.includes("Hi");
const languageName = label
.replace(/\s*Hi\d*$/, "")
.replace(/\s*Hi$/, "")
.replace(/\d+$/, "");
const language = labelToLanguageCode(languageName);
if (!language) continue;
vdrkCaptions.push({
id: subtitle.file,
language,
url: subtitle.file,
type: "vtt", // VDRK provides VTT files
needsProxy: false,
opensubtitles: true,
display: subtitle.label,
isHearingImpaired,
source: "granite",
});
}
}
console.log(`Found ${vdrkCaptions.length} VDRK subtitles`);
return vdrkCaptions;
} catch (error) {
console.error("Error fetching VDRK subtitles:", error);
return [];
}
}
export async function scrapeExternalSubtitles(
meta: PlayerMeta,
): Promise<CaptionListItem[]> {
@ -310,6 +381,7 @@ export async function scrapeExternalSubtitles(
episode,
);
// const febboxPromise = scrapeFebboxCaptions(imdbId, season, episode);
const vdrkPromise = scrapeVdrkCaptions(tmdbId, season, episode);
// Create timeout promises
const timeoutPromise = new Promise<CaptionListItem[]>((resolve) => {
@ -347,6 +419,10 @@ export async function scrapeExternalSubtitles(
// handleSourceCompletion("Febbox", captions);
// return captions;
// }),
Promise.race([vdrkPromise, timeoutPromise]).then((captions) => {
handleSourceCompletion("Granite", captions);
return captions;
}),
];
// Wait for all sources to complete (with timeouts)