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 7:00 pm
#8216
Moderator
Option H added, and some other fixes, that blocked downloads.
#!/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 # <--- FIX: Corrected syntax from '}' to '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
}
# ----------------------------------------------------------------------
# --- Cookie Flag Builder Function ---
# ----------------------------------------------------------------------
# Helper to generate the cookie flags string based on user input
get_cookie_flags() {
local use_cookies_choice="$1"
local browser_name="$2"
local profile_name="$3"
local cookie_flags=""
if [[ "$use_cookies_choice" =~ ^[Yy]$ ]]; then
# Aggressively clean and lowercase the browser name
local clean_browser_name
clean_browser_name=$(echo "$browser_name" | sed -e 's/^[[:space:]]*//' -e 's/[[:space:]]*$//' | tr '[:upper:]' '[:lower:]')
if [[ -n "$profile_name" ]]; then
# FIX: Removed internal quotes to prevent passing literal quotes to yt-dlp
cookie_flags="--cookies-from-browser ${clean_browser_name}:${profile_name}"
else
# FIX: Removed internal quotes to prevent passing literal quotes to yt-dlp
cookie_flags="--cookies-from-browser ${clean_browser_name}"
fi
fi
echo "$cookie_flags"
}
# ----------------------------------------------------------------------
# --- yt-dlp Command Builder Function (Now expects pre-built cookie flags) ---
# ----------------------------------------------------------------------
build_yt_dlp_command() {
local url="$1"
local output_template="$2"
local download_audio="$3" # 'y' or 'n'
local extra_options="$4"
local print_filename_flag="$5" # '--print filename' or ''
local cookie_flags="$6" # New: Pre-built cookie flags
# The command now includes the cookie flags at the start
local YTDLP_CMD="yt-dlp $cookie_flags \"$url\""
# RESTORING USER-AGENT and other robustness flags to bypass 403 errors.
YTDLP_CMD="$YTDLP_CMD --user-agent \"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/100.0.4896.60 Safari/537.36\" --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
# Append the filename print flag if requested
if [[ -n "$print_filename_flag" ]]; then
YTDLP_CMD="$YTDLP_CMD $print_filename_flag"
fi
echo "$YTDLP_CMD" # Only this line is printed to stdout and captured by $()
}
# ----------------------------------------------------------------------
# --- CORE DOWNLOAD FUNCTION (Updated to accept cookie flags) ---
# ----------------------------------------------------------------------
run_single_download() {
local url="$1"
local temp_output_template="$2"
local download_audio_choice="$3"
local interactive_mode="$4" # 'y' for [s], 'n' for [h]
local extra_options="$5" # Passed in
local cookie_flags="$6" # Passed in
# Check if we need the complex print filename logic (only if template contains %(ext)s)
local print_filename_flag=""
if [[ "$temp_output_template" =~ "%(ext)s" ]]; then
print_filename_flag="--print filename"
fi
# Build the command string (passing cookie flags)
YTDLP_CMD=$(build_yt_dlp_command "$url" "$temp_output_template" "$download_audio_choice" "$extra_options" "$print_filename_flag" "$cookie_flags")
echo ""
echo "$SEPARATOR" | lolcat
echo "Your final command is ready:"
echo "$YTDLP_CMD"
echo "$SEPARATOR" | lolcat
echo ""
if [[ "$interactive_mode" == "y" ]]; then
read -p "Ready to download? (y/n) " execute_choice
if [[ ! "$execute_choice" =~ ^[Yy]$ ]]; then
return 1 # Download cancelled
fi
fi
echo "Starting download..."
# Simple execution for fixed names (Used in [s] and [h])
# $YTDLP_CMD contains the cookie flags which expand to two arguments
eval "$YTDLP_CMD"
export FINAL_DOWNLOAD_STATUS=$?
export FINAL_DOWNLOAD_FILENAME="$temp_output_template"
if [ $FINAL_DOWNLOAD_STATUS -ne 0 ]; then
echo "An error occurred during the download."
# Clean up partial files using the known fixed name
rm -f "${temp_output_template}.part"
return 1
fi
echo "Download finished!"
return 0 # Download successful
}
# ----------------------------------------------------------------------
# --- 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 "mpv" "apt-get install -y mpv" # Install mpv for Option [h]
install_tool "smplayer" "apt-get install -y smplayer" "smplayer" # Keep smplayer for Option [s]
# At this point, all required tools should be installed or the user declined.
for cmd in yt-dlp figlet lolcat; do
if ! command -v "$cmd" &> /dev/null; then
type_text "Error: '$cmd' is not installed. Exiting."
exit 1
fi
done
# Check for at least one media player
if ! command -v "smplayer" &> /dev/null && ! command -v "mpv" &> /dev/null; then
type_text "Error: Neither 'smplayer' nor 'mpv' is installed. Please install at least one. Exiting."
exit 1
fi
# --- 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 (P/A/D logic) ---
# ----------------------------------------------------------------------
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
local use_cookies_choice
local browser_name=""
local profile_name=""
local cookie_flags=""
read -p "Do these videos require browser authentication (cookies)? (y/n) " use_cookies_choice
# --- COOKIE INTERACTION FOR [p] (Playlist mode) ---
if [[ "$use_cookies_choice" =~ ^[Yy]$ ]]; then
echo "Select a browser for cookies:"
local options=("Chrome" "Firefox" "Brave" "Edge")
select browser_name_temp in "${options[@]}"; do
if [[ -n "$browser_name_temp" ]]; then
browser_name="$browser_name_temp"
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
cookie_flags=$(get_cookie_flags "$use_cookies_choice" "$browser_name" "$profile_name")
fi
# --------------------------------------------------
mkdir -p playlist
echo "Starting download and play session from '$file_name'..."
while IFS= read -r url; do
if [ -n "$url" ]; then
echo "$SEPARATOR" | lolcat
echo "Processing video from URL: $url"
# Use the command builder, passing cookie flags
YTDLP_CMD=$(build_yt_dlp_command "$url" "playlist/%(title)s.%(ext)s" "n" "" "" "$cookie_flags")
echo "Executing: $YTDLP_CMD"
eval "$YTDLP_CMD"
if [ $? -eq 0 ]; then
echo "Download successful."
# Finding the file by last modified time is the most reliable way when using %(title)s.%(ext)s
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")"
# Default to smplayer here, as this is the standard playlist mode
if command -v "smplayer" &> /dev/null; then
smplayer -close-after-media-ended "$video_file"
elif command -v "mpv" &> /dev/null; then
mpv "$video_file"
fi
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"
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."
}
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"
}
# ----------------------------------------------------------------------
# --- Function: Download, Auto-Play, and Delete Loop ([h] Logic) ---
# ----------------------------------------------------------------------
hybrid_stream_loop() {
# The temporary fixed filename placeholder
local temp_filename="taksshack.com.mp4"
local MAX_RETRIES=10
local RETRY_DELAY=10
# Ensure mpv is installed, since this option relies on it for direct playback
if ! command -v "mpv" &> /dev/null; then
echo "Error: The [h] option requires 'mpv'. Please install it."
return 1
fi
while true; do
echo "$SEPARATOR" | lolcat
read -p "Please paste the YouTube URL you want to download and play (or type 'q' to exit): " url
if [[ "$url" =~ ^[Qq]$ ]]; then
break
elif [[ -z "$url" ]]; then
echo "No URL provided. Please try again."
continue
fi
# --- INTERACTION FOR [h] (Cookie and Extra Options) ---
local use_cookies_choice
local browser_name=""
local profile_name=""
local cookie_flags=""
read -p "Do you want to use a browser for authentication (cookies)? (y/n) " use_cookies_choice
# Follow-up questions for cookie details
if [[ "$use_cookies_choice" =~ ^[Yy]$ ]]; then
echo "Select a browser for cookies:"
local options=("Chrome" "Firefox" "Brave" "Edge")
select browser_name_temp in "${options[@]}"; do
if [[ -n "$browser_name_temp" ]]; then
browser_name="$browser_name_temp"
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
# Build the cookie flags immediately
cookie_flags=$(get_cookie_flags "$use_cookies_choice" "$browser_name" "$profile_name")
fi
read -p "Any other yt-dlp options (e.g., --verbose)? " extra_options
if [[ "$extra_options" == "n" ]]; then
extra_options=""
fi
# -------------------------------
# 1. Get the actual final filename, which includes the correct extension
# FIX: Now includes $cookie_flags to authenticate the filename lookup
local original_filename
# $cookie_flags is unquoted here, correctly expanding to "--cookies-from-browser chrome" (two arguments)
original_filename=$(yt-dlp --get-filename -o '%(title)s.%(ext)s' $cookie_flags "$url" 2>/dev/tty)
local status=$?
# Trim leading/trailing whitespace just in case (important if yt-dlp spits out newlines)
original_filename=$(echo "$original_filename" | sed -e 's/^[[:space:]]*//' -e 's/[[:space:]]*$//')
if [ $status -ne 0 ] || [ -z "$original_filename" ]; then
echo "Error: Could not determine the original filename/extension for the URL (yt-dlp exit code: $status). Aborting URL."
continue
fi
# 2. Download Loop with Retries
local RETRY_COUNT=1
local DOWNLOAD_SUCCESS=0
while [ $RETRY_COUNT -le $MAX_RETRIES ]; do
echo "$SEPARATOR" | lolcat
echo "--- Download Attempt $RETRY_COUNT of $MAX_RETRIES ---"
# Run the core download function (passing cookie flags)
run_single_download "$url" "$temp_filename" "n" "n" "$extra_options" "$cookie_flags"
if [ $? -eq 0 ]; then
DOWNLOAD_SUCCESS=1
break # Exit the retry loop on success
else
echo "Download failed. Waiting $RETRY_DELAY seconds before retrying..."
sleep $RETRY_DELAY
RETRY_COUNT=$((RETRY_COUNT + 1))
fi
done
if [ $DOWNLOAD_SUCCESS -eq 1 ]; then
# 3. Download was successful. Check if the placeholder file exists.
if [ -f "$temp_filename" ]; then
# 4. ATOMIC RENAME: Rename the placeholder to the actual name/extension.
local final_video_file="$original_filename"
mv "$temp_filename" "$final_video_file"
echo "$SEPARATOR" | lolcat
echo "Launching player (mpv) fullscreen and stretched for: $final_video_file"
# 5. Play the correctly named file using direct mpv with full screen and forced stretch
mpv --fullscreen --no-keepaspect --no-keepaspect-window "$final_video_file"
echo "Playback session ended. Auto-deleting file."
# 6. Auto-delete the final file
rm -f "$final_video_file"
echo "Temporary file deleted: $final_video_file"
else
echo "Error: Download was reported successful but the final file could not be located at the expected placeholder ($temp_filename)."
rm -f "${temp_filename}.part"
fi
else
echo "$SEPARATOR" | lolcat
echo "Download failed after $MAX_RETRIES attempts. Moving to next URL or exiting loop."
fi
echo "$SEPARATOR" | lolcat
echo "Operation complete."
echo "$SEPARATOR" | lolcat
read -p "Do you want to process another URL? (y/n) " play_again_choice
if [[ ! "$play_again_choice" =~ ^[Yy]$ ]]; then
break
fi
done
}
# ----------------------------------------------------------------------
# --- Single Download and Play/Save ([s] Logic) ---
# ----------------------------------------------------------------------
single_download_and_save() {
read -p "Please paste the YouTube URL you want to download: " url
# --- INTERACTION FOR [s] ---
local use_cookies_choice
local browser_name=""
local profile_name=""
local cookie_flags=""
read -p "Do you want to use a browser for authentication? (y/n) " use_cookies_choice
# Follow-up questions for cookie details
if [[ "$use_cookies_choice" =~ ^[Yy]$ ]]; then
echo "Select a browser for cookies:"
local options=("Chrome" "Firefox" "Brave" "Edge")
select browser_name_temp in "${options[@]}"; do
if [[ -n "$browser_name_temp" ]]; then
browser_name="$browser_name_temp"
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
# Build the cookie flags immediately
cookie_flags=$(get_cookie_flags "$use_cookies_choice" "$browser_name" "$profile_name")
fi
read -p "Any other yt-dlp options (e.g., --verbose)? " extra_options
if [[ "$extra_options" == "n" ]]; then
extra_options=""
fi
# ---------------------------
# Prompt for audio
read -p "Do you want to download just the audio? (y/n) " download_audio_choice
# Get original filename early to use for saving later (using cookie flags for authentication)
local original_filename
original_filename=$(yt-dlp --get-filename -o '%(title)s.%(ext)s' $cookie_flags "$url")
local temp_filename="taksshack.com.mp4"
# Run the core download function in interactive mode ("y"), passing cookie details
run_single_download "$url" "$temp_filename" "$download_audio_choice" "y" "$extra_options" "$cookie_flags"
if [ $? -eq 0 ]; then
# Download was successful
read -p "Do you want to play the downloaded media? (y/n) " play_choice
if [[ "$play_choice" =~ ^[Yy]$ ]]; then
if command -v "smplayer" &> /dev/null; then
smplayer "$temp_filename"
elif command -v "mpv" &> /dev/null; then
mpv "$temp_filename"
else
echo "Cannot play: Neither smplayer nor mpv found."
fi
fi
# Check the actual extension for saving
if [[ "$download_audio_choice" =~ ^[Yy]$ ]]; then
# If audio was downloaded, the final file is mp3, rename the original_filename variable
original_filename="${original_filename%.*}.mp3"
else
# For video, rename the placeholder to the original name/extension
local final_video_file="$original_filename"
mv "$temp_filename" "$final_video_file"
temp_filename="$final_video_file" # Update the reference for cleanup
# Reset original_filename to the correct name/extension for the prompt
original_filename="$final_video_file"
fi
read -p "Do you want to save the file as '$original_filename'? (y/n) " save_choice
if [[ "$save_choice" =~ ^[Yy]$ ]]; then
# If video, it's already renamed and saved. If audio, mv from temp_filename (which is taksshack.com.mp4)
if [[ "$download_audio_choice" =~ ^[Yy]$ ]]; then
mv "taksshack.com.mp4" "$original_filename"
fi
echo "File saved as '$original_filename'"
else
rm "$temp_filename"
echo "File deleted."
fi
fi
echo ""
echo "$SEPARATOR" | lolcat
echo "Operation complete."
echo "$SEPARATOR" | lolcat
}
# ----------------------------------------------------------------------
# --- 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 " [h] Download, Auto-Play, and Delete (Uses full download progress as buffer) ⭐ NEW"
read -p "Your choice (a/p/s/d/h): " main_choice
if [[ "$main_choice" =~ ^[Pp]$ ]]; then
download_and_play_playlist
elif [[ "$main_choice" =~ ^[Aa]$ ]]; then
add_url_to_playlist
elif [[ "$main_choice" =~ ^[Dd]$ ]]; then
add_url_to_playlist
elif [[ "$main_choice" =~ ^[Ss]$ ]]; then
single_download_and_save
elif [[ "$main_choice" =~ ^[Hh]$ ]]; then
hybrid_stream_loop
fi
