From bb1c084c4cbf822e3262955bb21c9acf7767da9a Mon Sep 17 00:00:00 2001 From: ZStrike Date: Sat, 24 Oct 2026 23:31:46 -0400 Subject: [PATCH] Fixed player UI dismissal bug --- .build/entry.js | 49 -- .build/sdk/config.js | 487 ------------------ .build/sdk/downloads/downloads.js | 53 -- .build/sdk/health.js | 38 -- .build/sdk/sdk.d.ts | 122 ----- .build/sdk/sdk.js | 68 --- .build/sdk/sources/111477.js | 101 ---- .build/sdk/sources/123anime.js | 57 -- .build/sdk/sources/anihq.js | 124 ----- .build/sdk/sources/anineko.js | 190 ------- .build/sdk/sources/bcine.js | 202 -------- .build/sdk/sources/dulo.js | 150 ------ .build/sdk/sources/flaxmovies.js | 118 ----- .build/sdk/sources/fsonline.js | 48 -- .build/sdk/sources/kisskh.js | 60 --- .build/sdk/sources/lmscript.js | 43 -- .build/sdk/sources/lookmovie.js | 80 --- .build/sdk/sources/movienight.js | 117 ----- .build/sdk/sources/movy.js | 282 ---------- .build/sdk/sources/pengu.js | 50 -- .build/sdk/sources/pstream.js | 68 --- .build/sdk/sources/purstream.js | 104 ---- .build/sdk/sources/rivestream.js | 179 ------- .build/sdk/sources/streamaggregator.js | 129 ----- .build/sdk/sources/vidapi.js | 115 ----- .build/sdk/sources/vidcore.js | 123 ----- .build/sdk/sources/vidfast.js | 123 ----- .build/sdk/sources/vidgod.js | 147 ------ .build/sdk/sources/vidlink.js | 28 - .build/sdk/sources/vidnest.js | 79 --- .build/sdk/sources/vidrock.js | 145 ------ .build/sdk/sources/vidup.js | 123 ----- .build/sdk/sources/vidvault.js | 188 ------- .build/sdk/sources/vidzee.js | 184 ------- .build/sdk/sources/vixsrc.js | 112 ---- .build/sdk/sources/xdownloader.js | 129 ----- .build/sdk/subtitles.js | 122 ----- .build/sdk/utils/helpers.js | 230 --------- .build/shim/crypto.js | 4 - .build/shim/inject.js | 7 - .gitignore | 3 +- README.md | 2 +- .../tv/vyla/app/ui/screens/PlayerScreen.kt | 5 + 43 files changed, 8 insertions(+), 4780 deletions(-) delete mode 100644 .build/entry.js delete mode 100644 .build/sdk/config.js delete mode 100644 .build/sdk/downloads/downloads.js delete mode 100644 .build/sdk/health.js delete mode 100644 .build/sdk/sdk.d.ts delete mode 100644 .build/sdk/sdk.js delete mode 100644 .build/sdk/sources/111477.js delete mode 100644 .build/sdk/sources/123anime.js delete mode 100644 .build/sdk/sources/anihq.js delete mode 100644 .build/sdk/sources/anineko.js delete mode 100644 .build/sdk/sources/bcine.js delete mode 100644 .build/sdk/sources/dulo.js delete mode 100644 .build/sdk/sources/flaxmovies.js delete mode 100644 .build/sdk/sources/fsonline.js delete mode 100644 .build/sdk/sources/kisskh.js delete mode 100644 .build/sdk/sources/lmscript.js delete mode 100644 .build/sdk/sources/lookmovie.js delete mode 100644 .build/sdk/sources/movienight.js delete mode 100644 .build/sdk/sources/movy.js delete mode 100644 .build/sdk/sources/pengu.js delete mode 100644 .build/sdk/sources/pstream.js delete mode 100644 .build/sdk/sources/purstream.js delete mode 100644 .build/sdk/sources/rivestream.js delete mode 100644 .build/sdk/sources/streamaggregator.js delete mode 100644 .build/sdk/sources/vidapi.js delete mode 100644 .build/sdk/sources/vidcore.js delete mode 100644 .build/sdk/sources/vidfast.js delete mode 100644 .build/sdk/sources/vidgod.js delete mode 100644 .build/sdk/sources/vidlink.js delete mode 100644 .build/sdk/sources/vidnest.js delete mode 100644 .build/sdk/sources/vidrock.js delete mode 100644 .build/sdk/sources/vidup.js delete mode 100644 .build/sdk/sources/vidvault.js delete mode 100644 .build/sdk/sources/vidzee.js delete mode 100644 .build/sdk/sources/vixsrc.js delete mode 100644 .build/sdk/sources/xdownloader.js delete mode 100644 .build/sdk/subtitles.js delete mode 100644 .build/sdk/utils/helpers.js delete mode 100644 .build/shim/crypto.js delete mode 100644 .build/shim/inject.js diff --git a/.build/entry.js b/.build/entry.js deleted file mode 100644 index e8cd3a4..0000000 --- a/.build/entry.js +++ /dev/null @@ -1,49 +0,0 @@ -import SOURCES from './sdk/config.js'; -import { createStreamArgs } from './sdk/utils/helpers.js'; -import { fetchSubtitles, getSubPathsMovie, getSubPathsTv } from './sdk/subtitles.js'; -import * as m0 from './sdk/sources/123anime.js'; -import * as m1 from './sdk/sources/111477.js'; -import * as m2 from './sdk/sources/anihq.js'; -import * as m3 from './sdk/sources/anineko.js'; -import * as m4 from './sdk/sources/bcine.js'; -import * as m5 from './sdk/sources/dulo.js'; -import * as m6 from './sdk/sources/flaxmovies.js'; -import * as m7 from './sdk/sources/fsonline.js'; -import * as m8 from './sdk/sources/kisskh.js'; -import * as m9 from './sdk/sources/lmscript.js'; -import * as m10 from './sdk/sources/lookmovie.js'; -import * as m11 from './sdk/sources/movienight.js'; -import * as m12 from './sdk/sources/movy.js'; -import * as m13 from './sdk/sources/pengu.js'; -import * as m14 from './sdk/sources/pstream.js'; -import * as m15 from './sdk/sources/purstream.js'; -import * as m16 from './sdk/sources/rivestream.js'; -import * as m17 from './sdk/sources/streamaggregator.js'; -import * as m18 from './sdk/sources/vidapi.js'; -import * as m19 from './sdk/sources/vidcore.js'; -import * as m20 from './sdk/sources/vidfast.js'; -import * as m21 from './sdk/sources/vidgod.js'; -import * as m22 from './sdk/sources/vidlink.js'; -import * as m23 from './sdk/sources/vidnest.js'; -import * as m24 from './sdk/sources/vidrock.js'; -import * as m25 from './sdk/sources/vidup.js'; -import * as m26 from './sdk/sources/vidvault.js'; -import * as m27 from './sdk/sources/vidzee.js'; -import * as m28 from './sdk/sources/vixsrc.js'; -import * as m29 from './sdk/sources/xdownloader.js'; -const MODS = { '123anime': m0, '111477': m1, 'anihq': m2, 'anineko': m3, 'bcine': m4, 'dulo': m5, 'flaxmovies': m6, 'fsonline': m7, 'kisskh': m8, 'lmscript': m9, 'lookmovie': m10, 'movienight': m11, 'movy': m12, 'pengu': m13, 'pstream': m14, 'purstream': m15, 'rivestream': m16, 'streamaggregator': m17, 'vidapi': m18, 'vidcore': m19, 'vidfast': m20, 'vidgod': m21, 'vidlink': m22, 'vidnest': m23, 'vidrock': m24, 'vidup': m25, 'vidvault': m26, 'vidzee': m27, 'vixsrc': m28, 'xdownloader': m29 }; -const core = { tmdbApiKey: null, penguManifest: null }; -const live = () => SOURCES.filter(c => !c.disabled && MODS[c.sourceFile]); -globalThis.VylaLocal = { - init(key) { core.tmdbApiKey = key; globalThis.process.env.TMDB_API_KEY = key; }, - sources() { return live(); }, - async stream(key, id, s, e, ip) { - const cfg = live().find(c => c.key === key); - if (!cfg) throw new Error('Source not found'); - return await MODS[cfg.sourceFile].getStream(await createStreamArgs(cfg, core, id, s, e, ip)); - }, - async subtitles(id, s, e) { - const paths = s != null && e != null ? await getSubPathsTv(id, s, e) : await getSubPathsMovie(id); - return await fetchSubtitles(paths); - } -}; diff --git a/.build/sdk/config.js b/.build/sdk/config.js deleted file mode 100644 index e0223a9..0000000 --- a/.build/sdk/config.js +++ /dev/null @@ -1,487 +0,0 @@ -// Currently active sources reported on 6:18:22 PM PST 9/13/2026 - -// None Anime Tested: 936075 -// Anime Tested: 37854 - -// Fshare/Fsonic Tested: 155 ( they don't have Michael ) - -export const SOURCES = [ - { - key: '123anime', - label: '123Anime', - sourceFile: '123anime', - proxyParam: 'a1', - timeout: 25000, - jitter: 500, - retries: 2, - multiUrl: false, - skipProxy: true, - cdnHeaders: [{ - pattern: /hlsx\d+cdn\.|burntburst\d+\.store|echovideo\.ru/i, - headers: { - Referer: 'https://play2.echovideo.ru/', - Origin: 'https://play2.echovideo.ru', - }, - },], - }, - - { - key: '111477', - label: '111477', - sourceFile: '111477', - proxyParam: 'a11', - timeout: 25000, - jitter: 500, - retries: 2, - multiUrl: true, - skipProxy: true, - cdnHeaders: [{ - pattern: /111477\.xyz/i, - headers: { - Referer: 'https://st.111477.xyz/', - Origin: 'https://st.111477.xyz', - }, - }], - }, - - { - key: 'anihq-sub', - label: 'AniHQ (Sub)', - sourceFile: 'anihq', - proxyParam: 'ahsub', - timeout: 25000, - jitter: 500, - retries: 2, - multiUrl: true, - skipProxy: true - }, - - { - key: 'anihq-dub', - label: 'AniHQ (Dub)', - sourceFile: 'anihq', - proxyParam: 'ahdub', - timeout: 25000, - jitter: 500, - retries: 2, - multiUrl: true, - skipProxy: true - }, - - { - key: 'anineko-sub', - sourceFile: 'anineko', - label: 'AniNeko (Sub)', - proxyParam: 'anksub', - timeout: 25000, - jitter: 500, - retries: 2 - }, - - { - key: 'anineko-dub', - sourceFile: 'anineko', - label: 'AniNeko (Dub)', - proxyParam: 'ankdub', - timeout: 25000, - jitter: 500, - retries: 2 - }, - - { - key: 'bcine', - label: 'Bcine', - sourceFile: 'bcine', - proxyParam: 'bc', - timeout: 25000, - jitter: 500, - retries: 2, - multiUrl: true, - cdnHeaders: [{ - pattern: /1embed\.cc|videasy\.to/i, - headers: { - Referer: 'https://bcine.ru/', - Origin: 'https://bcine.ru', - }, - }], - }, - - { - key: 'dulo', - label: 'Dulo', - sourceFile: 'dulo', - proxyParam: 'dl', - timeout: 25000, - jitter: 500, - retries: 2, - multiUrl: true, - skipProxy: true, - cdnHeaders: [{ - pattern: /dulo\.mov/i, - headers: { - Referer: 'https://dulo.mov/', - Origin: 'https://dulo.mov', - }, - }], - }, - - { - key: 'flaxmovies', - label: 'FlaxMovies', - sourceFile: 'flaxmovies', - proxyParam: 'fx', - timeout: 20000, - jitter: 500, - retries: 2, - multiUrl: true, - skipProxy: true, - cdnHeaders: [{ - pattern: /flix2watch\.pro/i, - headers: { - Referer: 'https://flaxmovies.xyz/', - Origin: 'https://flaxmovies.xyz', - }, - },], - }, - - { - key: 'fsonline', - label: 'FSOnline', - sourceFile: 'fsonline', - proxyParam: 'fo', - timeout: 20000, - retries: 1, - jitter: 0, - multiUrl: true, - skipProxy: true, - }, - - { - key: 'kisskh', - label: 'KissKH', - sourceFile: 'kisskh', - proxyParam: 'kk', - timeout: 30000, - jitter: 500, - retries: 1, - }, - - { - key: 'lmscript', - label: 'LMScript', - sourceFile: 'lmscript', - proxyParam: 'lmsc', - timeout: 20000, - jitter: 500, - retries: 2, - multiUrl: true, - }, - - { - key: 'lookmovie', - label: 'LookMovie', - sourceFile: 'lookmovie', - proxyParam: 'lm', - timeout: 20000, - jitter: 500, - retries: 2, - multiUrl: true, - verifyHeaders: { - 'Accept-Language': 'en-US,en;q=0.9', - }, - }, - - { - key: 'movienight', - label: 'MovieNight', - sourceFile: 'movienight', - proxyParam: 'mn', - timeout: 20000, - jitter: 500, - retries: 2, - multiUrl: true, - skipProxy: true, - cdnHeaders: [{ - pattern: /movienig\.ht/i, - headers: { - Referer: 'https://movienig.ht/', - Origin: 'https://movienig.ht', - }, - }], - }, - - { - key: 'movy', - label: 'Movy', - sourceFile: 'movy', - proxyParam: 'mv', - timeout: 25000, - jitter: 500, - retries: 2, - multiUrl: true, - skipProxy: true, - cdnHeaders: [{ - pattern: /wecollege\.net|movy\.bz/i, - headers: { - Referer: 'https://www.movy.bz/', - Origin: 'https://www.movy.bz', - }, - }], - }, - - { - key: 'pengu', - label: 'Pengu', - sourceFile: 'pengu', - proxyParam: 'pg', - timeout: 25000, - jitter: 500, - retries: 1, - multiUrl: true, - skipProxy: true, - disabled: false, // Enabled, but only returns streams when a manifest is provided - }, - - { - key: 'pstream', - label: 'PStream', - sourceFile: 'pstream', - proxyParam: 'ps', - timeout: 35000, - jitter: 500, - retries: 1, - multiUrl: true, - }, - - { - key: 'purstream', - sourceFile: 'purstream', - label: 'Purstream', - proxyParam: 'ps', - timeout: 20000, - jitter: 500, - retries: 2, - skipProxy: true - }, - - { - key: 'rivestream', - label: 'RiveStream', - sourceFile: 'rivestream', - proxyParam: 'rs', - timeout: 30000, - jitter: 500, - retries: 2, - multiUrl: true, - }, - - { - key: 'streamaggregator', - label: 'StreamAggregator', - sourceFile: 'streamaggregator', - proxyParam: 'sa', - timeout: 25000, - jitter: 500, - retries: 2, - multiUrl: true, - skipProxy: true, - cdnHeaders: [{ - pattern: /streamaggregator\.in/i, - headers: { - Referer: 'https://streamaggregator.in/', - Origin: 'https://streamaggregator.in', - }, - }], - }, - { - key: 'vidapi', - label: 'VidAPI', - sourceFile: 'vidapi', - proxyParam: 'va', - timeout: 25000, - jitter: 500, - retries: 1, - multiUrl: true - }, - - { - key: 'vidcore', - label: 'VidCore', - sourceFile: 'vidcore', - proxyParam: 'vc', - timeout: 35000, - jitter: 500, - retries: 1, - multiUrl: true, - }, - { - key: 'vidfast', - label: 'VidFast', - sourceFile: 'vidfast', - proxyParam: 'vf', - timeout: 35000, - jitter: 500, - retries: 1, - multiUrl: true, - }, - - { - key: 'vidgod', - label: 'VidGod', - sourceFile: 'vidgod', - proxyParam: 'vg', - timeout: 25000, - jitter: 500, - retries: 2, - multiUrl: true, - skipProxy: true, - }, - - { - key: 'vidlink', - label: 'Vidlink', - sourceFile: 'vidlink', - proxyParam: 'vl', - timeout: 20000, - jitter: 500, - retries: 2, - skipProxy: true, - multiUrl: true, - }, - - { - key: 'vidnest', - label: 'VidNest', - sourceFile: 'vidnest', - proxyParam: 'vdn', - timeout: 20000, - retries: 1, - jitter: 0, - multiUrl: true, - }, - - { - key: 'vidnest-sub', - label: 'VidNest (Sub)', - sourceFile: 'vidnest', - proxyParam: 'vdn', - timeout: 20000, - retries: 1, - jitter: 0, - multiUrl: true, - skipProxy: true, - }, - - { - key: 'vidnest-dub', - label: 'VidNest (Dub)', - sourceFile: 'vidnest', - proxyParam: 'vdn', - timeout: 20000, - retries: 1, - jitter: 0, - multiUrl: true, - skipProxy: true, - }, - - { - key: 'vidrock', - label: 'VidRock', - sourceFile: 'vidrock', - proxyParam: 'vr', - timeout: 20000, - jitter: 800, - retries: 3, - multiUrl: true, - cdnHeaders: [{ - pattern: /./, - headers: { - Accept: '/', - 'Accept-Language': 'en-US,en;q=0.9', - Referer: 'https://vidrock.ru/', - Origin: 'https://vidrock.ru', - }, - },], - }, - - { - key: 'vidup', - label: 'VidUp', - sourceFile: 'vidup', - proxyParam: 'vu', - timeout: 35000, - jitter: 500, - retries: 1, - multiUrl: true - }, - - { - key: 'vidvault', - label: 'VidVault', - sourceFile: 'vidvault', - proxyParam: 'vv', - timeout: 25000, - jitter: 500, - retries: 2, - multiUrl: true, - }, - - { - key: 'vidzee', - label: 'VidZee', - sourceFile: 'vidzee', - proxyParam: 'vz', - timeout: 20000, - sourcesTimeout: 10000, - jitter: 400, - retries: 3, - verifyHeaders: { - Accept: '/', - 'Accept-Language': 'en-US,en;q=0.9', - Referer: 'https://player.vidzee.wtf', - Origin: 'https://player.vidzee.wtf', - }, - }, - - { - key: 'vixsrc', - label: 'VixSrc', - sourceFile: 'vixsrc', - proxyParam: 'vx', - timeout: 35000, - jitter: 0, - retries: 2, - multiUrl: false, - skipProxy: true, - verifyHeaders: { - Accept: 'application/json, text/javascript, /; q=0.01', - 'Accept-Language': 'en-US,en;q=0.9', - Referer: 'https://vixsrc.to/', - Origin: 'https://vixsrc.to', - }, - }, - - { - key: 'xdownloader', - label: 'XDownloader', - sourceFile: 'xdownloader', - proxyParam: 'xd', - timeout: 25000, - jitter: 500, - retries: 2, - multiUrl: true, - skipProxy: true, - cdnHeaders: [{ - pattern: /films365\.org/i, - headers: { - Referer: 'https://www.films365.org/', - Origin: 'https://www.films365.org', - }, - }], - }, - -]; - -export const HEALTH_PROBE_ID = '155'; -export const SOURCE_MAP = Object.fromEntries(SOURCES.map(s => [s.key, s])); -export default SOURCES; \ No newline at end of file diff --git a/.build/sdk/downloads/downloads.js b/.build/sdk/downloads/downloads.js deleted file mode 100644 index c764c56..0000000 --- a/.build/sdk/downloads/downloads.js +++ /dev/null @@ -1,53 +0,0 @@ -import SOURCES from "../config.js"; - -export async function fetchDownloads(sdkOrId, idOrS = null, sOrE = null, maybeE = null) { - let sdk = null; - let id = sdkOrId; - let s = idOrS; - let e = sOrE; - - if (sdkOrId && typeof sdkOrId === 'object' && typeof sdkOrId.getStream === 'function') { - sdk = sdkOrId; - id = idOrS; - s = sOrE; - e = maybeE; - } - - if (!sdk || !id) return []; - - const activeSources = SOURCES.filter(cfg => !cfg.disabled && cfg.skipProxy); - const seenUrls = new Set(); - const downloads = []; - - const results = await Promise.allSettled( - activeSources.map(async (cfg) => { - try { - const res = await sdk.getStream(cfg.key, id, s, e); - if (!res) return; - - const items = Array.isArray(res.allUrls) && res.allUrls.length > 0 - ? res.allUrls - : (res.url ? [{ url: res.url, label: cfg.label }] : []); - - for (const item of items) { - if (!item?.url || typeof item.url !== 'string') continue; - const url = item.url.trim(); - - if (!url.startsWith('http') || url.includes('.m3u8')) continue; - if (!/\.mp4(\?|$)/i.test(url) && !url.includes('.mp4')) continue; - if (seenUrls.has(url)) continue; - - seenUrls.add(url); - - downloads.push({ - source: cfg.key, - label: item.label || cfg.label, - url, - }); - } - } catch { } - }) - ); - - return downloads; -} \ No newline at end of file diff --git a/.build/sdk/health.js b/.build/sdk/health.js deleted file mode 100644 index 08387be..0000000 --- a/.build/sdk/health.js +++ /dev/null @@ -1,38 +0,0 @@ -import { HEALTH_PROBE_ID } from "./config.js"; - -const withTimeout = (promise, ms) => Promise.race([promise, new Promise(r => setTimeout(() => r(null), ms))]); -async function withRetry(fn, attempts = 2, delay = 300) { - for (let i = 0; i < attempts; i++) { - try { - const result = await fn(); - if (result != null) return result; - } catch (err) { - if (i === attempts - 1) throw err; - await new Promise(r => setTimeout(r, delay + Math.random() * delay * 0.5)); - } - } - return null; -} - -export async function probeSource(sdk, cfg, mod) { - const audio = /dub$/.test(cfg.key) ? 'dub' : 'sub'; - const streamArgs = { - id: HEALTH_PROBE_ID, - s: null, - e: null, - clientIP: null, - absoluteBase: null, - audio, - sdk, - config: cfg, - }; - - const t = Date.now(); - const result = await withTimeout( - withRetry(() => mod.getStream(streamArgs), cfg.retries, 300), - cfg.timeout - ); - - const firstUrl = result?.url ?? result?.allUrls?.[0]?.url; - return { ok: !!(typeof firstUrl === 'string' && firstUrl.startsWith('http')), ms: Date.now() - t }; -} \ No newline at end of file diff --git a/.build/sdk/sdk.d.ts b/.build/sdk/sdk.d.ts deleted file mode 100644 index 0f27998..0000000 --- a/.build/sdk/sdk.d.ts +++ /dev/null @@ -1,122 +0,0 @@ -export interface SourceConfig { - key: string; - label: string; - sourceFile: string; - proxyParam: string; - timeout: number; - jitter: number; - retries: number; - multiUrl: boolean; - skipProxy?: boolean; - cdnHeaders?: { - pattern: RegExp; - headers: { - Referer: string; - Origin: string; - }; - }[]; - skipVerify?: boolean; - verifyHeaders?: boolean; - disabled?: boolean; - sourcesTimeout?: number; -} -export interface ProbeResult { - ok: boolean; - ms: number | null; -} -export interface StreamResult { - url: string; - headers: { - "User-Agent": string; - Referer: string; - Origin: string; - [key: string]: string; - }; - server: string; - quality: string; - type: "mp4" | "hls"; - skipVerify?: boolean; - skipProxy?: boolean; -} - -export interface DownloadResult { - url: string; - quality: string; - size: number | null; - type: "mkv"; - active: boolean; -} -export interface SubtitleResult { - label: string; - file: string; - type: "vtt" | "srt"; - source: string; -} - -export type ProbeAllResult = Record; - -export interface VylaSDKOptions { - tmdbApiKey?: string; -} - -export default class VylaSDK { - tmdbApiKey?: string; - - constructor(options?: VylaSDKOptions); - - /** - * Get the list of configured sources. - * @param excludeDisabled If true, filters out disabled sources. - */ - getSources(excludeDisabled?: boolean): SourceConfig[]; - - /** - * Probe all active (non-disabled) sources for availability. - */ - probeAllSources(): Promise; - - /** - * Probe a single source by key. - */ - probeSource(key: string): Promise; - - /** - * Get a playable stream for a given source/media id. - * @param key Source key - * @param id Media id (e.g. TMDB id) - * @param s Season number (for TV), or null for movies - * @param e Episode number (for TV), or null for movies - * @param clientIP Optional client IP for source-specific logic - */ - getStream( - key: string, - id: string | number, - s?: number | null, - e?: number | null, - clientIP?: string | null - ): Promise; - - /** - * Get subtitles for a movie or TV episode. - * @param id Media id - * @param s Season number (for TV), or null for movies - * @param e Episode number (for TV), or null for movies - */ - getSubtitles( - id: string | number, - s?: number | null, - e?: number | null - ): Promise; - - /** - * Get download links for a movie or TV episode. - * @param id Media id - * @param s Season number (for TV), or null for movies - * @param e Episode number (for TV), or null for movies - */ - getDownloads( - id: string | number, - s?: number | null, - e?: number | null - ): Promise; -} \ No newline at end of file diff --git a/.build/sdk/sdk.js b/.build/sdk/sdk.js deleted file mode 100644 index 1212e4e..0000000 --- a/.build/sdk/sdk.js +++ /dev/null @@ -1,68 +0,0 @@ -import SOURCES, { SOURCE_MAP } from "./config.js"; -import { fetchDownloads } from "./downloads/downloads.js"; -import { probeSource } from "./health.js"; -import { fetchSubtitles, getSubPathsMovie, getSubPathsTv } from "./subtitles.js"; -import { createStreamArgs } from "./utils/helpers.js"; - -const ALL_SOURCE_MODULES = Object.fromEntries( - await Promise.all(SOURCES.map(async cfg => [cfg.key, await import(`./sources/${cfg.sourceFile}.js`)])) -); - -const SOURCE_MODULES = Object.fromEntries( - Object.entries(ALL_SOURCE_MODULES).filter(([key]) => !SOURCE_MAP[key]?.disabled) -); - -export default class VylaSDK { - tmdbApiKey = null; - penguManifest = null; - constructor({ tmdbApiKey, penguManifest } = {}) { - this.tmdbApiKey = tmdbApiKey || null; - this.penguManifest = penguManifest || null; - } - getSources(excludeDisabled = false) { - if (excludeDisabled) { - return SOURCES.filter(cfg => !cfg.disabled); - } - return SOURCES; - } - async probeAllSources() { - const active = SOURCES.filter(cfg => !cfg.disabled); - - const results = await Promise.allSettled( - active.map(async cfg => await probeSource(cfg, SOURCE_MODULES[cfg.key])) - ); - - const sources = Object.fromEntries( - active.map((cfg, i) => [ - cfg.key, - results[i].status === 'fulfilled' ? results[i].value : { ok: false, ms: null }, - ]) - ); - - return sources; - } - async probeSource(key) { - const cfg = SOURCES.find(cfg => cfg.key === key); - if (!cfg) throw new Error(`Source with key "${key}" not found`); - const mod = SOURCE_MODULES[key]; - if (!mod) throw new Error(`Source module for key "${key}" not found`); - return await probeSource(this, cfg, mod); - } - async getStream(key, id, s = null, e = null, clientIP = null) { - const cfg = SOURCES.find(cfg => cfg.key === key); - if (!cfg) throw new Error(`Source with key "${key}" not found`); - const mod = SOURCE_MODULES[key]; - if (!mod) throw new Error(`Source module for key "${key}" not found`); - const streamArgs = await createStreamArgs(cfg, this, id, s, e, clientIP); - return await mod.getStream(streamArgs); - } - async getSubtitles(id, s = null, e = null) { - const paths = s != null && e != null - ? await getSubPathsTv(id, s, e) - : await getSubPathsMovie(id); - return await fetchSubtitles(paths); - } - async getDownloads(id, s = null, e = null) { - return await fetchDownloads(this, id, s, e); - } -} \ No newline at end of file diff --git a/.build/sdk/sources/111477.js b/.build/sdk/sources/111477.js deleted file mode 100644 index ca88abd..0000000 --- a/.build/sdk/sources/111477.js +++ /dev/null @@ -1,101 +0,0 @@ -import { getUA } from '../utils/helpers.js'; - -const SERVICE_ORIGIN = 'https://st.111477.xyz'; - -function generateManifestBaseUrl(tmdbKey) { - let config = 'https://a.111477.xyz/::sort=file-desc::limit=3'; - if (tmdbKey) { - config += `::tmdb=${tmdbKey}`; - } - const b64 = Buffer.from(config, 'utf8') - .toString('base64') - .replace(/\+/g, '-') - .replace(/\//g, '_') - .replace(/=+$/, ''); - return `${SERVICE_ORIGIN}/config/${b64}`; -} - -async function resolveImdbId(sdk, id, isTv) { - const apiKey = sdk?.tmdbApiKey || process.env.TMDB_API_KEY; - if (!apiKey) return null; - const type = isTv ? 'tv' : 'movie'; - try { - const res = await fetch(`https://api.themoviedb.org/3/${type}/${id}?api_key=${apiKey}&append_to_response=external_ids`, { - signal: AbortSignal.timeout(6000), - }); - if (!res.ok) return null; - const data = await res.json(); - return data.imdb_id || data.external_ids?.imdb_id || null; - } catch { - return null; - } -} - -export async function getStream({ id, s, e, sdk }) { - const isTv = Boolean(s && e); - const ua = getUA(); - const apiKey = sdk?.tmdbApiKey || process.env.TMDB_API_KEY; - - const imdbId = await resolveImdbId(sdk, id, isTv); - const targetIds = []; - - if (imdbId && imdbId.startsWith('tt')) { - targetIds.push(imdbId); - } - targetIds.push(`tmdb:${id}`); - - const addonBase = generateManifestBaseUrl(apiKey); - const seenUrls = new Set(); - const allUrls = []; - - const defaultHeaders = { - 'User-Agent': ua, - Accept: 'application/json, text/plain, */*', - }; - - for (const targetId of targetIds) { - const endpoint = isTv - ? `${addonBase}/stream/series/${targetId}:${s || 1}:${e || 1}.json` - : `${addonBase}/stream/movie/${targetId}.json`; - - try { - const res = await fetch(endpoint, { - headers: defaultHeaders, - signal: AbortSignal.timeout(12000), - }); - - if (!res.ok) continue; - const data = await res.json(); - - if (Array.isArray(data?.streams) && data.streams.length > 0) { - for (const item of data.streams) { - if (!item || typeof item !== 'object') continue; - const url = String(item.url || '').trim(); - if (!url || !url.startsWith('http') || seenUrls.has(url)) continue; - - seenUrls.add(url); - - const rawTitle = item.title ? String(item.title).trim() : ''; - const rawName = item.name ? String(item.name).trim() : '111477'; - const label = rawTitle || rawName; - - allUrls.push({ - url, - label, - headers: defaultHeaders, - }); - } - - if (allUrls.length > 0) break; - } - } catch { } - } - - if (allUrls.length === 0) return null; - - return { - url: allUrls[0].url, - allUrls, - headers: allUrls[0].headers, - }; -} \ No newline at end of file diff --git a/.build/sdk/sources/123anime.js b/.build/sdk/sources/123anime.js deleted file mode 100644 index a0fa6dd..0000000 --- a/.build/sdk/sources/123anime.js +++ /dev/null @@ -1,57 +0,0 @@ -import { getTmdbInfo, fetchJson, USER_AGENT } from '../utils/helpers.js'; - -async function resolveSlug(id, s, e, info) { - const titles = info?.titles || []; - const keywords = []; - for (const title of titles) { - const t = title.toLowerCase().replace(/[^a-z0-9\s]/g, ' ').replace(/\s+/g, ' ').trim(); - if (!keywords.includes(t)) keywords.push(t); - const words = title.split(/[\s:]+/).filter(w => w.length > 2); - if (words.length >= 2) { - const short = words.slice(0, 3).join(' ').toLowerCase(); - if (!keywords.includes(short)) keywords.push(short); - } - } - const slugCandidates = []; - for (const keyword of keywords) { - try { - const data = await fetchJson(`https://123animehub.cc/ajax/film/search?keyword=${encodeURIComponent(keyword)}&_=${Date.now()}`, { headers: { 'X-Requested-With': 'XMLHttpRequest', 'Referer': 'https://123animehub.cc', 'Accept': 'application/json', 'User-Agent': USER_AGENT }, signal: AbortSignal.timeout(8000) }); - let html = data.html || '', idx = 0; - while ((idx = html.indexOf('href="/anime/', idx)) !== -1) { - const start = idx + 13; - const end = html.indexOf('"', start); - const slug = html.slice(start, end); - if (!slugCandidates.includes(slug)) slugCandidates.push(slug); - idx = end; - } - } catch { } - if (slugCandidates.length) break; - } - for (const slug of slugCandidates) { - try { - const data = await fetchJson(`https://123animehub.cc/ajax/episode/info?epr=${encodeURIComponent(s ? `${slug}/${s}/${e}` : `${slug}/1`)}&ts=1&_=${Date.now()}`, { headers: { 'Referer': `https://123animehub.cc/anime/${slug}`, 'X-Requested-With': 'XMLHttpRequest', 'Accept': 'application/json, text/javascript, */*; q=0.01', 'User-Agent': USER_AGENT }, signal: AbortSignal.timeout(10000) }); - if (data?.target) return data.target; - } catch { } - } - return null; -} - -export async function getStream({ id, s, e }) { - if (!s) return null; - const info = await getTmdbInfo(id, 'tv', s); - if (!info.isAnime) return null; - const target = await resolveSlug(id, s, e, info); - if (!target) return null; - const embedMatch = target.match(/\/embed-[^/]+\/([A-Za-z0-9+/=]+)$/); - if (!embedMatch) return null; - const origin = new URL(target).origin; - try { - const embedRes = await fetch(target, { headers: { 'User-Agent': USER_AGENT }, signal: AbortSignal.timeout(10000) }); - if (!embedRes.ok) return null; - const setCookie = embedRes.headers.get('set-cookie'); - const data = await fetchJson(`${origin}/hs/getSources?id=${embedMatch[1]}`, { headers: { 'Referer': target, 'Accept': '*/*', 'User-Agent': USER_AGENT, ...(setCookie ? { 'Cookie': setCookie.split(';')[0].trim() } : {}) }, signal: AbortSignal.timeout(10000) }); - const src = typeof data.sources === 'string' && data.sources.length ? data.sources : (Array.isArray(data.sources) && data.sources.length ? (data.sources[0].file || data.sources[0].src || data.sources[0].url) : null); - if (src) return { url: src, headers: { 'Referer': 'https://play2.echovideo.ru/', 'Origin': 'https://play2.echovideo.ru' } }; - } catch { } - return null; -} \ No newline at end of file diff --git a/.build/sdk/sources/anihq.js b/.build/sdk/sources/anihq.js deleted file mode 100644 index bfdd461..0000000 --- a/.build/sdk/sources/anihq.js +++ /dev/null @@ -1,124 +0,0 @@ -import { getTmdbInfo, USER_AGENT } from '../utils/helpers.js'; - -async function extractVoe(voeUrl) { - try { - let res = await fetch(voeUrl, { - headers: { - 'User-Agent': USER_AGENT, - 'Referer': 'https://anihq.cc/' - } - }); - - let html = await res.text(); - - const redirectMatch = html.match(/window\.location\.href\s*=\s*['"](https?:\/\/[^'"]+)['"]/); - if (redirectMatch) { - res = await fetch(redirectMatch[1], { - headers: { - 'User-Agent': USER_AGENT, - 'Referer': 'https://anihq.cc/' - } - }); - html = await res.text(); - } - - const mirrorUrl = res.url; - - const scriptMatch = html.match(/