Spaces:
Paused
Paused
| # Backend | |
| the Express 5 + TypeScript service that powers stream resolution, muxing, the Spotify resolution race, and the Remix Lab API. for the project overview see [`../../README.md`](../../README.md). for self-hosting see [`../../docs/run-an-instance.md`](../../docs/run-an-instance.md). | |
| ## Layout | |
| ```text | |
| backend/ | |
| βββ src/ | |
| β βββ app.ts # Express setup, middleware, route wiring, lifecycle | |
| β βββ instrument.ts # Sentry instrumentation β must load before app.ts | |
| β βββ controllers/ | |
| β β βββ video.controller.ts # /info, /convert, /stream-urls handlers | |
| β β βββ keychanger.controller.ts # pitch-shift / key-change uploads | |
| β βββ routes/ | |
| β β βββ video.routes.ts # core video / stream endpoints | |
| β β βββ remix.routes.ts # Remix Lab kernel proxy + results | |
| β β βββ keychanger.routes.ts # key-changer route | |
| β βββ services/ | |
| β β βββ spotify/ # ISRC race, Turso registry, AI query synthesis | |
| β β βββ ytdlp/ # yt-dlp integration: streamer, info, turbo-mux, config | |
| β β βββ extractors/ # pure-JS extractors (YouTube/FB/IG/TikTok/SoundCloud) | |
| β β βββ extract.service.ts # generic metadata extractor | |
| β β βββ seeder.service.ts # background catalog seeder | |
| β β βββ social.service.ts # metascraper-based social-link metadata | |
| β β βββ ug-grounding.service.ts # Ultimate Guitar tab lookup | |
| β β βββ spotify.service.ts # Spotify facade | |
| β β βββ ytdlp.service.ts # yt-dlp facade | |
| β βββ utils/ | |
| β β βββ api/ # controller, response helpers | |
| β β βββ infra/ # db (Turso), logger, queue, redis, trace | |
| β β βββ media/ # format, fsm, metadata, spotify, stream, video | |
| β β βββ network/ # auth, cipher, cookie, proxy, secrets, security, sse, validation | |
| β βββ types/ # shared TS types | |
| βββ tests/ # Vitest suites + e2e helpers | |
| βββ scripts/ # test orchestration, benchmarks, Termux shim | |
| βββ Dockerfile # container build (node:22-slim base) | |
| ``` | |
| ## Routes | |
| `video.routes.ts`: | |
| | Method | Path | Purpose | | |
| | ------ | -------------------- | --------------------------------------- | | |
| | `GET` | `/events` | SSE telemetry stream. | | |
| | `GET` | `/info` | resolve a URL β metadata + format list. | | |
| | `GET` | `/stream-urls` | refresh CDN URLs for a known video. | | |
| | `POST` | `/telemetry` | frontend β backend telemetry ingest. | | |
| | `ALL` | `/convert` | stream / download a chosen format. | | |
| | `GET` | `/proxy` | authenticated stream proxy. | | |
| | `GET` | `/seed-intelligence` | trigger the background catalog seeder. | | |
| `remix.routes.ts` proxies the Python Remix Lab kernel and serves stem/chord/beat results. `keychanger.routes.ts` handles pitch-shift uploads. `/convert` and `/proxy` are gated by `concurrencyGuard(2)` (`utils/network/security.util.ts`) to keep memory bounded on Termux and free-tier hosts. | |
| response shapes for `/info` and `/convert` are documented in [`../../docs/api.md`](../../docs/api.md). | |
| ## Environment | |
| configure via `web/backend/.env`. the full reference is in [`../../docs/env-variables.md`](../../docs/env-variables.md). the backend boots without most of these β they enable optional features and degrade gracefully when unset. minimum to get something useful: | |
| - `REDIS_URL` β Redis for the metadata cache and BullMQ job queue (defaults to `redis://127.0.0.1:6379`). | |
| - `GEMINI_API_KEY` and/or `GROQ_API_KEY` β at least one for the AI fallback in Spotify resolution. | |
| - `SPOTIFY_CLIENT_ID` + `SPOTIFY_CLIENT_SECRET` β Spotify Web API for ISRC and metadata. | |
| - `TURSO_URL` + `TURSO_AUTH_TOKEN` β global edge registry. unset is fine for local dev (falls back to an in-memory mock). | |
| - `COOKIES_URL` β remote `yt-dlp` cookie sync. improves YouTube reliability. | |
| - `API_ONLY=true` β disable serving the bundled `frontend/dist` (split deployments). | |
| ## Running | |
| ```bash | |
| npm install | |
| npm run dev # tsc + node, listens on :5000 (or $PORT) | |
| ``` | |
| other scripts: | |
| - `npm run build` β TypeScript compile to `dist/`. | |
| - `npm test` β full Vitest suite (sequential, Termux-friendly). | |
| - `npm run test:fast` β core regression tests only. | |
| - `npm run test:lite` β node `--test` lite suite (no transpile). | |
| - `npm run lint` β ESLint on changed files (`npm run lint:all` for the whole package). | |
| - `npm run bench:convert` β convert-pipeline benchmark. | |
| ## Requirements | |
| - Node.js β₯ 22 β matches the Dockerfile and the project root. | |
| - `yt-dlp` and `ffmpeg` on `PATH`. `yt-dlp` is the fallback for sources without a native extractor; `ffmpeg` 7.x or 8.x handles muxing and audio transcoding. | |
| - Redis. an in-process mock is used in tests when none is reachable. | |
| ## Notes | |
| - **YouTube player clients**: `services/ytdlp/turbo-mux.ts` passes `--extractor-args youtube:player-client=...` to obtain DASH manifests and bypass the 360p limit on the default web client. the client list is chosen per request based on the requested format. | |
| - **Concurrency**: `concurrencyGuard(limit)` (`utils/network/security.util.ts`) caps in-flight downloads at `limit=2` per process to prevent OOM on small hosts. | |
| - **Cookie sync**: `utils/network/cookie.util.ts` pulls `youtube_cookies.txt` and `facebook_cookies.txt` from `COOKIES_URL` at boot when the variable is set. | |
| - **MP3 transcoding**: `services/ytdlp/streamer.ts` pipes raw audio through `ffmpeg -vn -ab 192k -f mp3 pipe:1` straight to the client β no temp files. | |
| - **MP4 finalization**: `-movflags +faststart` is set on finalized MP4 downloads so playback can start before the file finishes. | |
| - **SSE**: `/events` is the canonical telemetry channel. resolvers, downloaders, and the seeder push progress through `utils/network/sse.util.ts`. | |
| before putting an instance on the public internet, read [`../../docs/protect-an-instance.md`](../../docs/protect-an-instance.md). | |