diff --git a/src/extractor/Mixdrop.test.ts b/src/extractor/Mixdrop.test.ts index 946e795..e8e6046 100644 --- a/src/extractor/Mixdrop.test.ts +++ b/src/extractor/Mixdrop.test.ts @@ -7,7 +7,7 @@ import { Mixdrop } from './Mixdrop'; const logger = winston.createLogger({ transports: [new winston.transports.Console({ level: 'nope' })] }); const extractorRegistry = new ExtractorRegistry(logger, [new Mixdrop(new FetcherMock(`${__dirname}/__fixtures__/Mixdrop`))]); -const ctx = createTestContext({ mediaFlowProxyUrl: 'https://mediaflow.test.org', mediaFlowProxyPassword: 'test' }); +const ctx = createTestContext({ mediaFlowProxyUrl: 'https://mediaflow-proxy.test', mediaFlowProxyPassword: 'asdfg' }); describe('Mixdrop', () => { test('mixdrop.my /e/', async () => { diff --git a/src/extractor/Mixdrop.ts b/src/extractor/Mixdrop.ts index beb5455..7caf957 100644 --- a/src/extractor/Mixdrop.ts +++ b/src/extractor/Mixdrop.ts @@ -2,7 +2,7 @@ import bytes from 'bytes'; import * as cheerio from 'cheerio'; import { NotFoundError } from '../error'; import { Context, Format, Meta, UrlResult } from '../types'; -import { buildMediaFlowProxyExtractorStreamUrl, supportsMediaFlowProxy } from '../utils'; +import { buildMediaFlowProxyExtractorRedirectUrl, supportsMediaFlowProxy } from '../utils'; import { Extractor } from './Extractor'; export class Mixdrop extends Extractor { @@ -35,7 +35,7 @@ export class Mixdrop extends Extractor { return [ { - url: await buildMediaFlowProxyExtractorStreamUrl(ctx, this.fetcher, 'Mixdrop', url, headers), + url: buildMediaFlowProxyExtractorRedirectUrl(ctx, 'Mixdrop', url, headers), format: Format.mp4, label: this.label, sourceId: `${this.id}_${meta.countryCodes?.join('_')}`, diff --git a/src/extractor/Streamtape.ts b/src/extractor/Streamtape.ts index ea1fc82..8d25d18 100644 --- a/src/extractor/Streamtape.ts +++ b/src/extractor/Streamtape.ts @@ -1,7 +1,7 @@ import * as cheerio from 'cheerio'; import { Context, Format, Meta, UrlResult } from '../types'; import { - buildMediaFlowProxyExtractorStreamUrl, + buildMediaFlowProxyExtractorRedirectUrl, supportsMediaFlowProxy, } from '../utils'; import { guessSizeFromMp4 } from '../utils/size'; @@ -28,7 +28,7 @@ export class Streamtape extends Extractor { const $ = cheerio.load(html); const title = $('meta[name="og:title"]').attr('content') as string; - const mp4Url = await buildMediaFlowProxyExtractorStreamUrl(ctx, this.fetcher, 'Streamtape', url, headers); + const mp4Url = buildMediaFlowProxyExtractorRedirectUrl(ctx, 'Streamtape', url, headers); return [ { @@ -40,7 +40,7 @@ export class Streamtape extends Extractor { meta: { ...meta, title, - bytes: await guessSizeFromMp4(ctx, this.fetcher, mp4Url, { headers: { Referer: url.href } }), + bytes: await guessSizeFromMp4(ctx, this.fetcher, mp4Url), }, }, ]; diff --git a/src/extractor/Uqload.ts b/src/extractor/Uqload.ts index ae01abf..c14e38a 100644 --- a/src/extractor/Uqload.ts +++ b/src/extractor/Uqload.ts @@ -1,6 +1,6 @@ import * as cheerio from 'cheerio'; import { Context, Format, Meta, UrlResult } from '../types'; -import { buildMediaFlowProxyExtractorStreamUrl, supportsMediaFlowProxy } from '../utils'; +import { buildMediaFlowProxyExtractorRedirectUrl, supportsMediaFlowProxy } from '../utils'; import { guessSizeFromMp4 } from '../utils/size'; import { Extractor } from './Extractor'; @@ -29,7 +29,7 @@ export class Uqload extends Extractor { const $ = cheerio.load(html); const title = $('h1').text().trim(); - const mp4Url = await buildMediaFlowProxyExtractorStreamUrl(ctx, this.fetcher, 'Uqload', url, headers); + const mp4Url = buildMediaFlowProxyExtractorRedirectUrl(ctx, 'Uqload', url, headers); return [ { diff --git a/src/extractor/__fixtures__/Mixdrop/https:mediaflow.test.orgextractorvideohostMixdropandapi_passwordtestanddhttpspercent3Apercent2Fpercent2Fmixdrop.mypercent2Fepercent2Fknq0kj8waq44l8andh_refererhttpspercent3Apercent2Fpercent2Fmixdrop.mypercent2Fepercent2Fknq0kj8waq44l8 b/src/extractor/__fixtures__/Mixdrop/https:mediaflow.test.orgextractorvideohostMixdropandapi_passwordtestanddhttpspercent3Apercent2Fpercent2Fmixdrop.mypercent2Fepercent2Fknq0kj8waq44l8andh_refererhttpspercent3Apercent2Fpercent2Fmixdrop.mypercent2Fepercent2Fknq0kj8waq44l8 deleted file mode 100644 index c539f41..0000000 --- a/src/extractor/__fixtures__/Mixdrop/https:mediaflow.test.orgextractorvideohostMixdropandapi_passwordtestanddhttpspercent3Apercent2Fpercent2Fmixdrop.mypercent2Fepercent2Fknq0kj8waq44l8andh_refererhttpspercent3Apercent2Fpercent2Fmixdrop.mypercent2Fepercent2Fknq0kj8waq44l8 +++ /dev/null @@ -1 +0,0 @@ -{"destination_url":"https://s-delivery29.mxcontent.net/v2/knq0kj8waq44l8.mp4?s=85VD8DA80IfkbMa3zZR3XA&e=1758851244&_t=1758837735","request_headers":{"user-agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/136.0.0.0 Safari/537.36","referer":"https://mixdrop.my/e/knq0kj8waq44l8"},"mediaflow_proxy_url":"https://mediaflow.test.org/proxy/stream","query_params":{"api_password":"test"}} diff --git a/src/extractor/__fixtures__/Streamtape/head-https:mediaflow.test.org-e0b2005f2027508023cbe94c61ed2d21 b/src/extractor/__fixtures__/Streamtape/head-https:mediaflow.test.org-f07f944d9efd780e6bb41b27f95c2308 similarity index 100% rename from src/extractor/__fixtures__/Streamtape/head-https:mediaflow.test.org-e0b2005f2027508023cbe94c61ed2d21 rename to src/extractor/__fixtures__/Streamtape/head-https:mediaflow.test.org-f07f944d9efd780e6bb41b27f95c2308 diff --git a/src/extractor/__fixtures__/Streamtape/https:mediaflow.test.org-6a49ba4b2831cab213994ba51da632c7 b/src/extractor/__fixtures__/Streamtape/https:mediaflow.test.org-6a49ba4b2831cab213994ba51da632c7 deleted file mode 100644 index 6638ddc..0000000 --- a/src/extractor/__fixtures__/Streamtape/https:mediaflow.test.org-6a49ba4b2831cab213994ba51da632c7 +++ /dev/null @@ -1 +0,0 @@ -{"destination_url":"https://streamtape.com/get_video?id=DjmZBG0K9gHkJ7z&expires=1758899945&ip=F0AOKRISKxSHDN&token=uQu83SOzkLwi","request_headers":{"user-agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/136.0.0.0 Safari/537.36","referer":"https://streamtape.com/e/DjmZBG0K9gHkJ7z/WALL-E.2008.1080p.BrRip.x264.YIFY.mp4"},"mediaflow_proxy_url":"https://mediaflow.test.org/proxy/stream","query_params":{"api_password":"test"}} \ No newline at end of file diff --git a/src/extractor/__fixtures__/Uqload/head-https:mediaflow.test.org-908e293c3e7903d2e19c0107c64e73e8 b/src/extractor/__fixtures__/Uqload/head-https:mediaflow.test.orgextractorvideohostUqloadandapi_passwordtestanddhttpspercent3Apercent2Fpercent2Fuqload.netpercent2Fz0xbr87oz637.htmlandh_refererhttpspercent3Apercent2Fpercent2Fuqload.netpercent2Fz0xbr87oz637.htmlandredirect_streamtrue similarity index 76% rename from src/extractor/__fixtures__/Uqload/head-https:mediaflow.test.org-908e293c3e7903d2e19c0107c64e73e8 rename to src/extractor/__fixtures__/Uqload/head-https:mediaflow.test.orgextractorvideohostUqloadandapi_passwordtestanddhttpspercent3Apercent2Fpercent2Fuqload.netpercent2Fz0xbr87oz637.htmlandh_refererhttpspercent3Apercent2Fpercent2Fuqload.netpercent2Fz0xbr87oz637.htmlandredirect_streamtrue index 058c82d..31842cc 100644 --- a/src/extractor/__fixtures__/Uqload/head-https:mediaflow.test.org-908e293c3e7903d2e19c0107c64e73e8 +++ b/src/extractor/__fixtures__/Uqload/head-https:mediaflow.test.orgextractorvideohostUqloadandapi_passwordtestanddhttpspercent3Apercent2Fpercent2Fuqload.netpercent2Fz0xbr87oz637.htmlandh_refererhttpspercent3Apercent2Fpercent2Fuqload.netpercent2Fz0xbr87oz637.htmlandredirect_streamtrue @@ -1 +1 @@ -{"connection":"close","content-length":"431690639","content-range":"bytes 0-431690638/431690639","content-type":"video/mp4","date":"Thu, 25 Sep 2025 19:55:43 GMT","etag":"\"680029e2-19bb138f\"","last-modified":"Wed, 16 Apr 2025 22:06:26 GMT","server":"nginx/1.24.0 (Ubuntu)"} \ No newline at end of file +{"connection":"close","content-length":"431690639","content-range":"bytes 0-431690638/431690639","content-type":"video/mp4","date":"Thu, 28 Aug 2025 19:12:32 GMT","etag":"\"680029e2-19bb138f\"","last-modified":"Wed, 16 Apr 2025 22:06:26 GMT","server":"nginx/1.24.0 (Ubuntu)"} \ No newline at end of file diff --git a/src/extractor/__fixtures__/Uqload/https:mediaflow.test.orgextractorvideohostUqloadandapi_passwordtestanddhttpspercent3Apercent2Fpercent2Fuqload.netpercent2Fz0xbr87oz637.htmlandh_refererhttpspercent3Apercent2Fpercent2Fuqload.netpercent2Fz0xbr87oz637.html b/src/extractor/__fixtures__/Uqload/https:mediaflow.test.orgextractorvideohostUqloadandapi_passwordtestanddhttpspercent3Apercent2Fpercent2Fuqload.netpercent2Fz0xbr87oz637.htmlandh_refererhttpspercent3Apercent2Fpercent2Fuqload.netpercent2Fz0xbr87oz637.html deleted file mode 100644 index 997f3aa..0000000 --- a/src/extractor/__fixtures__/Uqload/https:mediaflow.test.orgextractorvideohostUqloadandapi_passwordtestanddhttpspercent3Apercent2Fpercent2Fuqload.netpercent2Fz0xbr87oz637.htmlandh_refererhttpspercent3Apercent2Fpercent2Fuqload.netpercent2Fz0xbr87oz637.html +++ /dev/null @@ -1 +0,0 @@ -{"destination_url":"https://m60.uqload.cx/3rfkr3ep2fw2q4drdinp7ppqco2xtt5ele76uwwvy24rwjscvdv3lq62jd3a/v.mp4","request_headers":{"user-agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/136.0.0.0 Safari/537.36","referer":"https://uqload.net/"},"mediaflow_proxy_url":"https://mediaflow.test.org/proxy/stream","query_params":{"api_password":"test"}} diff --git a/src/extractor/__snapshots__/Mixdrop.test.ts.snap b/src/extractor/__snapshots__/Mixdrop.test.ts.snap index 19cd061..4cdc7f3 100644 --- a/src/extractor/__snapshots__/Mixdrop.test.ts.snap +++ b/src/extractor/__snapshots__/Mixdrop.test.ts.snap @@ -14,7 +14,7 @@ exports[`Mixdrop mixdrop.my /e/ 1`] = ` }, "sourceId": "mixdrop_", "ttl": 900000, - "url": "https://mediaflow.test.org/proxy/stream?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%2Fmixdrop.my%2Fe%2Fknq0kj8waq44l8&d=https%3A%2F%2Fs-delivery29.mxcontent.net%2Fv2%2Fknq0kj8waq44l8.mp4%3Fs%3D85VD8DA80IfkbMa3zZR3XA%26e%3D1758851244%26_t%3D1758837735", + "url": "https://mediaflow-proxy.test/extractor/video?host=Mixdrop&api_password=asdfg&d=https%3A%2F%2Fmixdrop.my%2Fe%2Fknq0kj8waq44l8&h_referer=https%3A%2F%2Fmixdrop.my%2Fe%2Fknq0kj8waq44l8&redirect_stream=true", }, ] `; diff --git a/src/extractor/__snapshots__/Streamtape.test.ts.snap b/src/extractor/__snapshots__/Streamtape.test.ts.snap index 3e82304..ab5a797 100644 --- a/src/extractor/__snapshots__/Streamtape.test.ts.snap +++ b/src/extractor/__snapshots__/Streamtape.test.ts.snap @@ -12,7 +12,7 @@ exports[`Streamtape streamtape.com /e 1`] = ` }, "sourceId": "streamtape_", "ttl": 900000, - "url": "https://mediaflow.test.org/proxy/stream?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%2Fstreamtape.com%2Fe%2FDjmZBG0K9gHkJ7z%2FWALL-E.2008.1080p.BrRip.x264.YIFY.mp4&d=https%3A%2F%2Fstreamtape.com%2Fget_video%3Fid%3DDjmZBG0K9gHkJ7z%26expires%3D1758899945%26ip%3DF0AOKRISKxSHDN%26token%3DuQu83SOzkLwi", + "url": "https://mediaflow.test.org/extractor/video?host=Streamtape&api_password=test&d=https%3A%2F%2Fstreamtape.com%2Fe%2FDjmZBG0K9gHkJ7z%2FWALL-E.2008.1080p.BrRip.x264.YIFY.mp4&h_referer=https%3A%2F%2Fstreamtape.com%2Fe%2FDjmZBG0K9gHkJ7z%2FWALL-E.2008.1080p.BrRip.x264.YIFY.mp4&redirect_stream=true", }, ] `; diff --git a/src/extractor/__snapshots__/Uqload.test.ts.snap b/src/extractor/__snapshots__/Uqload.test.ts.snap index efaa83c..a9cfb40 100644 --- a/src/extractor/__snapshots__/Uqload.test.ts.snap +++ b/src/extractor/__snapshots__/Uqload.test.ts.snap @@ -13,7 +13,7 @@ exports[`Uqload uqload.net /embed- 1`] = ` }, "sourceId": "uqload_", "ttl": 900000, - "url": "https://mediaflow.test.org/proxy/stream?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%2Fuqload.net%2F&d=https%3A%2F%2Fm60.uqload.cx%2F3rfkr3ep2fw2q4drdinp7ppqco2xtt5ele76uwwvy24rwjscvdv3lq62jd3a%2Fv.mp4", + "url": "https://mediaflow.test.org/extractor/video?host=Uqload&api_password=test&d=https%3A%2F%2Fuqload.net%2Fz0xbr87oz637.html&h_referer=https%3A%2F%2Fuqload.net%2Fz0xbr87oz637.html&redirect_stream=true", }, ] `; diff --git a/src/utils/media-flow-proxy.ts b/src/utils/media-flow-proxy.ts index 53ebac8..ce5bb2c 100644 --- a/src/utils/media-flow-proxy.ts +++ b/src/utils/media-flow-proxy.ts @@ -24,6 +24,14 @@ const buildMediaFlowProxyExtractorUrl = (ctx: Context, host: string, url: URL, h return mediaFlowProxyUrl; }; +export const buildMediaFlowProxyExtractorRedirectUrl = (ctx: Context, host: string, url: URL, headers: Record): URL => { + const mediaFlowProxyUrl = buildMediaFlowProxyExtractorUrl(ctx, host, url, headers); + + mediaFlowProxyUrl.searchParams.append('redirect_stream', 'true'); + + return mediaFlowProxyUrl; +}; + export const buildMediaFlowProxyExtractorStreamUrl = async (ctx: Context, fetcher: Fetcher, host: string, url: URL, headers: Record = {}): Promise => { const mediaFlowProxyUrl = buildMediaFlowProxyExtractorUrl(ctx, host, url, headers);