mirror of
https://github.com/p-stream/p-stream.git
synced 2026-05-13 13:21:02 +00:00
add granite subtitle source
This commit is contained in:
parent
d527446eb4
commit
b875bc93aa
2 changed files with 77 additions and 0 deletions
|
|
@ -134,6 +134,7 @@ export function CaptionOption(props: {
|
||||||
"bg-blue-500": props.subtitleSource.includes("wyzie"),
|
"bg-blue-500": props.subtitleSource.includes("wyzie"),
|
||||||
"bg-orange-500": props.subtitleSource === "opensubs",
|
"bg-orange-500": props.subtitleSource === "opensubs",
|
||||||
"bg-purple-500": props.subtitleSource === "febbox",
|
"bg-purple-500": props.subtitleSource === "febbox",
|
||||||
|
"bg-green-500": props.subtitleSource === "granite",
|
||||||
},
|
},
|
||||||
)}
|
)}
|
||||||
>
|
>
|
||||||
|
|
|
||||||
|
|
@ -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(
|
export async function scrapeExternalSubtitles(
|
||||||
meta: PlayerMeta,
|
meta: PlayerMeta,
|
||||||
): Promise<CaptionListItem[]> {
|
): Promise<CaptionListItem[]> {
|
||||||
|
|
@ -310,6 +381,7 @@ export async function scrapeExternalSubtitles(
|
||||||
episode,
|
episode,
|
||||||
);
|
);
|
||||||
// const febboxPromise = scrapeFebboxCaptions(imdbId, season, episode);
|
// const febboxPromise = scrapeFebboxCaptions(imdbId, season, episode);
|
||||||
|
const vdrkPromise = scrapeVdrkCaptions(tmdbId, season, episode);
|
||||||
|
|
||||||
// Create timeout promises
|
// Create timeout promises
|
||||||
const timeoutPromise = new Promise<CaptionListItem[]>((resolve) => {
|
const timeoutPromise = new Promise<CaptionListItem[]>((resolve) => {
|
||||||
|
|
@ -347,6 +419,10 @@ export async function scrapeExternalSubtitles(
|
||||||
// handleSourceCompletion("Febbox", captions);
|
// handleSourceCompletion("Febbox", captions);
|
||||||
// return captions;
|
// return captions;
|
||||||
// }),
|
// }),
|
||||||
|
Promise.race([vdrkPromise, timeoutPromise]).then((captions) => {
|
||||||
|
handleSourceCompletion("Granite", captions);
|
||||||
|
return captions;
|
||||||
|
}),
|
||||||
];
|
];
|
||||||
|
|
||||||
// Wait for all sources to complete (with timeouts)
|
// Wait for all sources to complete (with timeouts)
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue