mirror of
https://github.com/p-stream/providers.git
synced 2026-04-20 18:32:09 +00:00
add hianime
enable cors for all Update hianime.ts Update valid.ts
This commit is contained in:
parent
4a28b23121
commit
f64582f5b6
4 changed files with 313 additions and 0 deletions
|
|
@ -1,5 +1,11 @@
|
|||
import { Embed, Sourcerer } from '@/providers/base';
|
||||
import { doodScraper } from '@/providers/embeds/dood';
|
||||
import {
|
||||
hianimeHd1DubEmbed,
|
||||
hianimeHd1SubEmbed,
|
||||
hianimeHd2DubEmbed,
|
||||
hianimeHd2SubEmbed,
|
||||
} from '@/providers/embeds/hianime';
|
||||
import { mixdropScraper } from '@/providers/embeds/mixdrop';
|
||||
import {
|
||||
riveAsiacloudScraper,
|
||||
|
|
@ -21,6 +27,7 @@ import { autoembedScraper } from '@/providers/sources/autoembed';
|
|||
import { catflixScraper } from '@/providers/sources/catflix';
|
||||
import { ee3Scraper } from '@/providers/sources/ee3';
|
||||
import { fsharetvScraper } from '@/providers/sources/fsharetv';
|
||||
import { hianimeScraper } from '@/providers/sources/hianime';
|
||||
import { insertunitScraper } from '@/providers/sources/insertunit';
|
||||
import { mp4hydraScraper } from '@/providers/sources/mp4hydra';
|
||||
import { riveScraper } from '@/providers/sources/rive';
|
||||
|
|
@ -117,6 +124,7 @@ export function gatherAllSources(): Array<Sourcerer> {
|
|||
EightStreamScraper,
|
||||
xprimeScraper,
|
||||
ConsumetScraper,
|
||||
hianimeScraper,
|
||||
];
|
||||
}
|
||||
|
||||
|
|
@ -181,5 +189,9 @@ export function gatherAllEmbeds(): Array<Embed> {
|
|||
ConsumetStreamSBScraper,
|
||||
ConsumetVidStreamingScraper,
|
||||
ConsumetStreamTapeScraper,
|
||||
hianimeHd1DubEmbed,
|
||||
hianimeHd2DubEmbed,
|
||||
hianimeHd1SubEmbed,
|
||||
hianimeHd2SubEmbed,
|
||||
];
|
||||
}
|
||||
|
|
|
|||
199
src/providers/embeds/hianime.ts
Normal file
199
src/providers/embeds/hianime.ts
Normal file
|
|
@ -0,0 +1,199 @@
|
|||
import { flags } from '@/entrypoint/utils/targets';
|
||||
import { EmbedOutput, makeEmbed } from '@/providers/base';
|
||||
import { NotFoundError } from '@/utils/errors';
|
||||
|
||||
export const hianimeHd1DubEmbed = makeEmbed({
|
||||
id: 'hianime-hd1-dub',
|
||||
name: 'Hianime HD-1 (Dub)',
|
||||
disabled: true,
|
||||
rank: 250,
|
||||
async scrape(ctx): Promise<EmbedOutput> {
|
||||
const query = JSON.parse(ctx.url);
|
||||
const url = `https://hianime.pstream.org/api/v2/hianime/episode/sources?animeEpisodeId=${query.episodeId}&server=hd-1&category=dub`;
|
||||
|
||||
const data = await ctx.fetcher(url);
|
||||
if (!data) throw new NotFoundError('No response received');
|
||||
if (!data.data?.sources?.[0]?.url) throw new NotFoundError('No stream URL found in response');
|
||||
|
||||
const thumbnailTrack = data.data.tracks?.find((track: { kind: string }) => track.kind === 'thumbnails')?.file;
|
||||
|
||||
return {
|
||||
stream: [
|
||||
{
|
||||
type: 'hls',
|
||||
id: 'primary',
|
||||
playlist: data.data.sources[0].url,
|
||||
flags: [flags.CORS_ALLOWED],
|
||||
captions: [],
|
||||
...(thumbnailTrack
|
||||
? {
|
||||
thumbnailTrack: {
|
||||
type: 'vtt',
|
||||
url: thumbnailTrack,
|
||||
},
|
||||
}
|
||||
: {}),
|
||||
headers: data.data.headers,
|
||||
},
|
||||
],
|
||||
};
|
||||
},
|
||||
});
|
||||
|
||||
export const hianimeHd2DubEmbed = makeEmbed({
|
||||
id: 'hianime-hd2-dub',
|
||||
name: 'Hianime HD-2 (Dub)',
|
||||
rank: 251,
|
||||
async scrape(ctx): Promise<EmbedOutput> {
|
||||
const query = JSON.parse(ctx.url);
|
||||
const url = `https://hianime.pstream.org/api/v2/hianime/episode/sources?animeEpisodeId=${query.episodeId}&server=hd-2&category=dub`;
|
||||
|
||||
const data = await ctx.fetcher(url);
|
||||
if (!data) throw new NotFoundError('No response received');
|
||||
if (!data.data?.sources?.[0]?.url) throw new NotFoundError('No stream URL found in response');
|
||||
|
||||
const thumbnailTrack = data.data.tracks?.find((track: { kind: string }) => track.kind === 'thumbnails')?.file;
|
||||
|
||||
return {
|
||||
// stream: [
|
||||
// {
|
||||
// type: 'hls',
|
||||
// id: 'primary',
|
||||
// playlist: data.data.sources[0].url,
|
||||
// flags: [flags.CORS_ALLOWED],
|
||||
// captions: [],
|
||||
// ...(thumbnailTrack
|
||||
// ? {
|
||||
// thumbnailTrack: {
|
||||
// type: 'vtt',
|
||||
// url: thumbnailTrack,
|
||||
// },
|
||||
// }
|
||||
// : {}),
|
||||
// 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)',
|
||||
disabled: true,
|
||||
rank: 252,
|
||||
async scrape(ctx): Promise<EmbedOutput> {
|
||||
const query = JSON.parse(ctx.url);
|
||||
const url = `https://hianime.pstream.org/api/v2/hianime/episode/sources?animeEpisodeId=${query.episodeId}&server=hd-1&category=sub`;
|
||||
|
||||
const data = await ctx.fetcher(url);
|
||||
if (!data) throw new NotFoundError('No response received');
|
||||
if (!data.data?.sources?.[0]?.url) throw new NotFoundError('No stream URL found in response');
|
||||
|
||||
const thumbnailTrack = data.data.tracks?.find((track: { kind: string }) => track.kind === 'thumbnails')?.file;
|
||||
|
||||
return {
|
||||
stream: [
|
||||
{
|
||||
type: 'hls',
|
||||
id: 'primary',
|
||||
playlist: data.data.sources[0].url,
|
||||
flags: [flags.CORS_ALLOWED],
|
||||
captions: [],
|
||||
...(thumbnailTrack
|
||||
? {
|
||||
thumbnailTrack: {
|
||||
type: 'vtt',
|
||||
url: thumbnailTrack,
|
||||
},
|
||||
}
|
||||
: {}),
|
||||
headers: data.data.headers,
|
||||
},
|
||||
],
|
||||
};
|
||||
},
|
||||
});
|
||||
|
||||
export const hianimeHd2SubEmbed = makeEmbed({
|
||||
id: 'hianime-hd2-sub',
|
||||
name: 'Hianime HD-2 (Sub)',
|
||||
rank: 253,
|
||||
async scrape(ctx): Promise<EmbedOutput> {
|
||||
const query = JSON.parse(ctx.url);
|
||||
const url = `https://hianime.pstream.org/api/v2/hianime/episode/sources?animeEpisodeId=${query.episodeId}&server=hd-2&category=sub`;
|
||||
|
||||
const data = await ctx.fetcher(url);
|
||||
if (!data) throw new NotFoundError('No response received');
|
||||
if (!data.data?.sources?.[0]?.url) throw new NotFoundError('No stream URL found in response');
|
||||
|
||||
const thumbnailTrack = data.data.tracks?.find((track: { kind: string }) => track.kind === 'thumbnails')?.file;
|
||||
|
||||
return {
|
||||
// stream: [
|
||||
// {
|
||||
// type: 'hls',
|
||||
// id: 'primary',
|
||||
// playlist: data.data.sources[0].url,
|
||||
// flags: [flags.CORS_ALLOWED],
|
||||
// captions: [],
|
||||
// ...(thumbnailTrack
|
||||
// ? {
|
||||
// thumbnailTrack: {
|
||||
// type: 'vtt',
|
||||
// url: thumbnailTrack,
|
||||
// },
|
||||
// }
|
||||
// : {}),
|
||||
// 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,
|
||||
},
|
||||
],
|
||||
};
|
||||
},
|
||||
});
|
||||
92
src/providers/sources/hianime.ts
Normal file
92
src/providers/sources/hianime.ts
Normal file
|
|
@ -0,0 +1,92 @@
|
|||
import { flags } from '@/entrypoint/utils/targets';
|
||||
import { SourcererOutput, makeSourcerer } from '@/providers/base';
|
||||
import { ShowScrapeContext } from '@/utils/context';
|
||||
|
||||
interface HianimeSearchResult {
|
||||
success: boolean;
|
||||
data: {
|
||||
animes: Array<{
|
||||
id: string;
|
||||
name: string;
|
||||
}>;
|
||||
};
|
||||
}
|
||||
|
||||
interface HianimeEpisodeResult {
|
||||
success: boolean;
|
||||
data: {
|
||||
episodes: Array<{
|
||||
number: number;
|
||||
title: string;
|
||||
episodeId: string;
|
||||
}>;
|
||||
};
|
||||
}
|
||||
|
||||
async function searchAnime(title: string): Promise<string> {
|
||||
const response = await fetch(`https://hianime.pstream.org/api/v2/hianime/search?q=${encodeURIComponent(title)}`);
|
||||
if (!response.ok) throw new Error('Failed to search anime');
|
||||
const data: HianimeSearchResult = await response.json();
|
||||
|
||||
if (!data.success || !data.data.animes.length) {
|
||||
throw new Error('Anime not found');
|
||||
}
|
||||
|
||||
// Return the ID of the first matching anime
|
||||
return data.data.animes[0].id;
|
||||
}
|
||||
|
||||
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');
|
||||
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);
|
||||
|
||||
// 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');
|
||||
|
||||
const embeds = [
|
||||
{
|
||||
embedId: 'hianime-hd1-dub',
|
||||
url: JSON.stringify({
|
||||
episodeId: episode.episodeId,
|
||||
}),
|
||||
},
|
||||
{
|
||||
embedId: 'hianime-hd2-dub',
|
||||
url: JSON.stringify({
|
||||
episodeId: episode.episodeId,
|
||||
}),
|
||||
},
|
||||
{
|
||||
embedId: 'hianime-hd1-sub',
|
||||
url: JSON.stringify({
|
||||
episodeId: episode.episodeId,
|
||||
}),
|
||||
},
|
||||
{
|
||||
embedId: 'hianime-hd2-sub',
|
||||
url: JSON.stringify({
|
||||
episodeId: episode.episodeId,
|
||||
}),
|
||||
},
|
||||
];
|
||||
|
||||
return { embeds };
|
||||
}
|
||||
|
||||
export const hianimeScraper = makeSourcerer({
|
||||
id: 'hianime',
|
||||
name: 'Hianime',
|
||||
rank: 7,
|
||||
disabled: false,
|
||||
flags: [flags.CORS_ALLOWED],
|
||||
scrapeShow: comboScraper,
|
||||
});
|
||||
|
|
@ -7,6 +7,12 @@ import {
|
|||
ConsumetVidStreamingScraper,
|
||||
} from '@/providers/embeds/consumet';
|
||||
import { FedAPIPrivateScraper, FedDBScraper } from '@/providers/embeds/fedapi';
|
||||
import {
|
||||
hianimeHd1DubEmbed,
|
||||
hianimeHd1SubEmbed,
|
||||
hianimeHd2DubEmbed,
|
||||
hianimeHd2SubEmbed,
|
||||
} from '@/providers/embeds/hianime';
|
||||
import { warezcdnembedMp4Scraper } from '@/providers/embeds/warezcdn/mp4';
|
||||
import { xprimeApolloEmbed, xprimeFoxEmbed, xprimeStreamboxEmbed } from '@/providers/embeds/xprime';
|
||||
import { embedsuScraper } from '@/providers/sources/embedsu';
|
||||
|
|
@ -33,6 +39,10 @@ const SKIP_VALIDATION_CHECK_IDS = [
|
|||
ConsumetStreamSBScraper.id,
|
||||
ConsumetVidStreamingScraper.id,
|
||||
ConsumetStreamTapeScraper.id,
|
||||
hianimeHd1DubEmbed.id,
|
||||
hianimeHd1SubEmbed.id,
|
||||
hianimeHd2DubEmbed.id,
|
||||
hianimeHd2SubEmbed.id,
|
||||
];
|
||||
|
||||
export function isValidStream(stream: Stream | undefined): boolean {
|
||||
|
|
|
|||
Loading…
Reference in a new issue