Skip to content

Add casting: Chromecast + DLNA receivers#67

Open
savvystartagency wants to merge 1 commit into
truelockmc:mainfrom
savvystartagency:feat/casting-chromecast-dlna
Open

Add casting: Chromecast + DLNA receivers#67
savvystartagency wants to merge 1 commit into
truelockmc:mainfrom
savvystartagency:feat/casting-chromecast-dlna

Conversation

@savvystartagency
Copy link
Copy Markdown

Summary

Adds a Cast button to Movie / TV / Downloads pages plus a device-picker modal and a mini-controller. Streams anime mp4, anime Sl-Hls, vidsrc / videasy / 2embed HLS captures, and completed local downloads to any Chromecast-built-in device (incl. XGIMI Android TV projectors) or DLNA renderer on the LAN.

Highlights

  • src/ipc/cast.js — main-process subsystem. Discovery via bonjour-service (_googlecast._tcp) + dlnacasts3 SSDP. Single active session (mirrors PIP) via castv2-client for Chromecast and dlnacasts3 for DLNA. Clean disconnect on before-quit.
  • LAN-routable HTTP server bound 0.0.0.0:<random> (separate from the 127.0.0.1 allmanga player server):
    • /file/:token — range-supported local file serve
    • /proxy/:token — header-injecting proxy with on-the-fly HLS playlist rewriting (segments + EXT-X-KEY / EXT-X-MAP child tokens) so receivers always speak to a Referer-injecting proxy
    • /sub/:token — VTT with CORS, inline SRT→VTT conversion
  • Preloadcast:* IPC surface modelled on existing PIP naming.
  • RendereruseCast() hook, CastPickerModal, CastMiniController (play/pause/scrubber/CC/volume/stop), CastIcon + CastingIcon. Wired into MoviePage, TVPage, DownloadsPage.
  • Settings — new "Cast & Devices" section: auto-discover, include-DLNA, auto-stop-on-player-stop, preferred device, rescan, limitations notes.
  • Storage — five new CAST_* keys.

Dependencies

castv2-client, bonjour-service, dlnacasts3 — all pure JS, no native deps.

Test plan

  • Settings → Cast & Devices: Chromecast / XGIMI Android TV appears within ~5s
  • Movie page → anime mp4 (AllManga) → Cast → plays on receiver
  • Movie page → vidsrc m3u8 → Cast → plays (proxy injects Referer)
  • TV page → episode → Cast → episode title + poster show on receiver
  • Downloads page → completed mp4 → Cast → plays; range seek works
  • Mini-controller play / pause / seek / volume / CC toggle / stop all work
  • App quit while casting → receiver returns to idle in ~2s
  • Disable DLNA in settings → DLNA devices vanish from picker

Known limitations (surfaced in Settings notes box)

  • One-time signed segment URLs may invalidate during long sessions
  • DRM (Widevine / PlayReady) won't play on receivers
  • Non-AndroidTV DLNA-only renderers usually reject HLS
  • Mid-segment seeks on rewritten HLS take 2–3s
  • Single active session at a time
  • Proxy injects Referer + User-Agent only — sources requiring cookies will not work

Adds a Cast button to Movie, TV and Downloads pages plus a device-picker
modal and mini-controller. Streams anime mp4, anime Sl-Hls, vidsrc /
videasy / 2embed HLS captures, and completed local downloads to any
Chromecast-built-in device (incl. XGIMI Android TV projectors) or DLNA
renderer on the LAN.

Highlights
- New main-process module src/ipc/cast.js
  - Discovery: bonjour-service (_googlecast._tcp) + dlnacasts3 SSDP
  - LAN-routable HTTP server bound 0.0.0.0:<random>
    - /file/:token  range-supported local file serve
    - /proxy/:token header-injecting proxy with on-the-fly HLS playlist
      rewriting (segments + EXT-X-KEY / EXT-X-MAP child tokens) so
      receivers always speak to a Referer-injecting proxy
    - /sub/:token   VTT with CORS, inline SRT->VTT conversion
  - Single active session (mirrors PIP). castv2-client for Chromecast,
    dlnacasts3 for DLNA. Clean disconnect on before-quit.
- Preload bridge: cast:* IPC surface modeled on existing PIP naming.
- Renderer
  - useCast() hook (src/utils/useCast.js) for device list + session state
  - CastPickerModal with recent / available device lists, CAST/DLNA badges
  - CastMiniController with play/pause/scrubber/CC toggle/volume/stop
  - CastIcon + CastingIcon in Icons.jsx
  - Wired into MoviePage, TVPage, DownloadsPage; Sidebar status via
    the global mini-controller variant
- Settings: new "Cast & Devices" section (auto-discover, include-DLNA,
  auto-stop, preferred device, rescan, limitations notes).
- Storage: CAST_* keys for the above preferences.

Dependencies
- castv2-client    (Chromecast control)
- bonjour-service  (mDNS for _googlecast._tcp)
- dlnacasts3       (DLNA SSDP + AVTransport)

All pure JS, no native deps.
@truelockmc
Copy link
Copy Markdown
Owner

truelockmc commented May 18, 2026

Looks interesting, I suppose you have a Device to test this?

Because I do not xD...

Also, do you understand the Code you shared here?
Because the Text and the comment's look pretty AI generated 😬

@savvystartagency
Copy link
Copy Markdown
Author

yes, I am using it on my projectors and my TV :) ;)

@savvystartagency
Copy link
Copy Markdown
Author

I am just adding some controls, will push shortly

@savvystartagency savvystartagency force-pushed the feat/casting-chromecast-dlna branch from c831caf to 5df2c8a Compare May 22, 2026 11:06
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants