diff --git a/src/extractor/DoodStream.ts b/src/extractor/DoodStream.ts index e37506f..cb656b8 100644 --- a/src/extractor/DoodStream.ts +++ b/src/extractor/DoodStream.ts @@ -1,7 +1,7 @@ import randomstring from 'randomstring'; import { Extractor } from './types'; import { Fetcher } from '../utils'; -import { Context } from '../types'; +import { Context, Meta } from '../types'; import { NotFoundError } from '../error'; export class DoodStream implements Extractor { @@ -19,7 +19,7 @@ export class DoodStream implements Extractor { readonly supports = (url: URL): boolean => null !== url.host.match(/dood|do[0-9]go/); - readonly extract = async (ctx: Context, url: URL, countryCode: string) => { + readonly extract = async (ctx: Context, url: URL, meta: Meta) => { const videoId = url.pathname.split('/').slice(-1)[0] as string; const normalizedUrl = new URL(`http://dood.to/e/${videoId}`); @@ -37,10 +37,8 @@ export class DoodStream implements Extractor { return { url: new URL(`${baseUrl}${randomstring.generate(10)}?token=${token}&expiry=${Date.now()}`), label: this.label, - sourceId: `${this.id}_${countryCode.toLowerCase()}`, - height: 0, - bytes: 0, - countryCode, + sourceId: `${this.id}_${meta.countryCode.toLowerCase()}`, + meta, requestHeaders: { Referer: 'http://dood.to/', }, diff --git a/src/extractor/Dropload.ts b/src/extractor/Dropload.ts index 9d6bdb4..39eab96 100644 --- a/src/extractor/Dropload.ts +++ b/src/extractor/Dropload.ts @@ -1,7 +1,7 @@ import bytes from 'bytes'; import { Extractor } from './types'; import { extractUrlFromPacked, Fetcher } from '../utils'; -import { Context } from '../types'; +import { Context, Meta } from '../types'; import { NotFoundError } from '../error'; export class Dropload implements Extractor { @@ -19,7 +19,7 @@ export class Dropload implements Extractor { readonly supports = (url: URL): boolean => null !== url.host.match(/dropload/); - readonly extract = async (ctx: Context, url: URL, countryCode: string) => { + readonly extract = async (ctx: Context, url: URL, meta: Meta) => { url.pathname = url.pathname.replace('/e/', '').replace('/embed-', '/'); const html = await this.fetcher.text(ctx, url); @@ -34,10 +34,12 @@ export class Dropload implements Extractor { return { url: extractUrlFromPacked(html, [/sources:\[{file:"(.*?)"/]), label: this.label, - sourceId: `${this.id}_${countryCode.toLowerCase()}`, - height: parseInt(heightMatch[1] as string) as number, - bytes: bytes.parse(sizeMatch[1] as string) as number, - countryCode, + sourceId: `${this.id}_${meta.countryCode.toLowerCase()}`, + meta: { + ...meta, + bytes: bytes.parse(sizeMatch[1] as string) as number, + height: parseInt(heightMatch[1] as string) as number, + }, }; }; } diff --git a/src/extractor/ExternalUrl.ts b/src/extractor/ExternalUrl.ts index 268bb54..76125c6 100644 --- a/src/extractor/ExternalUrl.ts +++ b/src/extractor/ExternalUrl.ts @@ -1,6 +1,6 @@ import { Extractor } from './types'; import { Fetcher } from '../utils'; -import { Context } from '../types'; +import { Context, Meta } from '../types'; export class ExternalUrl implements Extractor { readonly id = 'external'; @@ -17,7 +17,7 @@ export class ExternalUrl implements Extractor { readonly supports = (url: URL): boolean => null !== url.host.match(/.*/); - readonly extract = async (ctx: Context, url: URL, countryCode: string) => { + readonly extract = async (ctx: Context, url: URL, meta: Meta) => { // We only want to make sure that the URL is accessible await this.fetcher.head(ctx, url); @@ -25,10 +25,8 @@ export class ExternalUrl implements Extractor { url: url, isExternal: true, label: `${url.host}`, - sourceId: `${this.id}_${countryCode.toLowerCase()}`, - height: 0, - bytes: 0, - countryCode, + sourceId: `${this.id}_${meta.countryCode.toLowerCase()}`, + meta, }; }; } diff --git a/src/extractor/ExtractorRegistry.test.ts b/src/extractor/ExtractorRegistry.test.ts index 6bf5fcd..5e39223 100644 --- a/src/extractor/ExtractorRegistry.test.ts +++ b/src/extractor/ExtractorRegistry.test.ts @@ -13,27 +13,27 @@ describe('ExtractorRegistry', () => { const ctx: Context = { id: 'id', ip: '127.0.0.1', config: { de: 'on' } }; test('returns undefined when no extractor can be found', async () => { - const urlResult = await extractorRegistry.handle(ctx, new URL('https://some-url.test'), 'en'); + const urlResult = await extractorRegistry.handle(ctx, new URL('https://some-url.test'), { countryCode: 'en' }); expect(urlResult).toBeUndefined(); }); test('returns from memory cache if possible', async () => { - const urlResult1 = await extractorRegistry.handle(ctx, new URL('https://dropload.io/lyo2h1snpe5c.html'), 'de'); - const urlResult2 = await extractorRegistry.handle(ctx, new URL('https://dropload.io/lyo2h1snpe5c.html'), 'de'); + const urlResult1 = await extractorRegistry.handle(ctx, new URL('https://dropload.io/lyo2h1snpe5c.html'), { countryCode: 'de' }); + const urlResult2 = await extractorRegistry.handle(ctx, new URL('https://dropload.io/lyo2h1snpe5c.html'), { countryCode: 'de' }); expect(urlResult2).toBe(urlResult1); }); test('returns from memory cache if possible', async () => { - const urlResult1 = await extractorRegistry.handle(ctx, new URL('https://dropload.io/lyo2h1snpe5c.html'), 'de'); - const urlResult2 = await extractorRegistry.handle(ctx, new URL('https://dropload.io/lyo2h1snpe5c.html'), 'de'); + const urlResult1 = await extractorRegistry.handle(ctx, new URL('https://dropload.io/lyo2h1snpe5c.html'), { countryCode: 'de' }); + const urlResult2 = await extractorRegistry.handle(ctx, new URL('https://dropload.io/lyo2h1snpe5c.html'), { countryCode: 'de' }); expect(urlResult2).toBe(urlResult1); }); test('ignores not found errors', async () => { - const urlResult = await extractorRegistry.handle(ctx, new URL('https://dropload.io/asdfghijklmn.html'), 'de'); + const urlResult = await extractorRegistry.handle(ctx, new URL('https://dropload.io/asdfghijklmn.html'), { countryCode: 'de' }); expect(urlResult).toBeUndefined(); }); diff --git a/src/extractor/ExtractorRegistry.ts b/src/extractor/ExtractorRegistry.ts index ab01cfd..bd5062e 100644 --- a/src/extractor/ExtractorRegistry.ts +++ b/src/extractor/ExtractorRegistry.ts @@ -1,7 +1,7 @@ import TTLCache from '@isaacs/ttlcache'; import winston from 'winston'; import { Extractor } from './types'; -import { Context, UrlResult } from '../types'; +import { Context, Meta, UrlResult } from '../types'; import { Fetcher } from '../utils'; import { DoodStream } from './DoodStream'; import { Dropload } from './Dropload'; @@ -25,7 +25,7 @@ export class ExtractorRegistry { this.urlResultCache = new TTLCache({ max: 1024 }); } - readonly handle = async (ctx: Context, url: URL, countryCode: string): Promise => { + readonly handle = async (ctx: Context, url: URL, meta: Meta): Promise => { let urlResult = this.urlResultCache.get(url.href); if (this.urlResultCache.has(url.href)) { return urlResult; @@ -35,7 +35,7 @@ export class ExtractorRegistry { this.logger.info(`Extract stream URL using ${extractor.id} extractor from ${url}`, ctx); try { - urlResult = await extractor.extract(ctx, url, countryCode); + urlResult = await extractor.extract(ctx, url, meta); } catch (error) { if (error instanceof NotFoundError) { this.urlResultCache.set(url.href, urlResult, { ttl: extractor.ttl }); diff --git a/src/extractor/SuperVideo.ts b/src/extractor/SuperVideo.ts index baaec3d..31ca572 100644 --- a/src/extractor/SuperVideo.ts +++ b/src/extractor/SuperVideo.ts @@ -1,7 +1,7 @@ import bytes from 'bytes'; import { Extractor } from './types'; import { extractUrlFromPacked, Fetcher } from '../utils'; -import { Context } from '../types'; +import { Context, Meta } from '../types'; export class SuperVideo implements Extractor { readonly id = 'supervideo'; @@ -18,7 +18,7 @@ export class SuperVideo implements Extractor { readonly supports = (url: URL): boolean => null !== url.host.match(/supervideo/); - readonly extract = async (ctx: Context, url: URL, countryCode: string) => { + readonly extract = async (ctx: Context, url: URL, meta: Meta) => { url.pathname = url.pathname.replace('/e/', '').replace('/embed-', '/'); const html = await this.fetcher.text(ctx, url); @@ -27,10 +27,12 @@ export class SuperVideo implements Extractor { return { url: extractUrlFromPacked(html, [/sources:\[{file:"(.*?)"/]), label: this.label, - sourceId: `${this.id}_${countryCode.toLowerCase()}`, - height: parseInt(heightAndSizeMatch[1] as string) as number, - bytes: bytes.parse(heightAndSizeMatch[2] as string) as number, - countryCode, + sourceId: `${this.id}_${meta.countryCode.toLowerCase()}`, + meta: { + ...meta, + bytes: bytes.parse(heightAndSizeMatch[2] as string) as number, + height: parseInt(heightAndSizeMatch[1] as string) as number, + }, }; }; } diff --git a/src/extractor/types.ts b/src/extractor/types.ts index 124ee64..fdb7013 100644 --- a/src/extractor/types.ts +++ b/src/extractor/types.ts @@ -1,4 +1,4 @@ -import { Context, UrlResult } from '../types'; +import { Context, Meta, UrlResult } from '../types'; export interface Extractor { readonly id: string; @@ -9,5 +9,5 @@ export interface Extractor { readonly supports: (url: URL) => boolean; - readonly extract: (ctx: Context, url: URL, countryCode: string) => Promise; + readonly extract: (ctx: Context, url: URL, meta: Meta) => Promise; } diff --git a/src/handler/CineHDPlus.ts b/src/handler/CineHDPlus.ts index f8ed645..96cb755 100644 --- a/src/handler/CineHDPlus.ts +++ b/src/handler/CineHDPlus.ts @@ -49,7 +49,7 @@ export class CineHDPlus implements Handler { .map((_i, el) => new URL(($(el).attr('data-link') as string).replace(/^(https:)?\/\//, 'https://'))) .toArray() .filter(url => !url.host.match(/cinehdplus/)) - .map(url => this.extractorRegistry.handle(ctx, url, countryCode)), + .map(url => this.extractorRegistry.handle(ctx, url, { countryCode })), ); }; diff --git a/src/handler/Eurostreaming.ts b/src/handler/Eurostreaming.ts index a185215..7edd5de 100644 --- a/src/handler/Eurostreaming.ts +++ b/src/handler/Eurostreaming.ts @@ -47,7 +47,7 @@ export class Eurostreaming implements Handler { .map((_i, el) => new URL(($(el).attr('data-link') as string).replace(/^(https:)?\/\//, 'https://'))) .toArray() .filter(url => !url.host.match(/eurostreaming/)) - .map(url => this.extractorRegistry.handle(ctx, url, 'it')), + .map(url => this.extractorRegistry.handle(ctx, url, { countryCode: 'it' })), ); }; diff --git a/src/handler/Frembed.ts b/src/handler/Frembed.ts index 0eaa27f..177e8d9 100644 --- a/src/handler/Frembed.ts +++ b/src/handler/Frembed.ts @@ -46,7 +46,7 @@ export class Frembed implements Handler { } } - return Promise.all(urls.map(url => this.extractorRegistry.handle(ctx, url, 'fr'))); + return Promise.all(urls.map(url => this.extractorRegistry.handle(ctx, url, { countryCode: 'fr' }))); }; private readonly apiCall = async (ctx: Context, url: URL): Promise => { diff --git a/src/handler/FrenchCloud.ts b/src/handler/FrenchCloud.ts index bc6648c..65f9468 100644 --- a/src/handler/FrenchCloud.ts +++ b/src/handler/FrenchCloud.ts @@ -35,7 +35,7 @@ export class FrenchCloud implements Handler { .map((_i, el) => new URL(($(el).attr('data-link') as string).replace(/^(https:)?\/\//, 'https://'))) .toArray() .filter(url => !url.host.match(/frenchcloud/)) - .map(url => this.extractorRegistry.handle(ctx, url, 'fr')), + .map(url => this.extractorRegistry.handle(ctx, url, { countryCode: 'fr' })), ); }; } diff --git a/src/handler/KinoKiste.ts b/src/handler/KinoKiste.ts index ff7f880..963e1ce 100644 --- a/src/handler/KinoKiste.ts +++ b/src/handler/KinoKiste.ts @@ -44,7 +44,7 @@ export class KinoKiste implements Handler { .map((_i, el) => new URL(($(el).attr('data-link') as string).replace(/^(https:)?\/\//, 'https://'))) .toArray() .filter(url => !url.host.match(/kinokiste/)) - .map(url => this.extractorRegistry.handle(ctx, url, 'de')), + .map(url => this.extractorRegistry.handle(ctx, url, { countryCode: 'de' })), ); }; diff --git a/src/handler/MeineCloud.ts b/src/handler/MeineCloud.ts index 7f6efa6..08d28b2 100644 --- a/src/handler/MeineCloud.ts +++ b/src/handler/MeineCloud.ts @@ -35,7 +35,7 @@ export class MeineCloud implements Handler { .map((_i, el) => new URL(($(el).attr('data-link') as string).replace(/^(https:)?\/\//, 'https://'))) .toArray() .filter(url => !url.host.match(/meinecloud/)) - .map(url => this.extractorRegistry.handle(ctx, url, 'de')), + .map(url => this.extractorRegistry.handle(ctx, url, { countryCode: 'de' })), ); }; } diff --git a/src/handler/MostraGuarda.ts b/src/handler/MostraGuarda.ts index 73a6e31..9c9bab2 100644 --- a/src/handler/MostraGuarda.ts +++ b/src/handler/MostraGuarda.ts @@ -35,7 +35,7 @@ export class MostraGuarda implements Handler { .map((_i, el) => new URL(($(el).attr('data-link') as string).replace(/^(https:)?\/\//, 'https://'))) .toArray() .filter(url => !url.host.match(/mostraguarda/)) - .map(url => this.extractorRegistry.handle(ctx, url, 'it')), + .map(url => this.extractorRegistry.handle(ctx, url, { countryCode: 'it' })), ); }; } diff --git a/src/handler/VerHdLink.ts b/src/handler/VerHdLink.ts index 3e27e8a..2a085f6 100644 --- a/src/handler/VerHdLink.ts +++ b/src/handler/VerHdLink.ts @@ -46,7 +46,7 @@ export class VerHdLink implements Handler { .map((_i, el) => new URL(($(el).attr('data-link') as string).replace(/^(https:)?\/\//, 'https://'))) .toArray() .filter(url => !url.host.match(/verhdlink/)) - .map(url => this.extractorRegistry.handle(ctx, url, countryCode)); + .map(url => this.extractorRegistry.handle(ctx, url, { countryCode })); }), ); }; diff --git a/src/handler/__snapshots__/CineHDPlus.test.ts.snap b/src/handler/__snapshots__/CineHDPlus.test.ts.snap index bc0df7d..80abc85 100644 --- a/src/handler/__snapshots__/CineHDPlus.test.ts.snap +++ b/src/handler/__snapshots__/CineHDPlus.test.ts.snap @@ -3,18 +3,22 @@ exports[`CineHDPlus handle imdb babylon 5 s2e3 (es) 1`] = ` [ { - "bytes": 219571814, - "countryCode": "es", - "height": 344, "label": "SuperVideo", + "meta": { + "bytes": 219571814, + "countryCode": "es", + "height": 344, + }, "sourceId": "supervideo_es", "url": "https://hfs294.serversicuro.cc/hls/,dnzpealv5xg4a3gyvavh52jryms77x3wwakzvgy2ly3yfusnblczjnvvweua,.urlset/master.m3u8", }, { - "bytes": 219571814, - "countryCode": "es", - "height": 344, "label": "Dropload", + "meta": { + "bytes": 219571814, + "countryCode": "es", + "height": 344, + }, "sourceId": "dropload_es", "url": "https://srv29.dropload.io/hls2/01/00295/957hny8mzrvh_h/master.m3u8?t=VpcZJYlXpp0FJb0Nh0yJR0nyI8-SKB2tGFwpcTx9v2w&s=1747213958&e=14400&f=1476559&i=0.0&sp=0&ii=130.61.236.204", }, @@ -24,18 +28,22 @@ exports[`CineHDPlus handle imdb babylon 5 s2e3 (es) 1`] = ` exports[`CineHDPlus handle imdb black mirror s2e3 (mx) 1`] = ` [ { - "bytes": 146800640, - "countryCode": "mx", - "height": 360, "label": "SuperVideo", + "meta": { + "bytes": 146800640, + "countryCode": "mx", + "height": 360, + }, "sourceId": "supervideo_mx", "url": "https://hfs299.serversicuro.cc/hls/,dnzpff262hg4a3gyvcex5ojxt23vrieljzut7xhjydwidlbp4g7nqswkpfwq,.urlset/master.m3u8", }, { - "bytes": 146800640, - "countryCode": "mx", - "height": 360, "label": "Dropload", + "meta": { + "bytes": 146800640, + "countryCode": "mx", + "height": 360, + }, "sourceId": "dropload_mx", "url": "https://srv27.dropload.io/hls2/01/00075/t058ulwwkwn6_h/master.m3u8?t=GkktV2WgIMrvrgNLyjn6Bxeo2fArEAz6y9nSi_6dVAs&s=1747213564&e=14400&f=376684&i=0.0&sp=0&ii=130.61.236.204", }, diff --git a/src/handler/__snapshots__/Eurostreaming.test.ts.snap b/src/handler/__snapshots__/Eurostreaming.test.ts.snap index 6b8c76b..bdccd17 100644 --- a/src/handler/__snapshots__/Eurostreaming.test.ts.snap +++ b/src/handler/__snapshots__/Eurostreaming.test.ts.snap @@ -3,26 +3,32 @@ exports[`Eurostreaming handle imdb black mirror s2e4 1`] = ` [ { - "bytes": 875875532, - "countryCode": "it", - "height": 1080, "label": "SuperVideo", + "meta": { + "bytes": 875875532, + "countryCode": "it", + "height": 1080, + }, "sourceId": "supervideo_it", "url": "https://hfs309.serversicuro.cc/hls/dnzpdeoe5xg4a3gyvaqx5ojpswtxjd5a22rklgah7,khdhascykjrixs7huqq,obtfascykj3vna7rk5a,.urlset/master.m3u8", }, { - "bytes": 875875532, - "countryCode": "it", - "height": 1080, "label": "SuperVideo", + "meta": { + "bytes": 875875532, + "countryCode": "it", + "height": 1080, + }, "sourceId": "supervideo_it", "url": "https://hfs309.serversicuro.cc/hls/dnzpdeoe5xg4a3gyvaqx5ojpswtxjd5a22rklgah7,khdhascykjrixs7huqq,obtfascykj3vna7rk5a,.urlset/master.m3u8", }, { - "bytes": 875875532, - "countryCode": "it", - "height": 1080, "label": "Dropload", + "meta": { + "bytes": 875875532, + "countryCode": "it", + "height": 1080, + }, "sourceId": "dropload_it", "url": "https://srv24.dropload.io/hls2/01/00289/978xyyxi3ldq_h/master.m3u8?t=unq9qxjYC-zgcmoXiSQ6rkMu7qHrSpN_pWOc95IPYwk&s=1747217151&e=14400&f=1448116&i=0.0&sp=0&ii=130.61.236.204", }, diff --git a/src/handler/__snapshots__/Frembed.test.ts.snap b/src/handler/__snapshots__/Frembed.test.ts.snap index dccb9de..35b8c28 100644 --- a/src/handler/__snapshots__/Frembed.test.ts.snap +++ b/src/handler/__snapshots__/Frembed.test.ts.snap @@ -3,10 +3,10 @@ exports[`Frembed handle imdb black mirror s4e2 1`] = ` [ { - "bytes": 0, - "countryCode": "fr", - "height": 0, "label": "DoodStream", + "meta": { + "countryCode": "fr", + }, "requestHeaders": { "Referer": "http://dood.to/", }, @@ -14,20 +14,20 @@ exports[`Frembed handle imdb black mirror s4e2 1`] = ` "url": "https://ee317r.cloudatacdn.com/u5kj63yvxddlsdgge7qremqqka27irwiupc4k7o5cikbh7fdq4j4mwzraf7q/1y4sn4ndoi~mocked-random-string?token=fh3rdlhjvao7chgxndsi3ra7&expiry=639837296000", }, { - "bytes": 0, - "countryCode": "fr", - "height": 0, "isExternal": true, "label": "netu.frembed.art", + "meta": { + "countryCode": "fr", + }, "sourceId": "external_fr", "url": "https://netu.frembed.art/e/0DFgfkcXOsDP", }, { - "bytes": 0, - "countryCode": "fr", - "height": 0, "isExternal": true, "label": "johnalwayssame.com", + "meta": { + "countryCode": "fr", + }, "sourceId": "external_fr", "url": "https://johnalwayssame.com/e/cqy9oue7sv0g", }, diff --git a/src/handler/__snapshots__/FrenchCloud.test.ts.snap b/src/handler/__snapshots__/FrenchCloud.test.ts.snap index 392a786..2e862a5 100644 --- a/src/handler/__snapshots__/FrenchCloud.test.ts.snap +++ b/src/handler/__snapshots__/FrenchCloud.test.ts.snap @@ -3,35 +3,39 @@ exports[`FrenchCloud handle imdb the devil's bath 1`] = ` [ { - "bytes": 966682214, - "countryCode": "fr", - "height": 720, "label": "SuperVideo", + "meta": { + "bytes": 966682214, + "countryCode": "fr", + "height": 720, + }, "sourceId": "supervideo_fr", "url": "https://hfs292.serversicuro.cc/hls/,dnzpfwdj5dg4a3gyvbwx5lbvtu65tuwysrizwl7puv6u7dkpym3afmw5hnga,.urlset/master.m3u8", }, { - "bytes": 966682214, - "countryCode": "fr", - "height": 720, "label": "Dropload", + "meta": { + "bytes": 966682214, + "countryCode": "fr", + "height": 720, + }, "sourceId": "dropload_fr", "url": "https://srv28.dropload.io/hls2/01/00215/w4yit5wiia9y_h/master.m3u8?t=ujTsd4AYOdgaA6EhuMJDrC-xYzMVEbqrrd3qsoZ8iAY&s=1747054860&e=14400&f=1076096&i=0.0&sp=0&ii=130.61.236.204", }, { - "bytes": 0, - "countryCode": "fr", - "height": 0, "isExternal": true, "label": "mixdrop.ag", + "meta": { + "countryCode": "fr", + }, "sourceId": "external_fr", "url": "https://mixdrop.ag/e/l7v73zqrfdj19z", }, { - "bytes": 0, - "countryCode": "fr", - "height": 0, "label": "DoodStream", + "meta": { + "countryCode": "fr", + }, "requestHeaders": { "Referer": "http://dood.to/", }, diff --git a/src/handler/__snapshots__/KinoKiste.test.ts.snap b/src/handler/__snapshots__/KinoKiste.test.ts.snap index 6ec310b..f6fe712 100644 --- a/src/handler/__snapshots__/KinoKiste.test.ts.snap +++ b/src/handler/__snapshots__/KinoKiste.test.ts.snap @@ -3,18 +3,22 @@ exports[`KinoKiste handle imdb black mirror s2e4 1`] = ` [ { - "bytes": 733793484, - "countryCode": "de", - "height": 720, "label": "SuperVideo", + "meta": { + "bytes": 733793484, + "countryCode": "de", + "height": 720, + }, "sourceId": "supervideo_de", "url": "https://hfs279.serversicuro.cc/hls/,dnzpervt3xg4a3gyvdix52ttsqpj5jgxs7keazdmhvru2uyin5g7f67a5u4a,.urlset/master.m3u8", }, { - "bytes": 733793484, - "countryCode": "de", - "height": 720, "label": "Dropload", + "meta": { + "bytes": 733793484, + "countryCode": "de", + "height": 720, + }, "sourceId": "dropload_de", "url": "https://srv34.dropload.io/hls2/01/00007/jvjwrkpijr0f_h/master.m3u8?t=9B5k5sYgDD2kS_549tQ4WYh1o74hO1QR9zzyXrVRqv4&s=1746903685&e=14400&f=35986&srv=srv27&i=0.0&sp=0&ii=130.61.236.204&p1=srv27&p2=srv27", }, diff --git a/src/handler/__snapshots__/MeineCloud.test.ts.snap b/src/handler/__snapshots__/MeineCloud.test.ts.snap index 6ab5760..395ba17 100644 --- a/src/handler/__snapshots__/MeineCloud.test.ts.snap +++ b/src/handler/__snapshots__/MeineCloud.test.ts.snap @@ -3,35 +3,39 @@ exports[`MeineCloud handle imdb the devil's bath 1`] = ` [ { - "bytes": 1073741824, - "countryCode": "de", - "height": 720, "label": "SuperVideo", + "meta": { + "bytes": 1073741824, + "countryCode": "de", + "height": 720, + }, "sourceId": "supervideo_de", "url": "https://hfs290.serversicuro.cc/hls/,dnzpfi3d27g4a3gyvbmh5klwtl65qh654hyjtgupd6p56thhyqu6ra3olbfa,.urlset/master.m3u8", }, { - "bytes": 1395864371, - "countryCode": "de", - "height": 1080, "label": "Dropload", + "meta": { + "bytes": 1395864371, + "countryCode": "de", + "height": 1080, + }, "sourceId": "dropload_de", "url": "https://srv27.dropload.io/hls2/01/00197/lyo2h1snpe5c_h/master.m3u8?t=qTZsRGIMnUjXsQ4o2LRLlsT4tGG1AdJrRBRDGttNLPM&s=1746903744&e=14400&f=987607&i=0.0&sp=0&ii=130.61.236.204", }, { - "bytes": 0, - "countryCode": "de", - "height": 0, "isExternal": true, "label": "mixdrop.ag", + "meta": { + "countryCode": "de", + }, "sourceId": "external_de", "url": "https://mixdrop.ag/e/3nzwveprim63or6", }, { - "bytes": 0, - "countryCode": "de", - "height": 0, "label": "DoodStream", + "meta": { + "countryCode": "de", + }, "requestHeaders": { "Referer": "http://dood.to/", }, diff --git a/src/handler/__snapshots__/MostraGuarda.test.ts.snap b/src/handler/__snapshots__/MostraGuarda.test.ts.snap index 6e83687..c543528 100644 --- a/src/handler/__snapshots__/MostraGuarda.test.ts.snap +++ b/src/handler/__snapshots__/MostraGuarda.test.ts.snap @@ -3,35 +3,39 @@ exports[`MostraGuarda handle imdb the devil's bath 1`] = ` [ { - "bytes": 1181116006, - "countryCode": "it", - "height": 720, "label": "SuperVideo", + "meta": { + "bytes": 1181116006, + "countryCode": "it", + "height": 720, + }, "sourceId": "supervideo_it", "url": "https://hfs279.serversicuro.cc/hls/,dnzpejj427g4a3gyvbth53rxqewqgqqzp3wr6zwutysvud7zroar3cb75d3q,.urlset/master.m3u8", }, { - "bytes": 1181116006, - "countryCode": "it", - "height": 720, "label": "Dropload", + "meta": { + "bytes": 1181116006, + "countryCode": "it", + "height": 720, + }, "sourceId": "dropload_it", "url": "https://srv34.dropload.io/hls2/01/00200/xsr90y2ltdyx_h/master.m3u8?t=avFOZ-10hDxo6__iaoSUrq7o4yY3ldLw6XDlXxpXF8E&s=1747059001&e=14400&f=1004116&srv=srv24&i=0.0&sp=0&ii=130.61.236.204&p1=srv24&p2=srv24", }, { - "bytes": 0, - "countryCode": "it", - "height": 0, "isExternal": true, "label": "mixdrop.ag", + "meta": { + "countryCode": "it", + }, "sourceId": "external_it", "url": "https://mixdrop.ag/e/vk196d6xfzwwo1", }, { - "bytes": 0, - "countryCode": "it", - "height": 0, "label": "DoodStream", + "meta": { + "countryCode": "it", + }, "requestHeaders": { "Referer": "http://dood.to/", }, diff --git a/src/handler/__snapshots__/VerHdLink.test.ts.snap b/src/handler/__snapshots__/VerHdLink.test.ts.snap index 0338cfd..f6fe102 100644 --- a/src/handler/__snapshots__/VerHdLink.test.ts.snap +++ b/src/handler/__snapshots__/VerHdLink.test.ts.snap @@ -3,52 +3,60 @@ exports[`VerHdLink handle titanic 1`] = ` [ { - "bytes": 1503238553, - "countryCode": "mx", - "height": 556, "label": "SuperVideo", + "meta": { + "bytes": 1503238553, + "countryCode": "mx", + "height": 556, + }, "sourceId": "supervideo_mx", "url": "https://hfs292.serversicuro.cc/hls/,dnzpejlw37g4a3gyvdzh5p3xttjqd3ccheao6qexhjbv4ecdpod7hxlh4a7a,.urlset/master.m3u8", }, { - "bytes": 1503238553, - "countryCode": "mx", - "height": 556, "label": "Dropload", + "meta": { + "bytes": 1503238553, + "countryCode": "mx", + "height": 556, + }, "sourceId": "dropload_mx", "url": "https://srv22.dropload.io/hls2/01/00046/jjjx9j5joiz8_h/master.m3u8?t=_sOFVDjKUqBAK_gJtH7YVQnCm6nj7kr4df3PNsKeKAA&s=1747060128&e=14400&f=230703&i=0.0&sp=0&ii=130.61.236.204", }, { - "bytes": 0, - "countryCode": "mx", - "height": 0, "isExternal": true, "label": "mixdrop.ag", + "meta": { + "countryCode": "mx", + }, "sourceId": "external_mx", "url": "https://mixdrop.ag/e/vn0wx308fq984q", }, { - "bytes": 1610612736, - "countryCode": "es", - "height": 544, "label": "SuperVideo", + "meta": { + "bytes": 1610612736, + "countryCode": "es", + "height": 544, + }, "sourceId": "supervideo_es", "url": "https://hfs295.serversicuro.cc/hls/,dnzpfv3w37g4a3gyvdzh5kjeyi4vtoyw4x4it5gxl4zzwiv4t3fxkvagrhea,.urlset/master.m3u8", }, { - "bytes": 1610612736, - "countryCode": "es", - "height": 544, "label": "Dropload", + "meta": { + "bytes": 1610612736, + "countryCode": "es", + "height": 544, + }, "sourceId": "dropload_es", "url": "https://srv23.dropload.io/hls2/01/00046/ick4ti66vt6s_h/master.m3u8?t=OUbNiE0qRNUy69JP4AIj1bGcV5kaljyNrAUlCYWGVOs&s=1747060128&e=14400&f=230700&i=0.0&sp=0&ii=130.61.236.204", }, { - "bytes": 0, - "countryCode": "es", - "height": 0, "isExternal": true, "label": "mixdrop.ag", + "meta": { + "countryCode": "es", + }, "sourceId": "external_es", "url": "https://mixdrop.ag/e/xokzmv61hrwe8o", }, diff --git a/src/types.ts b/src/types.ts index d1d7444..3efd692 100644 --- a/src/types.ts +++ b/src/types.ts @@ -10,13 +10,17 @@ export type ManifestWithConfig = Manifest & { config: ManifestConfig[] }; export type Config = Record; +export interface Meta { + bytes?: number; + countryCode: string; + height?: number; +} + export interface UrlResult { url: URL; isExternal?: boolean; label: string; sourceId: string; - height: number; - bytes: number; - countryCode?: string; + meta: Meta; requestHeaders?: Record; } diff --git a/src/utils/StreamResolver.ts b/src/utils/StreamResolver.ts index b97344e..c78802a 100644 --- a/src/utils/StreamResolver.ts +++ b/src/utils/StreamResolver.ts @@ -52,12 +52,12 @@ export class StreamResolver { await Promise.all(handlerPromises); urlResults.sort((a, b) => { - const heightComparison = b.height - a.height; + const heightComparison = (b.meta.height ?? 0) - (a.meta.height ?? 0); if (heightComparison !== 0) { return heightComparison; } - const bytesComparison = b.bytes - a.bytes; + const bytesComparison = (b.meta.bytes ?? 0) - (a.meta.bytes ?? 0); if (bytesComparison !== 0) { return bytesComparison; } @@ -70,19 +70,19 @@ export class StreamResolver { streams.push( ...urlResults.map((urlResult) => { let name = 'WebStreamr'; - if (urlResult.height) { - name += ` ${urlResult.height}p`; + if (urlResult.meta.height) { + name += ` ${urlResult.meta.height}p`; } if (urlResult.isExternal) { name += ` external`; } let title = urlResult.label; - if (urlResult.bytes) { - title += ` | 💾 ${bytes.format(urlResult.bytes, { unitSeparator: ' ' })}`; + if (urlResult.meta.bytes) { + title += ` | 💾 ${bytes.format(urlResult.meta.bytes, { unitSeparator: ' ' })}`; } - if (urlResult.countryCode) { - title += ` | ${flag(urlResult.countryCode)}`; + if (urlResult.meta.countryCode) { + title += ` | ${flag(urlResult.meta.countryCode)}`; } return { @@ -95,7 +95,7 @@ export class StreamResolver { notWebReady: true, proxyHeaders: { request: urlResult.requestHeaders }, }), - ...(urlResult.bytes && { videoSize: urlResult.bytes }), + ...(urlResult.meta.bytes && { videoSize: urlResult.meta.bytes }), }, }; }),