nexstream-api / backend /README.md
circleci
deploy beb5a90
dae0a8c
|
Raw
History Blame Contribute Delete
6.3 kB

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. for self-hosting see ../../docs/run-an-instance.md.

Layout

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.

Environment

configure via web/backend/.env. the full reference is in ../../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

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.