A lightweight HLS proxy server with subtitle injection. Routes streaming manifests and segments through a proxy, rewrites URLs, and supports subtitle injection.
git clone https://github.com/makhembu/playa
cd playa
npm install
npm run dev
# Proxy running at http://localhost:3000GET /proxy/manifest?url=https://example.com/stream.m3u8
Returns the m3u8 with segment URLs rewritten to proxy through playa.
GET /proxy/segment?url=https://example.com/segment-001.ts
Proxies individual TS segments. Used by the rewritten manifest.
GET /proxy/with-subtitles?manifestUrl=<url>&subtitleUrl=<vtt>&subtitleLang=en
Injects an #EXT-X-MEDIA:TYPE=SUBTITLES track into an HLS manifest.
curl -X POST http://localhost:3000/convert/srt-to-vtt \
-H "Content-Type: text/plain" \
-d '1\n00:00:01,000 --> 00:00:04,000\nHello world'# Proxy a manifest
curl "http://localhost:3000/proxy/manifest?url=https://test-streams.mux.dev/x36xhzz/x36xhzz.m3u8"
# Check the server
curl http://localhost:3000- Bypass CORS restrictions on streaming sources
- Inject subtitles into existing HLS streams
- Rewrite segments for compatibility with different players
- Lightweight — no external player needed, works with any HLS.js player
- TypeScript
- Express.js
- HLS protocol handling
- Cloudflare Workers ready (uses standard Web API patterns)
- HLS manifest proxy with URL rewriting
- Segment proxy with streaming
- Subtitle injection into manifest
- SRT to WebVTT conversion
- Subtitle embedding into TS segments
- Bandwidth adaptation
- Cache layer (R2/Cloudflare Cache)
- DASH support
MIT