Install
openclaw skills install ytm-castDownload music from YouTube/YouTube Music and stream to Chromecast via Home Assistant. Complete CLI toolset with web server integration, configuration wizard, and playback controls.
openclaw skills install ytm-castYouTube music → your Chromecast. Simple, free, works.
Download audio from YouTube or YouTube Music and stream it through Home Assistant to any Cast-enabled device. No subscriptions, no cloud services, just your local network.
Download your favorite tracks in the morning, cast them throughout the day. No waiting, no buffering.
Download a playlist before guests arrive, then queue up songs without fumbling with phones or apps.
Play ambient music or podcasts while you work without worrying about ads or interruptions.
Stream the same track to multiple Chromecasts simultaneously (bedroom + living room + kitchen).
| Feature | YouTube Music Cast | Spotify Premium | YouTube Premium |
|---|---|---|---|
| Cost | Free forever | $10.99/month | $13.99/month |
| Quality | 320K MP3 | Up to 320K | Up to 1080p video |
| Offline | Yes, forever | Download limit | Download limit |
| Ads | None | None | None |
| Platforms | Any Chromecast | Spotify Connect devices | YouTube apps |
| Privacy | Local only | Cloud-based | Cloud-based |
# 1. Setup (one time, takes 2 minutes)
cast-setup
# 2. Download your first song
cast-download https://youtube.com/watch?v=dQw4w9WgXcQ
# 3. Start the web server
cast-server start
# 4. Cast it to your default device
cast-play never-gonna-give-you-up.mp3
That's it. Your music is playing through your Chromecast.
Three simple steps, one command each:
yt-dlp grabs audio from YouTube or YouTube Music, extracts it as MP3 (320K quality).
A lightweight Python HTTP server makes your downloaded files accessible over your local network. No setup required — just Python 3.
Home Assistant's media_player.play_media service sends the HTTP URL to your Chromecast, which streams the audio.
Home Assistant's play_media service requires a URL, not a file path. The web server bridges that gap.
# ✅ This works — HA can fetch via HTTP
media_content_id: "http://192.168.1.81:8735/song.mp3"
# ❌ This fails — HA can't read file paths
media_content_id: "/tmp/youtube-music/song.mp3"
Architecture:
YouTube URL → yt-dlp → MP3 file → Python HTTP server → Home Assistant API → Chromecast
yt-dlp, Python 3, curl, jq# Clone or download the skill
cd youtube-music-cast
# Make all scripts executable
chmod +x scripts/*
# Install globally (recommended)
./install.sh --global
# Or install locally
./install.sh
cast-setup
The wizard will ask for:
http://homeassistant.local:8123media_player.bedroom_display# Download a test song
cast-download https://youtube.com/watch?v=dQw4w9WgXcQ
# Start the server
cast-server start
# Cast it
cast-play song.mp3
If music plays, you're ready!
| Command | Description | Example |
|---|---|---|
cast-setup | Run configuration wizard | cast-setup |
cast-download <URL> [options] | Download from YouTube/YouTube Music | cast-download https://youtube.com/watch?v=... --video |
cast-radio <URL> [options] | Start radio mode with related songs | cast-radio https://youtube.com/watch?v=... --count 10 |
| `cast-server [start | stop | status]` |
cast-play <file> [device] | Cast music or video file to device | cast-play song.mp4 |
cast-stop [device] | Stop playback | cast-stop |
cast-status [device] | Show player status | cast-status |
cast-devices | List all available media players | cast-devices |
cast-list | List downloaded files | cast-list |
cast-help | Show help | cast-help |
# Download from YouTube
cast-download https://youtube.com/watch?v=dQw4w9WgXcQ
# Rename for cleaner URL (recommended)
mv "/tmp/youtube-music/Rick Astley - Never Gonna Give You Up.mp3" \
"/tmp/youtube-music/never-gonna-give-you-up.mp3"
# Start the web server
cast-server start
# Cast to your default device
cast-play never-gonna-give-you-up.mp3
# Living room TV
cast-play song.mp3 media_player.living_room
# Kitchen speaker
cast-play song.mp3 media_player.kitchen_speaker
# Bedroom Chromecast
cast-play song.mp3 media_player.bedroom_display
# Multiple rooms at once (run multiple commands)
cast-play song.mp3 media_player.living_room & \
cast-play song.mp3 media_player.bedroom_display
# Default device
cast-status
# Specific device
cast-status media_player.bedroom_display
Output:
📺 media_player.bedroom_display
State: playing
Friendly Name: Bedroom display
Volume: 22%
Now Playing:
Title: Never Gonna Give You Up
Artist: Rick Astley
Duration: 3:32
App: Default Media Receiver
# Stop default device
cast-stop
# Stop specific device
cast-stop media_player.living_room
# List all music files with sizes
cast-list
Output:
🎵 Downloaded Music
boneheads-bank-holiday.mp3 9.3M
never-gonna-give-you-up.mp3 8.2M
song-for-nary.mp3 7.8M
Total: 3 files
cast-devices
Output:
📺 Available Media Players
media_player.bedroom_display
Name: Bedroom display
State: idle
Supported: play_media, volume_set, volume_mute, ...
media_player.living_room
Name: Living room TV
State: off
Supported: play_media, volume_set, ...
Default device: media_player.bedroom_display
Radio mode automatically discovers and downloads related songs based on YouTube recommendations. After downloading a seed song, it searches for similar tracks and adds them to your queue.
Start radio mode:
# Basic radio (downloads seed + 3 related songs)
cast-radio https://youtube.com/watch?v=dQw4w9WgXcQ
# Custom number of related songs
cast-radio https://youtube.com/watch?v=dQw4w9WgXcQ --count 10
# Radio mode with video files
cast-radio https://youtube.com/watch?v=dQw4w9WgXcQ --video --count 5
Or use cast-download with --radio flag:
# Download with radio mode
cast-download https://youtube.com/watch?v=dQw4w9WgXcQ --radio
# Download with custom count
cast-download https://youtube.com/watch?v=dQw4w9WgXcQ --radio --radio-count 5
# Radio + video mode combined
cast-download https://youtube.com/watch?v=dQw4w9WgXcQ --radio --video
How it works:
radio_)Play your radio queue:
# Start server
cast-server start
# Play the first song
cast-play $(ls -t /tmp/youtube-music/*.mp3 | head -n 1 | xargs basename)
# Or play related songs sequentially
cast-play radio_some-song.mp3
cast-play radio_another-song.mp3
# ... etc
Tips:
radio_ for easy identification--count to control how many related songs to download--video flag for visual radio modeVideo mode creates MP4 videos instead of plain MP3 files. Each video includes:
Download a video:
# Download as MP4 with album art and text
cast-download https://youtube.com/watch?v=dQw4w9WgXcQ --video
# Cast the MP4 file
cast-server start
cast-play "Never Gonna Give You Up.mp4"
Radio mode with videos:
# Download seed + related songs as videos
cast-radio https://youtube.com/watch?v=dQw4w9WgXcQ --video --count 5
# Cast videos
cast-play "Never Gonna Give You Up.mp4"
cast-play "radio_Together Forever.mp4"
# ... etc
How it works:
Video output:
Notes:
Requirements for video mode:
ffmpeg must be installed on your system
# Debian/Ubuntu
sudo apt install ffmpeg
# macOS
brew install ffmpeg
cast-play automatically detects the file type:
.mp3, .wav, .ogg, .m4a, .flac → music.mp4, .mkv, .webm, .mov → videoYou can mix both formats in the same directory:
# Download some as MP3
cast-download https://youtube.com/watch?v=VIDEO_ID_1
# Download some as MP4
cast-download https://youtube.com/watch?v=VIDEO_ID_2 --video
# Play both - cast-play handles the difference
cast-play song.mp3
cast-play video.mp4
Config file: ~/.youtube-music-cast/config.sh
# Home Assistant
HA_URL="http://homeassistant.local:8123"
HA_TOKEN="your-long-lived-access-token-here"
# Web Server
SERVER_IP="192.168.1.81"
SERVER_PORT="8735"
# Default Device (override per command)
DEFAULT_DEVICE="media_player.bedroom_display"
# Directories
DOWNLOAD_DIR="/tmp/youtube-music"
CAST_DIR="$HOME/.youtube-music-cast"
Edit the file directly or re-run cast-setup to update.
Keep URLs clean. Simple filenames save you from headaches later.
❌ Bad filenames:
http://192.168.1.81:8735/Bonehead's%20Bank%20Holiday%20(Remastered).mp3
This URL is messy, hard to type, and prone to encoding errors.
✅ Good filenames:
http://192.168.1.81:8735/boneheads-bank-holiday.mp3
Clean, easy to type, no issues.
# After download, rename immediately
mv "Oasis - Bonehead's Bank Holiday (Remastered 1995).mp3" \
"oasis-boneheads-bank-holiday.mp3"
# Use lowercase, hyphens only
mv "My Awesome Song.mp3" "my-awesome-song.mp3"
# No special characters
mv "song@remix#.mp3" "song-remix.mp3"
Rule of thumb:
Problem: cast-devices shows no Chromecast devices.
Solution: Add Google Cast integration
If discovery fails:
Problem: cast-server start fails or says "port in use".
Solution:
# Check if port 8735 is in use
netstat -tlnp | grep 8735
# or
ss -tlnp | grep 8735
# Stop any existing server
cast-server stop
# Try starting manually to see error
cd /tmp/youtube-music
python3 -m http.server 8735
If port is in use by another process:
Edit ~/.youtube-music-cast/config.sh:
SERVER_PORT="8736" # Change to something else
Problem: cast-play song.mp3 says file not found.
Solution:
# List what's actually there
cast-list
# Check exact spelling (case-sensitive!)
cast-play "Exact-Filename.mp3" # Not "exact-filename.mp3"
# Verify server is running
cast-server status
Common mistakes:
Song.mp3 vs song.mp3song.MP3 vs song.mp3DOWNLOAD_DIR in configProblem: cast-download errors or hangs.
Solution:
# Update yt-dlp (YouTube changes often)
pip install --upgrade yt-dlp
# Check version
yt-dlp --version
# Try verbose output to see what's wrong
yt-dlp --verbose "URL"
# Try different URL format
# YouTube: https://youtube.com/watch?v=VIDEO_ID
# YouTube Music: https://music.youtube.com/watch?v=VIDEO_ID
If it's a geo-blocked video: Use a VPN or find an alternative upload of the same track.
Problem: curl errors when contacting HA.
Solution:
# Test your HA token manually
curl -H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
"http://homeassistant.local:8123/api/states"
# If you see JSON → token is good
# If 401 Unauthorized → token is wrong or expired
# If connection refused → URL is wrong or HA is down
Regenerate token if needed: HA → Profile → Scroll down → Long-Lived Access Tokens → Generate new
Problem: cast-download --video fails with "ffmpeg not found" or similar error.
Solution:
# Check if ffmpeg is installed
ffmpeg -version
# If not found, install it
# Debian/Ubuntu
sudo apt install ffmpeg
# macOS
brew install ffmpeg
Problem: Video creation is slow or takes too long.
Solution:
cast-download without --video) for faster downloads.cast-download and change -preset ultrafast to -preset fast for better quality but slower encoding).Problem: Text overlay doesn't appear or looks wrong.
Solution:
# Debian/Ubuntu
sudo apt install fonts-dejavu
# macOS (usually pre-installed)
Problem: Chromecast audio device plays video without visuals.
Solution:
Problem: MP4 files are too large.
Solution:
cast-download and changing -b:a 192k to -b:a 128k for audio, or adjust video codec settings.Problem: Radio mode downloads unrelated songs.
Solution:
radio_ prefix makes it easy to identify and remove unwanted downloads.Problem: Radio mode doesn't find any related songs.
Solution:
--radio-count 10 to get more results.Problem: Related songs don't play in sequence automatically.
Solution:
# Play all radio songs in sequence
for file in /tmp/youtube-music/radio_*.mp3; do
cast-play "$(basename "$file")"
sleep 5 # Wait between songs
done
Problem: cast-play doesn't return or music never starts.
Common causes:
cast-devices for stateSERVER_IP in config matches current IPcast-devices outputQuick fix:
# Restart everything
cast-server stop
cast-server start
cast-play song.mp3
# Check device is online
cast-devices
# Try casting from HA UI to isolate issue
youtube-music-cast/
├── scripts/
│ ├── cast-setup # Configuration wizard (interactive)
│ ├── cast-download # Download from YouTube (uses yt-dlp)
│ ├── cast-server # HTTP server manager (start/stop/status)
│ ├── cast-play # Cast to device (HA API)
│ ├── cast-stop # Stop playback
│ ├── cast-status # Player status query
│ ├── cast-devices # List all HA media players
│ ├── cast-list # List downloaded files
│ └── cast-help # Help documentation
├── install.sh # Installation script (--global, --help)
├── SKILL.md # This file (ClawdHub skill definition)
├── README.md # User-facing documentation
├── CHANGELOG.md # Version history
├── LICENSE # MIT license
├── .gitignore # Protects secrets and state
└── .clawdhub/
└── origin.json # ClawdHub metadata
~/.youtube-music-cast/
└── config.sh # Your configuration (don't commit to Git)
/tmp/youtube-music/
└── *.mp3 # Downloaded music files
pip install yt-dlp
Update regularly: pip install --upgrade yt-dlp
# Check version (usually pre-installed)
python3 --version
# Check version (usually pre-installed)
curl --version
# Debian/Ubuntu
sudo apt install jq
# macOS
brew install jq
Required for --video flag to create MP4 videos with album art and text overlays.
# Debian/Ubuntu
sudo apt install ffmpeg
# macOS
brew install ffmpeg
Check installation:
ffmpeg -version
Note: Video mode is optional. If you only download MP3s, you don't need ffmpeg.
Download multiple tracks or entire playlists at once:
# Download playlist
yt-dlp -x --audio-format mp3 --audio-quality 320K \
-o "/tmp/youtube-music/%(playlist_index)s-%(title)s.%(ext)s" \
"https://youtube.com/playlist?list=PLAYLIST_ID"
# Then cast them without waiting
cast-play 01-song.mp3
cast-play 02-song.mp3
cast-play 03-song.mp3
The HTTP server is lightweight (~5MB RAM). No need to stop/start between casts:
# Start once
cast-server start
# Cast as many songs as you want
cast-play song1.mp3
cast-play song2.mp3
# ... etc
Set DEFAULT_DEVICE in config to avoid typing it every time:
# In ~/.youtube-music-cast/config.sh
DEFAULT_DEVICE="media_player.bedroom_display"
# Now just cast
cast-play song.mp3 # Automatically uses bedroom_display
Files in /tmp/ are cleared on reboot by design, but you can manually clean:
# List all files with sizes
cast-list
# Remove old files
rm /tmp/youtube-music/*.mp3
If streaming glitches:
Add shell aliases for faster access:
# Add to ~/.bashrc or ~/.zshrc
alias cs='cast-server'
alias cd='cast-download'
alias cp='cast-play'
alias cl='cast-list'
alias cst='cast-status'
# Now just type
cs # Start server
cd URL # Download
cp song # Cast
cl # List
/tmp/youtube-music/ — cleared on reboot (by design)config.sh — don't commit to Git| Feature | YouTube Music Cast | Spotify Free | YouTube Premium |
|---|---|---|---|
| Cost | Free | Free (with ads) | $13.99/month |
| Ads | None | Yes, every few songs | None |
| Offline | Yes, forever | No (premium only) | Yes, with limit |
| Quality | 320K MP3 | 160K (variable) | Up to 1080p video |
| Privacy | Local only | Cloud-based | Cloud-based |
| Platform | Any Chromecast | Spotify Connect | YouTube apps |
| Queue management | Manual | Built-in | Built-in |
| Multi-room | Manual | Premium feature | No |
Bottom line: If you value privacy, want to own your music, and don't need cloud features, this is for you.
MIT License — use it, modify it, share it.
Version: 6.0.0 Author: Wobo License: MIT