mirror of
https://github.com/p-stream/providers.git
synced 2026-01-11 20:10:33 +00:00
Merge branch 'pr/43' into production
This commit is contained in:
commit
09872c43d8
4 changed files with 215 additions and 0 deletions
|
|
@ -81,6 +81,7 @@ import { coitusScraper } from './sources/coitus';
|
|||
import { cuevana3Scraper } from './sources/cuevana3';
|
||||
import { debridScraper } from './sources/debrid';
|
||||
import { embedsuScraper } from './sources/embedsu';
|
||||
import { fullhdfilmizleScraper } from './sources/fullhdfilmizle';
|
||||
import { hdRezkaScraper } from './sources/hdrezka';
|
||||
import { iosmirrorScraper } from './sources/iosmirror';
|
||||
import { iosmirrorPVScraper } from './sources/iosmirrorpv';
|
||||
|
|
@ -149,6 +150,7 @@ export function gatherAllSources(): Array<Sourcerer> {
|
|||
movies4fScraper,
|
||||
debridScraper,
|
||||
cinehdplusScraper,
|
||||
fullhdfilmizleScraper,
|
||||
];
|
||||
}
|
||||
|
||||
|
|
|
|||
80
src/providers/sources/fullhdfilmizle/decrypt.ts
Normal file
80
src/providers/sources/fullhdfilmizle/decrypt.ts
Normal file
|
|
@ -0,0 +1,80 @@
|
|||
import { PackerParams } from './types';
|
||||
|
||||
export function rtt(str: string) {
|
||||
return str.replace(/[a-z]/gi, (c) => {
|
||||
return String.fromCharCode(c.charCodeAt(0) + (c.toLowerCase() < 'n' ? 13 : -13));
|
||||
});
|
||||
}
|
||||
|
||||
export function decodeAtom(e: string) {
|
||||
const t = atob(e.split('').reverse().join(''));
|
||||
let o = '';
|
||||
for (let i = 0; i < t.length; i++) {
|
||||
const r = 'K9L'[i % 3];
|
||||
const n = t.charCodeAt(i) - ((r.charCodeAt(0) % 5) + 1);
|
||||
o += String.fromCharCode(n);
|
||||
}
|
||||
return atob(o);
|
||||
}
|
||||
|
||||
export function extractPackerParams(rawInput: string): PackerParams | null {
|
||||
const regex = /'((?:[^'\\]|\\.)*)',\s*(\d+),\s*(\d+),\s*'((?:[^'\\]|\\.)*)'\.split\('\|'\)/;
|
||||
|
||||
const match = regex.exec(rawInput);
|
||||
|
||||
if (!match) {
|
||||
console.error('Could not parse parameters. Format is not as expected.');
|
||||
return null;
|
||||
}
|
||||
|
||||
return {
|
||||
payload: match[1],
|
||||
radix: parseInt(match[2], 10),
|
||||
count: parseInt(match[3], 10),
|
||||
keywords: match[4].split('|'),
|
||||
};
|
||||
}
|
||||
|
||||
export function decodeDeanEdwards(params: PackerParams): string {
|
||||
const { payload, radix, count, keywords } = params;
|
||||
|
||||
const dict: { [key: string]: string } = Object.create(null);
|
||||
|
||||
const encodeBase = (num: number): string => {
|
||||
if (num < radix) {
|
||||
const char = num % radix;
|
||||
return char > 35 ? String.fromCharCode(char + 29) : char.toString(36);
|
||||
}
|
||||
|
||||
const prefix = encodeBase(Math.floor(num / radix));
|
||||
|
||||
const char = num % radix;
|
||||
const suffix = char > 35 ? String.fromCharCode(char + 29) : char.toString(36);
|
||||
|
||||
return prefix + suffix;
|
||||
};
|
||||
|
||||
let i = count;
|
||||
while (i--) {
|
||||
const key = encodeBase(i);
|
||||
const value = keywords[i] || key;
|
||||
dict[key] = value;
|
||||
}
|
||||
|
||||
return payload.replace(/\b\w+\b/g, (word) => {
|
||||
if (word in dict) {
|
||||
return dict[word];
|
||||
}
|
||||
return word;
|
||||
});
|
||||
}
|
||||
|
||||
export function decodeHex(str: string): string {
|
||||
return str.replace(/\\x([0-9A-Fa-f]{2})/g, (_match, hexGroup) => {
|
||||
return String.fromCharCode(parseInt(hexGroup, 16));
|
||||
});
|
||||
}
|
||||
|
||||
export function unescapeString(str: string) {
|
||||
return str.replace(/\\(.)/g, (match, char) => char);
|
||||
}
|
||||
127
src/providers/sources/fullhdfilmizle/index.ts
Normal file
127
src/providers/sources/fullhdfilmizle/index.ts
Normal file
|
|
@ -0,0 +1,127 @@
|
|||
import { flags } from '@/entrypoint/utils/targets';
|
||||
import { SourcererOutput, makeSourcerer } from '@/providers/base';
|
||||
import { MovieScrapeContext } from '@/utils/context';
|
||||
import { NotFoundError } from '@/utils/errors';
|
||||
import { createM3U8ProxyUrl } from '@/utils/proxy';
|
||||
|
||||
import { decodeAtom, decodeDeanEdwards, decodeHex, extractPackerParams, rtt, unescapeString } from './decrypt';
|
||||
|
||||
const baseUrl = 'https://www.fullhdfilmizlesene.tv';
|
||||
|
||||
const headers = {
|
||||
Referer: baseUrl,
|
||||
Accept: 'application/json, text/plain, */*',
|
||||
'User-Agent':
|
||||
'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36',
|
||||
};
|
||||
|
||||
function extractVidmoxy(body: string) {
|
||||
const regex = /eval\(function\(p,a,c,k,e,d\){.+}}return p}\((\\?'.+.split\(\\?'\|\\?'\)).+$/m;
|
||||
|
||||
let decoded = body;
|
||||
let i = 0;
|
||||
|
||||
while (decoded.includes('eval(')) {
|
||||
const decodedMatch = decoded.match(regex);
|
||||
if (!decodedMatch) {
|
||||
throw new NotFoundError('Decryption unsuccessful');
|
||||
}
|
||||
|
||||
const parameters = extractPackerParams(i > 0 ? unescapeString(decodedMatch[1]) : decodedMatch[1]);
|
||||
if (!parameters) throw new NotFoundError('Decryption unsuccessful');
|
||||
|
||||
decoded = decodeDeanEdwards(parameters);
|
||||
i++;
|
||||
}
|
||||
|
||||
const fileMatch = decoded.match(/"file":"(.+?)"/);
|
||||
if (!fileMatch) throw new NotFoundError('No playlist found');
|
||||
|
||||
const playlistUrl = unescapeString(decodeHex(fileMatch[1]));
|
||||
return playlistUrl;
|
||||
}
|
||||
|
||||
function extractAtom(body: string) {
|
||||
const fileMatch = body.match(/"file": av\('(.+)'\),$/m);
|
||||
|
||||
if (!fileMatch) throw new NotFoundError('No playlist found');
|
||||
|
||||
const playlistUrl = decodeAtom(fileMatch[1]);
|
||||
return playlistUrl;
|
||||
}
|
||||
|
||||
async function scrapeMovie(ctx: MovieScrapeContext): Promise<SourcererOutput> {
|
||||
if (!ctx.media.imdbId) {
|
||||
throw new NotFoundError('IMDb id not provided');
|
||||
}
|
||||
|
||||
const searchJson = await ctx.proxiedFetcher<{ prefix: string; dizilink: string }[]>(
|
||||
`/autocomplete/q.php?q=${ctx.media.imdbId}`,
|
||||
{
|
||||
baseUrl,
|
||||
headers,
|
||||
},
|
||||
);
|
||||
|
||||
ctx.progress(30);
|
||||
if (!searchJson.length) throw new NotFoundError('Media not found');
|
||||
|
||||
const searchResult = searchJson[0];
|
||||
|
||||
const mediaUrl = `/${searchResult.prefix}/${searchResult.dizilink}`;
|
||||
const mediaPage = await ctx.proxiedFetcher<string>(mediaUrl, {
|
||||
baseUrl,
|
||||
headers,
|
||||
});
|
||||
|
||||
const playerMatch = mediaPage.match(/var scx = {.+"t":\["(.+)"\]},/);
|
||||
if (!playerMatch) throw new NotFoundError('No source found');
|
||||
|
||||
ctx.progress(60);
|
||||
|
||||
const playerUrl = atob(rtt(playerMatch[1]));
|
||||
const isVidmoxy = playerUrl.startsWith('https://vidmoxy.com');
|
||||
|
||||
const playerResponse = await ctx.proxiedFetcher<string>(playerUrl + (isVidmoxy ? '?vst=1' : ''), {
|
||||
headers: {
|
||||
Accept: 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
|
||||
Referer: baseUrl,
|
||||
'Sec-Fetch-Dest': 'iframe',
|
||||
'Sec-Fetch-Mode': 'navigate',
|
||||
'Sec-Fetch-Site': 'cross-site',
|
||||
'Sec-Fetch-User': '?1',
|
||||
'Sec-GPC': '1',
|
||||
'Upgrade-Insecure-Requests': '1',
|
||||
'User-Agent':
|
||||
'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36',
|
||||
},
|
||||
});
|
||||
|
||||
ctx.progress(80);
|
||||
if (!playerResponse || playerResponse === '404') throw new NotFoundError('Player 404: Source is inaccessible');
|
||||
|
||||
const playlistUrl = isVidmoxy ? extractVidmoxy(playerResponse) : extractAtom(playerResponse);
|
||||
|
||||
return {
|
||||
embeds: [],
|
||||
stream: [
|
||||
{
|
||||
id: 'primary',
|
||||
type: 'hls',
|
||||
playlist: createM3U8ProxyUrl(playlistUrl, ctx.features, headers),
|
||||
headers,
|
||||
flags: [flags.CORS_ALLOWED],
|
||||
captions: [],
|
||||
},
|
||||
],
|
||||
};
|
||||
}
|
||||
|
||||
export const fullhdfilmizleScraper = makeSourcerer({
|
||||
id: 'fullhdfilmizle',
|
||||
name: 'FullHDFilmizle (Turkish)',
|
||||
rank: 3,
|
||||
disabled: false,
|
||||
flags: [flags.CORS_ALLOWED],
|
||||
scrapeMovie,
|
||||
});
|
||||
6
src/providers/sources/fullhdfilmizle/types.ts
Normal file
6
src/providers/sources/fullhdfilmizle/types.ts
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
export interface PackerParams {
|
||||
payload: string; // p
|
||||
radix: number; // a
|
||||
count: number; // c
|
||||
keywords: string[]; // k
|
||||
}
|
||||
Loading…
Reference in a new issue