perf(extractor): do not guess resolution via MFP playlist for FileMoon

This commit is contained in:
WebStreamr 2025-10-07 13:09:23 +00:00
parent bab0da2a8f
commit 312f60660a
No known key found for this signature in database
5 changed files with 99 additions and 13 deletions

View file

@ -3,9 +3,8 @@ import { NotFoundError } from '../error';
import { Context, Format, Meta, UrlResult } from '../types';
import {
buildMediaFlowProxyExtractorStreamUrl,
guessHeightFromPlaylist,
MEDIAFLOW_DEFAULT_INIT,
supportsMediaFlowProxy,
unpackEval,
} from '../utils';
import { Extractor } from './Extractor';
@ -46,7 +45,7 @@ export class FileMoon extends Extractor {
return new URL(url.href.replace('/e/', '/d/'));
}
protected async extractInternal(ctx: Context, url: URL, meta: Meta): Promise<UrlResult[]> {
protected async extractInternal(ctx: Context, url: URL, meta: Meta, originalUrl?: URL): Promise<UrlResult[]> {
const headers = { Referer: meta.referer ?? url.href };
const html = await this.fetcher.text(ctx, url, { headers });
@ -55,11 +54,19 @@ export class FileMoon extends Extractor {
throw new NotFoundError();
}
const playlistUrl = await buildMediaFlowProxyExtractorStreamUrl(ctx, this.fetcher, 'FileMoon', url, headers);
const $ = cheerio.load(html);
const title = $('h3').text().trim();
const iframeUrlMatch = html.match(/iframe.*?src=["'](.*?)["']/);
if (iframeUrlMatch && iframeUrlMatch[1]) {
return await this.extractInternal(ctx, new URL(iframeUrlMatch[1]), { title, ...meta }, url);
}
const playlistUrl = await buildMediaFlowProxyExtractorStreamUrl(ctx, this.fetcher, 'FileMoon', originalUrl as URL, headers);
const unpacked = unpackEval(html);
const heightMatch = unpacked.match(/(\d{3,})p/) as string[];
return [
{
url: playlistUrl,
@ -69,8 +76,7 @@ export class FileMoon extends Extractor {
ttl: this.ttl,
meta: {
...meta,
height: await guessHeightFromPlaylist(ctx, this.fetcher, playlistUrl, MEDIAFLOW_DEFAULT_INIT),
title,
height: parseInt(heightMatch[1] as string),
},
},
];

View file

@ -1,4 +0,0 @@
#EXTM3U
#EXT-X-STREAM-INF:PROGRAM-ID=1,BANDWIDTH=853331,RESOLUTION=1280x720,FRAME-RATE=24.000,CODECS="avc1.64001f,mp4a.40.2",VIDEO-RANGE=SDR
https://mediaflow.test.org/proxy/hls/manifest.m3u8?api_password=test&h_user-agent=Mozilla%2F5.0+%28Windows+NT+10.0%3B+Win64%3B+x64%29+AppleWebKit%2F537.36+%28KHTML%2C+like+Gecko%29+Chrome%2F136.0.0.0+Safari%2F537.36&h_referer=https%3A%2F%2Fz1ekv717.fun%2Fd%2Fwkhcbggdxf1d&d=https%3A%2F%2Fbe7713.rcr82.waw05.i8yz83pn.com%2Fhls2%2F01%2F09665%2Fwkhcbggdxf1d_h%2Findex-v1-a1.m3u8%3Ft%3D359izbQ_L-sOHaIjj275YKdBDyiPzUi3ETfbNoN9bzU%26s%3D1759754698%26e%3D10800%26f%3D48329866%26srv%3D1075%26asn%3D13335%26sp%3D4000%26p%3D
#EXT-X-I-FRAME-STREAM-INF:BANDWIDTH=49442,RESOLUTION=1280x720,CODECS="avc1.64001f",URI="https://mediaflow.test.org/proxy/hls/manifest.m3u8?api_password=test&h_user-agent=Mozilla%2F5.0+%28Windows+NT+10.0%3B+Win64%3B+x64%29+AppleWebKit%2F537.36+%28KHTML%2C+like+Gecko%29+Chrome%2F136.0.0.0+Safari%2F537.36&h_referer=https%3A%2F%2Fz1ekv717.fun%2Fd%2Fwkhcbggdxf1d&d=https%3A%2F%2Fbe7713.rcr82.waw05.i8yz83pn.com%2Fhls2%2F01%2F09665%2Fwkhcbggdxf1d_h%2Fiframes-v1-a1.m3u8%3Ft%3D359izbQ_L-sOHaIjj275YKdBDyiPzUi3ETfbNoN9bzU%26s%3D1759754698%26e%3D10800%26f%3D48329866%26srv%3D1075%26asn%3D13335%26sp%3D4000%26p%3D",VIDEO-RANGE=SDR

File diff suppressed because one or more lines are too long

View file

@ -1,12 +1,16 @@
import { unpack } from 'unpacker';
export const extractUrlFromPacked = (html: string, linkRegExps: RegExp[]): URL => {
export const unpackEval = (html: string): string => {
const evalMatch = html.match(/eval\(function\(p,a,c,k,e,d\).*\)\)/);
if (!evalMatch) {
throw new Error(`No p.a.c.k.e.d string found`);
}
const unpacked = unpack(evalMatch[0]);
return unpack(evalMatch[0]);
};
export const extractUrlFromPacked = (html: string, linkRegExps: RegExp[]): URL => {
const unpacked = unpackEval(html);
for (const linkRegexp of linkRegExps) {
const linkMatch = unpacked.match(linkRegexp);