Thanks to visit codestin.com
Credit goes to Github.com

Skip to content

macOS CLI that controls Apple Music playback and routes audio to HomePods

License

Notifications You must be signed in to change notification settings

agisilaos/homepodctl

Repository files navigation

homepodctl

homepodctl logo

release macOS arm64 and amd64

macOS CLI that controls Apple Music playback and routes audio to HomePods.

Requirements

  • macOS with the Music app
  • osascript (built-in)
  • shortcuts (built-in, optional for the native backend)
  • Go toolchain to build (if building from source)

Permissions

On first use, macOS may prompt you to allow your terminal (or the built binary) to control:

  • Music (via Apple Events)
  • Shortcuts (if you use the native backend)

Two playback backends

  • --backend airplay: selects Music.app AirPlay output device(s) and plays a playlist (the Mac is the sender).
  • --backend native: runs a Shortcuts automation you map in config.json (can be set up so HomePod plays natively).

Mental model (important)

  • “Rooms” = AirPlay device names as seen by Music.app (HomePods, Apple TVs, speakers, etc).
  • out set changes Music.app’s current AirPlay outputs (it does not edit your config).
  • play plays a Music.app user playlist (by fuzzy search or by ID).
  • config.json is only for defaults and aliases (so you don’t have to type --room every time).

Quick start (AirPlay)

List available AirPlay outputs (these names are what you pass as “rooms”):

homepodctl devices

Pick outputs to play through (sets Music.app’s current outputs):

homepodctl out set "Bedroom"

Play a playlist by fuzzy query:

homepodctl play chill

If the playlist name has spaces, quote it:

homepodctl play "Songs I've been obsessed recently pt. 2"

If multiple playlists match, auto-picks the best match; to pick interactively:

homepodctl play autumn --choose

See what’s playing (track/album/playlist + outputs):

homepodctl status

Shortcut for status:

homepodctl now

Watch changes:

homepodctl status --watch 1s

Search playlists (for IDs / debugging):

homepodctl playlists --query chill

If a playlist name is ambiguous or tricky to match (emoji/whitespace), use IDs:

homepodctl playlists --query autumn
homepodctl play --playlist-id <PERSISTENT_ID>

Set volume (if rooms are omitted, uses defaults.rooms; if that’s empty, uses the currently selected outputs in Music.app):

homepodctl vol 50
homepodctl volume 35 "Living Room"

Config (defaults + aliases)

Create a starter config:

homepodctl config-init

This writes config.json under your macOS user config dir (typically ~/Library/Application Support/homepodctl/config.json).

Defaults are used when flags are omitted. For example, if you set:

  • defaults.backend = "airplay"
  • defaults.rooms = ["Bedroom"]

…then you can just run:

homepodctl play chill

List configured aliases:

homepodctl aliases

Run an alias from your config:

homepodctl run bed-example

Native backend (optional)

Edit config.json, map room -> playlist -> shortcut name, and run:

homepodctl play --backend native --room "Bedroom" --playlist "Example Playlist"

Help

CLI help:

homepodctl --help
homepodctl --verbose status
homepodctl help play

Verbose diagnostics can also be enabled via HOMEPODCTL_VERBOSE=1.

Run built-in diagnostics:

homepodctl doctor
homepodctl doctor --json

Generate shell completions:

homepodctl completion zsh
homepodctl completion bash
homepodctl completion fish

Inspect and update config values:

homepodctl config validate --json
homepodctl config get defaults.backend
homepodctl config set defaults.backend airplay
homepodctl config set defaults.rooms "Bedroom" "Living Room"

Dry-run mutating commands without side effects:

homepodctl play chill --dry-run --json
homepodctl out set "Bedroom" --dry-run --json
homepodctl volume 30 --dry-run --json
homepodctl run bed --dry-run --json

Exit codes

  • 0: success
  • 2: usage/flag/validation error
  • 3: config or automation validation error
  • 4: backend command error (osascript / shortcuts)
  • 1: other runtime failures

Command cheat sheet

  • homepodctl devices / homepodctl out list: list AirPlay devices
  • homepodctl out set <room> ... [--json|--plain|--dry-run]: select Music.app outputs
  • homepodctl play <query> [--json|--plain|--dry-run] / homepodctl play --playlist-id <id>: play a playlist
  • homepodctl playlists --query <text> [--json|--plain]: search playlists
  • homepodctl status [--json|--plain] / homepodctl now / homepodctl status --watch 1s: now playing
  • homepodctl pause|stop|next|prev [--json|--plain]: transport controls
  • homepodctl volume <0-100> [room ...] [--json|--plain|--dry-run] / homepodctl vol ...: output volume
  • homepodctl aliases [--json|--plain] / homepodctl run <alias> [--json|--plain|--dry-run]: config shortcuts
  • homepodctl native-run --shortcut <name> [--json|--dry-run]: run a Shortcut directly
  • homepodctl config validate|get|set ...: validate and edit config values (defaults.*)
  • homepodctl config-init: create starter config
  • homepodctl doctor: diagnostics checklist
  • homepodctl completion <bash|zsh|fish>: generate completion script
  • homepodctl automation validate|plan|run|init ...: routine workflows (non-interactive by default; add --dry-run to preview)
  • homepodctl version: version info

Common gotchas

  • You built it but it still behaves “old”: if you run make build, the binary is ./homepodctl. Running homepodctl ... might be a different binary on your PATH.
  • Rooms are not flags: use --room "Bedroom" (repeatable), not --bedroom / --Bedroom.
  • out set doesn’t edit config: it only changes Music.app’s current outputs. Use config-init + edit defaults.rooms if you want persistent defaults.

Automation (v1 design)

Automation commands are being designed for routine playback flows and agent usage.

Design docs:

  • CLI spec: docs/automation-v1-cli-spec.md
  • User quickstart: docs/automation/quickstart-user.md
  • Agent quickstart: docs/automation/quickstart-agent.md
  • Preset templates: docs/automation/presets/

Canonical presets included:

  • docs/automation/presets/morning.yaml
  • docs/automation/presets/focus.yaml
  • docs/automation/presets/winddown.yaml
  • docs/automation/presets/party.yaml
  • docs/automation/presets/reset.yaml

Distribution

This tool is macOS-only (it relies on osascript + Music.app, and optionally shortcuts).

  • Homebrew (recommended):
    • brew tap agisilaos/tap
    • brew install homepodctl
  • From source (recommended while iterating): make build
  • Release preflight (recommended): make release-check VERSION=vX.Y.Z validates changelog/test/vet and produces a version-stamped local binary.
  • Prebuilt binaries: make release VERSION=vX.Y.Z publishes a GitHub Release and updates the Homebrew formula in agisilaos/homebrew-tap.
  • go install (after publishing): go install github.com/agisilaos/homepodctl/cmd/homepodctl@latest

Disclaimer

This project is not affiliated with Apple.

About

macOS CLI that controls Apple Music playback and routes audio to HomePods

Topics

Resources

License

Contributing

Security policy

Stars

Watchers

Forks

Packages

No packages published