Freepoorman
Active Member
I created this script to download individual videos (MP4) and/or audio tracks (MP3), as well as playlists. The requirements are yt-dlp and ffmpeg (which ships with yt-dlp).
Remember to download the dependencies and edit this line to the actual Downloads directory on your system:
Feel free to use, edit, and share as you wish.
Bash:
#!/bin/bash
# Function to check if a command exists
command_exists() {
command -v "$1" >/dev/null 2>&1
}
# Check for yt-dlp and ffmpeg installations
if ! command_exists yt-dlp; then
echo "Error: yt-dlp is not installed. Please install it and try again."
exit 1
fi
if ! command_exists ffmpeg; then
echo "Error: ffmpeg is not installed. Please install it and try again."
exit 1
fi
# Define output directory
OUTPUT_DIR="/home/<USER>/Downloads"
# Function to check if output directory exists and is writable
check_output_dir() {
if [ ! -d "$OUTPUT_DIR" ]; then
echo "Output directory does not exist. Creating directory..."
mkdir -p "$OUTPUT_DIR"
if [ $? -ne 0 ]; then
echo "Failed to create output directory. Exiting."
exit 1
fi
fi
if [ ! -w "$OUTPUT_DIR" ]; then
echo "Output directory is not writable. Exiting."
exit 1
fi
}
# Function to sanitize filenames by replacing invalid characters
sanitize_filename() {
echo "$1" | sed 's/[\/:*?"<>|]/_/g'
}
# Function to download a single MP4 video at best quality up to 720p
download_single_mp4() {
read -p "Enter the YouTube URL: " url
sanitized_title=$(sanitize_filename "$(yt-dlp --get-title "$url")")
yt-dlp -f "best[ext=mp4][height<=720]" \
--output "$OUTPUT_DIR/$sanitized_title.%(ext)s" \
--no-sponsorblock \
--fixup detect_or_warn \
--fragment-retries infinite \
--retries infinite \
--buffer-size 10M \
--limit-rate 5M \
--verbose "$url"
check_exit_status $?
}
# Function to download a single MP3 audio in best quality with metadata
download_single_mp3() {
read -p "Enter the YouTube URL: " url
sanitized_title=$(sanitize_filename "$(yt-dlp --get-title "$url")")
yt-dlp -x --audio-format mp3 --embed-metadata --add-metadata --embed-thumbnail \
--output "$OUTPUT_DIR/$sanitized_title.%(ext)s" "$url"
check_exit_status $?
}
# Function to download MP4 Playlist at best quality up to 720p
download_playlist_mp4() {
read -p "Enter the YouTube playlist URL: " url
download_playlist "$url" "mp4"
}
# Function to download MP3 Playlist in best quality with metadata
download_playlist_mp3() {
read -p "Enter the YouTube playlist URL: " url
download_playlist "$url" "mp3"
}
# Function to download a playlist
download_playlist() {
local url=$1
local format=$2
local temp_error_file=$(mktemp)
local playlist_title=$(yt-dlp --flat-playlist --get-title "$url" | head -n 1)
local playlist_dir="$OUTPUT_DIR/$(sanitize_filename "$playlist_title")"
mkdir -p "$playlist_dir"
if [ "$format" == "mp4" ]; then
yt-dlp --yes-playlist -f "best[ext=mp4][height<=720]" \
--output "$playlist_dir/%(title)s.%(ext)s" \
--no-sponsorblock \
--fixup detect_or_warn \
--fragment-retries infinite \
--retries infinite \
--buffer-size 10M \
--limit-rate 5M \
--verbose "$url" 2> "$temp_error_file"
elif [ "$format" == "mp3" ]; then
yt-dlp --yes-playlist -x --audio-format mp3 --embed-metadata --add-metadata --embed-thumbnail \
--output "$playlist_dir/%(title)s.%(ext)s" "$url" 2> "$temp_error_file"
fi
if [ -s "$temp_error_file" ]; then
echo "Some files in the playlist failed to download. Here are the errors:"
cat "$temp_error_file"
read -p "Press Enter to continue..."
fi
rm -f "$temp_error_file"
}
# Function to check exit status and handle errors
check_exit_status() {
if [ $1 -ne 0 ]; then
echo "An error occurred during the download. Please check the URL and try again."
read -p "Press Enter to continue..."
fi
}
# Function to display the main menu
show_menu() {
echo "----------------------------------------"
echo " Download Menu"
echo "----------------------------------------"
echo "1. Download single MP4 (<=720p quality)"
echo "2. Download single MP3 (best quality)"
echo "3. Download MP4 Playlist (<=720p quality)"
echo "4. Download MP3 Playlist (best quality)"
echo "5. Exit"
echo "----------------------------------------"
read -p "Please select an option [1-5]: " choice
case $choice in
1) download_single_mp4 ;;
2) download_single_mp3 ;;
3) download_playlist_mp4 ;;
4) download_playlist_mp3 ;;
5) exit 0 ;;
*) echo "Invalid option. Please select a number between 1 and 5." ;;
esac
}
# Main script execution
check_output_dir
while true; do
show_menu
done
Remember to download the dependencies and edit this line to the actual Downloads directory on your system:
Bash:
OUTPUT_DIR="/home/<USER>/Downloads"
Feel free to use, edit, and share as you wish.