mirror of
https://github.com/p-stream/providers.git
synced 2026-05-07 02:19:56 +00:00
update zoro and consumet
This commit is contained in:
parent
640c82ba52
commit
4487e9e818
3 changed files with 100 additions and 64 deletions
|
|
@ -4,7 +4,7 @@ import { NotFoundError } from '@/utils/errors';
|
|||
|
||||
export const hianimeHd1DubEmbed = makeEmbed({
|
||||
id: 'hianime-hd1-dub',
|
||||
name: 'Hianime HD-1 (Dub)',
|
||||
name: 'HD-1 (Dub)',
|
||||
disabled: true,
|
||||
rank: 250,
|
||||
async scrape(ctx): Promise<EmbedOutput> {
|
||||
|
|
@ -42,7 +42,7 @@ export const hianimeHd1DubEmbed = makeEmbed({
|
|||
|
||||
export const hianimeHd2DubEmbed = makeEmbed({
|
||||
id: 'hianime-hd2-dub',
|
||||
name: 'Hianime HD-2 (Dub)',
|
||||
name: 'HD-2 (Dub)',
|
||||
rank: 251,
|
||||
async scrape(ctx): Promise<EmbedOutput> {
|
||||
const query = JSON.parse(ctx.url);
|
||||
|
|
@ -55,11 +55,34 @@ export const hianimeHd2DubEmbed = makeEmbed({
|
|||
const thumbnailTrack = data.data.tracks?.find((track: { kind: string }) => track.kind === 'thumbnails')?.file;
|
||||
|
||||
return {
|
||||
stream: [
|
||||
{
|
||||
type: 'hls',
|
||||
id: 'primary',
|
||||
playlist: `https://proxy-m3u8.uira.live/m3u8-proxy?url=${data.data.sources[0].url}&headers=${encodeURIComponent(JSON.stringify(data.data.headers))}`,
|
||||
flags: [flags.CORS_ALLOWED],
|
||||
captions: [],
|
||||
...(thumbnailTrack
|
||||
? {
|
||||
thumbnailTrack: {
|
||||
type: 'vtt',
|
||||
url: thumbnailTrack,
|
||||
},
|
||||
}
|
||||
: {}),
|
||||
// headers: data.data.headers,
|
||||
},
|
||||
],
|
||||
// stream: [
|
||||
// {
|
||||
// type: 'hls',
|
||||
// type: 'file',
|
||||
// id: 'primary',
|
||||
// playlist: data.data.sources[0].url,
|
||||
// qualities: {
|
||||
// unknown: {
|
||||
// type: 'mp4',
|
||||
// url: data.data.sources[0].url,
|
||||
// },
|
||||
// },
|
||||
// flags: [flags.CORS_ALLOWED],
|
||||
// captions: [],
|
||||
// ...(thumbnailTrack
|
||||
|
|
@ -73,36 +96,13 @@ export const hianimeHd2DubEmbed = makeEmbed({
|
|||
// headers: data.data.headers,
|
||||
// },
|
||||
// ],
|
||||
stream: [
|
||||
{
|
||||
type: 'file',
|
||||
id: 'primary',
|
||||
qualities: {
|
||||
unknown: {
|
||||
type: 'mp4',
|
||||
url: data.data.sources[0].url,
|
||||
},
|
||||
},
|
||||
flags: [flags.CORS_ALLOWED],
|
||||
captions: [],
|
||||
...(thumbnailTrack
|
||||
? {
|
||||
thumbnailTrack: {
|
||||
type: 'vtt',
|
||||
url: thumbnailTrack,
|
||||
},
|
||||
}
|
||||
: {}),
|
||||
headers: data.data.headers,
|
||||
},
|
||||
],
|
||||
};
|
||||
},
|
||||
});
|
||||
|
||||
export const hianimeHd1SubEmbed = makeEmbed({
|
||||
id: 'hianime-hd1-sub',
|
||||
name: 'Hianime HD-1 (Sub)',
|
||||
name: 'HD-1 (Sub)',
|
||||
disabled: true,
|
||||
rank: 252,
|
||||
async scrape(ctx): Promise<EmbedOutput> {
|
||||
|
|
@ -140,7 +140,7 @@ export const hianimeHd1SubEmbed = makeEmbed({
|
|||
|
||||
export const hianimeHd2SubEmbed = makeEmbed({
|
||||
id: 'hianime-hd2-sub',
|
||||
name: 'Hianime HD-2 (Sub)',
|
||||
name: 'HD-2 (Sub)',
|
||||
rank: 253,
|
||||
async scrape(ctx): Promise<EmbedOutput> {
|
||||
const query = JSON.parse(ctx.url);
|
||||
|
|
@ -153,11 +153,34 @@ export const hianimeHd2SubEmbed = makeEmbed({
|
|||
const thumbnailTrack = data.data.tracks?.find((track: { kind: string }) => track.kind === 'thumbnails')?.file;
|
||||
|
||||
return {
|
||||
stream: [
|
||||
{
|
||||
type: 'hls',
|
||||
id: 'primary',
|
||||
playlist: `https://proxy-m3u8.uira.live/m3u8-proxy?url=${data.data.sources[0].url}&headers=${encodeURIComponent(JSON.stringify(data.data.headers))}`,
|
||||
flags: [flags.CORS_ALLOWED],
|
||||
captions: [],
|
||||
...(thumbnailTrack
|
||||
? {
|
||||
thumbnailTrack: {
|
||||
type: 'vtt',
|
||||
url: thumbnailTrack,
|
||||
},
|
||||
}
|
||||
: {}),
|
||||
// headers: data.data.headers,
|
||||
},
|
||||
],
|
||||
// stream: [
|
||||
// {
|
||||
// type: 'hls',
|
||||
// type: 'file',
|
||||
// id: 'primary',
|
||||
// playlist: data.data.sources[0].url,
|
||||
// qualities: {
|
||||
// unknown: {
|
||||
// type: 'mp4',
|
||||
// url: data.data.sources[0].url,
|
||||
// },
|
||||
// },
|
||||
// flags: [flags.CORS_ALLOWED],
|
||||
// captions: [],
|
||||
// ...(thumbnailTrack
|
||||
|
|
@ -171,29 +194,6 @@ export const hianimeHd2SubEmbed = makeEmbed({
|
|||
// headers: data.data.headers,
|
||||
// },
|
||||
// ],
|
||||
stream: [
|
||||
{
|
||||
type: 'file',
|
||||
id: 'primary',
|
||||
qualities: {
|
||||
unknown: {
|
||||
type: 'mp4',
|
||||
url: data.data.sources[0].url,
|
||||
},
|
||||
},
|
||||
flags: [flags.CORS_ALLOWED],
|
||||
captions: [],
|
||||
...(thumbnailTrack
|
||||
? {
|
||||
thumbnailTrack: {
|
||||
type: 'vtt',
|
||||
url: thumbnailTrack,
|
||||
},
|
||||
}
|
||||
: {}),
|
||||
headers: data.data.headers,
|
||||
},
|
||||
],
|
||||
};
|
||||
},
|
||||
});
|
||||
|
|
|
|||
|
|
@ -65,7 +65,7 @@ async function consumetScraper(ctx: ShowScrapeContext): Promise<SourcererOutput>
|
|||
|
||||
export const ConsumetScraper = makeSourcerer({
|
||||
id: 'consumet',
|
||||
name: 'Zoro (Anime)',
|
||||
name: 'Consumet (Anime)',
|
||||
rank: 4,
|
||||
flags: [flags.CORS_ALLOWED],
|
||||
scrapeShow: consumetScraper,
|
||||
|
|
|
|||
|
|
@ -1,6 +1,8 @@
|
|||
/* eslint-disable no-console */
|
||||
import { flags } from '@/entrypoint/utils/targets';
|
||||
import { SourcererOutput, makeSourcerer } from '@/providers/base';
|
||||
import { ShowScrapeContext } from '@/utils/context';
|
||||
import { NotFoundError } from '@/utils/errors';
|
||||
|
||||
interface HianimeSearchResult {
|
||||
success: boolean;
|
||||
|
|
@ -32,25 +34,59 @@ async function searchAnime(title: string): Promise<string> {
|
|||
throw new Error('Anime not found');
|
||||
}
|
||||
|
||||
// Return the ID of the first matching anime
|
||||
return data.data.animes[0].id;
|
||||
// Try to find exact match (case-insensitive)
|
||||
const match = data.data.animes.find((anime) => anime.name.toLowerCase() === title.toLowerCase());
|
||||
|
||||
// Return the matched ID or fallback to the first result
|
||||
return match?.id ?? data.data.animes[0].id;
|
||||
}
|
||||
|
||||
async function fetchTmdbSeasonEpisodes(tmdbShowId: string, seasonNumber: number): Promise<any[]> {
|
||||
const apiKey = '5b9790d9305dca8713b9a0afad42ea8d'; // plz dont abuse
|
||||
const response = await fetch(
|
||||
`https://api.themoviedb.org/3/tv/${tmdbShowId}/season/${seasonNumber}?api_key=${apiKey}`,
|
||||
);
|
||||
if (!response.ok) throw new NotFoundError('Failed to fetch season data from TMDB');
|
||||
const data = await response.json();
|
||||
return data.episodes; // each item has 'episode_number' and 'season_number'
|
||||
}
|
||||
|
||||
async function calculateAbsoluteEpisodeNumber(
|
||||
tmdbShowId: string,
|
||||
seasonNumber: number,
|
||||
episodeNumber: number,
|
||||
): Promise<number> {
|
||||
const previousSeasons = await Promise.all(
|
||||
Array.from({ length: seasonNumber - 1 }, (_, i) => fetchTmdbSeasonEpisodes(tmdbShowId, i + 1)),
|
||||
);
|
||||
|
||||
const episodesBefore = previousSeasons.reduce((sum, seasonEpisodes) => sum + seasonEpisodes.length, 0);
|
||||
|
||||
return episodesBefore + episodeNumber;
|
||||
}
|
||||
|
||||
async function fetchEpisodeData(animeId: string): Promise<HianimeEpisodeResult> {
|
||||
const response = await fetch(`https://hianime.pstream.org/api/v2/hianime/anime/${animeId}/episodes`);
|
||||
if (!response.ok) throw new Error('Failed to fetch episode data');
|
||||
if (!response.ok) throw new NotFoundError('Failed to fetch episode data');
|
||||
return response.json();
|
||||
}
|
||||
|
||||
async function comboScraper(ctx: ShowScrapeContext): Promise<SourcererOutput> {
|
||||
// First, search for the anime to get its Hianime ID
|
||||
const animeId = await searchAnime(ctx.media.title);
|
||||
// console.log(animeId);
|
||||
|
||||
const absoluteEp = await calculateAbsoluteEpisodeNumber(
|
||||
ctx.media.tmdbId,
|
||||
ctx.media.season.number,
|
||||
ctx.media.episode.number,
|
||||
);
|
||||
|
||||
// console.log(absoluteEp);
|
||||
|
||||
// Then, get the episode data
|
||||
const episodeData = await fetchEpisodeData(animeId);
|
||||
const episode = episodeData.data.episodes.find((ep) => ep.number === ctx.media.episode.number);
|
||||
|
||||
if (!episode) throw new Error('Episode not found');
|
||||
// console.log(episodeData);
|
||||
const episode = episodeData.data.episodes.find((ep) => ep.number === absoluteEp);
|
||||
if (!episode) throw new NotFoundError('Episode not found');
|
||||
|
||||
const embeds = [
|
||||
{
|
||||
|
|
@ -84,7 +120,7 @@ async function comboScraper(ctx: ShowScrapeContext): Promise<SourcererOutput> {
|
|||
|
||||
export const hianimeScraper = makeSourcerer({
|
||||
id: 'hianime',
|
||||
name: 'Hianime',
|
||||
name: 'Zoro (Anime)',
|
||||
rank: 7,
|
||||
disabled: false,
|
||||
flags: [flags.CORS_ALLOWED],
|
||||
|
|
|
|||
Loading…
Reference in a new issue