Skip to content

Fix: Chromecast Casting Not Playing - #7273

Open
dude-stash wants to merge 5 commits into
stashapp:developfrom
dude-stash:chromecast/cast-fix
Open

dude-stash wants to merge 5 commits into
stashapp:developfrom
dude-stash:chromecast/cast-fix

Conversation

@dude-stash

@dude-stash dude-stash commented Oct 8, 2026 •

Copy link
Copy Markdown
Contributor

Description

Casting to a Chromecast connects, but the TV never plays anything. There are two reasons:

  1. Stash sends the TV the stream the browser is playing. It is labelled video/mp4 even for MKV, AVI or WMV files, which the TV can't play.
  2. The stream URL points at localhost, which for the TV is the TV itself.

This keeps @silvermine/videojs-chromecast unmodified and fixes casting around it:

  • The server now reports its LAN addresses in systemStatus.localIPs.
  • Before each load, the plugin's modifyLoadRequestFn option swaps in a stream the TV can play: the direct stream for H.264 or H.265 with AAC or MP3 in MP4, otherwise HLS. localhost is replaced with the LAN address. Signed URLs keep working.
  • Seeking a transcoded scene while casting goes to the TV, because live.ts steps aside while the Chromecast tech is active.
  • The Cast SDK is loaded once per page, so casting keeps going while you browse between scenes.

The @silvermine/videojs-chromecast plugin hasn't been maintained since 2024, so instead of patching it, ScenePlayer/chromecast-tech.ts registers a subclass of its tech. It copes with a cast that outlives the previous player (no source or session manager yet, events after disposal), which was the plugin's open issue #96, and implements loop, setLoop and seeking.

It also defines setSource itself, because Video.js only calls it on a tech whose own prototype has it. This makes Chromecast work with Video.js 7 without patching the package.

Only the last three commits are specific to the Video.js 7 player (ScenePlayer.tsx, live.ts and the tech subclass).

The first two stay needed after a move to Video.js 10, because they don't touch the player: localIPs on the server, and utils/castMedia.ts, which picks the stream and address.

Related Issue

Fixes #4136. Replaces #7220.

Testing

Manual testing with a Chromecast with Google TV, an older Chromecast and a Google Nest Hub, from Chrome on macOS:

  • H.264 and H.265 MP4 plays directly. MKV, AVI and WMV play through HLS.
  • Seeking while casting, including transcoded scenes.
  • Opening another scene while casting, and going to the scenes list and back.
  • The queue moving on to the next scene when one ends.

Automated checks:

  • go build ./... and go test ./pkg/utils/ ./internal/manager/
  • golangci-lint on the changed Go packages
  • pnpm run validate (biome, tsc, format)

Screenshots

No visual changes.

Checklist

  • I have read and understood the Contributing document.
  • I have read and understood the AI Usage Policy document.
  • I have made corresponding changes to the documentation (if applicable).

AI Usage Disclosure

  • I have used AI tools to assist with this pull request, and I have disclosed the tools and how I used them below.

I used Claude Code to investigate the problem, write the code and commit messages, and draft this description. I directed the work, reviewed every commit and did the manual testing on my own devices.

Additional Context

The commits are meant to be reviewed one at a time.

dude-stash and others added 5 commits October 7, 2026 22:18
A Chromecast fetches media itself and can't reach localhost, so the UI needs an address of this machine on the LAN.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Every stream endpoint claims video/mp4, so the direct stream is only chosen when the file's container and codecs allow it, otherwise HLS. A localhost URL is pointed at a LAN address instead.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The Chromecast tech now casts the stream picked for the device, at this machine's LAN address, with the scene title.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Seeking now works while casting a transcoded scene: the device seeks the stream itself, so the transcode offset only applies to the browser's own player.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Opening another scene while casting no longer breaks the scene page, and the next scene loads on the Chromecast. The Chromecast tech is extended in the app instead of patched: it copes with a cast that outlives the previous player (no source or session manager yet, events after disposal), and defines setSource itself because Video.js only calls it on a tech whose own prototype has it. The Cast SDK is also loaded once per page, so the cast keeps going between scenes.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
@dude-stash

Copy link
Copy Markdown
Contributor Author

@Gykes I found another way to fix casting on vjs 7 without patching the silvermine chromecast plugin.

The first two commits are what makes stash send a valid url to chromecast instead of localhost, which is also needed for vis 10 anyway. But this PR makes chromecast completely usable on vjs 7.

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.

Can't cast any video to Chromecast

1 participant