Update TurboVidPlay.ts
Lints fix.
This commit is contained in:
parent
57cd8a3d37
commit
724740383d
1 changed files with 70 additions and 44 deletions
|
|
@ -23,44 +23,62 @@ export class TurboVidPlay extends Extractor {
|
|||
];
|
||||
|
||||
public supports(ctx: Context, url: URL): boolean {
|
||||
return this.domains.some(d => url.host.includes(d)) &&
|
||||
supportsMediaFlowProxy(ctx);
|
||||
return (
|
||||
this.domains.some(d => url.host.includes(d))
|
||||
&& supportsMediaFlowProxy(ctx)
|
||||
);
|
||||
}
|
||||
|
||||
public override normalize(url: URL): URL {
|
||||
return new URL(url.href.replace(/\/(e|d|embed-)\//, '/t/'));
|
||||
}
|
||||
|
||||
protected async extractInternal(ctx: Context, url: URL, meta: Meta): Promise<UrlResult[]> {
|
||||
protected async extractInternal(
|
||||
ctx: Context,
|
||||
url: URL,
|
||||
meta: Meta,
|
||||
): Promise<UrlResult[]> {
|
||||
const headers: Record<string, string> = {
|
||||
Referer: url.origin,
|
||||
};
|
||||
|
||||
// ---- Correct CustomRequestInit ----
|
||||
const headers: Record<string, string> = { Referer: url.origin };
|
||||
|
||||
// ---- 1. Fetch embed HTML ----
|
||||
const html = await this.fetcher.text(ctx, url, headers);
|
||||
if (!html || html.includes('File Not Found') || html.includes('Pending in queue')) {
|
||||
if (
|
||||
!html
|
||||
|| html.includes('File Not Found')
|
||||
|| html.includes('Pending in queue')
|
||||
) {
|
||||
throw new NotFoundError();
|
||||
}
|
||||
|
||||
// ---- 2. Extract media URL ----
|
||||
const match = html.match(/(?:urlPlay|data-hash)\s*=\s*['"](?<url>[^"']+)/);
|
||||
const mediaUrl = match?.groups?.['url'];
|
||||
if (!mediaUrl) throw new NotFoundError('Video link not found');
|
||||
|
||||
const masterUrl =
|
||||
mediaUrl.startsWith('//') ? 'https:' + mediaUrl :
|
||||
mediaUrl.startsWith('/') ? url.origin + mediaUrl :
|
||||
mediaUrl;
|
||||
const mediaUrl
|
||||
= match?.groups?.url;
|
||||
|
||||
if (!mediaUrl) {
|
||||
throw new NotFoundError('Video link not found');
|
||||
}
|
||||
|
||||
const masterUrl
|
||||
= mediaUrl.startsWith('//')
|
||||
? `https:${mediaUrl}`
|
||||
: mediaUrl.startsWith('/')
|
||||
? url.origin + mediaUrl
|
||||
: mediaUrl;
|
||||
|
||||
// ---- 3. Look for /data/ variants ----
|
||||
let directDataStream: string | null = null;
|
||||
|
||||
try {
|
||||
const playlistText = await this.fetcher.text(ctx, new URL(masterUrl), headers);
|
||||
const playlistText = await this.fetcher.text(
|
||||
ctx,
|
||||
new URL(masterUrl),
|
||||
headers,
|
||||
);
|
||||
|
||||
const variantMatches = [...playlistText.matchAll(
|
||||
/#EXT-X-STREAM-INF[^\n]*\n([^\n]+)/g
|
||||
)];
|
||||
const variantMatches = [
|
||||
...playlistText.matchAll(/#EXT-X-STREAM-INF[^\n]*\n([^\n]+)/g),
|
||||
];
|
||||
|
||||
for (const m of variantMatches) {
|
||||
const variantUrl = m[1];
|
||||
|
|
@ -69,8 +87,8 @@ export class TurboVidPlay extends Extractor {
|
|||
if (variantUrl.includes('/data/')) {
|
||||
const base = new URL(masterUrl);
|
||||
|
||||
directDataStream =
|
||||
variantUrl.startsWith('http')
|
||||
directDataStream
|
||||
= variantUrl.startsWith('http')
|
||||
? variantUrl
|
||||
: variantUrl.startsWith('/')
|
||||
? new URL(variantUrl, base.origin).href
|
||||
|
|
@ -80,42 +98,50 @@ export class TurboVidPlay extends Extractor {
|
|||
}
|
||||
}
|
||||
} catch {
|
||||
// intentionally ignored
|
||||
}
|
||||
|
||||
// ---- 4. Title ----
|
||||
const $ = cheerio.load(html);
|
||||
const title = $('title').text().trim() || this.label;
|
||||
|
||||
// ---- 5. DIRECT if /data/ found ----
|
||||
if (directDataStream) {
|
||||
return [{
|
||||
url: new URL(directDataStream),
|
||||
format: Format.hls,
|
||||
label: this.label,
|
||||
sourceId: `${this.id}_${meta.countryCodes?.join('_') ?? 'all'}`,
|
||||
ttl: this.ttl,
|
||||
requestHeaders: headers,
|
||||
meta: { ...meta, title },
|
||||
}];
|
||||
return [
|
||||
{
|
||||
url: new URL(directDataStream),
|
||||
format: Format.hls,
|
||||
label: this.label,
|
||||
sourceId: `${this.id}_${meta.countryCodes?.join('_') ?? 'all'}`,
|
||||
ttl: this.ttl,
|
||||
requestHeaders: headers,
|
||||
meta: {
|
||||
...meta,
|
||||
title,
|
||||
},
|
||||
},
|
||||
];
|
||||
}
|
||||
|
||||
// ---- 6. OTHERWISE → pass EMBED URL to MediaFlow ----
|
||||
const proxiedUrl = await buildMediaFlowProxyExtractorStreamUrl(
|
||||
ctx,
|
||||
this.fetcher,
|
||||
this.id,
|
||||
url,
|
||||
headers
|
||||
headers,
|
||||
);
|
||||
|
||||
return [{
|
||||
url: proxiedUrl,
|
||||
format: Format.hls,
|
||||
label: this.label,
|
||||
sourceId: `${this.id}_${meta.countryCodes?.join('_') ?? 'all'}`,
|
||||
ttl: this.ttl,
|
||||
requestHeaders: headers,
|
||||
meta: { ...meta, title },
|
||||
}];
|
||||
return [
|
||||
{
|
||||
url: proxiedUrl,
|
||||
format: Format.hls,
|
||||
label: this.label,
|
||||
sourceId: `${this.id}_${meta.countryCodes?.join('_') ?? 'all'}`,
|
||||
ttl: this.ttl,
|
||||
requestHeaders: headers,
|
||||
meta: {
|
||||
...meta,
|
||||
title,
|
||||
},
|
||||
},
|
||||
];
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue