From 1f98cd3636fafb16c31cec5a35598b6cd39b321e Mon Sep 17 00:00:00 2001 From: Pas <74743263+Pasithea0@users.noreply.github.com> Date: Tue, 21 Oct 2025 16:35:32 -0600 Subject: [PATCH] use ext to proxy m3u8 streams with createM3U8ProxyUrl func --- src/providers/archive/sources/vidsrcsu.ts | 10 +++++----- src/providers/embeds/cinemaos.ts | 3 ++- src/providers/embeds/madplay.ts | 12 ++++++++---- src/providers/embeds/myanimedub.ts | 5 ++++- src/providers/embeds/myanimesub.ts | 5 ++++- src/providers/embeds/streamwish.ts | 3 ++- src/providers/embeds/turbovid.ts | 3 ++- src/providers/embeds/vidify.ts | 2 +- src/providers/embeds/vidnest.ts | 3 ++- src/providers/embeds/vidsrcvip.ts | 3 ++- src/providers/embeds/viper.ts | 3 ++- src/providers/sources/coitus.ts | 7 +++++-- src/providers/sources/iosmirror.ts | 3 ++- src/providers/sources/iosmirrorpv.ts | 3 ++- src/runners/individualRunner.ts | 2 ++ src/runners/runner.ts | 1 + src/utils/context.ts | 2 ++ src/utils/proxy.ts | 14 +++++++++++--- 18 files changed, 59 insertions(+), 25 deletions(-) diff --git a/src/providers/archive/sources/vidsrcsu.ts b/src/providers/archive/sources/vidsrcsu.ts index 1d2ca03..3e7210d 100644 --- a/src/providers/archive/sources/vidsrcsu.ts +++ b/src/providers/archive/sources/vidsrcsu.ts @@ -5,14 +5,14 @@ import { NotFoundError } from '@/utils/errors'; import { createM3U8ProxyUrl, updateM3U8ProxyUrl } from '@/utils/proxy'; // REQUIRES A PROXY FOR MOST SERVERS set it up here https://github.com/Pasithea0/M3U8-Proxy -function createProxyUrl(originalUrl: string, referer: string): string { +function createProxyUrl(originalUrl: string, referer: string, features?: any): string { const headers = { referer, }; - return createM3U8ProxyUrl(originalUrl, headers); + return createM3U8ProxyUrl(originalUrl, features, headers); } -function processProxiedURL(url: string): string { +function processProxiedURL(url: string, ctx: MovieScrapeContext | ShowScrapeContext): string { // Handle orbitproxy URLs if (url.includes('orbitproxy')) { try { @@ -25,7 +25,7 @@ function processProxiedURL(url: string): string { const originalUrl = jsonData.u; const referer = jsonData.r || ''; - return createProxyUrl(originalUrl, referer); + return createProxyUrl(originalUrl, referer, ctx.features); } catch (jsonError) { console.error('Error decoding/parsing orbitproxy data:', jsonError); } @@ -85,7 +85,7 @@ async function comboScraper(ctx: ShowScrapeContext | MovieScrapeContext): Promis const processedServers = servers.map((server) => ({ ...server, - url: processProxiedURL(server.url), + url: processProxiedURL(server.url, ctx), })); const embeds: SourcererEmbed[] = processedServers.map((server) => ({ diff --git a/src/providers/embeds/cinemaos.ts b/src/providers/embeds/cinemaos.ts index b9a4c2f..8237a78 100644 --- a/src/providers/embeds/cinemaos.ts +++ b/src/providers/embeds/cinemaos.ts @@ -123,7 +123,8 @@ export function makeCinemaOSHexaEmbed(id: string, rank: number = 100) { { id: 'primary', type: 'hls', - playlist: createM3U8ProxyUrl(directUrl, headers), + playlist: createM3U8ProxyUrl(directUrl, ctx.features, headers), + headers, flags: [flags.CORS_ALLOWED], captions: [], }, diff --git a/src/providers/embeds/madplay.ts b/src/providers/embeds/madplay.ts index 6ddf8ad..ca692f5 100644 --- a/src/providers/embeds/madplay.ts +++ b/src/providers/embeds/madplay.ts @@ -48,7 +48,8 @@ export const madplayBaseEmbed = makeEmbed({ { id: 'primary', type: 'hls', - playlist: createM3U8ProxyUrl(stream.file, headers), + playlist: createM3U8ProxyUrl(stream.file, ctx.features, headers), + headers, flags: [flags.CORS_ALLOWED], captions: [], }, @@ -92,7 +93,8 @@ export const madplayNsapiEmbed = makeEmbed({ { id: 'primary', type: 'hls', - playlist: createM3U8ProxyUrl(stream.url, stream.headers || headers), + playlist: createM3U8ProxyUrl(stream.url, ctx.features, stream.headers || headers), + headers: stream.headers || headers, flags: [flags.CORS_ALLOWED], captions: [], }, @@ -136,7 +138,8 @@ export const madplayRoperEmbed = makeEmbed({ { id: 'primary', type: 'hls', - playlist: createM3U8ProxyUrl(stream.url, stream.headers || headers), + playlist: createM3U8ProxyUrl(stream.url, ctx.features, stream.headers || headers), + headers: stream.headers || headers, flags: [flags.CORS_ALLOWED], captions: [], }, @@ -180,7 +183,8 @@ export const madplayNsapiVidFastEmbed = makeEmbed({ { id: 'primary', type: 'hls', - playlist: createM3U8ProxyUrl(stream.url, stream.headers || headers), + playlist: createM3U8ProxyUrl(stream.url, ctx.features, stream.headers || headers), + headers: stream.headers || headers, flags: [flags.CORS_ALLOWED], captions: [], }, diff --git a/src/providers/embeds/myanimedub.ts b/src/providers/embeds/myanimedub.ts index 5784293..f89a3cc 100644 --- a/src/providers/embeds/myanimedub.ts +++ b/src/providers/embeds/myanimedub.ts @@ -33,9 +33,12 @@ export const myanimedubScraper = makeEmbed({ { id: 'dub', type: 'hls', - playlist: createM3U8ProxyUrl(streamData.results.streamingLink.link.file, { + playlist: createM3U8ProxyUrl(streamData.results.streamingLink.link.file, ctx.features, { Referer: 'https://rapid-cloud.co/', }), + headers: { + Referer: 'https://rapid-cloud.co/', + }, flags: [flags.CORS_ALLOWED], captions: (streamData.results.streamingLink.tracks diff --git a/src/providers/embeds/myanimesub.ts b/src/providers/embeds/myanimesub.ts index b392762..6612399 100644 --- a/src/providers/embeds/myanimesub.ts +++ b/src/providers/embeds/myanimesub.ts @@ -33,9 +33,12 @@ export const myanimesubScraper = makeEmbed({ { id: 'sub', type: 'hls', - playlist: createM3U8ProxyUrl(streamData.results.streamingLink.link.file, { + playlist: createM3U8ProxyUrl(streamData.results.streamingLink.link.file, ctx.features, { Referer: 'https://rapid-cloud.co/', }), + headers: { + Referer: 'https://rapid-cloud.co/', + }, flags: [flags.CORS_ALLOWED], captions: (streamData.results.streamingLink.tracks diff --git a/src/providers/embeds/streamwish.ts b/src/providers/embeds/streamwish.ts index 714dbc5..7f2423e 100644 --- a/src/providers/embeds/streamwish.ts +++ b/src/providers/embeds/streamwish.ts @@ -224,7 +224,8 @@ function embed(provider: { id: string; name: string; rank: number }) { { id: 'primary', type: 'hls', - playlist: createM3U8ProxyUrl(videoUrl, videoHeaders), + playlist: createM3U8ProxyUrl(videoUrl, ctx.features, videoHeaders), + headers: videoHeaders, flags: [flags.CORS_ALLOWED], captions: [], }, diff --git a/src/providers/embeds/turbovid.ts b/src/providers/embeds/turbovid.ts index 4b39128..b873418 100644 --- a/src/providers/embeds/turbovid.ts +++ b/src/providers/embeds/turbovid.ts @@ -94,7 +94,8 @@ export const turbovidScraper = makeEmbed({ { type: 'hls', id: 'primary', - playlist: createM3U8ProxyUrl(playlist, streamHeaders), + playlist: createM3U8ProxyUrl(playlist, ctx.features, streamHeaders), + headers: streamHeaders, flags: [], captions: [], }, diff --git a/src/providers/embeds/vidify.ts b/src/providers/embeds/vidify.ts index 0b36d72..c968838 100644 --- a/src/providers/embeds/vidify.ts +++ b/src/providers/embeds/vidify.ts @@ -132,7 +132,7 @@ export function makeVidifyEmbed(id: string, rank: number = 100) { playlist = decodeURIComponent(playlistUrl); } else { console.log(`Found normal stream: `, playlistUrl); - playlist = createM3U8ProxyUrl(decodeURIComponent(playlistUrl), streamHeaders); + playlist = createM3U8ProxyUrl(decodeURIComponent(playlistUrl), ctx.features, streamHeaders); } ctx.progress(100); diff --git a/src/providers/embeds/vidnest.ts b/src/providers/embeds/vidnest.ts index ae23890..484f1e1 100644 --- a/src/providers/embeds/vidnest.ts +++ b/src/providers/embeds/vidnest.ts @@ -19,7 +19,8 @@ export const vidnestHollymoviehdEmbed = makeEmbed({ streams.push({ id: `hollymoviehd-${source.label}`, type: 'hls', - playlist: createM3U8ProxyUrl(source.file), + playlist: createM3U8ProxyUrl(source.file, ctx.features), + headers: {}, flags: [flags.CORS_ALLOWED], captions: [], } as HlsBasedStream); diff --git a/src/providers/embeds/vidsrcvip.ts b/src/providers/embeds/vidsrcvip.ts index a37615f..f7517e9 100644 --- a/src/providers/embeds/vidsrcvip.ts +++ b/src/providers/embeds/vidsrcvip.ts @@ -37,7 +37,8 @@ function makeVidSrcEmbed(provider: { id: string; name: string; rank: number }) { { id: 'primary', type: 'hls', - playlist: createM3U8ProxyUrl(ctx.url, headers), + playlist: createM3U8ProxyUrl(ctx.url, ctx.features, headers), + headers, flags: [flags.CORS_ALLOWED], captions: [], }, diff --git a/src/providers/embeds/viper.ts b/src/providers/embeds/viper.ts index e1d1d35..31833ed 100644 --- a/src/providers/embeds/viper.ts +++ b/src/providers/embeds/viper.ts @@ -34,7 +34,8 @@ export const viperScraper = makeEmbed({ { type: 'hls', id: 'primary', - playlist: createM3U8ProxyUrl(playlistUrl, headers), + playlist: createM3U8ProxyUrl(playlistUrl, ctx.features, headers), + headers, flags: [flags.CORS_ALLOWED], captions: [], }, diff --git a/src/providers/sources/coitus.ts b/src/providers/sources/coitus.ts index 1979477..b7988e3 100644 --- a/src/providers/sources/coitus.ts +++ b/src/providers/sources/coitus.ts @@ -17,6 +17,8 @@ async function comboScraper(ctx: ShowScrapeContext | MovieScrapeContext): Promis if (!apiRes.videoSource) throw new NotFoundError('No watchable item found'); let processedUrl = apiRes.videoSource; + let streamHeaders: Record = {}; + if (processedUrl.includes('orbitproxy')) { try { const urlParts = processedUrl.split(/orbitproxy\.[^/]+\//); @@ -31,8 +33,8 @@ async function comboScraper(ctx: ShowScrapeContext | MovieScrapeContext): Promis const originalUrl = jsonData.u; const referer = jsonData.r || ''; - const headers = { referer }; - processedUrl = createM3U8ProxyUrl(originalUrl, headers); + streamHeaders = { referer }; + processedUrl = createM3U8ProxyUrl(originalUrl, ctx.features, streamHeaders); } catch (jsonError) { console.error('Error decoding/parsing orbitproxy data:', jsonError); } @@ -54,6 +56,7 @@ async function comboScraper(ctx: ShowScrapeContext | MovieScrapeContext): Promis captions: [], playlist: processedUrl, type: 'hls', + headers: streamHeaders, flags: [flags.CORS_ALLOWED], }, ], diff --git a/src/providers/sources/iosmirror.ts b/src/providers/sources/iosmirror.ts index 192c944..2b0cca1 100644 --- a/src/providers/sources/iosmirror.ts +++ b/src/providers/sources/iosmirror.ts @@ -117,7 +117,7 @@ const universalScraper = async (ctx: ShowScrapeContext | MovieScrapeContext): Pr cookie: makeCookieHeader({ hd: 'on' }), }; - const playlist = createM3U8ProxyUrl(`${baseUrl}${autoFile}`, headers); + const playlist = createM3U8ProxyUrl(`${baseUrl}${autoFile}`, ctx.features, headers); ctx.progress(90); return { @@ -127,6 +127,7 @@ const universalScraper = async (ctx: ShowScrapeContext | MovieScrapeContext): Pr id: 'primary', playlist, type: 'hls', + headers, flags: [flags.CORS_ALLOWED], captions: [], }, diff --git a/src/providers/sources/iosmirrorpv.ts b/src/providers/sources/iosmirrorpv.ts index 609a677..073a345 100644 --- a/src/providers/sources/iosmirrorpv.ts +++ b/src/providers/sources/iosmirrorpv.ts @@ -114,7 +114,7 @@ const universalScraper = async (ctx: ShowScrapeContext | MovieScrapeContext): Pr cookie: makeCookieHeader({ hd: 'on' }), }; - const playlist = createM3U8ProxyUrl(`${baseUrl}${autoFile}`, headers); + const playlist = createM3U8ProxyUrl(`${baseUrl}${autoFile}`, ctx.features, headers); ctx.progress(90); return { @@ -124,6 +124,7 @@ const universalScraper = async (ctx: ShowScrapeContext | MovieScrapeContext): Pr id: 'primary', playlist, type: 'hls', + headers, flags: [flags.CORS_ALLOWED], captions: [], }, diff --git a/src/runners/individualRunner.ts b/src/runners/individualRunner.ts index 7c4268b..0f96cd2 100644 --- a/src/runners/individualRunner.ts +++ b/src/runners/individualRunner.ts @@ -31,6 +31,7 @@ export async function scrapeInvidualSource( const contextBase: ScrapeContext = { fetcher: ops.fetcher, proxiedFetcher: ops.proxiedFetcher, + features: ops.features, progress(val) { ops.events?.update?.({ id: sourceScraper.id, @@ -107,6 +108,7 @@ export async function scrapeIndividualEmbed( const output = await embedScraper.scrape({ fetcher: ops.fetcher, proxiedFetcher: ops.proxiedFetcher, + features: ops.features, url, progress(val) { ops.events?.update?.({ diff --git a/src/runners/runner.ts b/src/runners/runner.ts index 92f65cb..13fd0f7 100644 --- a/src/runners/runner.ts +++ b/src/runners/runner.ts @@ -52,6 +52,7 @@ export async function runAllProviders(list: ProviderList, ops: ProviderRunnerOpt const contextBase: ScrapeContext = { fetcher: ops.fetcher, proxiedFetcher: ops.proxiedFetcher, + features: ops.features, progress(val) { ops.events?.update?.({ id: lastId, diff --git a/src/utils/context.ts b/src/utils/context.ts index 6f16bca..2077efb 100644 --- a/src/utils/context.ts +++ b/src/utils/context.ts @@ -1,10 +1,12 @@ import { MovieMedia, ShowMedia } from '@/entrypoint/utils/media'; +import { FeatureMap } from '@/entrypoint/utils/targets'; import { UseableFetcher } from '@/fetchers/types'; export type ScrapeContext = { proxiedFetcher: UseableFetcher; fetcher: UseableFetcher; progress(val: number): void; + features: FeatureMap; }; export type EmbedInput = { diff --git a/src/utils/proxy.ts b/src/utils/proxy.ts index facabc6..c8890b1 100644 --- a/src/utils/proxy.ts +++ b/src/utils/proxy.ts @@ -1,4 +1,4 @@ -import { flags } from '@/entrypoint/utils/targets'; +import { FeatureMap, flags } from '@/entrypoint/utils/targets'; import { Stream } from '@/providers/streams'; // Default proxy URL for general purpose proxying @@ -67,10 +67,18 @@ export function setupProxy(stream: Stream): Stream { /** * Creates a proxied M3U8 URL using the configured M3U8 proxy * @param url - The original M3U8 URL to proxy + * @param features - Feature map to determine if local proxy (extension/native) is available * @param headers - Headers to include with the request - * @returns The proxied M3U8 URL + * @returns The proxied M3U8 URL or original URL if local proxy is available */ -export function createM3U8ProxyUrl(url: string, headers: Record = {}): string { +export function createM3U8ProxyUrl(url: string, features?: FeatureMap, headers: Record = {}): string { + // If we have features and local proxy is available (no CORS restrictions), return original URL + // The stream headers will handle the proxying through the extension/native environment + if (features && !features.requires.includes(flags.CORS_ALLOWED)) { + return url; + } + + // Otherwise, use the external M3U8 proxy const encodedUrl = encodeURIComponent(url); const encodedHeaders = encodeURIComponent(JSON.stringify(headers)); return `${CONFIGURED_M3U8_PROXY_URL}/m3u8-proxy?url=${encodedUrl}${headers ? `&headers=${encodedHeaders}` : ''}`;