What makes us different from other similar websites? › Forums › Tech › How to Stop Ad Blocker Detection on Websites Like YouTube › Reply To: How to Stop Ad Blocker Detection on Websites Like YouTube
October 21, 2025 at 5:29 pm
#8215
Moderator
Updated code that fixes the error “ERROR: unable to download video data: HTTP Error 403: Forbidden“:
#!/bin/bash
# Function to type text character by character for a cool visual effect
type_text() {
text="$1"
for ((i=0; i<${#text}; i++)); do
echo -n "${text:$i:1}"
sleep 0.05 # Adjust this value to change the typing speed
done
echo "" # Add a newline at the end
}
# ----------------------------------------------------------------------
# --- yt-dlp Update Check ---
# ----------------------------------------------------------------------
update_yt_dlp() {
if command -v "yt-dlp" &> /dev/null; then
read -p "A new version of yt-dlp may be available. Do you want to check for updates? (y/n) " update_choice
if [[ "$update_choice" =~ ^[Yy]$ ]]; then
echo "Checking for and installing updates..."
# Check if yt-dlp was installed via pip
if command -v "pip" &> /dev/null && pip freeze | grep "yt-dlp" &> /dev/null; then
pip install -U yt-dlp
else
# Fallback to the self-update command
yt-dlp -U
fi
if [ $? -eq 0 ]; then
echo "yt-dlp updated successfully!"
else
echo "Failed to update yt-dlp."
fi
fi
fi
}
# ----------------------------------------------------------------------
# --- Dependency Checks with Installation Prompts ---
# ----------------------------------------------------------------------
# Function to safely install a tool
install_tool() {
local tool_name="$1"
local install_cmd="$2"
local snap_install="$3"
# First, check if the tool is already installed
if command -v "$tool_name" &> /dev/null; then
echo "'$tool_name' is already installed."
return 0
fi
# If not, prompt the user for installation
echo "The '$tool_name' tool is required for this script."
read -p "Do you want to install it now? (y/n) " install_choice
if [[ "$install_choice" =~ ^[Yy]$ ]]; then
echo "Installing $tool_name..."
if [ -n "$snap_install" ]; then
sudo snap install "$snap_install"
else
sudo $install_cmd
fi
# Check if the installation was successful
if [ $? -eq 0 ]; then
echo "'$tool_name' installed successfully!"
# Add a small delay and re-check to ensure the shell updates
sleep 1
if ! command -v "$tool_name" &> /dev/null; then
echo "Warning: '$tool_name' was installed but not found in PATH. Please open a new terminal or run 'source ~/.bashrc'."
return 1
fi
return 0
else
echo "Failed to install '$tool_name'. Please install it manually."
return 1
fi
else
echo "Skipping '$tool_name' installation. Some features may not work."
return 1
fi
}
# ----------------------------------------------------------------------
# --- yt-dlp Command Builder Function (FIXED) ---
# ----------------------------------------------------------------------
build_yt_dlp_command() {
local url="$1"
local output_template="$2"
local use_cookies="$3" # 'y' or 'n'
local download_audio="$4" # 'y' or 'n'
local extra_options="$5"
local YTDLP_CMD="yt-dlp \"$url\""
if [[ "$use_cookies" =~ ^[Yy]$ ]]; then
echo "Select a browser for cookies:" >&2 # Output to stderr
local options=("Chrome" "Firefox" "Brave" "Edge")
select selected_browser in "${options[@]}"; do
if [[ -n "$selected_browser" ]]; then
break
else
echo "Invalid selection. Please choose a number from the list." >&2 # Output to stderr
fi
done
read -p "Enter profile name (e.g., 'Default') or leave blank: " profile_name
if [[ -n "$profile_name" ]]; then
YTDLP_CMD="$YTDLP_CMD --cookies-from-browser \"${selected_browser,,}:$profile_name\""
else
YTDLP_CMD="$YTDLP_CMD --cookies-from-browser \"${selected_browser,,}\""
fi
fi
# ALWAYS add general robustness flags.
YTDLP_CMD="$YTDLP_CMD --no-check-certificate"
if [[ "$download_audio" =~ ^[Yy]$ ]]; then
YTDLP_CMD="$YTDLP_CMD -x --audio-format mp3 -o '$output_template'"
echo "Got it! We'll download the audio in MP3 format." >&2 # Output to stderr
else
# Default to best video/audio combination
YTDLP_CMD="$YTDLP_CMD -f 'bestvideo[ext=mp4]+bestaudio[ext=m4a]/best[ext=mp4]/best' -o '$output_template'"
echo "Downloading the best quality video (MP4 preferred)." >&2 # Output to stderr
fi
if [[ -n "$extra_options" ]]; then
YTDLP_CMD="$YTDLP_CMD $extra_options"
fi
echo "$YTDLP_CMD" # Only this line is printed to stdout and captured by $()
}
# ----------------------------------------------------------------------
# --- Main Script Logic and Dependency Management ---
# ----------------------------------------------------------------------
# Run update check first
update_yt_dlp
echo "Checking for required dependencies..."
if ! command -v "snap" &> /dev/null; then
install_tool "snapd" "apt install snapd"
else
echo "'snapd' is already installed."
fi
install_tool "figlet" "apt install figlet"
install_tool "lolcat" "" "lolcat"
install_tool "yt-dlp" "apt install yt-dlp"
install_tool "smplayer" "apt-get install -y smplayer" "smplayer"
install_tool "ffmpeg" "apt install ffmpeg" # <--- NEW DEPENDENCY FOR SCREEN CAPTURE
# At this point, all required tools should be installed or the user declined.
for cmd in yt-dlp figlet lolcat smplayer; do
if ! command -v "$cmd" &> /dev/null; then
type_text "Error: '$cmd' is not installed. Exiting."
exit 1
fi
done
# --- Script Configuration ---
SEPARATOR="---------------------------------------------------"
echo "$SEPARATOR" | lolcat
figlet "YTDLP" | lolcat
echo "$SEPARATOR" | lolcat
# Define a configuration file to save settings
CONFIG_FILE=".yt-dlp_config"
# ----------------------------------------------------------------------
# --- Function: Download and Play from a Playlist File ---
# ----------------------------------------------------------------------
download_and_play_playlist() {
read -p "Enter the name of the text file with the links: " file_name
if [ ! -f "$file_name" ]; then
echo "Error: File '$file_name' not found."
return
fi
# Check for cookies ONCE
read -p "Do these videos require browser authentication (cookies)? (y/n) " use_cookies_choice
# Create the playlist folder if it doesn't exist
mkdir -p playlist
echo "Starting download and play session from '$file_name'..."
# Read each URL and process it one by one
while IFS= read -r url; do
if [ -n "$url" ]; then
echo "$SEPARATOR" | lolcat
echo "Processing video from URL: $url"
# Use the new builder function for consistency
YTDLP_CMD=$(build_yt_dlp_command "$url" "playlist/%(title)s.%(ext)s" "$use_cookies_choice" "n" "")
echo "Executing: $YTDLP_CMD"
eval "$YTDLP_CMD"
if [ $? -eq 0 ]; then
echo "Download successful."
# Find the downloaded file (improved find logic)
# Find the most recently modified file in the playlist directory
video_file=$(find playlist -type f -mtime -1m -printf '%T@ %p\n' 2>/dev/null | sort -n | tail -1 | cut -d' ' -f2-)
if [ -n "$video_file" ] && [ -f "$video_file" ]; then
echo "Playing: $(basename "$video_file")"
# Use smplayer to play the video and then exit when it's done.
smplayer -close-after-media-ended "$video_file"
# After playing, prompt for deletion and removal
read -p "Finished playing. Do you want to delete this video and remove the link from the file? (y/n) " delete_choice
if [[ "$delete_choice" =~ ^[Yy]$ ]]; then
rm "$video_file"
# Use sed to remove the URL only if it's the exact line (safer regex)
sed -i.bak "\@^$url$@d" "$file_name"
echo "Deleted video and removed link from $file_name."
else
echo "Skipped deletion and link removal."
fi
else
echo "Could not reliably find the downloaded video file."
fi
else
echo "Download failed for URL: $url"
fi
fi
done < "$file_name"
echo "$SEPARATOR" | lolcat
echo "Playlist session complete."
}
# ----------------------------------------------------------------------
# --- Function to add a URL to a playlist file without downloading ---
# ----------------------------------------------------------------------
add_url_to_playlist() {
read -p "Please paste the YouTube URL you want to add to a playlist: " url
if [[ -z "$url" ]]; then
type_text "No URL provided. Exiting."
return
fi
LAST_PLAYLIST_FILE="playlist.txt"
if [ -f "$CONFIG_FILE" ]; then
LAST_PLAYLIST_FILE=$(grep "^LAST_PLAYLIST_FILE=" "$CONFIG_FILE" | cut -d'=' -f2-)
if [ -z "$LAST_PLAYLIST_FILE" ]; then
LAST_PLAYLIST_FILE="playlist.txt"
fi
fi
read -p "Enter the name of the playlist file to add the link to (default: $LAST_PLAYLIST_FILE): " playlist_file_input
if [ -z "$playlist_file_input" ]; then
playlist_file="$LAST_PLAYLIST_FILE"
else
playlist_file="$playlist_file_input"
fi
echo "$url" >> "$playlist_file"
type_text "URL added to $playlist_file"
echo "LAST_PLAYLIST_FILE=$playlist_file" > "$CONFIG_FILE"
}
# ----------------------------------------------------------------------
# --- Main Script Execution ---
# ----------------------------------------------------------------------
type_text "Welcome to the yt-dlp interactive downloader!"
echo "https://taksshack.com"
echo ""
echo "Please choose an option:"
echo " [a] Add a single video to a playlist file (after downloading)"
echo " [p] Run and play a list of videos from a file"
echo " [s] Download a single video and ask to play/save it"
echo " [d] Add a single URL to a playlist file (without downloading)"
echo " [l] Live Stream/Play without downloading"
read -p "Your choice (a/p/s/d/l): " main_choice
if [[ "$main_choice" =~ ^[Pp]$ ]]; then
download_and_play_playlist
elif [[ "$main_choice" =~ ^[Aa]$ ]]; then
read -p "Please paste the YouTube URL you want to add: " url
# Get original filename early
original_filename=$(yt-dlp --get-filename -o '%(title)s.%(ext)s' "$url")
temp_output_file="playlist.mp4"
read -p "Do you want to use a browser for authentication? (y/n) " use_cookies_choice
# Build the command using the new function
YTDLP_CMD=$(build_yt_dlp_command "$url" "$temp_output_file" "$use_cookies_choice" "n" "")
echo ""
echo "$SEPARATOR" | lolcat
echo "Your final download command is ready:"
echo "$YTDLP_CMD"
echo "$SEPARATOR" | lolcat
echo ""
read -p "Ready to download and add to playlist? (y/n) " execute_choice
if [[ "$execute_choice" =~ ^[Yy]$ ]]; then
echo "Starting download..."
eval "$YTDLP_CMD"
if [[ $? -eq 0 ]]; then
echo "Download finished!"
smplayer "$temp_output_file"
read -p "Finished playing. Do you want to delete the video? (y/n) " delete_video_choice
if [[ "$delete_video_choice" =~ ^[Yy]$ ]]; then
rm "$temp_output_file"
echo "Deleted $temp_output_file"
else
mv "$temp_output_file" "$original_filename"
echo "Video renamed to '$original_filename'"
fi
LAST_PLAYLIST_FILE="playlist.txt"
if [ -f "$CONFIG_FILE" ]; then
LAST_PLAYLIST_FILE=$(grep "^LAST_PLAYLIST_FILE=" "$CONFIG_FILE" | cut -d'=' -f2-)
if [ -z "$LAST_PLAYLIST_FILE" ]; then
LAST_PLAYLIST_FILE="playlist.txt"
fi
fi
read -p "Enter the name of the playlist file to add the link to (default: $LAST_PLAYLIST_FILE): " playlist_file_input
if [ -z "$playlist_file_input" ]; then
playlist_file="$LAST_PLAYLIST_FILE"
else
playlist_file="$playlist_file_input"
fi
echo "$url" >> "$playlist_file"
echo "URL added to $playlist_file"
echo "LAST_PLAYLIST_FILE=$playlist_file" > "$CONFIG_FILE"
else
echo "--- DOWNLOAD FAILED ---"
read -p "The primary download failed. Do you want to try screen capturing as a backup? (y/n) " capture_choice
if [[ "$capture_choice" =~ ^[Yy]$ ]]; then
if command -v "ffmpeg" &> /dev/null; then
type_text "FFmpeg is installed. To screen record the video (Last Resort):"
echo "1. Play the video in a full-screen browser or player now."
echo "2. Open a NEW terminal and run the command below. (You may need to adjust '1920x1080' and ':0.0')."
echo "3. Press 'q' in the new terminal to stop recording."
# Provide the generic, common FFmpeg command for Linux (X11)
echo ""
echo "--- BACKUP COMMAND ---" | lolcat
echo "ffmpeg -f x11grab -s 1920x1080 -i :0.0 -c:v libx264 -preset veryfast -crf 23 -pix_fmt yuv420p 'Screen_Capture_Backup_$(date +%Y%m%d_%H%M%S).mp4'" | lolcat
echo "----------------------" | lolcat
type_text "Recording will be saved in your current directory."
else
echo "FFmpeg (the best command-line screen recorder) is not installed."
echo "Please install it (e.g., 'sudo apt install ffmpeg') or use a graphical screen capture tool like OBS Studio."
fi
else
echo "Backup capture skipped."
fi
fi
echo "$SEPARATOR" | lolcat
else
echo "Download cancelled."
fi
elif [[ "$main_choice" =~ ^[Dd]$ ]]; then
add_url_to_playlist
elif [[ "$main_choice" =~ ^[Ss]$ ]]; then
read -p "Please paste the YouTube URL you want to download: " url
# Get original filename early
original_filename=$(yt-dlp --get-filename -o '%(title)s.%(ext)s' "$url")
temp_filename="taksshack.com.mp4" # Use a consistent temp filename
read -p "Do you want to use a browser for authentication? (y/n) " use_cookies_choice
read -p "Do you want to download just the audio? (y/n) " download_audio_choice
read -p "Any other yt-dlp options (e.g., --verbose)? " extra_options
if [[ "$extra_options" == "n" ]]; then
extra_options=""
fi
# Build the command using the new function
YTDLP_CMD=$(build_yt_dlp_command "$url" "$temp_filename" "$use_cookies_choice" "$download_audio_choice" "$extra_options")
echo ""
echo "$SEPARATOR" | lolcat
echo "Your final command is ready:"
echo "$YTDLP_CMD"
echo "$SEPARATOR" | lolcat
echo ""
read -p "Ready to download? (y/n) " execute_choice
if [[ "$execute_choice" =~ ^[Yy]$ ]]; then
echo "Starting download..."
eval "$YTDLP_CMD"
if [[ $? -eq 0 ]]; then
echo "Download finished!"
read -p "Do you want to play the downloaded media? (y/n) " play_choice
if [[ "$play_choice" =~ ^[Yy]$ ]]; then
smplayer "$temp_filename"
fi
# Check the actual extension of the downloaded file
if [[ "$download_audio_choice" =~ ^[Yy]$ ]]; then
original_filename="${original_filename%.*}.mp3" # Ensure .mp3 extension if audio was downloaded
fi
read -p "Do you want to save the file as '$original_filename'? (y/n) " save_choice
if [[ "$save_choice" =~ ^[Yy]$ ]]; then
mv "$temp_filename" "$original_filename"
echo "File saved as '$original_filename'"
else
rm "$temp_filename"
echo "File deleted."
fi
else
echo "--- DOWNLOAD FAILED ---"
read -p "The primary download failed. Do you want to try screen capturing as a backup? (y/n) " capture_choice
if [[ "$capture_choice" =~ ^[Yy]$ ]]; then
if command -v "ffmpeg" &> /dev/null; then
type_text "FFmpeg is installed. To screen record the video (Last Resort):"
echo "1. Play the video in a full-screen browser or player now."
echo "2. Open a NEW terminal and run the command below. (You may need to adjust '1920x1080' and ':0.0')."
echo "3. Press 'q' in the new terminal to stop recording."
# Provide the generic, common FFmpeg command for Linux (X11)
echo ""
echo "--- BACKUP COMMAND ---" | lolcat
echo "ffmpeg -f x11grab -s 1920x1080 -i :0.0 -c:v libx264 -preset veryfast -crf 23 -pix_fmt yuv420p 'Screen_Capture_Backup_$(date +%Y%m%d_%H%M%S).mp4'" | lolcat
echo "----------------------" | lolcat
type_text "Recording will be saved in your current directory."
else
echo "FFmpeg (the best command-line screen recorder) is not installed."
echo "Please install it (e.g., 'sudo apt install ffmpeg') or use a graphical screen capture tool like OBS Studio."
fi
else
echo "Backup capture skipped."
fi
fi
echo ""
echo "$SEPARATOR" | lolcat
echo "Operation complete."
echo "$SEPARATOR" | lolcat
else
echo "Download cancelled."
fi
elif [[ "$main_choice" =~ ^[Ll]$ ]]; then
read -p "Please paste the YouTube URL you want to stream live: " url
read -p "Do you want to use a browser for authentication? (y/n) " use_cookies_choice
# Set up the base command for piping to STDOUT
STREAM_CMD="yt-dlp \"$url\" -f 'best' -o - --no-check-certificate"
if [[ "$use_cookies_choice" =~ ^[Yy]$ ]]; then
echo "Select a browser for cookies:"
options=("Chrome" "Firefox" "Brave" "Edge")
select selected_browser in "${options[@]}"; do
if [[ -n "$selected_browser" ]]; then
break
else
echo "Invalid selection. Please choose a number from the list."
fi
done
read -p "Enter profile name (e.g., 'Default') or leave blank: " profile_name
if [[ -n "$profile_name" ]]; then
STREAM_CMD="$STREAM_CMD --cookies-from-browser \"${selected_browser,,}:$profile_name\""
else
STREAM_CMD="$STREAM_CMD --cookies-from-browser \"${selected_browser,,}\""
fi
fi
echo ""
echo "$SEPARATOR" | lolcat
echo "Starting live stream. Press Ctrl+C to stop playback."
echo "Executing: $STREAM_CMD | smplayer -"
echo "$SEPARATOR" | lolcat
# Execute the command and pipe its raw output into smplayer
eval "$STREAM_CMD | smplayer -"
echo "$SEPARATOR" | lolcat
echo "Live stream complete."
fi
