# go-chromecast: driving Chromecast and Home devices from a terminal

> go-chromecast is a Go CLI that discovers Chromecast and Google Home devices over multicast DNS and drives them from the shell, including playing local files by streaming them over a local HTTP server. It covers a narrow slice of the Cast protocol and relies on ffmpeg for anything the device cannot play directly.

**vishen/go-chromecast** — cli for Google Chromecast, Home devices and Cast Groups

- Repository: https://github.com/vishen/go-chromecast
- Stars: 979 · Forks: 99
- Language: Go
- License: Apache-2.0
- Published: 2026-10-20 · Updated: 2026-10-20 · Language: en
- Canonical page: https://hysenlabs.com/projects/vishen-go-chromecast

## Discovery over multicast DNS, with a cache for the second call

Every command in go-chromecast starts by working out which device to talk to, and that step uses the network rather than a saved configuration.

The mechanism is a DNS multicast used to determine the Chromecast and Google Home devices on the local network. When several devices answer, the tool prints them and prompts for a selection. The output is a numbered list with the device type, the device name, the address on port 8009, the status and the uuid:

```bash
$ go-chromecast ls
Found 2 cast devices
1) device="Chromecast" device_name="MarieGotGame?" address="192.168.0.115:8009" status="" uuid="b380c5847b3182e4fb2eb0d0e270bf16"
2) device="Google Home Mini" device_name="Living Room Speaker" address="192.168.0.52:8009" status="" uuid="b87d86bed423a6feb8b91a7d2778b55c"
```

The caching detail is what makes repeat use bearable. The cast DNS entry is cached, so passing the device name with -n or the uuid with -u connects to the device instantly instead of waiting for another multicast round. That same pair of flags also lets you skip the interactive prompt entirely, and there is a --disable-cache flag when you want the lookup to happen every time. The --dns-timeout flag controls how many seconds the multicast search waits, with a default of 3.

The repository layout separates the concerns into distinct packages: dns for the lookup, cast for the protocol, http for the media server, storage, playlists, tts and ui. The discovery dependency is github.com/grandcat/zeroconf.

## Local files are served by an HTTP server the tool starts

A Chromecast is, at heart, a client that plays URLs. That is the constraint that shapes this project, and it is the reason the tool starts a web server.

The documentation states that local media files are played by creating an http server that will stream the media file to the cast device. So when you point the CLI at a file on your disk, the tool serves it over the local network and hands the device the address of that stream. The http directory at the repository root is that server, and the --iface flag selects the network interface used when looking for a local address for the http server, which matters on a machine with several interfaces such as a laptop with VPN and Wi-Fi.

The same applies to internet-hosted media. The load command takes a URL directly, so the two cases end in the same place from the device's point of view, which is a stream it can fetch.

One command exists for exactly this server so it can be run on its own: httpserver, described as starting the HTTP server. That separation is useful if you want the server running ahead of time, and it is also what the media commands rely on internally.

Note the security implication that follows from the design. The device has to fetch the media over the network from a machine on that network, so the stream is not private to the device in the way a local file is.

## Format support is a fixed list, and ffmpeg fills the gap

The playable formats are enumerated in the documentation, and the list is short enough to be worth knowing exactly:

```
Supported Media formats:
    - MP3
    - AVI
    - MKV
    - MP4
    - WebM
    - FLAC
    - WAV
```

Anything outside that list gets handled by transcoding. If an unknown video file is found, the tool uses ffmpeg to transcode it to MP4 and streams it to the chromecast. The detection of an unknown file is done with github.com/h2non/filetype, so the decision is made by inspecting the file rather than trusting the extension.

There is an escape hatch. With --transcode=false the file is sent as it is, whatever it is, and it is up to the chromecast to play it. That is the setting to use when you already know the device handles the file, or when you would rather find out from the device than pay for a transcode.

The cost of the default path is a full ffmpeg transcode on the serving machine, in real time, for a file the device cannot read. On a slow box that turns a play command into a wait, which is the practical downside of the convenience.

## Subtitles, playlists and slideshows extend the media story

The media commands go beyond a single file.

Subtitles are attached at load time. The documentation describes them as a WebVTT file or its url, or any other file that ffmpeg can convert to WebVTT, which includes srt and ass, and it also covers a video with embedded subtitles, either the first track or the one picked with --subtitles-track:

```bash
$ go-chromecast load ~/Downloads/video.mkv --subtitles ~/Downloads/video.mkv --subtitles-track 2
```

The playlist command is described as looking at all the files in a folder and playing them sorted by numerically, which means the numbering in the filenames decides the order rather than the modification time. The playlists directory in the repository is where that logic sits.

The slideshow command plays a slideshow of photos. The transcode command transcodes and plays media, and load-app loads and plays content on a Chromecast app rather than on the default receiver, which is the path to a specific streaming service.

