I have added several long conversational youtube videos into a playlist, hoping I’ll come back to the them some day, but in reality I never do that. Recently I found out that Spotify has released a new save-to-spotify CLI tool that lets you upload any audio file into your Spotify account as a private podcast episode. This is perfect for me, as I can download those youtube videos as audio files, upload them to Spotify, and listen to them while I’m driving.
Here’s how you can do that:
Download the Audio from Youtube
Install yt-dlp and ffmpeg:
brew install yt-dlp ffmpeg
Download and extract the audio:
yt-dlp --extract-audio --audio-format mp3 --audio-quality 0 -o "%(title)s.%(ext)s" "https://www.youtube.com/watch?v=YOUR_VIDEO_ID"
Save to Spotify
Install save-to-spotify:
curl -fsSL https://saveto.spotify.com/install.sh | bash -s -- --no-skills
echo 'export PATH="$HOME/.local/bin:$PATH"' >> ~/.zshrc && source ~/.zshrc
Update (October 2026): the install script started failing for me with ERROR: Asset not found in release v0.2.0, even though the release has the file. If that happens, install the binary from the latest GitHub release
directly (works on macOS and Linux, verifies the checksum):
VERSION=$(curl -fsSLI -o /dev/null -w '%{url_effective}' https://github.com/spotify/save-to-spotify/releases/latest | sed 's#.*/v##')
OS=$(uname -s | tr '[:upper:]' '[:lower:]')
ARCH=$(uname -m | sed 's/x86_64/amd64/; s/aarch64/arm64/')
ASSET="save-to-spotify-$OS-$ARCH-v$VERSION.zip"
cd "$(mktemp -d)"
curl -fsSLO "https://github.com/spotify/save-to-spotify/releases/download/v$VERSION/$ASSET"
curl -fsSLO "https://github.com/spotify/save-to-spotify/releases/download/v$VERSION/$ASSET.sha256"
shasum -a 256 -c "$ASSET.sha256"
unzip -q "$ASSET" save-to-spotify
mkdir -p ~/.local/bin && mv save-to-spotify ~/.local/bin/
Then add ~/.local/bin to your PATH as above, if it isn’t already.
Then authenticate with your Spotify account:
save-to-spotify auth login
Now you can:
- Add a new episode and create a new show:
save-to-spotify upload file.mp3 --title "TITLE" --new-show "SHOW"
- Add a new episode to an existing show:
save-to-spotify upload file.mp3 --title "TITLE" --show-id spotify:show:abcd1234
If --show-id is not specified, it will use the most recently created show.
Then visit your Spotify account and find the show and episode in your library (it takes a few minutes to show up there).
One Command
To combine yt-dlp and save-to-spotify in one command, the following bash script gets the audio, description, and thumbnail from Youtube and saves them to Spotify:
#!/usr/bin/env bash
set -euo pipefail
usage() {
echo "Usage: $0 <video-id> [--new-show NAME | --show-id ID]"
exit 1
}
[[ $# -lt 1 ]] && usage
URL="https://www.youtube.com/watch?v=$1"
shift
SHOW_ARGS=()
while [[ $# -gt 0 ]]; do
case "$1" in
--new-show) SHOW_ARGS+=(--new-show "$2"); shift 2 ;;
--show-id) SHOW_ARGS+=(--show-id "$2"); shift 2 ;;
*) usage ;;
esac
done
TMPDIR="$(mktemp -d)"
trap 'rm -rf "$TMPDIR"' EXIT
echo "Downloading audio, thumbnail, and metadata..."
yt-dlp \
--extract-audio --audio-format mp3 --audio-quality 0 \
--write-thumbnail --convert-thumbnails jpg \
--write-info-json \
-o "$TMPDIR/%(id)s.%(ext)s" \
"$URL"
AUDIO="$(ls "$TMPDIR"/*.mp3)"
INFO="$(ls "$TMPDIR"/*.info.json)"
THUMB="$(ls "$TMPDIR"/*.jpg 2>/dev/null || true)"
TITLE="$(python3 -c "import json,sys; print(json.load(open(sys.argv[1]))['title'])" "$INFO")"
DESC="$(python3 -c "import json,sys; print(json.load(open(sys.argv[1])).get('description','')[:4000])" "$INFO")"
UPLOAD_ARGS=(--title "$TITLE")
[[ -n "$DESC" ]] && UPLOAD_ARGS+=(--summary "$DESC")
if [[ -n "$THUMB" ]]; then
THUMB_SIZE="$(stat -f%z "$THUMB" 2>/dev/null || stat -c%s "$THUMB" 2>/dev/null)"
if [[ "$THUMB_SIZE" -le 1048576 ]]; then
UPLOAD_ARGS+=(--image "$THUMB")
else
echo "Thumbnail exceeds 1 MB, skipping."
fi
fi
echo "Uploading to Spotify..."
save-to-spotify upload "$AUDIO" "${UPLOAD_ARGS[@]}" ${SHOW_ARGS[@]+"${SHOW_ARGS[@]}"}
echo "Done! '$TITLE' saved to Spotify."
Save it as yt2spotify.sh and make it executable:
chmod +x yt2spotify.sh
Then run:
yt2spotify.sh VIDEO_ID
yt2spotify.sh VIDEO_ID --new-show "YouTube Listens"
yt2spotify.sh VIDEO_ID --show-id spotify:show:abc123