movie/tv streaming for arcelia. https://tv.arcelia.space/
  • Svelte 49%
  • TypeScript 42.5%
  • CSS 7.4%
  • Dockerfile 0.8%
  • HTML 0.2%
Find a file
Repository files (latest commit first)
Filename Latest commit message Latest commit date
ruri 1598175200
All checks were successful
build and publish / check-build-publish (push) Successful in 1m44s
hide provider error details
2026-08-15 13:47:06 +08:00
.forgejo/workflows inject version and rev at build time 2026-08-09 21:52:38 +08:00
apps use mobile player panel sheet 2026-08-15 13:42:24 +08:00
deploy/chart support anubis-protected media 2026-08-09 20:18:05 +08:00
docs add external subtitles 2026-08-14 19:25:06 +08:00
packages hide provider error details 2026-08-15 13:47:06 +08:00
.dockerignore add containers and project documentation 2026-08-06 14:25:03 +08:00
.env.example add external subtitles 2026-08-14 19:25:06 +08:00
.gitignore add shared contracts and streaming backend 2026-08-06 14:24:33 +08:00
.oxfmtrc.json setup oxc lint/fmt 2026-08-10 15:50:24 +08:00
.oxlintrc.json setup oxc lint/fmt 2026-08-10 15:50:24 +08:00
bun.lock setup oxc lint/fmt 2026-08-10 15:50:24 +08:00
docker-compose.yml add external subtitles 2026-08-14 19:25:06 +08:00
package.json setup oxc lint/fmt 2026-08-10 15:50:24 +08:00
README.md add external subtitles 2026-08-14 19:25:06 +08:00
tsconfig.json add shared contracts and streaming backend 2026-08-06 14:24:33 +08:00

arcelia tv

A small, self-hosted streaming interface. It browses TMDB metadata, resolves third-party HLS sources through the internal Videasy port, and keeps upstream stream URLs behind signed proxy routes.

workspace

  • apps/web — SvelteKit browser and player UI
  • apps/api — Hono metadata and playback API
  • apps/proxy — signed streaming proxy and HLS playlist rewriter
  • packages/shared — Zod contracts, types, and token signing
  • packages/videasy — TypeScript port of the internal Python resolver

The browser talks only to the API and proxy. TMDB images are streamed through a fixed API image route. Stream URLs accepted by the proxy must carry a valid HMAC token; there is no client-controlled upstream URL parameter.

local development

Requirements: Bun 1.3.14+, a TMDB v4 read access token, Valkey or Redis, and three terminals.

cp .env.example .env
bun install
docker compose up -d cache
bun run --cwd apps/proxy dev
bun run --cwd apps/api dev
bun run --cwd apps/web dev

Set TMDB_ACCESS_TOKEN and a random PROXY_SECRET of at least 32 characters in .env. Set OPENSUBTITLES_API_KEY to an OpenSubtitles.com consumer key to enable external captions; the player remains usable without it. The development scripts explicitly load this root environment file even though each process runs from its app directory.

REDIS_URL enables the shared API cache. TMDB metadata uses the same 260 minute TTLs sent to browsers. Successful Videasy source resolution is cached for five minutes, but proxy URLs are signed fresh for every playback response. Cache errors fail open, so provider requests continue if Valkey is down. Images and streamed media bodies are not stored in Valkey.

Default endpoints:

  • web: http://localhost:5173
  • API: http://localhost:3001
  • proxy: http://localhost:3002

Run all checks with:

bun run check
bun run test
bun run build

The Videasy cipher parity test uses the unchanged Python project at /home/ruri/stuff/videasy/videasy by default. Set PYTHON_VIDEASY_PATH when it lives elsewhere.

containers

docker compose up --build

Compose reads .env. PUBLIC_API_URL, PROXY_PUBLIC_URL, and WEB_ORIGIN must be addresses the viewer's browser can reach; internal Docker service names do not work in browser URLs. API_INTERNAL_URL is server-only and may use the Compose network.

deployment constraints

  • The API and proxy must share the same PROXY_SECRET.
  • Playback tokens default to four hours so signed HLS segment URLs remain valid for a full viewing session. They are non-renewable and never stored.
  • The proxy is bandwidth-heavy and keeps streaming connections open. Tune MAX_CONNECTIONS and upstream/load-balancer timeouts for expected concurrency.
  • API and proxy instances are stateless. They can scale horizontally as long as the signing secret is shared.
  • Valkey is private and ephemeral, with persistence disabled, a 128 MB memory cap, and allkeys-lru eviction. Losing it only causes upstream cache misses.
  • Allow outbound HTTPS to TMDB, OpenSubtitles, speedracelight.com, and the media hosts returned by the resolver.
  • Terminate TLS before exposing the services publicly. Set exact HTTPS origins for CORS; do not use wildcard origins.
  • Viewing history and watchlist stay in browser local storage. Clearing site data removes them.

Only stream media you are permitted to access. Source availability and host behavior are outside this project's control.