Then there is tts for text to speech, backed by the cloud.google.com/go/texttospeech package, and google.golang.org/api for the authentication it needs. That one command reaches out to Google's cloud rather than staying on the local network, which is worth knowing before assuming the tool is entirely offline.

## A cobra command tree with JSON output for scripting

The command set is built with spf13/cobra, and the help output shows the whole surface in one place. The playback controls are the ones you would expect: pause, unpause, next, previous, restart, rewind by seconds, seek by seconds, seek-to a timestamp, and playback-rate to change the rate of the current media. Volume has volume to get or set it, volume-up and volume-down, alongside mute and unmute. status reports the current state, stop stops casting, ls lists devices, and watch observes all events sent from a chromecast device.

There is a terminal UI as well, with the ui command and a --with-ui flag, built on github.com/jroimartin/gocui, and the --ui-theme flag pointing at a theme.json file for the colours of the UI.

For scripting, the status command has a JSON mode, and the documentation shows piping it into jq to pull out a single field:

```bash
$ go-chromecast status --json | jq -r .media.media.metadata.title
```

That is the part that makes the tool usable in a home automation script rather than only by hand. Device selection is by name, by address or by uuid, so a script can avoid the interactive prompt that would otherwise block it:

```bash
$ go-chromecast status -u b87d86bed423a6feb8b91a7d2778b55c
Idle (Default Media Receiver), volume=0.17 muted=false
```

The -a flag takes an address and -p sets the port, with a default of 8009, for the case where the device is not discoverable by multicast at all.

## What the tool does not cover, and where it stands

The scope is narrow and the project says so plainly: it implements a small number of the google chromecast commands. Everything else about the Cast platform, the full application catalogue, cast groups, and structured home device control, is outside what this CLI offers, even though the repository description mentions Cast Groups.

The dependency on Google cloud services for the tts command is a second boundary. The rest of the tool works on the local network, but text to speech requires credentials for a Google API and network access to it.

On maintenance, the last push was on 2026-10-12, which is recent, but the published releases are slower: v0.3.4 on 2025-04-21, v0.3.3 on 2025-03-13 and v0.3.2 on 2024-11-03. A project with a handful of releases a year means you should check the changelog before bumping the version, and the fact that the module requires go 1.25.0 while the project documentation still describes the go install path for Go 1.18 and above is a discrepancy worth resolving for yourself.

The licence is Apache-2.0, which is permissive for both commercial and internal use, and the repository ships a .goreleaser.yaml, so the binary distribution for your platform comes from the release pipeline rather than from a hand-built artifact.

## Conclusion

go-chromecast fits someone who wants the terminal to be the remote control for a house full of cast devices, especially where a local media library has to be pushed to a device that only accepts URLs. It does not fit a project that needs the full Cast application catalogue, group management, or a maintained protocol implementation, since the command set is a small number of Cast commands and the releases have slowed to a few a year. Before adopting it, check that the device you target is reachable over multicast DNS on your network, and confirm your local files are in the listed formats or that ffmpeg is installed, because transcode depends on it.

## FAQ

### How do I install go-chromecast?

On Go 1.18 and above the documented method is go install github.com/vishen/go-chromecast@latest. On Linux you can also download the latest release, unzip it with tar -xzf go-chromecast.tar.gz and install the binary with sudo install ./go-chromecast /usr/bin/.

### How does go-chromecast find Chromecast devices?

It uses a DNS multicast to determine the Chromecast and Google Home devices on the network. The lookup result is cached, so selecting a device by name with -n or by uuid with -u connects instantly on later calls.

### Can go-chromecast play a video file from my computer?

Yes. The tool starts an HTTP server that streams the media file to the cast device. Formats outside the supported list are transcoded to MP4 with ffmpeg, unless you pass --transcode=false to send the file as it is.

### How do I control which device go-chromecast talks to?

Use -n for a device name, -u for a device uuid, -a for an address with the optional -p port flag that defaults to 8009, or --first to use the first cast device found. Without any of these it prints the discovered devices and asks you to select one.

### Which media formats does go-chromecast support?

The documented list is MP3, AVI, MKV, MP4, WebM, FLAC and WAV. An unknown video file is transcoded to MP4 with ffmpeg before being streamed.

## Sources

- [Issues](https://github.com/vishen/go-chromecast/issues)
- [License: Apache-2.0](https://github.com/vishen/go-chromecast/blob/master/LICENSE)
- [README](https://github.com/vishen/go-chromecast/blob/master/README.md)
- [Releases](https://github.com/vishen/go-chromecast/releases)
- [vishen/go-chromecast on GitHub](https://github.com/vishen/go-chromecast)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/vishen-go-chromecast
