Last active
October 23, 2025 18:10
-
-
Save 32teeth/5d571a09aaababb015bbd43b0720265e to your computer and use it in GitHub Desktop.
YouTube Audio Downloader
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| # youtube.sh | |
| # | |
| # Description: | |
| # Downloads a single YouTube (or supported site) video as a high-quality MP3 (320 kbps) | |
| # using yt-dlp and ffmpeg. It: | |
| # - Validates required commands (yt-dlp, ffmpeg) | |
| # - Fetches video title and uploader | |
| # - Sanitizes the title for a safe filename | |
| # - Downloads best available audio | |
| # - Extracts / converts to MP3 @ 320k | |
| # - Embeds thumbnail and metadata (artist, title) | |
| # - Falls back to listing formats if the main download attempt fails | |
| # | |
| # Requirements: | |
| # - yt-dlp (https://github.com/yt-dlp/yt-dlp) | |
| # - ffmpeg | |
| # | |
| # Installation (example): | |
| # brew install yt-dlp ffmpeg | |
| # | |
| # Usage: | |
| # youtube <YouTube URL> | |
| # | |
| # Example: | |
| # youtube "https://www.youtube.com/watch?v=dQw4w9WgXcQ" | |
| # | |
| # Notes: | |
| # - Output file name is derived from the video title, sanitized. | |
| # - If metadata extraction fails, a generic filename is used. | |
| # - Does not process playlists (single video only). | |
| # | |
| # To source in zsh (e.g. from ~/.zshrc): | |
| # source /Users/andreug/.zsh_functions/utils/youtube.sh | |
| youtube() { | |
| local url="$1" | |
| # Ensure a URL was provided | |
| if [[ -z "$url" ]]; then | |
| echo "Usage: youtube <YouTube URL>" | |
| return 1 | |
| fi | |
| # Verify required commands exist | |
| for cmd in yt-dlp ffmpeg; do | |
| if ! command -v "$cmd" >/dev/null 2>&1; then | |
| echo "Error: $cmd is not installed." >&2 | |
| return 1 | |
| fi | |
| done | |
| # Show yt-dlp version (helps debugging) | |
| yt-dlp --version | |
| # Retrieve title and uploader (suppress warnings; ignore failure) | |
| local title artist safe_title | |
| title="$(yt-dlp --no-warnings --skip-download --print title -- "$url" 2>/dev/null || true)" | |
| artist="$(yt-dlp --no-warnings --skip-download --print uploader -- "$url" 2>/dev/null || true)" | |
| # Sanitize title for filesystem (fallback to 'audio' if empty) | |
| safe_title="$(printf '%s' "${title:-audio}" \ | |
| | tr '/<>:\"\\|?*' '_' \ | |
| | tr -cd '[:alnum:] _-' \ | |
| | sed -E 's/ +/ /g; s/[[:space:]]+$//')" | |
| # Prefer multiple player clients to improve success rate | |
| local extractor_args="youtube:player_client=ios,android,web" | |
| echo "Downloading and converting → ${safe_title}.mp3" | |
| # Main download & convert | |
| yt-dlp \ | |
| --no-playlist \ | |
| --extractor-args "$extractor_args" \ | |
| -f "bestaudio/best" \ | |
| -o "${safe_title}.%(ext)s" \ | |
| -x --audio-format mp3 --audio-quality 320k \ | |
| --add-metadata \ | |
| --parse-metadata "%(uploader)s:%(artist)s" \ | |
| --parse-metadata "%(title)s:%(title)s" \ | |
| --embed-thumbnail \ | |
| -- "$url" || { | |
| # On failure, attempt a format listing with a stricter single client | |
| echo "yt-dlp failed. Trying a stricter fallback client (web only) to inspect formats..." | |
| yt-dlp --extractor-args "youtube:player_client=web" -F -- "$url" | |
| return 2 | |
| } | |
| echo "Done: ${safe_title}.mp3" | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment