// Server-only Insertunit source resolver (api.insertunit.ws). Resolves a TMDB // id to an IMDB id, scrapes the embed HTML, and extracts the dash/hls streams, // audio-track names and cc (subtitle) list. Streams live on interkh.com and // require the insertunit Referer, so they must be proxied. export interface InsertunitResult { dash: string | null; dasha: string | null; hls: string | null; audio: { names: string[]; order: number[] } | null; cc: { url: string; name: string }[] | null; } const HEADERS: Record = { accept: "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8", "accept-language": "en-GB,en;q=0.9", "cache-control": "max-age=0", "sec-ch-ua": '"Chromium";v="148", "Brave";v="148", "Not/A)Brand";v="99"', "sec-ch-ua-mobile": "?0", "sec-ch-ua-platform": '"macOS"', "sec-fetch-dest": "document", "sec-fetch-mode": "navigate", "sec-fetch-site": "none", "sec-fetch-user": "?1", "upgrade-insecure-requests": "1", }; export const INSERTUNIT_REFERER = "https://api.insertunit.ws/"; function safeJsonLoad(s: string): T | null { try { return JSON.parse(s) as T; } catch { // strip trailing commas from sloppy JS objects, retry const clean = s.replace(/,\s*}/g, "}").replace(/,\s*\]/g, "]"); try { return JSON.parse(clean) as T; } catch { return null; } } } export class InsertunitScraper { private tmdbKey = process.env.TMDB_API_KEY || ""; private async getImdbId(tmdbId: number, isTv: boolean): Promise { const mt = isTv ? "tv" : "movie"; try { const r = await fetch( `https://api.themoviedb.org/3/${mt}/${tmdbId}/external_ids?api_key=${this.tmdbKey}` ); if (!r.ok) return null; const d = await r.json(); return d.imdb_id || null; } catch { return null; } } // Finds the dynamic token suffix appended to media URLs to bypass 403s. private extractDynamicToken(html: string): string { const varMatch = html.match( /o\[k\]\s*\+=\s*'&'\s*\+\s*([a-zA-Z0-9_]+);/ ); if (!varMatch) return ""; const name = varMatch[1]; const valMatch = html.match( new RegExp(`${name}\\s*=\\s*"([^"]+)"`) ); if (!valMatch) return ""; return `&${valMatch[1]}`; } async fetchSources( tmdbId: number, season = 0, episode = 0 ): Promise { const isTv = !!(season && episode); const imdb = await this.getImdbId(tmdbId, isTv); if (!imdb) return null; let html: string; try { const r = await fetch(`https://api.insertunit.ws/embed/imdb/${imdb}`, { headers: HEADERS, cache: "no-store", // fresh tokens each resolve }); if (!r.ok) return null; html = await r.text(); } catch { return null; } return isTv ? this.parseTv(html, season, episode) : this.parseMovie(html); } private parseMovie(html: string): InsertunitResult | null { const m = html.match(/source:\s*({[\s\S]*?})/); if (!m) return null; const src = m[1]; const tok = this.extractDynamicToken(html); const dash = src.match(/dash:\s*"(.*?)"/); const dasha = src.match(/dasha:\s*"(.*?)"/); const hls = src.match(/hls:\s*"(.*?)"/); const audio = src.match(/audio:\s*({[\s\S]*?})/); const cc = src.match(/cc:\s*(\[[\s\S]*?\])/); return { dash: dash ? dash[1] + tok : null, dasha: dasha ? dasha[1] + tok : null, hls: hls ? hls[1] + tok : null, audio: audio ? safeJsonLoad(audio[1]) : null, cc: cc ? safeJsonLoad(cc[1]) : null, }; } private parseTv( html: string, season: number, episode: number ): InsertunitResult | null { // Isolate the season block to avoid cross-season episode mismatches. const seasonRe = new RegExp( `"season":\\s*${season}\\s*,\\s*"blocked"[\\s\\S]*?(?="season":\\s*\\d+\\s*,|$)` ); const sm = html.match(seasonRe); if (!sm) return null; const seasonHtml = sm[0]; const epRe = new RegExp( `"episode":\\s*"${episode}"[\\s\\S]*?(?="episode":\\s*"\\d+"|$)` ); const em = seasonHtml.match(epRe); if (!em) return null; const eh = em[0]; const tok = this.extractDynamicToken(html); const dash = eh.match(/"dash":\s*"(.*?)"/); const dasha = eh.match(/"dasha":\s*"(.*?)"/); const hls = eh.match(/"hls":\s*"(.*?)"/); const audio = eh.match(/"audio":\s*({[\s\S]*?})/); const cc = eh.match(/"cc":\s*(\[[\s\S]*?\])/); return { dash: dash ? dash[1] + tok : null, dasha: dasha ? dasha[1] + tok : null, hls: hls ? hls[1] + tok : null, audio: audio ? safeJsonLoad(audio[1]) : null, cc: cc ? safeJsonLoad(cc[1]) : null, }; } } import type { SourceModule } from "./types"; // Best-effort language code from an Insertunit cc track name. function guessLang(name: string): string { const n = (name || "").toLowerCase(); if (n.includes("eng") || n.includes("english")) return "en"; if (n.includes("рус") || n.includes("rus")) return "ru"; if (n.includes("укр") || n.includes("ukr")) return "uk"; if (n.includes("span") || n.includes("esp")) return "es"; if (n.includes("fr")) return "fr"; if (n.includes("de") || n.includes("ger")) return "de"; return ""; } const _insertunit = new InsertunitScraper(); // interkh streams need the insertunit Referer, so both streams and cc subs are // proxied. Prefer DASH (its [0] is a real CDN host; the HLS variant // uses an "x-bc" placeholder host that 410s). export const insertunit: SourceModule = { id: "insertunit", name: "Ari", label: "Multi-audio · built-in subs", active: true, rank: 2, async fetch(ctx) { const r = await _insertunit .fetchSources(ctx.tmdbId, ctx.season, ctx.episode) .catch(() => null); if (!r) return null; const ref = INSERTUNIT_REFERER; const streams = []; if (r.dash) { streams.push({ file: ctx.proxyStream(r.dash, ref), label: "auto", type: "dash" as const, }); } else if (r.hls) { streams.push({ file: ctx.proxyStream(r.hls, ref), label: "auto", type: "hls" as const, }); } if (!streams.length) return null; const subtitles = (r.cc || []).map((c) => ({ url: ctx.proxySub(c.url, ref), display: c.name, language: guessLang(c.name), source: "Ari", })); return { streams, subtitles }; }, };