mirror of
https://github.com/p-stream/providers.git
synced 2026-04-21 07:42:22 +00:00
add 8stream
This commit is contained in:
parent
cf7c449d54
commit
995bbfde5c
5 changed files with 263 additions and 0 deletions
|
|
@ -61,6 +61,7 @@ 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 { webtor1080Scraper, webtor480Scraper, webtor4kScraper, webtor720Scraper } from './embeds/webtor';
|
import { webtor1080Scraper, webtor480Scraper, webtor4kScraper, webtor720Scraper } from './embeds/webtor';
|
||||||
|
import { EightStreamScraper } from './sources/8stream';
|
||||||
import { coitusScraper } from './sources/coitus';
|
import { coitusScraper } from './sources/coitus';
|
||||||
import { embedsuScraper } from './sources/embedsu';
|
import { embedsuScraper } from './sources/embedsu';
|
||||||
import { FedAPIScraper } from './sources/fedapi';
|
import { FedAPIScraper } from './sources/fedapi';
|
||||||
|
|
@ -104,6 +105,7 @@ export function gatherAllSources(): Array<Sourcerer> {
|
||||||
streamboxScraper,
|
streamboxScraper,
|
||||||
nunflixScraper,
|
nunflixScraper,
|
||||||
riveScraper,
|
riveScraper,
|
||||||
|
EightStreamScraper,
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
85
src/providers/sources/8stream/8Stream.ts
Normal file
85
src/providers/sources/8stream/8Stream.ts
Normal file
|
|
@ -0,0 +1,85 @@
|
||||||
|
import { MovieScrapeContext, ShowScrapeContext } from '@/utils/context';
|
||||||
|
import { NotFoundError } from '@/utils/errors';
|
||||||
|
|
||||||
|
import getInfo from './getInfo';
|
||||||
|
import getStream from './getStream';
|
||||||
|
|
||||||
|
export async function getMovie(ctx: ShowScrapeContext | MovieScrapeContext, id: string, lang: string = 'English') {
|
||||||
|
try {
|
||||||
|
const mediaInfo = await getInfo(ctx, id);
|
||||||
|
if (mediaInfo?.success) {
|
||||||
|
const playlist = mediaInfo?.data?.playlist;
|
||||||
|
if (!playlist || !Array.isArray(playlist)) {
|
||||||
|
throw new NotFoundError('Playlist not found or invalid');
|
||||||
|
}
|
||||||
|
let file = playlist.find((item: any) => item?.title === lang);
|
||||||
|
if (!file) {
|
||||||
|
file = playlist?.[0];
|
||||||
|
}
|
||||||
|
if (!file) {
|
||||||
|
throw new NotFoundError('No file found');
|
||||||
|
}
|
||||||
|
const availableLang = playlist.map((item: any) => item?.title);
|
||||||
|
const key = mediaInfo?.data?.key;
|
||||||
|
ctx.progress(70);
|
||||||
|
const streamUrl = await getStream(ctx, file?.file, key);
|
||||||
|
if (streamUrl?.success) {
|
||||||
|
return { success: true, data: streamUrl?.data, availableLang };
|
||||||
|
}
|
||||||
|
throw new NotFoundError('No stream url found');
|
||||||
|
}
|
||||||
|
throw new NotFoundError('No media info found');
|
||||||
|
} catch (error) {
|
||||||
|
if (error instanceof NotFoundError) throw error;
|
||||||
|
throw new NotFoundError('Failed to fetch movie data');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function getTV(
|
||||||
|
ctx: ShowScrapeContext | MovieScrapeContext,
|
||||||
|
id: string,
|
||||||
|
season: number,
|
||||||
|
episode: number,
|
||||||
|
lang: string,
|
||||||
|
) {
|
||||||
|
try {
|
||||||
|
const mediaInfo = await getInfo(ctx, id);
|
||||||
|
if (!mediaInfo?.success) {
|
||||||
|
throw new NotFoundError('No media info found');
|
||||||
|
}
|
||||||
|
const playlist = mediaInfo?.data?.playlist;
|
||||||
|
const getSeason = playlist.find((item: any) => item?.id === season.toString());
|
||||||
|
if (!getSeason) {
|
||||||
|
throw new NotFoundError('No season found');
|
||||||
|
}
|
||||||
|
const getEpisode = getSeason?.folder.find((item: any) => item?.episode === episode.toString());
|
||||||
|
if (!getEpisode) {
|
||||||
|
throw new NotFoundError('No episode found');
|
||||||
|
}
|
||||||
|
let file = getEpisode?.folder.find((item: any) => item?.title === lang);
|
||||||
|
if (!file) {
|
||||||
|
file = getEpisode?.folder?.[0];
|
||||||
|
}
|
||||||
|
if (!file) {
|
||||||
|
throw new NotFoundError('No file found');
|
||||||
|
}
|
||||||
|
const availableLang = getEpisode?.folder.map((item: any) => {
|
||||||
|
return item?.title;
|
||||||
|
});
|
||||||
|
const filterLang = availableLang.filter((item: any) => item?.length > 0);
|
||||||
|
const key = mediaInfo?.data?.key;
|
||||||
|
ctx.progress(70);
|
||||||
|
const streamUrl = await getStream(ctx, file?.file, key);
|
||||||
|
if (streamUrl?.success) {
|
||||||
|
return {
|
||||||
|
success: true,
|
||||||
|
data: streamUrl?.data,
|
||||||
|
availableLang: filterLang,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
throw new NotFoundError('No stream url found');
|
||||||
|
} catch (error) {
|
||||||
|
if (error instanceof NotFoundError) throw error;
|
||||||
|
throw new NotFoundError('Failed to fetch TV data');
|
||||||
|
}
|
||||||
|
}
|
||||||
63
src/providers/sources/8stream/getInfo.ts
Normal file
63
src/providers/sources/8stream/getInfo.ts
Normal file
|
|
@ -0,0 +1,63 @@
|
||||||
|
import * as cheerio from 'cheerio';
|
||||||
|
|
||||||
|
import { MovieScrapeContext, ShowScrapeContext } from '@/utils/context';
|
||||||
|
import { NotFoundError } from '@/utils/errors';
|
||||||
|
|
||||||
|
export default async function getStream(ctx: ShowScrapeContext | MovieScrapeContext, id: string): Promise<any> {
|
||||||
|
try {
|
||||||
|
const baseUrl = 'https://ftmoh345xme.com';
|
||||||
|
const headers = {
|
||||||
|
Origin: 'https://friness-cherlormur-i-275.site',
|
||||||
|
Referer: 'https://google.com/',
|
||||||
|
Dnt: '1',
|
||||||
|
};
|
||||||
|
const url = `${baseUrl}/play/${id}`;
|
||||||
|
const result = await ctx.proxiedFetcher(url, {
|
||||||
|
headers: {
|
||||||
|
...headers,
|
||||||
|
},
|
||||||
|
method: 'GET',
|
||||||
|
});
|
||||||
|
const $ = cheerio.load(result);
|
||||||
|
const script = $('script').last().html()!;
|
||||||
|
if (!script) {
|
||||||
|
throw new NotFoundError('Failed to extract script data');
|
||||||
|
}
|
||||||
|
const content = script.match(/(\{[^;]+});/)?.[1] || script.match(/\((\{.*\})\)/)?.[1];
|
||||||
|
if (!content) {
|
||||||
|
throw new NotFoundError('Media not found');
|
||||||
|
}
|
||||||
|
const data = JSON.parse(content);
|
||||||
|
let file = data.file;
|
||||||
|
if (!file) {
|
||||||
|
throw new NotFoundError('File not found');
|
||||||
|
}
|
||||||
|
if (file.startsWith('/')) {
|
||||||
|
file = baseUrl + file;
|
||||||
|
}
|
||||||
|
const key = data.key;
|
||||||
|
const headers2 = {
|
||||||
|
Origin: 'https://friness-cherlormur-i-275.site',
|
||||||
|
Referer: 'https://google.com/',
|
||||||
|
Dnt: '1',
|
||||||
|
'X-Csrf-Token': key,
|
||||||
|
};
|
||||||
|
const PlayListRes = await ctx.proxiedFetcher(file, {
|
||||||
|
headers: {
|
||||||
|
...headers2,
|
||||||
|
},
|
||||||
|
method: 'GET',
|
||||||
|
});
|
||||||
|
const playlist = PlayListRes;
|
||||||
|
return {
|
||||||
|
success: true,
|
||||||
|
data: {
|
||||||
|
playlist,
|
||||||
|
key,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
} catch (error) {
|
||||||
|
if (error instanceof NotFoundError) throw error;
|
||||||
|
throw new NotFoundError('Failed to fetch media info');
|
||||||
|
}
|
||||||
|
}
|
||||||
36
src/providers/sources/8stream/getStream.ts
Normal file
36
src/providers/sources/8stream/getStream.ts
Normal file
|
|
@ -0,0 +1,36 @@
|
||||||
|
import { MovieScrapeContext, ShowScrapeContext } from '@/utils/context';
|
||||||
|
import { NotFoundError } from '@/utils/errors';
|
||||||
|
|
||||||
|
export default async function getStream(
|
||||||
|
ctx: ShowScrapeContext | MovieScrapeContext,
|
||||||
|
file: string,
|
||||||
|
key: string,
|
||||||
|
): Promise<any> {
|
||||||
|
const f = file as string;
|
||||||
|
const path = `${f.slice(1)}.txt`;
|
||||||
|
try {
|
||||||
|
const baseUrl = 'https://ftmoh345xme.com';
|
||||||
|
const headers = {
|
||||||
|
Origin: 'https://friness-cherlormur-i-275.site',
|
||||||
|
Referer: 'https://google.com/',
|
||||||
|
Dnt: '1',
|
||||||
|
'X-Csrf-Token': key,
|
||||||
|
};
|
||||||
|
const url = `${baseUrl}/playlist/${path}`;
|
||||||
|
const result = await ctx.proxiedFetcher(url, {
|
||||||
|
headers: {
|
||||||
|
...headers,
|
||||||
|
},
|
||||||
|
method: 'GET',
|
||||||
|
});
|
||||||
|
|
||||||
|
return {
|
||||||
|
success: true,
|
||||||
|
data: {
|
||||||
|
link: result,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
} catch (error) {
|
||||||
|
throw new NotFoundError('Failed to fetch stream data');
|
||||||
|
}
|
||||||
|
}
|
||||||
77
src/providers/sources/8stream/index.ts
Normal file
77
src/providers/sources/8stream/index.ts
Normal file
|
|
@ -0,0 +1,77 @@
|
||||||
|
import { flags } from '@/entrypoint/utils/targets';
|
||||||
|
import { SourcererOutput, makeSourcerer } from '@/providers/base';
|
||||||
|
import { MovieScrapeContext, ShowScrapeContext } from '@/utils/context';
|
||||||
|
import { NotFoundError } from '@/utils/errors';
|
||||||
|
|
||||||
|
import { getMovie, getTV } from './8Stream';
|
||||||
|
|
||||||
|
async function comboScraper(ctx: ShowScrapeContext | MovieScrapeContext): Promise<SourcererOutput> {
|
||||||
|
const query = {
|
||||||
|
title: ctx.media.title,
|
||||||
|
releaseYear: ctx.media.releaseYear,
|
||||||
|
tmdbId: ctx.media.tmdbId,
|
||||||
|
imdbId: ctx.media.imdbId,
|
||||||
|
type: ctx.media.type,
|
||||||
|
season: '',
|
||||||
|
episode: '',
|
||||||
|
};
|
||||||
|
|
||||||
|
if (ctx.media.type === 'show') {
|
||||||
|
query.season = ctx.media.season.number.toString();
|
||||||
|
query.episode = ctx.media.episode.number.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ctx.media.type === 'movie') {
|
||||||
|
ctx.progress(40);
|
||||||
|
const res = await getMovie(ctx, ctx.media.imdbId as string);
|
||||||
|
if (res?.success) {
|
||||||
|
ctx.progress(90);
|
||||||
|
return {
|
||||||
|
embeds: [],
|
||||||
|
stream: [
|
||||||
|
{
|
||||||
|
id: 'primary',
|
||||||
|
captions: [],
|
||||||
|
playlist: res.data.link,
|
||||||
|
type: 'hls',
|
||||||
|
flags: [flags.CORS_ALLOWED],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
};
|
||||||
|
}
|
||||||
|
throw new NotFoundError('No providers available');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ctx.media.type === 'show') {
|
||||||
|
ctx.progress(40);
|
||||||
|
const lang = 'English';
|
||||||
|
const res = await getTV(ctx, ctx.media.imdbId as string, ctx.media.season.number, ctx.media.episode.number, lang);
|
||||||
|
if (res?.success) {
|
||||||
|
ctx.progress(90);
|
||||||
|
return {
|
||||||
|
embeds: [],
|
||||||
|
stream: [
|
||||||
|
{
|
||||||
|
id: 'primary',
|
||||||
|
captions: [],
|
||||||
|
playlist: res.data.link,
|
||||||
|
type: 'hls',
|
||||||
|
flags: [flags.CORS_ALLOWED],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
};
|
||||||
|
}
|
||||||
|
throw new NotFoundError('No providers available');
|
||||||
|
}
|
||||||
|
throw new NotFoundError('No providers available');
|
||||||
|
}
|
||||||
|
|
||||||
|
export const EightStreamScraper = makeSourcerer({
|
||||||
|
id: '8stream',
|
||||||
|
name: '8stream',
|
||||||
|
rank: 111,
|
||||||
|
flags: [],
|
||||||
|
disabled: false,
|
||||||
|
scrapeMovie: comboScraper,
|
||||||
|
scrapeShow: comboScraper,
|
||||||
|
});
|
||||||
Loading…
Reference in a new issue