mirror of
https://github.com/p-stream/providers.git
synced 2026-03-11 17:55:36 +00:00
update zunime
This commit is contained in:
parent
897d16450d
commit
c6f259bd3d
3 changed files with 57 additions and 82 deletions
|
|
@ -61,6 +61,7 @@ import { viperScraper } from './embeds/viper';
|
||||||
import { warezcdnembedHlsScraper } from './embeds/warezcdn/hls';
|
import { warezcdnembedHlsScraper } from './embeds/warezcdn/hls';
|
||||||
import { warezcdnembedMp4Scraper } from './embeds/warezcdn/mp4';
|
import { warezcdnembedMp4Scraper } from './embeds/warezcdn/mp4';
|
||||||
import { warezPlayerScraper } from './embeds/warezcdn/warezplayer';
|
import { warezPlayerScraper } from './embeds/warezcdn/warezplayer';
|
||||||
|
import { zunimeEmbeds } from './embeds/zunime';
|
||||||
import { EightStreamScraper } from './sources/8stream';
|
import { EightStreamScraper } from './sources/8stream';
|
||||||
import { animeflvScraper } from './sources/animeflv';
|
import { animeflvScraper } from './sources/animeflv';
|
||||||
import { cinemaosScraper } from './sources/cinemaos';
|
import { cinemaosScraper } from './sources/cinemaos';
|
||||||
|
|
@ -81,6 +82,7 @@ import { vidapiClickScraper } from './sources/vidapiclick';
|
||||||
import { vidifyScraper } from './sources/vidify';
|
import { vidifyScraper } from './sources/vidify';
|
||||||
import { warezcdnScraper } from './sources/warezcdn';
|
import { warezcdnScraper } from './sources/warezcdn';
|
||||||
import { wecimaScraper } from './sources/wecima';
|
import { wecimaScraper } from './sources/wecima';
|
||||||
|
import { zunimeScraper } from './sources/zunime';
|
||||||
|
|
||||||
export function gatherAllSources(): Array<Sourcerer> {
|
export function gatherAllSources(): Array<Sourcerer> {
|
||||||
// all sources are gathered here
|
// all sources are gathered here
|
||||||
|
|
@ -119,6 +121,7 @@ export function gatherAllSources(): Array<Sourcerer> {
|
||||||
rgshowsScraper,
|
rgshowsScraper,
|
||||||
vidifyScraper,
|
vidifyScraper,
|
||||||
rivestreamScraper,
|
rivestreamScraper,
|
||||||
|
zunimeScraper,
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -174,5 +177,6 @@ export function gatherAllEmbeds(): Array<Embed> {
|
||||||
madplayNsapiVidFastEmbed,
|
madplayNsapiVidFastEmbed,
|
||||||
...vidifyEmbeds,
|
...vidifyEmbeds,
|
||||||
...rivestreamEmbeds,
|
...rivestreamEmbeds,
|
||||||
|
...zunimeEmbeds,
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,70 +1,8 @@
|
||||||
/* eslint-disable no-console */
|
|
||||||
import { flags } from '@/entrypoint/utils/targets';
|
|
||||||
import { NotFoundError } from '@/utils/errors';
|
import { NotFoundError } from '@/utils/errors';
|
||||||
// import { createM3U8ProxyUrl } from '@/utils/proxy';
|
|
||||||
|
|
||||||
import { EmbedOutput, makeEmbed } from '../base';
|
import { EmbedOutput, makeEmbed } from '../base';
|
||||||
|
|
||||||
const ZUNIME_SERVERS = ['hd-2', 'miko', 'shiro', 'zaza'] as const;
|
const ZUNIME_SERVERS = ['hd-2', 'miko', 'shiro', 'zaza'];
|
||||||
|
|
||||||
const M3U8_URL_REGEX = /https?:\/\/[^\s"'<>]+?\.m3u8[^\s"'<>]*/i;
|
|
||||||
|
|
||||||
function extractFromString(input: string): string | null {
|
|
||||||
const match = input.match(M3U8_URL_REGEX);
|
|
||||||
return match ? match[0] : null;
|
|
||||||
}
|
|
||||||
|
|
||||||
function findFirstM3U8Url(input: unknown): string | null {
|
|
||||||
// eslint-disable-next-line no-console
|
|
||||||
console.log(input);
|
|
||||||
const visited = new Set<unknown>();
|
|
||||||
|
|
||||||
function dfs(node: unknown): string | null {
|
|
||||||
if (node == null) return null;
|
|
||||||
if (visited.has(node)) return null;
|
|
||||||
if (typeof node === 'object') visited.add(node);
|
|
||||||
|
|
||||||
if (typeof node === 'string') return extractFromString(node);
|
|
||||||
|
|
||||||
if (Array.isArray(node)) {
|
|
||||||
for (const element of node) {
|
|
||||||
const found = dfs(element);
|
|
||||||
if (found) return found;
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (typeof node === 'object') {
|
|
||||||
for (const value of Object.values(node as Record<string, unknown>)) {
|
|
||||||
if (typeof value === 'string') {
|
|
||||||
const foundInString = extractFromString(value);
|
|
||||||
if (foundInString) return foundInString;
|
|
||||||
} else {
|
|
||||||
const found = dfs(value);
|
|
||||||
if (found) return found;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
return dfs(input);
|
|
||||||
}
|
|
||||||
|
|
||||||
function getFirstM3U8FromSources(sources: any): string | null {
|
|
||||||
if (Array.isArray(sources)) {
|
|
||||||
for (const source of sources) {
|
|
||||||
if (typeof source?.url === 'string' && source.url.includes('.m3u8')) {
|
|
||||||
return source.url;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
if (typeof sources?.url === 'string' && sources.url.includes('.m3u8')) {
|
|
||||||
return sources.url;
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
const baseUrl = 'https://backend.xaiby.sbs';
|
const baseUrl = 'https://backend.xaiby.sbs';
|
||||||
const headers = {
|
const headers = {
|
||||||
|
|
@ -83,9 +21,7 @@ export function makeZunimeEmbed(id: string, rank: number = 100) {
|
||||||
const serverName = id as (typeof ZUNIME_SERVERS)[number];
|
const serverName = id as (typeof ZUNIME_SERVERS)[number];
|
||||||
|
|
||||||
const query = JSON.parse(ctx.url);
|
const query = JSON.parse(ctx.url);
|
||||||
const { type, malId, episode } = query;
|
const { malId, episode } = query;
|
||||||
|
|
||||||
if (type !== 'movie' && type !== 'show') throw new NotFoundError('Unsupported media type');
|
|
||||||
|
|
||||||
const res = await ctx.proxiedFetcher(`${'/sources'}`, {
|
const res = await ctx.proxiedFetcher(`${'/sources'}`, {
|
||||||
baseUrl,
|
baseUrl,
|
||||||
|
|
@ -98,21 +34,16 @@ export function makeZunimeEmbed(id: string, rank: number = 100) {
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
console.log('Zunime API Response:', JSON.stringify(res, null, 2));
|
|
||||||
const resAny: any = res as any;
|
const resAny: any = res as any;
|
||||||
|
|
||||||
const playlistUrl: string | null =
|
if (!resAny?.success || !resAny?.sources?.url) {
|
||||||
getFirstM3U8FromSources(resAny?.sources) ??
|
throw new NotFoundError('No stream URL found in response');
|
||||||
(typeof resAny?.url === 'string' && resAny.url.includes('.m3u8') ? resAny.url : null) ??
|
}
|
||||||
findFirstM3U8Url(resAny);
|
|
||||||
|
|
||||||
console.log('Extracted playlistUrl:', playlistUrl); // silly debugging heheh
|
|
||||||
|
|
||||||
|
const streamUrl = resAny.sources.url;
|
||||||
const upstreamHeaders: Record<string, string> =
|
const upstreamHeaders: Record<string, string> =
|
||||||
resAny?.sources?.headers && Object.keys(resAny.sources.headers).length > 0 ? resAny.sources.headers : headers;
|
resAny?.sources?.headers && Object.keys(resAny.sources.headers).length > 0 ? resAny.sources.headers : headers;
|
||||||
|
|
||||||
if (!playlistUrl) throw new NotFoundError('No playlist URL found');
|
|
||||||
|
|
||||||
ctx.progress(100);
|
ctx.progress(100);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
|
@ -120,9 +51,9 @@ export function makeZunimeEmbed(id: string, rank: number = 100) {
|
||||||
{
|
{
|
||||||
id: 'primary',
|
id: 'primary',
|
||||||
type: 'hls',
|
type: 'hls',
|
||||||
playlist: `https://proxy-2.madaraverse.online/proxy?url=${encodeURIComponent(playlistUrl)}`,
|
playlist: `https://proxy-2.madaraverse.online/proxy?url=${encodeURIComponent(streamUrl)}`,
|
||||||
headers: upstreamHeaders,
|
headers: upstreamHeaders,
|
||||||
flags: [flags.CORS_ALLOWED],
|
flags: [],
|
||||||
captions: [],
|
captions: [],
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,50 @@
|
||||||
import { flags } from '@/entrypoint/utils/targets';
|
import { SourcererOutput, makeSourcerer } from '@/providers/base';
|
||||||
import { makeMalSource } from '@/providers/sources/_helpers/mal';
|
import { MovieScrapeContext, ShowScrapeContext } from '@/utils/context';
|
||||||
|
import { getMalIdFromMedia } from '@/utils/mal';
|
||||||
|
|
||||||
export const zunimeScraper = makeMalSource({
|
async function comboScraper(ctx: ShowScrapeContext | MovieScrapeContext): Promise<SourcererOutput> {
|
||||||
|
const malId = await getMalIdFromMedia(ctx, ctx.media);
|
||||||
|
|
||||||
|
const query: any = {
|
||||||
|
type: ctx.media.type,
|
||||||
|
title: ctx.media.title,
|
||||||
|
tmdbId: ctx.media.tmdbId,
|
||||||
|
imdbId: ctx.media.imdbId,
|
||||||
|
malId,
|
||||||
|
...(ctx.media.type === 'show' && {
|
||||||
|
season: ctx.media.season.number,
|
||||||
|
episode: ctx.media.episode.number,
|
||||||
|
}),
|
||||||
|
...(ctx.media.type === 'movie' && { episode: 1 }),
|
||||||
|
releaseYear: ctx.media.releaseYear,
|
||||||
|
};
|
||||||
|
|
||||||
|
return {
|
||||||
|
embeds: [
|
||||||
|
{
|
||||||
|
embedId: 'zunime-hd-2',
|
||||||
|
url: JSON.stringify(query),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
embedId: 'zunime-miko',
|
||||||
|
url: JSON.stringify(query),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
embedId: 'zunime-shiro',
|
||||||
|
url: JSON.stringify(query),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
embedId: 'zunime-zaza',
|
||||||
|
url: JSON.stringify(query),
|
||||||
|
},
|
||||||
|
],
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export const zunimeScraper = makeSourcerer({
|
||||||
id: 'zunime',
|
id: 'zunime',
|
||||||
name: 'Zunime',
|
name: 'Zunime',
|
||||||
rank: 125,
|
rank: 125,
|
||||||
embedIds: ['zunime-hd-2', 'zunime-miko', 'zunime-shiro', 'zunime-zaza'],
|
flags: [],
|
||||||
flags: [flags.CORS_ALLOWED],
|
scrapeShow: comboScraper,
|
||||||
});
|
});
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue