loader image

Reply To: How to Stop Ad Blocker Detection on Websites Like YouTube

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

#8215
thumbtak
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
TAKs Shack
Wishing you and yours a very happy Thanksgiving!
This is default text for notification bar