mirror of
https://github.com/p-stream/providers.git
synced 2026-05-08 03:49:57 +00:00
add consumet
add other emebeds remove headers update dont proxy and just use useragent revert no user agent
This commit is contained in:
parent
c8cffb6111
commit
4a28b23121
5 changed files with 282 additions and 0 deletions
|
|
@ -35,6 +35,12 @@ import {
|
|||
autoembedTeluguScraper,
|
||||
} from './embeds/autoembed';
|
||||
import { closeLoadScraper } from './embeds/closeload';
|
||||
import {
|
||||
ConsumetStreamSBScraper,
|
||||
ConsumetStreamTapeScraper,
|
||||
ConsumetVidCloudScraper,
|
||||
ConsumetVidStreamingScraper,
|
||||
} from './embeds/consumet';
|
||||
import { FedAPIPrivateScraper, FedDBScraper } from './embeds/fedapi';
|
||||
import { mp4hydraServer1Scraper, mp4hydraServer2Scraper } from './embeds/mp4hydra';
|
||||
import { ridooScraper } from './embeds/ridoo';
|
||||
|
|
@ -64,6 +70,7 @@ import { webtor1080Scraper, webtor480Scraper, webtor4kScraper, webtor720Scraper
|
|||
import { xprimeApolloEmbed, xprimeFoxEmbed, xprimeStreamboxEmbed } from './embeds/xprime';
|
||||
import { EightStreamScraper } from './sources/8stream';
|
||||
import { coitusScraper } from './sources/coitus';
|
||||
import { ConsumetScraper } from './sources/consumet';
|
||||
import { embedsuScraper } from './sources/embedsu';
|
||||
import { FedAPIScraper } from './sources/fedapi';
|
||||
import { hdRezkaScraper } from './sources/hdrezka';
|
||||
|
|
@ -109,6 +116,7 @@ export function gatherAllSources(): Array<Sourcerer> {
|
|||
riveScraper,
|
||||
EightStreamScraper,
|
||||
xprimeScraper,
|
||||
ConsumetScraper,
|
||||
];
|
||||
}
|
||||
|
||||
|
|
@ -169,5 +177,9 @@ export function gatherAllEmbeds(): Array<Embed> {
|
|||
xprimeFoxEmbed,
|
||||
xprimeApolloEmbed,
|
||||
xprimeStreamboxEmbed,
|
||||
ConsumetVidCloudScraper,
|
||||
ConsumetStreamSBScraper,
|
||||
ConsumetVidStreamingScraper,
|
||||
ConsumetStreamTapeScraper,
|
||||
];
|
||||
}
|
||||
|
|
|
|||
152
src/providers/embeds/consumet.ts
Normal file
152
src/providers/embeds/consumet.ts
Normal file
|
|
@ -0,0 +1,152 @@
|
|||
/* eslint-disable no-console */
|
||||
import { flags } from '@/entrypoint/utils/targets';
|
||||
import { EmbedOutput, makeEmbed } from '@/providers/base';
|
||||
import { NotFoundError } from '@/utils/errors';
|
||||
|
||||
import { Caption } from '../captions';
|
||||
|
||||
interface StreamData {
|
||||
headers: {
|
||||
Referer: string;
|
||||
Origin?: string;
|
||||
};
|
||||
intro: {
|
||||
start: number;
|
||||
end: number;
|
||||
};
|
||||
outro: {
|
||||
start: number;
|
||||
end: number;
|
||||
};
|
||||
sources: Array<{
|
||||
url: string;
|
||||
isM3U8: boolean;
|
||||
type: string;
|
||||
}>;
|
||||
subtitles: Array<{
|
||||
url: string;
|
||||
lang: string;
|
||||
}>;
|
||||
}
|
||||
|
||||
const providers = [
|
||||
{
|
||||
id: 'consumet-vidcloud',
|
||||
rank: 405,
|
||||
name: 'VidCloud',
|
||||
server: 'vidcloud',
|
||||
},
|
||||
{
|
||||
id: 'consumet-streamsb',
|
||||
rank: 404,
|
||||
name: 'StreamSB',
|
||||
server: 'streamsb',
|
||||
disabled: true,
|
||||
},
|
||||
{
|
||||
id: 'consumet-vidstreaming',
|
||||
rank: 403,
|
||||
name: 'VidStreaming',
|
||||
server: 'vidstreaming',
|
||||
disabled: true,
|
||||
},
|
||||
{
|
||||
id: 'consumet-streamtape',
|
||||
rank: 402,
|
||||
name: 'StreamTape',
|
||||
server: 'streamtape',
|
||||
disabled: true,
|
||||
},
|
||||
];
|
||||
|
||||
const languageMap: Record<string, string> = {
|
||||
English: 'en',
|
||||
Spanish: 'es',
|
||||
French: 'fr',
|
||||
German: 'de',
|
||||
Italian: 'it',
|
||||
Portuguese: 'pt',
|
||||
Arabic: 'ar',
|
||||
Russian: 'ru',
|
||||
Japanese: 'ja',
|
||||
Korean: 'ko',
|
||||
Chinese: 'zh',
|
||||
Hindi: 'hi',
|
||||
Turkish: 'tr',
|
||||
Dutch: 'nl',
|
||||
Polish: 'pl',
|
||||
Swedish: 'sv',
|
||||
Indonesian: 'id',
|
||||
Thai: 'th',
|
||||
Vietnamese: 'vi',
|
||||
};
|
||||
|
||||
function embed(provider: { id: string; rank: number; name: string; server: string; disabled?: boolean }) {
|
||||
return makeEmbed({
|
||||
id: provider.id,
|
||||
name: provider.name,
|
||||
rank: provider.rank,
|
||||
disabled: provider.disabled,
|
||||
async scrape(ctx): Promise<EmbedOutput> {
|
||||
const query = JSON.parse(ctx.url);
|
||||
const apiUrl = `https://consumet.pstream.org/anime/zoro/watch?episodeId=${query.episodeId}&server=${provider.server}`;
|
||||
|
||||
const data = await ctx.fetcher<StreamData>(apiUrl);
|
||||
|
||||
if (!data?.sources?.length) {
|
||||
throw new NotFoundError('No stream found');
|
||||
}
|
||||
|
||||
ctx.progress(50);
|
||||
|
||||
const captions: Caption[] = data.subtitles
|
||||
.filter((sub) => sub.lang !== 'thumbnails')
|
||||
.map((sub) => ({
|
||||
type: 'vtt',
|
||||
id: sub.url,
|
||||
url: sub.url,
|
||||
language: languageMap[sub.lang] || 'unknown',
|
||||
hasCorsRestrictions: false,
|
||||
}));
|
||||
|
||||
const streams = data.sources.reduce(
|
||||
(acc, source) => {
|
||||
if (source.isM3U8) {
|
||||
acc.unknown = source.url;
|
||||
}
|
||||
return acc;
|
||||
},
|
||||
{} as Record<string, string>,
|
||||
);
|
||||
|
||||
const thumbnailTrack = data.subtitles.find((sub) => sub.lang === 'thumbnails');
|
||||
|
||||
ctx.progress(90);
|
||||
|
||||
return {
|
||||
stream: [
|
||||
{
|
||||
id: 'primary',
|
||||
captions,
|
||||
playlist: `https://proxy.fifthwit.net/m3u8-proxy?url=${encodeURIComponent(streams.unknown)}&headers=${encodeURIComponent(JSON.stringify({ ...(data.headers.Referer && { referer: data.headers.Referer }), ...(data.headers.Origin && { origin: data.headers.Origin }) }))}`,
|
||||
type: 'hls',
|
||||
flags: [flags.CORS_ALLOWED],
|
||||
...(thumbnailTrack && {
|
||||
thumbnailTrack: {
|
||||
type: 'vtt',
|
||||
url: thumbnailTrack.url,
|
||||
},
|
||||
}),
|
||||
},
|
||||
],
|
||||
};
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
export const [
|
||||
ConsumetVidCloudScraper,
|
||||
ConsumetStreamSBScraper,
|
||||
ConsumetVidStreamingScraper,
|
||||
ConsumetStreamTapeScraper,
|
||||
] = providers.map(embed);
|
||||
72
src/providers/sources/consumet/index.ts
Normal file
72
src/providers/sources/consumet/index.ts
Normal file
|
|
@ -0,0 +1,72 @@
|
|||
import { flags } from '@/entrypoint/utils/targets';
|
||||
import { SourcererOutput, makeSourcerer } from '@/providers/base';
|
||||
import { ShowScrapeContext } from '@/utils/context';
|
||||
|
||||
import { InfoResponse, SearchResponse } from './types';
|
||||
|
||||
async function consumetScraper(ctx: ShowScrapeContext): Promise<SourcererOutput> {
|
||||
// Search
|
||||
const searchQuery = ctx.media.title;
|
||||
const page = 1;
|
||||
|
||||
const searchUrl = `https://consumet.pstream.org/anime/zoro/${encodeURIComponent(searchQuery)}?page=${page}`;
|
||||
const searchResponse = await ctx.fetcher<SearchResponse>(searchUrl);
|
||||
|
||||
if (!searchResponse?.results?.length) {
|
||||
throw new Error('No results found');
|
||||
}
|
||||
|
||||
const bestMatch =
|
||||
searchResponse.results.find((result) => result.title.toLowerCase() === ctx.media.title.toLowerCase()) ||
|
||||
searchResponse.results[0];
|
||||
|
||||
// Get episode list
|
||||
const infoUrl = `https://consumet.pstream.org/anime/zoro/info?id=${bestMatch.id}`;
|
||||
const infoResponse = await ctx.fetcher<InfoResponse>(infoUrl);
|
||||
|
||||
if (!infoResponse?.episodes?.length) {
|
||||
throw new Error('No episodes found');
|
||||
}
|
||||
|
||||
const targetEpisode = infoResponse.episodes.find((ep) => ep.number === ctx.media.episode.number);
|
||||
|
||||
if (!targetEpisode) {
|
||||
throw new Error('Episode not found');
|
||||
}
|
||||
|
||||
// Parse embeds
|
||||
const query = {
|
||||
episodeId: `${bestMatch.id}$${ctx.media.season.number}$${targetEpisode.id}$both`,
|
||||
};
|
||||
|
||||
const embeds = [
|
||||
{
|
||||
embedId: 'consumet-vidcloud',
|
||||
url: JSON.stringify({ ...query, server: 'vidcloud' }),
|
||||
},
|
||||
{
|
||||
embedId: 'consumet-streamsb',
|
||||
url: JSON.stringify({ ...query, server: 'streamsb' }),
|
||||
},
|
||||
{
|
||||
embedId: 'consumet-vidstreaming',
|
||||
url: JSON.stringify({ ...query, server: 'vidstreaming' }),
|
||||
},
|
||||
{
|
||||
embedId: 'consumet-streamtape',
|
||||
url: JSON.stringify({ ...query, server: 'streamtape' }),
|
||||
},
|
||||
];
|
||||
|
||||
return {
|
||||
embeds,
|
||||
};
|
||||
}
|
||||
|
||||
export const ConsumetScraper = makeSourcerer({
|
||||
id: 'consumet',
|
||||
name: 'Zoro (Anime)',
|
||||
rank: 4,
|
||||
flags: [flags.CORS_ALLOWED],
|
||||
scrapeShow: consumetScraper,
|
||||
});
|
||||
36
src/providers/sources/consumet/types.ts
Normal file
36
src/providers/sources/consumet/types.ts
Normal file
|
|
@ -0,0 +1,36 @@
|
|||
export interface SearchResult {
|
||||
id: string;
|
||||
title: string;
|
||||
image: string;
|
||||
releaseDate: string | null;
|
||||
subOrDub: 'sub' | 'dub';
|
||||
}
|
||||
|
||||
export interface SearchResponse {
|
||||
totalPages: number;
|
||||
currentPage: number;
|
||||
hasNextPage: boolean;
|
||||
results: SearchResult[];
|
||||
}
|
||||
|
||||
export interface Episode {
|
||||
id: string;
|
||||
number: number;
|
||||
url: string;
|
||||
}
|
||||
|
||||
export interface InfoResponse {
|
||||
id: string;
|
||||
title: string;
|
||||
url: string;
|
||||
image: string;
|
||||
releaseDate: string | null;
|
||||
description: string | null;
|
||||
genres: string[];
|
||||
subOrDub: 'sub' | 'dub';
|
||||
type: string | null;
|
||||
status: string;
|
||||
otherName: string | null;
|
||||
totalEpisodes: number;
|
||||
episodes: Episode[];
|
||||
}
|
||||
|
|
@ -1,5 +1,11 @@
|
|||
// import { alphaScraper, deltaScraper } from '@/providers/embeds/nsbx';
|
||||
// import { astraScraper, novaScraper, orionScraper } from '@/providers/embeds/whvx';
|
||||
import {
|
||||
ConsumetStreamSBScraper,
|
||||
ConsumetStreamTapeScraper,
|
||||
ConsumetVidCloudScraper,
|
||||
ConsumetVidStreamingScraper,
|
||||
} from '@/providers/embeds/consumet';
|
||||
import { FedAPIPrivateScraper, FedDBScraper } from '@/providers/embeds/fedapi';
|
||||
import { warezcdnembedMp4Scraper } from '@/providers/embeds/warezcdn/mp4';
|
||||
import { xprimeApolloEmbed, xprimeFoxEmbed, xprimeStreamboxEmbed } from '@/providers/embeds/xprime';
|
||||
|
|
@ -23,6 +29,10 @@ const SKIP_VALIDATION_CHECK_IDS = [
|
|||
xprimeFoxEmbed.id,
|
||||
xprimeApolloEmbed.id,
|
||||
xprimeStreamboxEmbed.id,
|
||||
ConsumetVidCloudScraper.id,
|
||||
ConsumetStreamSBScraper.id,
|
||||
ConsumetVidStreamingScraper.id,
|
||||
ConsumetStreamTapeScraper.id,
|
||||
];
|
||||
|
||||
export function isValidStream(stream: Stream | undefined): boolean {
|
||||
|
|
|
|||
Loading…
Reference in a new issue