From 18d8ee6b79967fc7719272f38abfcbfa1d1c1252 Mon Sep 17 00:00:00 2001 From: WebStreamr <210764791+webstreamr@users.noreply.github.com> Date: Thu, 28 Aug 2025 19:17:21 +0000 Subject: [PATCH] chore(extractor): use guessSizeFromMp4 in Streamtape, Uqload and XPrime --- src/extractor/Mixdrop.ts | 6 +- src/extractor/Streamtape.test.ts | 2 +- src/extractor/Streamtape.ts | 6 +- src/extractor/Uqload.test.ts | 2 +- src/extractor/Uqload.ts | 6 +- src/extractor/XPrime.ts | 3 +- ...ent2F84Kb3mkoYAiokmWandredirect_streamtrue | 1 + .../https:streamtape.come84Kb3mkoYAiokmW | 68 +++++++------ ...t2Fz0xbr87oz637.htmlandredirect_streamtrue | 1 + .../Uqload/https:uqload.netz0xbr87oz637.html | 96 +++++++++---------- .../__snapshots__/Streamtape.test.ts.snap | 3 +- .../__snapshots__/Uqload.test.ts.snap | 6 +- src/types.ts | 2 +- 13 files changed, 110 insertions(+), 92 deletions(-) create mode 100644 src/extractor/__fixtures__/Streamtape/head-https:mediaflow.test.orgextractorvideohostStreamtapeandapi_passwordtestanddhttpspercent3Apercent2Fpercent2Fstreamtape.compercent2Fepercent2F84Kb3mkoYAiokmWandredirect_streamtrue create mode 100644 src/extractor/__fixtures__/Uqload/head-https:mediaflow.test.orgextractorvideohostUqloadandapi_passwordtestanddhttpspercent3Apercent2Fpercent2Fuqload.netpercent2Fz0xbr87oz637.htmlandredirect_streamtrue diff --git a/src/extractor/Mixdrop.ts b/src/extractor/Mixdrop.ts index fba3df7..f1f9b0e 100644 --- a/src/extractor/Mixdrop.ts +++ b/src/extractor/Mixdrop.ts @@ -28,7 +28,7 @@ export class Mixdrop extends Extractor { throw new NotFoundError(); } - const sizeMatch = html.match(/([\d.,]+ ?[GM]B)/); + const sizeMatch = html.match(/([\d.,]+ ?[GM]B)/) as string[]; const $ = cheerio.load(html); const title = $('.title b').text().trim(); @@ -42,10 +42,8 @@ export class Mixdrop extends Extractor { ttl: this.ttl, meta: { countryCodes: [countryCode], + bytes: bytes.parse((sizeMatch[1] as string).replace(',', '')) as number, title, - ...(sizeMatch && { - bytes: bytes.parse((sizeMatch[1] as string).replace(',', '')) as number, - }), }, }, ]; diff --git a/src/extractor/Streamtape.test.ts b/src/extractor/Streamtape.test.ts index 21eef6b..cb845fc 100644 --- a/src/extractor/Streamtape.test.ts +++ b/src/extractor/Streamtape.test.ts @@ -8,7 +8,7 @@ import { Streamtape } from './Streamtape'; const logger = winston.createLogger({ transports: [new winston.transports.Console({ level: 'nope' })] }); const extractorRegistry = new ExtractorRegistry(logger, [new Streamtape(new FetcherMock(`${__dirname}/__fixtures__/Streamtape`))]); -const ctx = createTestContext({ mediaFlowProxyUrl: 'https://mediaflow-proxy.test', mediaFlowProxyPassword: 'asdfg' }); +const ctx = createTestContext({ mediaFlowProxyUrl: 'https://mediaflow.test.org', mediaFlowProxyPassword: 'test' }); describe('Streamtape', () => { test('streamtape.com /e', async () => { diff --git a/src/extractor/Streamtape.ts b/src/extractor/Streamtape.ts index 6813301..96110a6 100644 --- a/src/extractor/Streamtape.ts +++ b/src/extractor/Streamtape.ts @@ -4,6 +4,7 @@ import { buildMediaFlowProxyExtractorRedirectUrl, supportsMediaFlowProxy, } from '../utils'; +import { guessSizeFromMp4 } from '../utils/size'; import { Extractor } from './Extractor'; export class Streamtape extends Extractor { @@ -23,9 +24,11 @@ export class Streamtape extends Extractor { const $ = cheerio.load(html); const title = $('meta[name="og:title"]').attr('content') as string; + const mp4Url = buildMediaFlowProxyExtractorRedirectUrl(ctx, 'Streamtape', url); + return [ { - url: buildMediaFlowProxyExtractorRedirectUrl(ctx, 'Streamtape', url), + url: mp4Url, format: Format.mp4, label: this.label, sourceId: `${this.id}_${countryCode}`, @@ -33,6 +36,7 @@ export class Streamtape extends Extractor { meta: { countryCodes: [countryCode], title, + bytes: await guessSizeFromMp4(ctx, this.fetcher, mp4Url), }, }, ]; diff --git a/src/extractor/Uqload.test.ts b/src/extractor/Uqload.test.ts index 1634aa8..acc7e71 100644 --- a/src/extractor/Uqload.test.ts +++ b/src/extractor/Uqload.test.ts @@ -8,7 +8,7 @@ import { Uqload } from './Uqload'; const logger = winston.createLogger({ transports: [new winston.transports.Console({ level: 'nope' })] }); const extractorRegistry = new ExtractorRegistry(logger, [new Uqload(new FetcherMock(`${__dirname}/__fixtures__/Uqload`))]); -const ctx = createTestContext({ mediaFlowProxyUrl: 'https://mediaflow-proxy.test', mediaFlowProxyPassword: 'asdfg' }); +const ctx = createTestContext({ mediaFlowProxyUrl: 'https://mediaflow.test.org', mediaFlowProxyPassword: 'test' }); describe('Uqload', () => { test('uqload.net /embed-', async () => { diff --git a/src/extractor/Uqload.ts b/src/extractor/Uqload.ts index fa63938..a54718f 100644 --- a/src/extractor/Uqload.ts +++ b/src/extractor/Uqload.ts @@ -1,6 +1,7 @@ import * as cheerio from 'cheerio'; import { Context, CountryCode, Format, UrlResult } from '../types'; import { buildMediaFlowProxyExtractorRedirectUrl, supportsMediaFlowProxy } from '../utils'; +import { guessSizeFromMp4 } from '../utils/size'; import { Extractor } from './Extractor'; export class Uqload extends Extractor { @@ -28,9 +29,11 @@ export class Uqload extends Extractor { const $ = cheerio.load(html); const title = $('h1').text().trim(); + const mp4Url = buildMediaFlowProxyExtractorRedirectUrl(ctx, 'Uqload', url); + return [ { - url: buildMediaFlowProxyExtractorRedirectUrl(ctx, 'Uqload', url), + url: mp4Url, format: Format.mp4, label: this.label, sourceId: `${this.id}_${countryCode}`, @@ -38,6 +41,7 @@ export class Uqload extends Extractor { meta: { countryCodes: [countryCode], title, + bytes: await guessSizeFromMp4(ctx, this.fetcher, mp4Url), ...(heightMatch && { height: parseInt(heightMatch[1] as string), }), diff --git a/src/extractor/XPrime.ts b/src/extractor/XPrime.ts index 44dd233..1407126 100644 --- a/src/extractor/XPrime.ts +++ b/src/extractor/XPrime.ts @@ -1,4 +1,5 @@ import { Context, CountryCode, Format, UrlResult } from '../types'; +import { guessSizeFromMp4 } from '../utils/size'; import { Extractor } from './Extractor'; interface XPrimePrimeboxResponsePartial { @@ -43,7 +44,7 @@ export class XPrime extends Extractor { ttl: this.ttl, meta: { countryCodes: [countryCode], - bytes: parseInt((await this.fetcher.head(ctx, url, { headers: { Referer: referer }, minCacheTtl: this.ttl }))['content-length'] as string), + bytes: await guessSizeFromMp4(ctx, this.fetcher, url, { headers: { Referer: referer }, minCacheTtl: this.ttl }), height: parseInt(resolution), title, }, diff --git a/src/extractor/__fixtures__/Streamtape/head-https:mediaflow.test.orgextractorvideohostStreamtapeandapi_passwordtestanddhttpspercent3Apercent2Fpercent2Fstreamtape.compercent2Fepercent2F84Kb3mkoYAiokmWandredirect_streamtrue b/src/extractor/__fixtures__/Streamtape/head-https:mediaflow.test.orgextractorvideohostStreamtapeandapi_passwordtestanddhttpspercent3Apercent2Fpercent2Fstreamtape.compercent2Fepercent2F84Kb3mkoYAiokmWandredirect_streamtrue new file mode 100644 index 0000000..91858cc --- /dev/null +++ b/src/extractor/__fixtures__/Streamtape/head-https:mediaflow.test.orgextractorvideohostStreamtapeandapi_passwordtestanddhttpspercent3Apercent2Fpercent2Fstreamtape.compercent2Fepercent2F84Kb3mkoYAiokmWandredirect_streamtrue @@ -0,0 +1 @@ +{"connection":"close","content-length":"1187340184","content-range":"bytes 0-1187340183/1187340184","content-type":"video/mp4","date":"Thu, 28 Aug 2025 19:09:50 GMT","etag":"\"68acb5cc-46c55f98\"","last-modified":"Mon, 25 Aug 2025 19:13:16 GMT","server":"nginx/1.24.0 (Ubuntu)"} \ No newline at end of file diff --git a/src/extractor/__fixtures__/Streamtape/https:streamtape.come84Kb3mkoYAiokmW b/src/extractor/__fixtures__/Streamtape/https:streamtape.come84Kb3mkoYAiokmW index 4f9a09f..c0e9d00 100644 --- a/src/extractor/__fixtures__/Streamtape/https:streamtape.come84Kb3mkoYAiokmW +++ b/src/extractor/__fixtures__/Streamtape/https:streamtape.come84Kb3mkoYAiokmW @@ -157,18 +157,18 @@ try{count++;if(loop && !did && count < 100) setTimeout(function(){adblock(loop); } adblock(true); document.addEventListener("readystatechange", function(){adblock();}); -window.jLWmxnGlQy=adblock; +window.ychkrLfxAj=adblock; })(); - + + var vidconfig = {"id":"84Kb3mkoYAiokmW","cors":"https:\/\/thumb.tapecontent.net\/remotecaption\/expires=1756478189&ip=FOSOF0xJREWYFxf&token=UyXWd6O5GOik","showtitle":"","subload":false,"subsize":true,"logo":null}; - - - - @@ -197,37 +197,43 @@ document.getElementById('robotlink').innerHTML = '//strea'+ ('xcdmtape.com/get_v - - - + + - + + - - - + + - - - + + - - - + + - + + - + + - - + + - + + + + + + + + - - - - - - - + + + + + + + - + @@ -37,7 +37,7 @@
- - + + - + - + @@ -408,20 +408,20 @@ document.getElementsByTagName("head")[0].appendChild(s); - +
diff --git a/src/extractor/__snapshots__/Streamtape.test.ts.snap b/src/extractor/__snapshots__/Streamtape.test.ts.snap index 1d1b8c7..7ac6356 100644 --- a/src/extractor/__snapshots__/Streamtape.test.ts.snap +++ b/src/extractor/__snapshots__/Streamtape.test.ts.snap @@ -6,6 +6,7 @@ exports[`Streamtape streamtape.com /e 1`] = ` "format": "mp4", "label": "Streamtape (via MediaFlow Proxy)", "meta": { + "bytes": 1187340184, "countryCodes": [ "es", ], @@ -13,7 +14,7 @@ exports[`Streamtape streamtape.com /e 1`] = ` }, "sourceId": "streamtape_es", "ttl": 0, - "url": "https://mediaflow-proxy.test/extractor/video?host=Streamtape&api_password=asdfg&d=https%3A%2F%2Fstreamtape.com%2Fe%2F84Kb3mkoYAiokmW&redirect_stream=true", + "url": "https://mediaflow.test.org/extractor/video?host=Streamtape&api_password=test&d=https%3A%2F%2Fstreamtape.com%2Fe%2F84Kb3mkoYAiokmW&redirect_stream=true", }, ] `; diff --git a/src/extractor/__snapshots__/Uqload.test.ts.snap b/src/extractor/__snapshots__/Uqload.test.ts.snap index 3af216a..86b9089 100644 --- a/src/extractor/__snapshots__/Uqload.test.ts.snap +++ b/src/extractor/__snapshots__/Uqload.test.ts.snap @@ -6,6 +6,7 @@ exports[`Uqload uqload.net / 1`] = ` "format": "mp4", "label": "Uqload (via MediaFlow Proxy)", "meta": { + "bytes": 431690639, "countryCodes": [ "fr", ], @@ -14,7 +15,7 @@ exports[`Uqload uqload.net / 1`] = ` }, "sourceId": "uqload_fr", "ttl": 0, - "url": "https://mediaflow-proxy.test/extractor/video?host=Uqload&api_password=asdfg&d=https%3A%2F%2Fuqload.net%2Fz0xbr87oz637.html&redirect_stream=true", + "url": "https://mediaflow.test.org/extractor/video?host=Uqload&api_password=test&d=https%3A%2F%2Fuqload.net%2Fz0xbr87oz637.html&redirect_stream=true", }, ] `; @@ -25,6 +26,7 @@ exports[`Uqload uqload.net /embed- 1`] = ` "format": "mp4", "label": "Uqload (via MediaFlow Proxy)", "meta": { + "bytes": 431690639, "countryCodes": [ "fr", ], @@ -33,7 +35,7 @@ exports[`Uqload uqload.net /embed- 1`] = ` }, "sourceId": "uqload_fr", "ttl": 0, - "url": "https://mediaflow-proxy.test/extractor/video?host=Uqload&api_password=asdfg&d=https%3A%2F%2Fuqload.net%2Fz0xbr87oz637.html&redirect_stream=true", + "url": "https://mediaflow.test.org/extractor/video?host=Uqload&api_password=test&d=https%3A%2F%2Fuqload.net%2Fz0xbr87oz637.html&redirect_stream=true", }, ] `; diff --git a/src/types.ts b/src/types.ts index 92f046e..6e2402d 100644 --- a/src/types.ts +++ b/src/types.ts @@ -40,7 +40,7 @@ export enum BlockedReason { } export interface Meta { - bytes?: number; + bytes?: number | undefined; countryCodes: CountryCode[]; height?: number | undefined; title?: string | undefined;