mirror of
https://github.com/p-stream/providers.git
synced 2026-01-11 20:10:33 +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 { warezPlayerScraper } from './embeds/warezcdn/warezplayer';
|
||||
import { webtor1080Scraper, webtor480Scraper, webtor4kScraper, webtor720Scraper } from './embeds/webtor';
|
||||
import { EightStreamScraper } from './sources/8stream';
|
||||
import { coitusScraper } from './sources/coitus';
|
||||
import { embedsuScraper } from './sources/embedsu';
|
||||
import { FedAPIScraper } from './sources/fedapi';
|
||||
|
|
@ -104,6 +105,7 @@ export function gatherAllSources(): Array<Sourcerer> {
|
|||
streamboxScraper,
|
||||
nunflixScraper,
|
||||
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