Skip to content

Add YouTube fallback download with full Spotify metadata#890

Open
vo1dee wants to merge 3 commits into
spotbye:mainfrom
vo1dee:main
Open

Add YouTube fallback download with full Spotify metadata#890
vo1dee wants to merge 3 commits into
spotbye:mainfrom
vo1dee:main

Conversation

@vo1dee
Copy link
Copy Markdown

@vo1dee vo1dee commented May 16, 2026

Summary

  • Adds YouTube as a last-resort fallback when all configured services (Tidal, Amazon Music, Qobuz) fail to download a track
  • Downloads the best-matching audio via yt-dlp (auto-installed to ~/.spotiflac/ on first use, same pattern as ffmpeg), converts to MP3 320kbps via ffmpeg, then embeds full Spotify metadata + cover art
  • Adds a YouTube Fallback toggle in Settings (visible only in Auto downloader mode)

How it works

  1. After all other services fail, SpotiFLAC searches YouTube for "<track> <artist>" (top 5 results) and picks the result whose duration is closest to the Spotify track duration
  2. yt-dlp downloads the best available audio stream; ffmpeg converts it to MP3 320kbps with source metadata stripped
  3. Spotify cover art is downloaded separately, then a second ffmpeg pass embeds all ID3 tags (title, artist, album, album artist, track/disc numbers, ISRC, genre, cover art, etc.) using -codec copy — no quality loss

New files

  • backend/youtube.goYouTubeDownloader, yt-dlp auto-install, search, duration matching, full download pipeline
  • .github/workflows/build-macos.yml — GitHub Actions workflow for macOS DMG (cannot cross-compile from Linux)

Modified files

  • app.gocase "youtube": added to the download service switch
  • backend/metadata.goembedMetadataToMP3WithFFmpeg() added (ffmpeg-based MP3 tag writing, analogous to existing M4A approach)
  • frontend/src/types/api.tsservice union extended with "youtube"
  • frontend/src/lib/settings.tsyoutubeFallback: boolean setting added
  • frontend/src/components/SettingsPage.tsx — YouTube Fallback switch + YouTubeIcon
  • frontend/src/components/PlatformIcons.tsxYouTubeIcon SVG component
  • frontend/src/hooks/useDownload.ts — YouTube fallback wired into both downloadWithAutoFallback and downloadWithItemID

vo1dee added 3 commits May 16, 2026 20:00
When downloader is set to Auto and all configured services (Tidal, Amazon
Music, Qobuz) fail, the app can optionally fall back to YouTube via yt-dlp.

Changes:
- backend/youtube.go: new YouTubeDownloader that auto-installs yt-dlp on
  first use, searches YouTube (ytsearch5), picks the candidate closest in
  duration to the Spotify track, downloads best available audio, converts
  to MP3 320kbps via ffmpeg, and embeds full Spotify metadata + cover art
- app.go: add case 'youtube' to DownloadTrack switch
- frontend/src/lib/settings.ts: add youtubeFallback boolean setting
- frontend/src/types/api.ts: extend DownloadRequest.service with 'youtube'
- frontend/src/components/PlatformIcons.tsx: add YouTubeIcon SVG component
- frontend/src/components/SettingsPage.tsx: add YouTube Fallback toggle
  (visible in Auto mode, off by default)
- frontend/src/hooks/useDownload.ts: after Tidal/Amazon/Qobuz all fail,
  attempt YouTube when youtubeFallback setting is enabled (both
  downloadWithAutoFallback and downloadWithItemID paths)
- .github/workflows/build-macos.yml: CI workflow to build macOS DMG
  (macOS cannot be cross-compiled from Linux)
The bogem/id3v2 library was silently failing to write tags to
ffmpeg-converted MP3 files. Switch to an ffmpeg-based second pass
(matching the existing M4A approach) which reliably writes ID3 tags
and embeds cover art in the same step.
@vo1dee
Copy link
Copy Markdown
Author

vo1dee commented May 16, 2026

Some screenshots
image
image

@borntohonk
Copy link
Copy Markdown

Too bad it's not flac and thus not really scope of this project, spotube (web) linked in the readme does the same, and outputs .mp3

@vo1dee
Copy link
Copy Markdown
Author

vo1dee commented May 16, 2026

Too bad it's not flac and thus not really scope of this project, spotube (web) linked in the readme does the same, and outputs .mp3

Well, I see. But it's still option to get a full release, in case only some tracks are failed to download, which happened to me. Not sure why, but only Amazon works for me (with VPN), and also, on some obscure releases it failed to download 3 out of 7 tracks.
But yeah, I understand that it might not be 100% scope of this project

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants