diff --git a/src/extractor/VixSrc.ts b/src/extractor/VixSrc.ts index fcab676..14720e7 100644 --- a/src/extractor/VixSrc.ts +++ b/src/extractor/VixSrc.ts @@ -28,7 +28,7 @@ export class VixSrc extends Extractor { playlistUrl.searchParams.append('expires', expiresMatch[1] as string); playlistUrl.searchParams.append('h', '1'); - const countryCodes = meta.countryCodes ?? await this.determineCountryCodesFromPlaylist(ctx, playlistUrl, { headers }); + const countryCodes = meta.countryCodes ?? [CountryCode.multi, ...(await this.determineCountryCodesFromPlaylist(ctx, playlistUrl, { headers }))]; if (!hasMultiEnabled(ctx.config) && !countryCodes.some(countryCode => countryCode in ctx.config)) { return []; @@ -42,7 +42,7 @@ export class VixSrc extends Extractor { ttl: this.ttl, meta: { ...meta, - countryCodes: countryCodes.length ? countryCodes : [CountryCode.multi], + countryCodes, height: meta.height ?? await guessHeightFromPlaylist(ctx, this.fetcher, playlistUrl, { headers }), }, }, diff --git a/src/extractor/__snapshots__/VixSrc.test.ts.snap b/src/extractor/__snapshots__/VixSrc.test.ts.snap index 9bf12ef..9965e64 100644 --- a/src/extractor/__snapshots__/VixSrc.test.ts.snap +++ b/src/extractor/__snapshots__/VixSrc.test.ts.snap @@ -7,6 +7,7 @@ exports[`VixSrc Black Mirror 1`] = ` "label": "VixSrc", "meta": { "countryCodes": [ + "multi", "en", "it", ], @@ -28,6 +29,7 @@ exports[`VixSrc Full Metal Jacket 1`] = ` "label": "VixSrc", "meta": { "countryCodes": [ + "multi", "en", "it", ], diff --git a/src/index.ts b/src/index.ts index 52319bd..4df1fac 100644 --- a/src/index.ts +++ b/src/index.ts @@ -50,7 +50,7 @@ const addon = express(); addon.set('trust proxy', true); if (envIsProd()) { - addon.use(rateLimit({ windowMs: 60 * 1000, limit: 10 })); + addon.use(rateLimit({ windowMs: 60 * 1000, limit: 30 })); } addon.use((req: Request, res: Response, next: NextFunction) => { diff --git a/src/source/FourKHDHub.ts b/src/source/FourKHDHub.ts index 69651fe..e811dfd 100644 --- a/src/source/FourKHDHub.ts +++ b/src/source/FourKHDHub.ts @@ -50,7 +50,7 @@ export class FourKHDHub extends Source { $(`.episode-item`) .filter((_i, el) => $('.episode-title', el).text().includes(`S${String(tmdbId.season).padStart(2, '0')}`)) .map((_i, el) => ({ - countryCodes: findCountryCodes($(el).html() as string), + countryCodes: [CountryCode.multi, ...findCountryCodes($(el).html() as string)], downloadItem: $('.episode-download-item', el) .filter((_i, el) => $(el).text().includes(`Episode-${String(tmdbId.episode).padStart(2, '0')}`)) .get(0), @@ -62,7 +62,7 @@ export class FourKHDHub extends Source { return Promise.all( $(`.download-item`) - .map(async (_i, el) => await this.extractSourceResults(ctx, $, el, findCountryCodes($(el).html() as string))) + .map(async (_i, el) => await this.extractSourceResults(ctx, $, el, [CountryCode.multi, ...findCountryCodes($(el).html() as string)])) .toArray(), ); }; diff --git a/src/source/RgShows.ts b/src/source/RgShows.ts index 516805d..2147480 100644 --- a/src/source/RgShows.ts +++ b/src/source/RgShows.ts @@ -8,6 +8,8 @@ export class RgShows extends Source { public readonly label = 'RgShows'; + public override readonly isFallback = true; + public readonly contentTypes: ContentType[] = ['movie', 'series']; public readonly countryCodes: CountryCode[] = [CountryCode.multi]; diff --git a/src/source/Source.ts b/src/source/Source.ts index 86364aa..bca53b1 100644 --- a/src/source/Source.ts +++ b/src/source/Source.ts @@ -27,6 +27,8 @@ export abstract class Source { public readonly ttl: number = 43200000; // 12h + public readonly isFallback: boolean = false; // fallback sources are only considered if we don't have enough URLs from others already + public abstract readonly contentTypes: ContentType[]; public abstract readonly countryCodes: CountryCode[]; diff --git a/src/source/VidSrc.ts b/src/source/VidSrc.ts index 017010b..0ca4688 100644 --- a/src/source/VidSrc.ts +++ b/src/source/VidSrc.ts @@ -8,6 +8,8 @@ export class VidSrc extends Source { public readonly label = 'VidSrc'; + public override readonly isFallback = true; + public readonly contentTypes: ContentType[] = ['movie', 'series']; public readonly countryCodes: CountryCode[] = [CountryCode.multi]; diff --git a/src/source/__snapshots__/FourKHDHub.test.ts.snap b/src/source/__snapshots__/FourKHDHub.test.ts.snap index 0aaa42f..c6f7088 100644 --- a/src/source/__snapshots__/FourKHDHub.test.ts.snap +++ b/src/source/__snapshots__/FourKHDHub.test.ts.snap @@ -6,6 +6,7 @@ exports[`FourKHDHub handle avengers: endgame 1`] = ` "meta": { "bytes": 67645734912, "countryCodes": [ + "multi", "en", "hi", ], @@ -18,6 +19,7 @@ exports[`FourKHDHub handle avengers: endgame 1`] = ` "meta": { "bytes": 50036368998, "countryCodes": [ + "multi", "en", "hi", ], @@ -30,6 +32,7 @@ exports[`FourKHDHub handle avengers: endgame 1`] = ` "meta": { "bytes": 37795712204, "countryCodes": [ + "multi", "en", "hi", ], @@ -42,6 +45,7 @@ exports[`FourKHDHub handle avengers: endgame 1`] = ` "meta": { "bytes": 26736171417, "countryCodes": [ + "multi", "en", "hi", ], @@ -54,6 +58,7 @@ exports[`FourKHDHub handle avengers: endgame 1`] = ` "meta": { "bytes": 20615843020, "countryCodes": [ + "multi", "en", "hi", ], @@ -66,6 +71,7 @@ exports[`FourKHDHub handle avengers: endgame 1`] = ` "meta": { "bytes": 17824114278, "countryCodes": [ + "multi", "en", "hi", ], @@ -78,6 +84,7 @@ exports[`FourKHDHub handle avengers: endgame 1`] = ` "meta": { "bytes": 15998753177, "countryCodes": [ + "multi", "en", "hi", ], @@ -90,6 +97,7 @@ exports[`FourKHDHub handle avengers: endgame 1`] = ` "meta": { "bytes": 9126805504, "countryCodes": [ + "multi", "en", "hi", ], @@ -102,6 +110,7 @@ exports[`FourKHDHub handle avengers: endgame 1`] = ` "meta": { "bytes": 8321499136, "countryCodes": [ + "multi", "en", "hi", ], @@ -114,6 +123,7 @@ exports[`FourKHDHub handle avengers: endgame 1`] = ` "meta": { "bytes": 8010114007, "countryCodes": [ + "multi", "en", "hi", ], @@ -126,6 +136,7 @@ exports[`FourKHDHub handle avengers: endgame 1`] = ` "meta": { "bytes": 7730941132, "countryCodes": [ + "multi", "en", "hi", ], @@ -138,6 +149,7 @@ exports[`FourKHDHub handle avengers: endgame 1`] = ` "meta": { "bytes": 7000796692, "countryCodes": [ + "multi", "en", "hi", ], @@ -150,6 +162,7 @@ exports[`FourKHDHub handle avengers: endgame 1`] = ` "meta": { "bytes": 4015794421, "countryCodes": [ + "multi", "en", "hi", ], @@ -167,6 +180,7 @@ exports[`FourKHDHub handle crank 2006 1`] = ` "meta": { "bytes": 17255031111, "countryCodes": [ + "multi", "en", "hi", ], @@ -179,6 +193,7 @@ exports[`FourKHDHub handle crank 2006 1`] = ` "meta": { "bytes": 10479720202, "countryCodes": [ + "multi", "en", "hi", ], @@ -191,6 +206,7 @@ exports[`FourKHDHub handle crank 2006 1`] = ` "meta": { "bytes": 4176855695, "countryCodes": [ + "multi", "en", "hi", ], @@ -208,6 +224,7 @@ exports[`FourKHDHub handle crayon shin-chan 1993 1`] = ` "meta": { "bytes": 28550795100, "countryCodes": [ + "multi", "hi", "ja", ], @@ -220,6 +237,7 @@ exports[`FourKHDHub handle crayon shin-chan 1993 1`] = ` "meta": { "bytes": 10383083438, "countryCodes": [ + "multi", "hi", "ja", ], @@ -232,6 +250,7 @@ exports[`FourKHDHub handle crayon shin-chan 1993 1`] = ` "meta": { "bytes": 5776731013, "countryCodes": [ + "multi", "hi", "ja", ], @@ -251,6 +270,7 @@ exports[`FourKHDHub handle dark 2017 s01e02 1`] = ` "meta": { "bytes": 2126008811, "countryCodes": [ + "multi", "de", "en", ], @@ -263,6 +283,7 @@ exports[`FourKHDHub handle dark 2017 s01e02 1`] = ` "meta": { "bytes": 4348654387, "countryCodes": [ + "multi", "de", "en", ], @@ -280,6 +301,7 @@ exports[`FourKHDHub handle dexter original sin 2024 s01e01 1`] = ` "meta": { "bytes": 5733781340, "countryCodes": [ + "multi", "en", ], "height": 2160, @@ -291,6 +313,7 @@ exports[`FourKHDHub handle dexter original sin 2024 s01e01 1`] = ` "meta": { "bytes": 5143223336, "countryCodes": [ + "multi", "en", ], "height": 2160, @@ -302,6 +325,7 @@ exports[`FourKHDHub handle dexter original sin 2024 s01e01 1`] = ` "meta": { "bytes": 5046586572, "countryCodes": [ + "multi", "en", ], "height": 2160, @@ -313,6 +337,7 @@ exports[`FourKHDHub handle dexter original sin 2024 s01e01 1`] = ` "meta": { "bytes": 5057323991, "countryCodes": [ + "multi", "en", ], "height": 2160, @@ -329,6 +354,7 @@ exports[`FourKHDHub handle dexter resurrection 2025 s01e01 1`] = ` "meta": { "bytes": 6012954214, "countryCodes": [ + "multi", "en", ], "height": 2160, @@ -340,6 +366,7 @@ exports[`FourKHDHub handle dexter resurrection 2025 s01e01 1`] = ` "meta": { "bytes": 3285649981, "countryCodes": [ + "multi", "en", ], "height": 1080, @@ -351,6 +378,7 @@ exports[`FourKHDHub handle dexter resurrection 2025 s01e01 1`] = ` "meta": { "bytes": 935109591, "countryCodes": [ + "multi", "en", ], "height": 1080, @@ -367,6 +395,7 @@ exports[`FourKHDHub handle f1 1`] = ` "meta": { "bytes": 71296457113, "countryCodes": [ + "multi", "en", "hi", "ta", @@ -381,6 +410,7 @@ exports[`FourKHDHub handle f1 1`] = ` "meta": { "bytes": 41414222151, "countryCodes": [ + "multi", "en", "hi", "ta", @@ -395,6 +425,7 @@ exports[`FourKHDHub handle f1 1`] = ` "meta": { "bytes": 30096983326, "countryCodes": [ + "multi", "en", "hi", "ta", @@ -409,6 +440,7 @@ exports[`FourKHDHub handle f1 1`] = ` "meta": { "bytes": 29785598197, "countryCodes": [ + "multi", "en", "hi", "ta", @@ -423,6 +455,7 @@ exports[`FourKHDHub handle f1 1`] = ` "meta": { "bytes": 21496311316, "countryCodes": [ + "multi", "en", "hi", "ta", @@ -437,6 +470,7 @@ exports[`FourKHDHub handle f1 1`] = ` "meta": { "bytes": 19520626360, "countryCodes": [ + "multi", "en", "hi", "ta", @@ -451,6 +485,7 @@ exports[`FourKHDHub handle f1 1`] = ` "meta": { "bytes": 11424613007, "countryCodes": [ + "multi", "en", "hi", "ta", @@ -470,6 +505,7 @@ exports[`FourKHDHub handle lovely runner 2024 s01e01 1`] = ` "meta": { "bytes": 3586297692, "countryCodes": [ + "multi", "hi", "ko", ], @@ -482,6 +518,7 @@ exports[`FourKHDHub handle lovely runner 2024 s01e01 1`] = ` "meta": { "bytes": 10340133765, "countryCodes": [ + "multi", "hi", "ko", ], @@ -596,6 +633,7 @@ exports[`FourKHDHub handle superman 2025 1`] = ` "meta": { "bytes": 65326452572, "countryCodes": [ + "multi", "en", "hi", "ta", @@ -610,6 +648,7 @@ exports[`FourKHDHub handle superman 2025 1`] = ` "meta": { "bytes": 36335423324, "countryCodes": [ + "multi", "en", "hi", "ta", @@ -624,6 +663,7 @@ exports[`FourKHDHub handle superman 2025 1`] = ` "meta": { "bytes": 26940182364, "countryCodes": [ + "multi", "en", "hi", "ta", @@ -638,6 +678,7 @@ exports[`FourKHDHub handle superman 2025 1`] = ` "meta": { "bytes": 26671746908, "countryCodes": [ + "multi", "en", "hi", "ta", @@ -652,6 +693,7 @@ exports[`FourKHDHub handle superman 2025 1`] = ` "meta": { "bytes": 26661009489, "countryCodes": [ + "multi", "en", "hi", "ta", @@ -666,6 +708,7 @@ exports[`FourKHDHub handle superman 2025 1`] = ` "meta": { "bytes": 23665269800, "countryCodes": [ + "multi", "en", "hi", "ta", @@ -680,6 +723,7 @@ exports[`FourKHDHub handle superman 2025 1`] = ` "meta": { "bytes": 21775484190, "countryCodes": [ + "multi", "en", "hi", "ta", @@ -694,6 +738,7 @@ exports[`FourKHDHub handle superman 2025 1`] = ` "meta": { "bytes": 20862803640, "countryCodes": [ + "multi", "en", "hi", "ta", @@ -708,6 +753,7 @@ exports[`FourKHDHub handle superman 2025 1`] = ` "meta": { "bytes": 16943645982, "countryCodes": [ + "multi", "en", "hi", "ta", @@ -722,6 +768,7 @@ exports[`FourKHDHub handle superman 2025 1`] = ` "meta": { "bytes": 10307921510, "countryCodes": [ + "multi", "en", "hi", "ta", @@ -736,6 +783,7 @@ exports[`FourKHDHub handle superman 2025 1`] = ` "meta": { "bytes": 9384503541, "countryCodes": [ + "multi", "en", "hi", "ta", @@ -750,6 +798,7 @@ exports[`FourKHDHub handle superman 2025 1`] = ` "meta": { "bytes": 7451768258, "countryCodes": [ + "multi", "en", "hi", "ta", diff --git a/src/source/index.ts b/src/source/index.ts index 9d31170..2cf1b5b 100644 --- a/src/source/index.ts +++ b/src/source/index.ts @@ -28,12 +28,11 @@ export const createSources = (fetcher: Fetcher): Source[] => { return [ // multi new FourKHDHub(fetcher), - new RgShows(fetcher), new VixSrc(fetcher), + new VidSrc(), + new RgShows(fetcher), // AL new Kokoshka(fetcher), - // EN - new VidSrc(), // ES / MX new CineHDPlus(fetcher), new Cuevana(fetcher), diff --git a/src/utils/StreamResolver.test.ts b/src/utils/StreamResolver.test.ts index 974e2fc..5985193 100644 --- a/src/utils/StreamResolver.test.ts +++ b/src/utils/StreamResolver.test.ts @@ -2,21 +2,27 @@ import { ContentType } from 'stremio-addon-sdk'; import winston from 'winston'; import { BlockedError, HttpError, NotFoundError, QueueIsFullError, TimeoutError, TooManyRequestsError, TooManyTimeoutsError } from '../error'; import { createExtractors, Extractor, ExtractorRegistry } from '../extractor'; +import { HubCloud } from '../extractor/HubCloud'; +import { VidSrc as VidSrcExtractor } from '../extractor/VidSrc'; import { Source, SourceResult } from '../source'; +import { FourKHDHub } from '../source/FourKHDHub'; import { MeineCloud } from '../source/MeineCloud'; import { MostraGuarda } from '../source/MostraGuarda'; +import { VidSrc } from '../source/VidSrc'; import { createTestContext } from '../test'; import { BlockedReason, CountryCode, Format, UrlResult } from '../types'; import { FetcherMock } from './FetcherMock'; -import { ImdbId } from './id'; +import { ImdbId, TmdbId } from './id'; import { StreamResolver } from './StreamResolver'; const logger = winston.createLogger({ transports: [new winston.transports.Console({ level: 'nope' })] }); const fetcher = new FetcherMock(`${__dirname}/__fixtures__/StreamResolver`); const ctx = createTestContext({ de: 'on', it: 'on' }); +const fourKhdHub = new FourKHDHub(fetcher); const meineCloud = new MeineCloud(fetcher); const mostraGuarda = new MostraGuarda(fetcher); +const vidSrc = new VidSrc(); describe('resolve', () => { test('returns info as stream if no sources were configured', async () => { @@ -68,6 +74,20 @@ describe('resolve', () => { expect(streamsWithExternalUrls.streams).toMatchSnapshot(); }); + test('skips fallback sources if possible', async () => { + const streamResolver = new StreamResolver(logger, new ExtractorRegistry(logger, [new HubCloud(fetcher), new VidSrcExtractor(fetcher, ['vidsrc-embed.ru'])])); + + const streams = await streamResolver.resolve(createTestContext(), [fourKhdHub, vidSrc], 'movie', new TmdbId(812583, undefined, undefined)); + expect(streams.streams).toMatchSnapshot(); + }); + + test('keeps fallback sources if needed', async () => { + const streamResolver = new StreamResolver(logger, new ExtractorRegistry(logger, [new HubCloud(fetcher), new VidSrcExtractor(fetcher, ['vidsrc-embed.ru'])])); + + const streams = await streamResolver.resolve(createTestContext(), [vidSrc], 'movie', new TmdbId(812583, undefined, undefined)); + expect(streams.streams).toMatchSnapshot(); + }); + test('adds error info', async () => { class MockSource extends Source { public readonly id = 'mocksource'; diff --git a/src/utils/StreamResolver.ts b/src/utils/StreamResolver.ts index 8955c43..5ccf121 100644 --- a/src/utils/StreamResolver.ts +++ b/src/utils/StreamResolver.ts @@ -1,14 +1,15 @@ +import { Mutex } from 'async-mutex'; import bytes from 'bytes'; import { ContentType, Stream } from 'stremio-addon-sdk'; import winston from 'winston'; import { logErrorAndReturnNiceString } from '../error'; import { ExtractorRegistry } from '../extractor'; import { Source } from '../source'; -import { Context, Format, UrlResult } from '../types'; +import { Context, CountryCode, Format, UrlResult } from '../types'; import { showErrors, showExternalUrls } from './config'; import { envGetAppName } from './env'; import { Id } from './id'; -import { flagFromCountryCode } from './language'; +import { countryCodesFromConfig, flagFromCountryCode } from './language'; interface ResolveResponse { streams: Stream[]; @@ -40,22 +41,39 @@ export class StreamResolver { const streams: Stream[] = []; let sourceErrorCount = 0; - const urlResults: UrlResult[] = []; - const sourcePromises = sources.map(async (source) => { - if (!source.contentTypes.includes(type)) { - return; - } + const sourceErrorCountMutex = new Mutex(); + const urlResults: UrlResult[] = []; + + const urlResultsCountByCountryCode = new Map(); + const urlResultsCountByCountryCodeMutex = new Mutex(); + + const skippedFallbackSources: Source[] = []; + + const handleSource = async (source: Source) => { try { const sourceResults = await source.handle(ctx, type, id); - const sourceUrlResults = await Promise.all( sourceResults.map(({ url, meta }) => this.extractorRegistry.handle(ctx, url, { ...meta, sourceLabel: source.label, sourceId: source.id }, true)), ); - urlResults.push(...sourceUrlResults.flat()); + const urlResultsToAdd = sourceUrlResults.flat(); + for (const urlResult of urlResultsToAdd) { + if (urlResult.error) { + continue; + } + + await urlResultsCountByCountryCodeMutex.runExclusive(() => { + urlResult.meta?.countryCodes?.forEach((countryCode) => { + urlResultsCountByCountryCode.set(countryCode, (urlResultsCountByCountryCode.get(countryCode) ?? 0) + 1); + }); + }); + } + urlResults.push(...urlResultsToAdd); } catch (error) { - sourceErrorCount++; + await sourceErrorCountMutex.runExclusive(() => { + sourceErrorCount++; + }); if (showErrors(ctx.config)) { streams.push({ @@ -65,9 +83,34 @@ export class StreamResolver { }); } } + }; + + // Resolve non-fallback sources in parallel extracting all their results + const sourcePromises = sources.map(async (source) => { + if (!source.contentTypes.includes(type)) { + return; + } + + if (source.isFallback) { + skippedFallbackSources.push(source); + return; + } + + await handleSource(source); }); await Promise.all(sourcePromises); + // Resolve fallback sources if we didn't get enough results already + for (const skippedFallbackSource of skippedFallbackSources) { + const configCountryCodes = countryCodesFromConfig(ctx.config); + const resultCount = urlResults.reduce((accumulator, urlResult) => accumulator + Number(this.arraysIntersect(urlResult.meta?.countryCodes as CountryCode[], configCountryCodes)), 0); + if (resultCount > 2) { + continue; + } + + await handleSource(skippedFallbackSource); + } + urlResults.sort((a, b) => { if (a.error || b.error) { return a.isExternal ? -1 : 1; @@ -119,6 +162,10 @@ export class StreamResolver { }; }; + private arraysIntersect(arr1: T[], arr2: T[]): boolean { + return arr1.filter(item => arr2.includes(item)).length > 0; + } + private determineTtl(urlResults: UrlResult[]): number | undefined { if (!urlResults.length) { return 900000; // 15m diff --git a/src/utils/__fixtures__/StreamResolver/head-https:4khdhub.dad b/src/utils/__fixtures__/StreamResolver/head-https:4khdhub.dad new file mode 100644 index 0000000..0b0cdb7 --- /dev/null +++ b/src/utils/__fixtures__/StreamResolver/head-https:4khdhub.dad @@ -0,0 +1 @@ +{"date":"Thu, 15 Jan 2026 13:33:06 GMT","content-type":"text/html; charset=UTF-8","connection":"close","server":"cloudflare","nel":"{\"report_to\":\"cf-nel\",\"success_fraction\":0.0,\"max_age\":604800}","x-turbo-charged-by":"LiteSpeed","expires":"Thu, 19 Nov 1981 08:52:00 GMT","cache-control":"no-store, must-revalidate","pragma":"no-cache","report-to":"{\"group\":\"cf-nel\",\"max_age\":604800,\"endpoints\":[{\"url\":\"https://a.nel.cloudflare.com/report/v4?s=tCHWJJ%2FBuH3jYaypQEgAWtVWsve%2BjP83m%2BuZ4jMQRk%2BLOAoSGca22nV3HU5gzVHQW%2B7DI5AVcaPJSrCqJK4fkN%2FaCvWKm4KoVOzG\"}]}","vary":"Accept-Encoding","cf-cache-status":"MISS","last-modified":"Thu, 15 Jan 2026 13:33:06 GMT","cf-ray":"9be5be30da220ac2-FRA","alt-svc":"h3=\":443\"; ma=86400"} \ No newline at end of file diff --git a/src/utils/__fixtures__/StreamResolver/https:4khdhub.dadsWakepercent20Uppercent20Deadpercent20Manpercent3Apercent20Apercent20Knivespercent20Outpercent20Mystery b/src/utils/__fixtures__/StreamResolver/https:4khdhub.dadsWakepercent20Uppercent20Deadpercent20Manpercent3Apercent20Apercent20Knivespercent20Outpercent20Mystery new file mode 100644 index 0000000..17c01d4 --- /dev/null +++ b/src/utils/__fixtures__/StreamResolver/https:4khdhub.dadsWakepercent20Uppercent20Deadpercent20Manpercent3Apercent20Apercent20Knivespercent20Outpercent20Mystery @@ -0,0 +1,342 @@ + + + + + + + Search - Wake Up Dead Man: A Knives Out Mystery - 4KHDHub + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+
+ +
+ + + + +
+ + + + + +
+ + + + + +
+
+
+ + + + + + + + + +
+ + +
+ +
+ +
+
+
+
+

4KHDHub

+

+ Your one-stop destination for high-quality movies and TV shows in various formats. +

+
+ +
+

Quick Links

+ +
+ +
+

Connect

+

Stay updated with the latest releases and news.

+
+
+ +
+

© 2025 4KHDHub - All rights reserved.

+
+
+
+ + +
+ + + + \ No newline at end of file diff --git a/src/utils/__fixtures__/StreamResolver/https:4khdhub.dadwake-up-dead-man-a-knives-out-mystery-movie-4860 b/src/utils/__fixtures__/StreamResolver/https:4khdhub.dadwake-up-dead-man-a-knives-out-mystery-movie-4860 new file mode 100644 index 0000000..c4b2665 --- /dev/null +++ b/src/utils/__fixtures__/StreamResolver/https:4khdhub.dadwake-up-dead-man-a-knives-out-mystery-movie-4860 @@ -0,0 +1,2125 @@ + + + + + + Wake Up Dead Man: A Knives Out Mystery (2025) - 4K-HDHub + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
+
+ +
+ + + + +
+ + + + + +
+ + + + + +
+
+
+ + + + + + + + + +
+ + +
+
+ + +
+ +
+
+

Wake Up Dead Man: A Knives Out Mystery (2025)

+ + + + +

He works in mysterious ways.

+ +
+ +
+ + 7.4 +
+ + + Comedy + + Crime + + Mystery + + Movies + + 1080p + + 2160p + + Dual Language + + DV HDR + + English + + HEVC + + Hindi + + SDR + + +
+ +
+ +
+
+ + + + +
+ +

+ When young priest Jud Duplenticy is sent to assist charismatic firebrand Monsignor Jefferson Wicks, it’s clear that all is not well in the pews. After a sudden and seemingly impossible murder rocks the town, the lack of an obvious suspect prompts local police chief Geraldine Scott to join forces with renowned detective Benoit Blanc to unravel a mystery that defies all logic.

+ + + + + + +
+ +
+ +

Download Links

+ + + +
+ + +
+
+ +
+ + Wake Up Dead Man: A Knives Out Mystery (2160p WEB-DL HDR DV HEVC) +
20.89 GB + Hindi, English + WEB-DL + +
+ + + + +
+ +
+ +
+
+ +
+ + Wake Up Dead Man: A Knives Out Mystery (2160p WEB-DL HEVC) +
17.97 GB + Hindi, English + WEB-DL + +
+ + + + +
+ +
+ +
+
+ +
+ + Wake Up Dead Man: A Knives Out Mystery (1080p WEB-DL HEVC) +
9.33 GB + Hindi, English + WEB-DL + +
+ + + + +
+ +
+ +
+
+ +
+ + Wake Up Dead Man: A Knives Out Mystery (1080p WEB-DL x264) +
9.3 GB + Hindi, English + WEB-DL + +
+ + + + +
+ +
+ +
+
+ +
+ + Wake Up Dead Man: A Knives Out Mystery (1080p WEB-DL HDR DV HEVC) +
5.32 GB + Hindi, English + WEB-DL + +
+ + + + +
+ +
+ +
+
+ +
+ + Wake Up Dead Man: A Knives Out Mystery (1080p WEB-DL AV1) +
1.28 GB + Hindi, English + WEB-DL + +
+ + + + +
+ +
+ + +
+
+ +
+
+ + + + + +

How to Download

+
+
    +
  1. Click on the download link of your choice.
  2. +
  3. Wait for the page to load and bypass any ads if necessary.
  4. +
  5. Click on the download button on the file hosting site.
  6. +
  7. Enjoy your high-quality movie!
  8. +
+
+ + +
+
+
+
+ +
+
+
+
+

4K-HDHub

+

+ Your one-stop destination for high-quality movies and TV shows in various formats. +

+
+ + +
+

Quick Links

+ +
+ +
+

Connect

+

Stay updated with the latest releases and news.

+
+
+ + +
+

© 2025 4K-HDHub - All rights reserved.

+
+
+
+ + + + + + + + + + + +
+ + + + + diff --git a/src/utils/__fixtures__/StreamResolver/https:api.themoviedb.org3movie812583 b/src/utils/__fixtures__/StreamResolver/https:api.themoviedb.org3movie812583 new file mode 100644 index 0000000..99fe5e2 --- /dev/null +++ b/src/utils/__fixtures__/StreamResolver/https:api.themoviedb.org3movie812583 @@ -0,0 +1 @@ +{"adult":false,"backdrop_path":"/fiRDzpcJe7qz3yIR43hdXIE3NHv.jpg","belongs_to_collection":{"id":722971,"name":"Knives Out Collection","poster_path":"/pkjW3K0UDnwYWDcUR83VzfHNQA4.jpg","backdrop_path":"/G7qYINSq5xyDd0I0zn3DpAssA0.jpg"},"budget":210000000,"genres":[{"id":53,"name":"Thriller"},{"id":9648,"name":"Mystery"},{"id":35,"name":"Comedy"}],"homepage":"https://www.wakeupdeadmanfilm.com/home","id":812583,"imdb_id":"tt14364480","origin_country":["US"],"original_language":"en","original_title":"Wake Up Dead Man: A Knives Out Mystery","overview":"When young priest Jud Duplenticy is sent to assist charismatic firebrand Monsignor Jefferson Wicks, it’s clear that all is not well in the pews. After a sudden and seemingly impossible murder rocks the town, the lack of an obvious suspect prompts local police chief Geraldine Scott to join forces with renowned detective Benoit Blanc to unravel a mystery that defies all logic.","popularity":41.1958,"poster_path":"/qCOGGi8JBVEZMc3DVby8rUivyXz.jpg","production_companies":[{"id":37871,"logo_path":"/aUOo1S2AabqQnRrXK6XuObWPDyK.png","name":"T-Street","origin_country":"US"}],"production_countries":[{"iso_3166_1":"US","name":"United States of America"}],"release_date":"2025-11-26","revenue":4000000,"runtime":145,"spoken_languages":[{"english_name":"English","iso_639_1":"en","name":"English"}],"status":"Released","tagline":"He works in mysterious ways.","title":"Wake Up Dead Man: A Knives Out Mystery","video":false,"vote_average":7.211,"vote_count":1767} \ No newline at end of file diff --git a/src/utils/__fixtures__/StreamResolver/https:cloudnestra.com-0c8acb0a3f7236028f194565b1af79b3 b/src/utils/__fixtures__/StreamResolver/https:cloudnestra.com-0c8acb0a3f7236028f194565b1af79b3 new file mode 100644 index 0000000..d83b0ba --- /dev/null +++ b/src/utils/__fixtures__/StreamResolver/https:cloudnestra.com-0c8acb0a3f7236028f194565b1af79b3 @@ -0,0 +1,145 @@ + + + + + + + + + + + + + + + + +
+
+
+ Wake Up Dead Man: A Knives Out Mystery (2025)
+ +
+
+ +
+ + + + + + + + + + + + + + + + + + diff --git a/src/utils/__fixtures__/StreamResolver/https:cloudnestra.com-bc18cccb96a2e04e8e4615e2576ac261 b/src/utils/__fixtures__/StreamResolver/https:cloudnestra.com-bc18cccb96a2e04e8e4615e2576ac261 new file mode 100644 index 0000000..574b0c7 --- /dev/null +++ b/src/utils/__fixtures__/StreamResolver/https:cloudnestra.com-bc18cccb96a2e04e8e4615e2576ac261 @@ -0,0 +1,942 @@ + + + +Wake Up Dead Man: A Knives Out Mystery (2025) + + + + + + + + + + + +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/utils/__fixtures__/StreamResolver/https:gadgetsweb.xyzidQ1dxTzFnbjhrQm5kMG5lL01tQzcvZzhmMjZOTkNrdktvSEp1VXBaU3FnYzJ3QkJQM1lXVlpSYjREQ3N5aU9GbkNMbkdjd2RPZDJqMHVlSk9CNlQ4MkE9PQ b/src/utils/__fixtures__/StreamResolver/https:gadgetsweb.xyzidQ1dxTzFnbjhrQm5kMG5lL01tQzcvZzhmMjZOTkNrdktvSEp1VXBaU3FnYzJ3QkJQM1lXVlpSYjREQ3N5aU9GbkNMbkdjd2RPZDJqMHVlSk9CNlQ4MkE9PQ new file mode 100644 index 0000000..f34be1b --- /dev/null +++ b/src/utils/__fixtures__/StreamResolver/https:gadgetsweb.xyzidQ1dxTzFnbjhrQm5kMG5lL01tQzcvZzhmMjZOTkNrdktvSEp1VXBaU3FnYzJ3QkJQM1lXVlpSYjREQ3N5aU9GbkNMbkdjd2RPZDJqMHVlSk9CNlQ4MkE9PQ @@ -0,0 +1,20 @@ + + +Redirecting ... + + + + + + + + + +Redirecting .. + + + + \ No newline at end of file diff --git a/src/utils/__fixtures__/StreamResolver/https:gadgetsweb.xyzidQ1dxTzFnbjhrQm5kMG5lL01tQzcvZzhmMjZOTkNrdktvSEp1VXBaU3FnZURBd2FuM2JaTS9Nblcrei95ckVmeXhnUVp6cHlyZVN3VFFIR0hQR0dvTlE9PQ b/src/utils/__fixtures__/StreamResolver/https:gadgetsweb.xyzidQ1dxTzFnbjhrQm5kMG5lL01tQzcvZzhmMjZOTkNrdktvSEp1VXBaU3FnZURBd2FuM2JaTS9Nblcrei95ckVmeXhnUVp6cHlyZVN3VFFIR0hQR0dvTlE9PQ new file mode 100644 index 0000000..7b09451 --- /dev/null +++ b/src/utils/__fixtures__/StreamResolver/https:gadgetsweb.xyzidQ1dxTzFnbjhrQm5kMG5lL01tQzcvZzhmMjZOTkNrdktvSEp1VXBaU3FnZURBd2FuM2JaTS9Nblcrei95ckVmeXhnUVp6cHlyZVN3VFFIR0hQR0dvTlE9PQ @@ -0,0 +1,20 @@ + + +Redirecting ... + + + + + + + + + +Redirecting .. + + + + \ No newline at end of file diff --git a/src/utils/__fixtures__/StreamResolver/https:gadgetsweb.xyzidQ1dxTzFnbjhrQm5kMG5lL01tQzcvZzhmMjZOTkNrdktvSEp1VXBaU3FnZUlZeUtKM2tHc0J2bEp5NnlVSC8xTjJueVpzOXpOeXcxVFZJZmg1ckoxT0E9PQ b/src/utils/__fixtures__/StreamResolver/https:gadgetsweb.xyzidQ1dxTzFnbjhrQm5kMG5lL01tQzcvZzhmMjZOTkNrdktvSEp1VXBaU3FnZUlZeUtKM2tHc0J2bEp5NnlVSC8xTjJueVpzOXpOeXcxVFZJZmg1ckoxT0E9PQ new file mode 100644 index 0000000..3b55c38 --- /dev/null +++ b/src/utils/__fixtures__/StreamResolver/https:gadgetsweb.xyzidQ1dxTzFnbjhrQm5kMG5lL01tQzcvZzhmMjZOTkNrdktvSEp1VXBaU3FnZUlZeUtKM2tHc0J2bEp5NnlVSC8xTjJueVpzOXpOeXcxVFZJZmg1ckoxT0E9PQ @@ -0,0 +1,20 @@ + + +Redirecting ... + + + + + + + + + +Redirecting .. + + + + \ No newline at end of file diff --git a/src/utils/__fixtures__/StreamResolver/https:gadgetsweb.xyzidQ1dxTzFnbjhrQm5kMG5lL01tQzcvZzhmMjZOTkNrdktvSEp1VXBaU3FnZitGdU5NcEhjYk8wZWxzRC9KS3BJa3EzTHRJMXgzZVEwV3RSK3h5czBSZmc9PQ b/src/utils/__fixtures__/StreamResolver/https:gadgetsweb.xyzidQ1dxTzFnbjhrQm5kMG5lL01tQzcvZzhmMjZOTkNrdktvSEp1VXBaU3FnZitGdU5NcEhjYk8wZWxzRC9KS3BJa3EzTHRJMXgzZVEwV3RSK3h5czBSZmc9PQ new file mode 100644 index 0000000..e9611f5 --- /dev/null +++ b/src/utils/__fixtures__/StreamResolver/https:gadgetsweb.xyzidQ1dxTzFnbjhrQm5kMG5lL01tQzcvZzhmMjZOTkNrdktvSEp1VXBaU3FnZitGdU5NcEhjYk8wZWxzRC9KS3BJa3EzTHRJMXgzZVEwV3RSK3h5czBSZmc9PQ @@ -0,0 +1,20 @@ + + +Redirecting ... + + + + + + + + + +Redirecting .. + + + + \ No newline at end of file diff --git a/src/utils/__fixtures__/StreamResolver/https:gadgetsweb.xyzidQ1dxTzFnbjhrQm5kMG5lL01tQzcvZzhmMjZOTkNrdktvSEp1VXBaU3FnZkl4ekFYVUZJVHBaNjUvS1hqVEhPZE4vZDUrMU13M1F4S3MzOEIvdS9kUHc9PQ b/src/utils/__fixtures__/StreamResolver/https:gadgetsweb.xyzidQ1dxTzFnbjhrQm5kMG5lL01tQzcvZzhmMjZOTkNrdktvSEp1VXBaU3FnZkl4ekFYVUZJVHBaNjUvS1hqVEhPZE4vZDUrMU13M1F4S3MzOEIvdS9kUHc9PQ new file mode 100644 index 0000000..19b2761 --- /dev/null +++ b/src/utils/__fixtures__/StreamResolver/https:gadgetsweb.xyzidQ1dxTzFnbjhrQm5kMG5lL01tQzcvZzhmMjZOTkNrdktvSEp1VXBaU3FnZkl4ekFYVUZJVHBaNjUvS1hqVEhPZE4vZDUrMU13M1F4S3MzOEIvdS9kUHc9PQ @@ -0,0 +1,20 @@ + + +Redirecting ... + + + + + + + + + +Redirecting .. + + + + \ No newline at end of file diff --git a/src/utils/__fixtures__/StreamResolver/https:gadgetsweb.xyzidQ1dxTzFnbjhrQm5kMG5lL01tQzcvZzhmMjZOTkNrdktvSEp1VXBaU3FnZnNxVEE4dEo3WUVSOTU4c0t2VSthNTZ3cWR3L2QyTWpHV29FNGdJNk0wTUE9PQ b/src/utils/__fixtures__/StreamResolver/https:gadgetsweb.xyzidQ1dxTzFnbjhrQm5kMG5lL01tQzcvZzhmMjZOTkNrdktvSEp1VXBaU3FnZnNxVEE4dEo3WUVSOTU4c0t2VSthNTZ3cWR3L2QyTWpHV29FNGdJNk0wTUE9PQ new file mode 100644 index 0000000..6c8e8a4 --- /dev/null +++ b/src/utils/__fixtures__/StreamResolver/https:gadgetsweb.xyzidQ1dxTzFnbjhrQm5kMG5lL01tQzcvZzhmMjZOTkNrdktvSEp1VXBaU3FnZnNxVEE4dEo3WUVSOTU4c0t2VSthNTZ3cWR3L2QyTWpHV29FNGdJNk0wTUE9PQ @@ -0,0 +1,20 @@ + + +Redirecting ... + + + + + + + + + +Redirecting .. + + + + \ No newline at end of file diff --git a/src/utils/__fixtures__/StreamResolver/https:gamerxyt.comhubcloud.phphosthubcloudandid4bttg4jurgo151wandtokenYksveTVQSkpSOGJRd1RMeTZaRU4zalJmWityRk5wbHlRb1NqNmczMHZhQT0 b/src/utils/__fixtures__/StreamResolver/https:gamerxyt.comhubcloud.phphosthubcloudandid4bttg4jurgo151wandtokenYksveTVQSkpSOGJRd1RMeTZaRU4zalJmWityRk5wbHlRb1NqNmczMHZhQT0 new file mode 100644 index 0000000..0f90e65 --- /dev/null +++ b/src/utils/__fixtures__/StreamResolver/https:gamerxyt.comhubcloud.phphosthubcloudandid4bttg4jurgo151wandtokenYksveTVQSkpSOGJRd1RMeTZaRU4zalJmWityRk5wbHlRb1NqNmczMHZhQT0 @@ -0,0 +1,376 @@ + + + + + + + +Wake.Up.Dead.Man.A.Knives.Out.Mystery.2025.1080p.NF.WEB-DL.Hindi.DDP5.1.Atmos-English.DDP5.1.Atmos.H.265-4kHdHub.Com.mkv + + + + + + + + + + + + + + + + + + + + +
+
+
+HubCloud | Login +
+ +
+
+

+
+ +
+ +
+ Wake.Up.Dead.Man.A.Knives.Out.Mystery.2025.1080p.NF.WEB-DL.Hindi.DDP5.1.Atmos-English.DDP5.1.Atmos.H.265-4kHdHub.Com.mkv
+ +
+
    +
  • File Size9.33 GB
  • +
  • File Typevideo/x-matrosk
  • +
  • Share Date12-Dec-2025 08:21:55
  • +
+ +
+
+ + +
+

Download Link Generated

+
+ +
+ Copy Share Link +
+
+ + + + + + + + + +
+ + +
+ + + + + + Download [FSL Server] + + + + + + + + + + Download [Server : 10Gbps] + +

+ Resume Not Supported in 10Gbps So Use only if you have stable internet (: +

+ + + + + + + Download [PixelServer : 2] + + + + + + + + + + + + + + + + + + + +

+ + + + + + +
+ + + +
+
+ +
+ +
+
+
+

+
+Msc + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/utils/__fixtures__/StreamResolver/https:gamerxyt.comhubcloud.phphosthubcloudandid6w6tm1hfcsmshwkandtokenZmVqK0pteE9QemNSbmc0b1l0eVM3anJjWmRLZlhZRkwybmJpeGplM3c0UT0 b/src/utils/__fixtures__/StreamResolver/https:gamerxyt.comhubcloud.phphosthubcloudandid6w6tm1hfcsmshwkandtokenZmVqK0pteE9QemNSbmc0b1l0eVM3anJjWmRLZlhZRkwybmJpeGplM3c0UT0 new file mode 100644 index 0000000..d8a1c2b --- /dev/null +++ b/src/utils/__fixtures__/StreamResolver/https:gamerxyt.comhubcloud.phphosthubcloudandid6w6tm1hfcsmshwkandtokenZmVqK0pteE9QemNSbmc0b1l0eVM3anJjWmRLZlhZRkwybmJpeGplM3c0UT0 @@ -0,0 +1,376 @@ + + + + + + + +Wake.Up.Dead.Man.A.Knives.Out.Mystery.2025.1080p.NF.WEB-DL.Hindi.DDP5.1.Atmos-English.DDP5.1.Atmos.HDR-DV.H.265-4kHdHub.Com.mkv + + + + + + + + + + + + + + + + + + + + +
+
+
+HubCloud | Login +
+ +
+
+

+
+ +
+ +
+ Wake.Up.Dead.Man.A.Knives.Out.Mystery.2025.1080p.NF.WEB-DL.Hindi.DDP5.1.Atmos-English.DDP5.1.Atmos.HDR-DV.H.265-4kHdHub.Com.mkv
+ +
+
    +
  • File Size5.32 GB
  • +
  • File Typevideo/x-matrosk
  • +
  • Share Date12-Dec-2025 08:21:00
  • +
+ +
+
+ + +
+

Download Link Generated

+
+ +
+ Copy Share Link +
+
+ + + + + + + + + +
+ + +
+ + + + + + Download [FSL Server] + + + + + + + + + + Download [Server : 10Gbps] + +

+ Resume Not Supported in 10Gbps So Use only if you have stable internet (: +

+ + + + + + + Download [PixelServer : 2] + + + + + + + + + + + + + + + + + + + +

+ + + + + + +
+ + + +
+
+ +
+ +
+
+
+

+
+Msc + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/utils/__fixtures__/StreamResolver/https:gamerxyt.comhubcloud.phphosthubcloudandida55vjuuwj4vbthaandtokenNlgvb1l0TVNtUlNqbEFxTm5yNUJ2eWdEWFMvK2ZhdVgxNWJMSlQwOXJsMD0 b/src/utils/__fixtures__/StreamResolver/https:gamerxyt.comhubcloud.phphosthubcloudandida55vjuuwj4vbthaandtokenNlgvb1l0TVNtUlNqbEFxTm5yNUJ2eWdEWFMvK2ZhdVgxNWJMSlQwOXJsMD0 new file mode 100644 index 0000000..01825d7 --- /dev/null +++ b/src/utils/__fixtures__/StreamResolver/https:gamerxyt.comhubcloud.phphosthubcloudandida55vjuuwj4vbthaandtokenNlgvb1l0TVNtUlNqbEFxTm5yNUJ2eWdEWFMvK2ZhdVgxNWJMSlQwOXJsMD0 @@ -0,0 +1,376 @@ + + + + + + + +Wake.Up.Dead.Man.A.Knives.Out.Mystery.2025.2160p.NF.WEB-DL.DUAL.DDP5.1.Atmos.H.265-4kHDHub.Com.mkv + + + + + + + + + + + + + + + + + + + + +
+
+
+HubCloud | Login +
+ +
+
+

+
+ +
+ +
+ Wake.Up.Dead.Man.A.Knives.Out.Mystery.2025.2160p.NF.WEB-DL.DUAL.DDP5.1.Atmos.H.265-4kHDHub.Com.mkv
+ +
+
    +
  • File Size17.97 GB
  • +
  • File Typevideo/x-matrosk
  • +
  • Share Date12-Dec-2025 08:59:40
  • +
+ +
+
+ + +
+

Download Link Generated

+
+ +
+ Copy Share Link +
+
+ + + + + + + + + +
+ + +
+ + + + + + Download [FSL Server] + + + + + + + + + + Download [Server : 10Gbps] + +

+ Resume Not Supported in 10Gbps So Use only if you have stable internet (: +

+ + + + + + + Download [PixelServer : 2] + + + + + + + + + + + + + + + + + + + +

+ + + + + + +
+ + + +
+
+ +
+ +
+
+
+

+
+Msc + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/utils/__fixtures__/StreamResolver/https:gamerxyt.comhubcloud.phphosthubcloudandidmvsevbmwskarnmyandtokenQjFHOGo1MXB1OFI0Q2YrMjZ6T0NUTWh4THVjUTJWbW5PQk1DVmxqQlNmWT0 b/src/utils/__fixtures__/StreamResolver/https:gamerxyt.comhubcloud.phphosthubcloudandidmvsevbmwskarnmyandtokenQjFHOGo1MXB1OFI0Q2YrMjZ6T0NUTWh4THVjUTJWbW5PQk1DVmxqQlNmWT0 new file mode 100644 index 0000000..40e6bc8 --- /dev/null +++ b/src/utils/__fixtures__/StreamResolver/https:gamerxyt.comhubcloud.phphosthubcloudandidmvsevbmwskarnmyandtokenQjFHOGo1MXB1OFI0Q2YrMjZ6T0NUTWh4THVjUTJWbW5PQk1DVmxqQlNmWT0 @@ -0,0 +1,378 @@ + + + + + + + +Wake.Up.Dead.Man.A.Knives.Out.Mystery.2025.1080p.NF.WEB-DL.Hindi.AAC5.1-English.AAC5.1.AV1-4kHdHub.Com.mkv + + + + + + + + + + + + + + + + + + + + +
+
+
+HubCloud | Login +
+ +
+
+

+
+ +
+ +
+ Wake.Up.Dead.Man.A.Knives.Out.Mystery.2025.1080p.NF.WEB-DL.Hindi.AAC5.1-English.AAC5.1.AV1-4kHdHub.Com.mkv
+ +
+
    +
  • File Size1.28 GB
  • +
  • File Typevideo/x-matrosk
  • +
  • Share Date12-Dec-2025 08:20:28
  • +
+ +
+
+ + +
+

Download Link Generated

+
+ +
+ Copy Share Link +
+
+ + + + + + + + + +
+ + +
+ + + + + + Download [FSL Server] + + + + + + + + + + Download [Server : 10Gbps] + +

+ Resume Not Supported in 10Gbps So Use only if you have stable internet (: +

+ + + + + + + Download [PixelServer : 2] + + + + + + + + + + + + + + +
+ Downoad From Telegram + + + + + +

+ + + + + + +
+ + + +
+
+ +
+ +
+
+
+

+
+Msc + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/utils/__fixtures__/StreamResolver/https:gamerxyt.comhubcloud.phphosthubcloudandidtskphjtms4ovpklandtokenVmRkcG5seHh3K3crb1ZDdnJMNTNuNmFjTzhLNW1TLzhjM0lnK2xncEN0OD0 b/src/utils/__fixtures__/StreamResolver/https:gamerxyt.comhubcloud.phphosthubcloudandidtskphjtms4ovpklandtokenVmRkcG5seHh3K3crb1ZDdnJMNTNuNmFjTzhLNW1TLzhjM0lnK2xncEN0OD0 new file mode 100644 index 0000000..302716b --- /dev/null +++ b/src/utils/__fixtures__/StreamResolver/https:gamerxyt.comhubcloud.phphosthubcloudandidtskphjtms4ovpklandtokenVmRkcG5seHh3K3crb1ZDdnJMNTNuNmFjTzhLNW1TLzhjM0lnK2xncEN0OD0 @@ -0,0 +1,373 @@ + + + + + + + +Wake.Up.Dead.Man.A.Knives.Out.Mystery.2025.2160p.NF.WEB-DL.DUAL.DDP5.1.Atmos.DV.HDR.H.265-4kHDHub.Com.mkv + + + + + + + + + + + + + + + + + + + + +
+
+
+HubCloud | Login +
+ +
+
+

+
+ +
+ +
+ Wake.Up.Dead.Man.A.Knives.Out.Mystery.2025.2160p.NF.WEB-DL.DUAL.DDP5.1.Atmos.DV.HDR.H.265-4kHDHub.Com.mkv
+ +
+
    +
  • File Size20.89 GB
  • +
  • File Typevideo/x-matrosk
  • +
  • Share Date12-Dec-2025 08:59:26
  • +
+ +
+
+ + +
+

Download Link Generated

+
+ +
+ Copy Share Link +
+
+ + + + + + + + + +
+ + +
+ + + + + + Download [FSL Server] + + + + + + + + + + Download [Server : 10Gbps] + +

+ Resume Not Supported in 10Gbps So Use only if you have stable internet (: +

+ + + + + + + + + + + + + + + + + + + + + + + +

+ + + + + + +
+ + + +
+
+ +
+ +
+
+
+

+
+Msc + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/utils/__fixtures__/StreamResolver/https:gamerxyt.comhubcloud.phphosthubcloudandidxoun4ifeynizfs9andtokendEF5YnQ5NUpzWFhjOE5sUjhkZWQ0ZnliVklxWGZlaDAyekwvK2ZxaHlLQT0 b/src/utils/__fixtures__/StreamResolver/https:gamerxyt.comhubcloud.phphosthubcloudandidxoun4ifeynizfs9andtokendEF5YnQ5NUpzWFhjOE5sUjhkZWQ0ZnliVklxWGZlaDAyekwvK2ZxaHlLQT0 new file mode 100644 index 0000000..9da0c89 --- /dev/null +++ b/src/utils/__fixtures__/StreamResolver/https:gamerxyt.comhubcloud.phphosthubcloudandidxoun4ifeynizfs9andtokendEF5YnQ5NUpzWFhjOE5sUjhkZWQ0ZnliVklxWGZlaDAyekwvK2ZxaHlLQT0 @@ -0,0 +1,376 @@ + + + + + + + +Wake.Up.Dead.Man.A.Knives.Out.Mystery.2025.1080p.NF.WEB-DL.Hindi.DDP5.1.Atmos-English.DDP5.1.Atmos.H.264-4kHdHub.Com.mkv + + + + + + + + + + + + + + + + + + + + +
+
+
+HubCloud | Login +
+ +
+
+

+
+ +
+ +
+ Wake.Up.Dead.Man.A.Knives.Out.Mystery.2025.1080p.NF.WEB-DL.Hindi.DDP5.1.Atmos-English.DDP5.1.Atmos.H.264-4kHdHub.Com.mkv
+ +
+
    +
  • File Size9.3 GB
  • +
  • File Typevideo/x-matrosk
  • +
  • Share Date12-Dec-2025 08:04:31
  • +
+ +
+
+ + +
+

Download Link Generated

+
+ +
+ Copy Share Link +
+
+ + + + + + + + + +
+ + +
+ + + + + + Download [FSL Server] + + + + + + + + + + Download [Server : 10Gbps] + +

+ Resume Not Supported in 10Gbps So Use only if you have stable internet (: +

+ + + + + + + Download [PixelServer : 2] + + + + + + + + + + + + + + + + + + + +

+ + + + + + +
+ + + +
+
+ +
+ +
+
+
+

+
+Msc + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/utils/__fixtures__/StreamResolver/https:hubcloud.foodrive4bttg4jurgo151w b/src/utils/__fixtures__/StreamResolver/https:hubcloud.foodrive4bttg4jurgo151w new file mode 100644 index 0000000..bce5308 --- /dev/null +++ b/src/utils/__fixtures__/StreamResolver/https:hubcloud.foodrive4bttg4jurgo151w @@ -0,0 +1,328 @@ + + +Wake.Up.Dead.Man.A.Knives.Out.Mystery.2025.1080p.NF.WEB-DL.Hindi.DDP5.1.Atmos-English.DDP5.1.Atmos.H.265-4kHdHub.Com.mkv + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ + +
+HubCloud | Create An Account |Login +
+
+
+
+

+
+ +
+ +
+ Wake.Up.Dead.Man.A.Knives.Out.Mystery.2025.1080p.NF.WEB-DL.Hindi.DDP5.1.Atmos-English.DDP5.1.Atmos.H.265-4kHdHub.Com.mkv
+ +
+
    +
  • File Size9.33 GB
  • +
  • File Typevideo/x-matrosk
  • +
  • Share Date12-Dec-2025 08:21:55
  • +
+ + +
+
+ + +
+ + + +
+ + + + + +
+ +
+ + + + + + + + + + + + + + + + + + + +

Please Wait While Page is loading

+
+
+ + + + Generate Direct Download Link + + +
+ + + +
+ + + + + +
+

+
+ + + + + +
+ + + + + +
+ + + + + + +
+
+ +
+ +
+
+
+

+
+ + + + + + \ No newline at end of file diff --git a/src/utils/__fixtures__/StreamResolver/https:hubcloud.foodrive6w6tm1hfcsmshwk b/src/utils/__fixtures__/StreamResolver/https:hubcloud.foodrive6w6tm1hfcsmshwk new file mode 100644 index 0000000..de6c772 --- /dev/null +++ b/src/utils/__fixtures__/StreamResolver/https:hubcloud.foodrive6w6tm1hfcsmshwk @@ -0,0 +1,328 @@ + + +Wake.Up.Dead.Man.A.Knives.Out.Mystery.2025.1080p.NF.WEB-DL.Hindi.DDP5.1.Atmos-English.DDP5.1.Atmos.HDR-DV.H.265-4kHdHub.Com.mkv + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ + +
+HubCloud | Create An Account |Login +
+
+
+
+

+
+ +
+ +
+ Wake.Up.Dead.Man.A.Knives.Out.Mystery.2025.1080p.NF.WEB-DL.Hindi.DDP5.1.Atmos-English.DDP5.1.Atmos.HDR-DV.H.265-4kHdHub.Com.mkv
+ +
+
    +
  • File Size5.32 GB
  • +
  • File Typevideo/x-matrosk
  • +
  • Share Date12-Dec-2025 08:21:00
  • +
+ + +
+
+ + +
+ + + +
+ + + + + +
+ +
+ + + + + + + + + + + + + + + + + + + +

Please Wait While Page is loading

+
+
+ + + + Generate Direct Download Link + + +
+ + + +
+ + + + + +
+

+
+ + + + + +
+ + + + + +
+ + + + + + +
+
+ +
+ +
+
+
+

+
+ + + + + + \ No newline at end of file diff --git a/src/utils/__fixtures__/StreamResolver/https:hubcloud.foodrivea55vjuuwj4vbtha b/src/utils/__fixtures__/StreamResolver/https:hubcloud.foodrivea55vjuuwj4vbtha new file mode 100644 index 0000000..f3ade28 --- /dev/null +++ b/src/utils/__fixtures__/StreamResolver/https:hubcloud.foodrivea55vjuuwj4vbtha @@ -0,0 +1,328 @@ + + +Wake.Up.Dead.Man.A.Knives.Out.Mystery.2025.2160p.NF.WEB-DL.DUAL.DDP5.1.Atmos.H.265-4kHDHub.Com.mkv + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ + +
+HubCloud | Create An Account |Login +
+
+
+
+

+
+ +
+ +
+ Wake.Up.Dead.Man.A.Knives.Out.Mystery.2025.2160p.NF.WEB-DL.DUAL.DDP5.1.Atmos.H.265-4kHDHub.Com.mkv
+ +
+
    +
  • File Size17.97 GB
  • +
  • File Typevideo/x-matrosk
  • +
  • Share Date12-Dec-2025 08:59:40
  • +
+ + +
+
+ + +
+ + + +
+ + + + + +
+ +
+ + + + + + + + + + + + + + + + + + + +

Please Wait While Page is loading

+
+
+ + + + Generate Direct Download Link + + +
+ + + +
+ + + + + +
+

+
+ + + + + +
+ + + + + +
+ + + + + + +
+
+ +
+ +
+
+
+

+
+ + + + + + \ No newline at end of file diff --git a/src/utils/__fixtures__/StreamResolver/https:hubcloud.foodrivemvsevbmwskarnmy b/src/utils/__fixtures__/StreamResolver/https:hubcloud.foodrivemvsevbmwskarnmy new file mode 100644 index 0000000..a0ab444 --- /dev/null +++ b/src/utils/__fixtures__/StreamResolver/https:hubcloud.foodrivemvsevbmwskarnmy @@ -0,0 +1,328 @@ + + +Wake.Up.Dead.Man.A.Knives.Out.Mystery.2025.1080p.NF.WEB-DL.Hindi.AAC5.1-English.AAC5.1.AV1-4kHdHub.Com.mkv + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ + +
+HubCloud | Create An Account |Login +
+
+
+
+

+
+ +
+ +
+ Wake.Up.Dead.Man.A.Knives.Out.Mystery.2025.1080p.NF.WEB-DL.Hindi.AAC5.1-English.AAC5.1.AV1-4kHdHub.Com.mkv
+ +
+
    +
  • File Size1.28 GB
  • +
  • File Typevideo/x-matrosk
  • +
  • Share Date12-Dec-2025 08:20:28
  • +
+ + +
+
+ + +
+ + + +
+ + + + + +
+ +
+ + + + + + + + + + + + + + + + + + + +

Please Wait While Page is loading

+
+
+ + + + Generate Direct Download Link + + +
+ + + +
+ + + + + +
+

+
+ + + + + +
+ + + + + +
+ + + + + + +
+
+ +
+ +
+
+
+

+
+ + + + + + \ No newline at end of file diff --git a/src/utils/__fixtures__/StreamResolver/https:hubcloud.foodrivetskphjtms4ovpkl b/src/utils/__fixtures__/StreamResolver/https:hubcloud.foodrivetskphjtms4ovpkl new file mode 100644 index 0000000..49fe578 --- /dev/null +++ b/src/utils/__fixtures__/StreamResolver/https:hubcloud.foodrivetskphjtms4ovpkl @@ -0,0 +1,328 @@ + + +Wake.Up.Dead.Man.A.Knives.Out.Mystery.2025.2160p.NF.WEB-DL.DUAL.DDP5.1.Atmos.DV.HDR.H.265-4kHDHub.Com.mkv + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ + +
+HubCloud | Create An Account |Login +
+
+
+
+

+
+ +
+ +
+ Wake.Up.Dead.Man.A.Knives.Out.Mystery.2025.2160p.NF.WEB-DL.DUAL.DDP5.1.Atmos.DV.HDR.H.265-4kHDHub.Com.mkv
+ +
+
    +
  • File Size20.89 GB
  • +
  • File Typevideo/x-matrosk
  • +
  • Share Date12-Dec-2025 08:59:26
  • +
+ + +
+
+ + +
+ + + +
+ + + + + +
+ +
+ + + + + + + + + + + + + + + + + + + +

Please Wait While Page is loading

+
+
+ + + + Generate Direct Download Link + + +
+ + + +
+ + + + + +
+

+
+ + + + + +
+ + + + + +
+ + + + + + +
+
+ +
+ +
+
+
+

+
+ + + + + + \ No newline at end of file diff --git a/src/utils/__fixtures__/StreamResolver/https:hubcloud.foodrivexoun4ifeynizfs9 b/src/utils/__fixtures__/StreamResolver/https:hubcloud.foodrivexoun4ifeynizfs9 new file mode 100644 index 0000000..010125a --- /dev/null +++ b/src/utils/__fixtures__/StreamResolver/https:hubcloud.foodrivexoun4ifeynizfs9 @@ -0,0 +1,328 @@ + + +Wake.Up.Dead.Man.A.Knives.Out.Mystery.2025.1080p.NF.WEB-DL.Hindi.DDP5.1.Atmos-English.DDP5.1.Atmos.H.264-4kHdHub.Com.mkv + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ + +
+HubCloud | Create An Account |Login +
+
+
+
+

+
+ +
+ +
+ Wake.Up.Dead.Man.A.Knives.Out.Mystery.2025.1080p.NF.WEB-DL.Hindi.DDP5.1.Atmos-English.DDP5.1.Atmos.H.264-4kHdHub.Com.mkv
+ +
+
    +
  • File Size9.3 GB
  • +
  • File Typevideo/x-matrosk
  • +
  • Share Date12-Dec-2025 08:04:31
  • +
+ + +
+
+ + +
+ + + +
+ + + + + +
+ +
+ + + + + + + + + + + + + + + + + + + +

Please Wait While Page is loading

+
+
+ + + + Generate Direct Download Link + + +
+ + + +
+ + + + + +
+

+
+ + + + + +
+ + + + + +
+ + + + + + +
+
+ +
+ +
+
+
+

+
+ + + + + + \ No newline at end of file diff --git a/src/utils/__fixtures__/StreamResolver/https:tmstr4.cloudnestra.com-218ec81a9b9bd0339f6550a292a93989 b/src/utils/__fixtures__/StreamResolver/https:tmstr4.cloudnestra.com-218ec81a9b9bd0339f6550a292a93989 new file mode 100644 index 0000000..d017ab4 --- /dev/null +++ b/src/utils/__fixtures__/StreamResolver/https:tmstr4.cloudnestra.com-218ec81a9b9bd0339f6550a292a93989 @@ -0,0 +1,8 @@ +#EXTM3U +#EXT-X-INDEPENDENT-SEGMENTS +#EXT-X-STREAM-INF:BANDWIDTH=956290,CODECS="mp4a.40.2,avc1.42c01e",RESOLUTION=640x360,FRAME-RATE=24,VIDEO-RANGE=SDR,CLOSED-CAPTIONS=NONE +/pl/H4sIAAAAAAAAAwXB0ZKCIBQA0F8CMSf3sTUrAlpQLsYbqE2jWM7WbOLX7zkk6ck2y3ybo_SW4a5zeer7bXbLvWvRBn1Vo5IsAWoPY5SP8SOJeLUQXhWRaY130aGwCEMXi.6Kl2H2JkxnUl66cZ4VoUxpxWC4pvXxFK9aBIZmCdraPiheYVgtqKH_fv_BQJkn4mBqirwu1x7U7lLQn64Ruk44FkdYvZELfwTCVv3xexn7o_7ravXUw27jcTe7cVZmAmG1iupAn3KCeE1ASNyxS6N_W1JK.Sgbvb9HV1jHCwpt9V5NIZBAtK6M3YiCRzUobJrw5Hsc6ykwF04rH8Tiy5A6Avac2MYB_dgV5f.vyM6uQQEAAA--/7a67bab9038b6ca38d13b08cead24c49/index.m3u8 +#EXT-X-STREAM-INF:BANDWIDTH=3024126,CODECS="mp4a.40.2,avc1.64001f",RESOLUTION=1280x720,FRAME-RATE=24,VIDEO-RANGE=SDR,CLOSED-CAPTIONS=NONE +/pl/H4sIAAAAAAAAAwXB0ZKCIBQA0F8CMSf3sTUrAlpQLsYbqE2jWM7WbOLX7zkk6ck2y3ybo_SW4a5zeer7bXbLvWvRBn1Vo5IsAWoPY5SP8SOJeLUQXhWRaY130aGwCEMXi.6Kl2H2JkxnUl66cZ4VoUxpxWC4pvXxFK9aBIZmCdraPiheYVgtqKH_fv_BQJkn4mBqirwu1x7U7lLQn64Ruk44FkdYvZELfwTCVv3xexn7o_7ravXUw27jcTe7cVZmAmG1iupAn3KCeE1ASNyxS6N_W1JK.Sgbvb9HV1jHCwpt9V5NIZBAtK6M3YiCRzUobJrw5Hsc6ykwF04rH8Tiy5A6Avac2MYB_dgV5f.vyM6uQQEAAA--/7e39f90815d0cbca3fcb1178fb9fa803/index.m3u8 +#EXT-X-STREAM-INF:BANDWIDTH=5679378,CODECS="mp4a.40.2,avc1.640028",RESOLUTION=1920x1080,FRAME-RATE=24,VIDEO-RANGE=SDR,CLOSED-CAPTIONS=NONE +/pl/H4sIAAAAAAAAAwXB0ZKCIBQA0F8CMSf3sTUrAlpQLsYbqE2jWM7WbOLX7zkk6ck2y3ybo_SW4a5zeer7bXbLvWvRBn1Vo5IsAWoPY5SP8SOJeLUQXhWRaY130aGwCEMXi.6Kl2H2JkxnUl66cZ4VoUxpxWC4pvXxFK9aBIZmCdraPiheYVgtqKH_fv_BQJkn4mBqirwu1x7U7lLQn64Ruk44FkdYvZELfwTCVv3xexn7o_7ravXUw27jcTe7cVZmAmG1iupAn3KCeE1ASNyxS6N_W1JK.Sgbvb9HV1jHCwpt9V5NIZBAtK6M3YiCRzUobJrw5Hsc6ykwF04rH8Tiy5A6Avac2MYB_dgV5f.vyM6uQQEAAA--/9e523ae15b61dc766f5c818726881ecf/index.m3u8 \ No newline at end of file diff --git a/src/utils/__fixtures__/StreamResolver/https:vidsrc-embed.ruembedmovie812583 b/src/utils/__fixtures__/StreamResolver/https:vidsrc-embed.ruembedmovie812583 new file mode 100644 index 0000000..e7cc44f --- /dev/null +++ b/src/utils/__fixtures__/StreamResolver/https:vidsrc-embed.ruembedmovie812583 @@ -0,0 +1,274 @@ + + + +Wake Up Dead Man: A Knives Out Mystery (2025) + + + + + + + + + + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + diff --git a/src/utils/__snapshots__/StreamResolver.test.ts.snap b/src/utils/__snapshots__/StreamResolver.test.ts.snap index 57f4bc5..157b9b7 100644 --- a/src/utils/__snapshots__/StreamResolver.test.ts.snap +++ b/src/utils/__snapshots__/StreamResolver.test.ts.snap @@ -167,6 +167,21 @@ exports[`resolve ignores not found errors 1`] = ` } `; +exports[`resolve keeps fallback sources if needed 1`] = ` +[ + { + "behaviorHints": { + "bingeGroup": "webstreamr-vidsrc-vidsrc-multi", + "notWebReady": true, + }, + "name": "WebStreamr 🌐 1080p", + "title": "Wake Up Dead Man: A Knives Out Mystery (2025) +🔗 CloudStream Pro from VidSrc", + "url": "https://tmstr4.cloudnestra.com/pl/H4sIAAAAAAAAAwXB0ZKCIBQA0F8CMSf3sTUrAlpQLsYbqE2jWM7WbOLX7zkk6ck2y3ybo_SW4a5zeer7bXbLvWvRBn1Vo5IsAWoPY5SP8SOJeLUQXhWRaY130aGwCEMXi.6Kl2H2JkxnUl66cZ4VoUxpxWC4pvXxFK9aBIZmCdraPiheYVgtqKH_fv_BQJkn4mBqirwu1x7U7lLQn64Ruk44FkdYvZELfwTCVv3xexn7o_7ravXUw27jcTe7cVZmAmG1iupAn3KCeE1ASNyxS6N_W1JK.Sgbvb9HV1jHCwpt9V5NIZBAtK6M3YiCRzUobJrw5Hsc6ykwF04rH8Tiy5A6Avac2MYB_dgV5f.vyM6uQQEAAA--/master.m3u8", + }, +] +`; + exports[`resolve returns empty array if no source found anything 1`] = ` { "streams": [], @@ -391,3 +406,129 @@ exports[`resolve returns source errors as stream 2`] = ` ], } `; + +exports[`resolve skips fallback sources if possible 1`] = ` +[ + { + "behaviorHints": { + "bingeGroup": "webstreamr-4khdhub-hubcloud_fsl-multi_en_hi", + "notWebReady": true, + "videoSize": 22430466703, + }, + "name": "WebStreamr 🌐 🇺🇸 🇮🇳 2160p", + "title": "Wake.Up.Dead.Man.A.Knives.Out.Mystery.2025.2160p.NF.WEB-DL.DUAL.DDP5.1.Atmos.DV.HDR.H.265-4kHDHub.Com.mkv +💾 20.89 GB 🔗 HubCloud (FSL) from 4KHDHub", + "url": "https://fsl.master.surf/03ee346a29b2b13afa1935bfbd6d05e8?token=1768483596", + }, + { + "behaviorHints": { + "bingeGroup": "webstreamr-4khdhub-hubcloud_fsl-multi_en_hi", + "notWebReady": true, + "videoSize": 19295140577, + }, + "name": "WebStreamr 🌐 🇺🇸 🇮🇳 2160p", + "title": "Wake.Up.Dead.Man.A.Knives.Out.Mystery.2025.2160p.NF.WEB-DL.DUAL.DDP5.1.Atmos.H.265-4kHDHub.Com.mkv +💾 17.97 GB 🔗 HubCloud (FSL) from 4KHDHub", + "url": "https://fsl.master.surf/e25e157cd10b4c203ad281a9280d5931?token=1768483596", + }, + { + "behaviorHints": { + "bingeGroup": "webstreamr-4khdhub-hubcloud_pixelserver-multi_en_hi", + "notWebReady": true, + "videoSize": 19295140577, + }, + "name": "WebStreamr 🌐 🇺🇸 🇮🇳 2160p", + "title": "Wake.Up.Dead.Man.A.Knives.Out.Mystery.2025.2160p.NF.WEB-DL.DUAL.DDP5.1.Atmos.H.265-4kHDHub.Com.mkv +💾 17.97 GB 🔗 HubCloud (PixelServer) from 4KHDHub", + "url": "https://pixeldrain.dev/api/file/Kd5MqbDS", + }, + { + "behaviorHints": { + "bingeGroup": "webstreamr-4khdhub-hubcloud_fsl-multi_en_hi", + "notWebReady": true, + "videoSize": 10018011217, + }, + "name": "WebStreamr 🌐 🇺🇸 🇮🇳 1080p", + "title": "Wake.Up.Dead.Man.A.Knives.Out.Mystery.2025.1080p.NF.WEB-DL.Hindi.DDP5.1.Atmos-English.DDP5.1.Atmos.H.265-4kHdHub.Com.mkv +💾 9.33 GB 🔗 HubCloud (FSL) from 4KHDHub", + "url": "https://fsl.master.surf/7a5fb128b139c4170291e04f0f6cd729?token=1768483596", + }, + { + "behaviorHints": { + "bingeGroup": "webstreamr-4khdhub-hubcloud_pixelserver-multi_en_hi", + "notWebReady": true, + "videoSize": 10018011217, + }, + "name": "WebStreamr 🌐 🇺🇸 🇮🇳 1080p", + "title": "Wake.Up.Dead.Man.A.Knives.Out.Mystery.2025.1080p.NF.WEB-DL.Hindi.DDP5.1.Atmos-English.DDP5.1.Atmos.H.265-4kHdHub.Com.mkv +💾 9.33 GB 🔗 HubCloud (PixelServer) from 4KHDHub", + "url": "https://pixeldrain.dev/api/file/h7hpWDSW", + }, + { + "behaviorHints": { + "bingeGroup": "webstreamr-4khdhub-hubcloud_fsl-multi_en_hi", + "notWebReady": true, + "videoSize": 9985798963, + }, + "name": "WebStreamr 🌐 🇺🇸 🇮🇳 1080p", + "title": "Wake.Up.Dead.Man.A.Knives.Out.Mystery.2025.1080p.NF.WEB-DL.Hindi.DDP5.1.Atmos-English.DDP5.1.Atmos.H.264-4kHdHub.Com.mkv +💾 9.3 GB 🔗 HubCloud (FSL) from 4KHDHub", + "url": "https://fsl.master.surf/f956e46a610fa88657d505d07be917e9?token=1768483435", + }, + { + "behaviorHints": { + "bingeGroup": "webstreamr-4khdhub-hubcloud_pixelserver-multi_en_hi", + "notWebReady": true, + "videoSize": 9985798963, + }, + "name": "WebStreamr 🌐 🇺🇸 🇮🇳 1080p", + "title": "Wake.Up.Dead.Man.A.Knives.Out.Mystery.2025.1080p.NF.WEB-DL.Hindi.DDP5.1.Atmos-English.DDP5.1.Atmos.H.264-4kHdHub.Com.mkv +💾 9.3 GB 🔗 HubCloud (PixelServer) from 4KHDHub", + "url": "https://pixeldrain.dev/api/file/yzyxiGzC", + }, + { + "behaviorHints": { + "bingeGroup": "webstreamr-4khdhub-hubcloud_fsl-multi_en_hi", + "notWebReady": true, + "videoSize": 5712306503, + }, + "name": "WebStreamr 🌐 🇺🇸 🇮🇳 1080p", + "title": "Wake.Up.Dead.Man.A.Knives.Out.Mystery.2025.1080p.NF.WEB-DL.Hindi.DDP5.1.Atmos-English.DDP5.1.Atmos.HDR-DV.H.265-4kHdHub.Com.mkv +💾 5.32 GB 🔗 HubCloud (FSL) from 4KHDHub", + "url": "https://fsl.master.surf/27df6ba61996f9a2e1725d5faa4a0cbb?token=1768483596", + }, + { + "behaviorHints": { + "bingeGroup": "webstreamr-4khdhub-hubcloud_pixelserver-multi_en_hi", + "notWebReady": true, + "videoSize": 5712306503, + }, + "name": "WebStreamr 🌐 🇺🇸 🇮🇳 1080p", + "title": "Wake.Up.Dead.Man.A.Knives.Out.Mystery.2025.1080p.NF.WEB-DL.Hindi.DDP5.1.Atmos-English.DDP5.1.Atmos.HDR-DV.H.265-4kHdHub.Com.mkv +💾 5.32 GB 🔗 HubCloud (PixelServer) from 4KHDHub", + "url": "https://pixeldrain.dev/api/file/gPsPz3B7", + }, + { + "behaviorHints": { + "bingeGroup": "webstreamr-4khdhub-hubcloud_fsl-multi_en_hi", + "notWebReady": true, + "videoSize": 1374389534, + }, + "name": "WebStreamr 🌐 🇺🇸 🇮🇳 1080p", + "title": "Wake.Up.Dead.Man.A.Knives.Out.Mystery.2025.1080p.NF.WEB-DL.Hindi.AAC5.1-English.AAC5.1.AV1-4kHdHub.Com.mkv +💾 1.28 GB 🔗 HubCloud (FSL) from 4KHDHub", + "url": "https://fsl.master.surf/f391f8beec927157dc784b261af950c2?token=1768483596", + }, + { + "behaviorHints": { + "bingeGroup": "webstreamr-4khdhub-hubcloud_pixelserver-multi_en_hi", + "notWebReady": true, + "videoSize": 1374389534, + }, + "name": "WebStreamr 🌐 🇺🇸 🇮🇳 1080p", + "title": "Wake.Up.Dead.Man.A.Knives.Out.Mystery.2025.1080p.NF.WEB-DL.Hindi.AAC5.1-English.AAC5.1.AV1-4kHdHub.Com.mkv +💾 1.28 GB 🔗 HubCloud (PixelServer) from 4KHDHub", + "url": "https://pixeldrain.dev/api/file/XsNetT2P", + }, +] +`; diff --git a/src/utils/__snapshots__/manifest.test.ts.snap b/src/utils/__snapshots__/manifest.test.ts.snap index 7982062..0a31055 100644 --- a/src/utils/__snapshots__/manifest.test.ts.snap +++ b/src/utils/__snapshots__/manifest.test.ts.snap @@ -86,7 +86,7 @@ exports[`buildManifest default manifest 1`] = ` Supported languages: Albanian, German, Castilian Spanish, French, Hindi, Italian, Latin American Spanish, Tamil, Telugu -Supported sources: 4KHDHub, RgShows, VixSrc, Kokoshka, VidSrc, CineHDPlus, Cuevana, HomeCine, VerHdLink, Einschalten, KinoGer, MegaKino, MeineCloud, StreamKiste, Frembed, FrenchCloud, Movix, Eurostreaming, MostraGuarda +Supported sources: 4KHDHub, CineHDPlus, Cuevana, Einschalten, Eurostreaming, Frembed, FrenchCloud, HomeCine, KinoGer, Kokoshka, MegaKino, MeineCloud, MostraGuarda, Movix, RgShows, StreamKiste, VerHdLink, VidSrc, VixSrc Supported extractors: ", "id": "webstreamr", @@ -251,11 +251,6 @@ exports[`buildManifest has checked source with appropriate config 1`] = ` exports[`buildManifest has unchecked source without a config 1`] = ` [ - { - "key": "multi", - "title": "Multi 🌐 (VixSrc)", - "type": "checkbox", - }, { "key": "de", "title": "German 🇩🇪 (MeineCloud, StreamKiste)", @@ -266,6 +261,11 @@ exports[`buildManifest has unchecked source without a config 1`] = ` "title": "Castilian Spanish 🇪🇸 (VerHdLink)", "type": "checkbox", }, + { + "key": "multi", + "title": "Multi 🌐 (VixSrc)", + "type": "checkbox", + }, { "key": "it", "title": "Italian 🇮🇹 (VixSrc)", diff --git a/src/utils/language.ts b/src/utils/language.ts index bb4294f..9e0173b 100644 --- a/src/utils/language.ts +++ b/src/utils/language.ts @@ -1,4 +1,4 @@ -import { CountryCode } from '../types'; +import { Config, CountryCode } from '../types'; const countryCodeMap: Record = { multi: { language: 'Multi', flag: '🌐', iso639: undefined }, @@ -64,7 +64,19 @@ export const findCountryCodes = (value: string): CountryCode[] => { const countryCodes: CountryCode[] = []; for (const countryCode in countryCodeMap) { - if (value.includes(countryCodeMap[countryCode as CountryCode]['language'])) { + if (!countryCodes.includes(countryCode as CountryCode) && value.includes(countryCodeMap[countryCode as CountryCode]['language'])) { + countryCodes.push(countryCode as CountryCode); + } + } + + return countryCodes; +}; + +export const countryCodesFromConfig = (config: Config): CountryCode[] => { + const countryCodes: CountryCode[] = []; + + for (const countryCode in countryCodeMap) { + if (countryCode in config) { countryCodes.push(countryCode as CountryCode); } } diff --git a/src/utils/manifest.ts b/src/utils/manifest.ts index 6eed930..b9761e9 100644 --- a/src/utils/manifest.ts +++ b/src/utils/manifest.ts @@ -35,6 +35,8 @@ export const buildManifest = (sources: Source[], extractors: Extractor[], config }, }; + sources.sort((sourceA, sourceB) => sourceA.label.localeCompare(sourceB.label)); + const countryCodeSources: Partial> = {}; sources.forEach(source => source.countryCodes