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

Comment? Reply via Email, Bluesky or Twitter.