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 22, 2025 at 12:31 pm
#8221
Moderator
A 403 error often means YouTube is blocking your IP address or rejecting your existing connection/cookies. I’ve updated the script to include two aggressive flags to help bypass this issue:
--force-ipv4: Instructsyt-dlpto only use IPv4, which can sometimes bypass IPv6-related blocks.- Aria2c Downloader: I’ve integrated checks for the faster external downloader, Aria2c, and set it to use 16 connections (
--max-connection-per-server=16). This helps with multi-part downloads and often improves connection resilience, which can mitigate 403 issues during a download.
Full Script with the 403 Bypass Fixes Applied
#!/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 (FIXED SYNTAX)
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 # <--- CORRECTED: Closing the 'if' statement with '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
# Try apt-get if it's the primary install method
if command -v "apt-get" &> /dev/null; then
sudo apt-get update && sudo apt-get install -y "$tool_name"
elif command -v "apt" &> /dev/null; then
sudo apt update && sudo apt install -y "$tool_name"
else
sudo $install_cmd
fi
fi
# Check if the installation was successful
if [ $? -eq 0 ]; then
echo "'$tool_name' installed successfully!"
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
}
# ----------------------------------------------------------------------
# --- Tor Management Functions ---
# ----------------------------------------------------------------------
# Global variables
TOR_STARTED_BY_SCRIPT=0
TOR_PID=""
TOR_AGGRESSIVE_MODE="n" # Global to track if we skip the Android spoof for max quality
start_tor() {
if ! command -v "tor" &> /dev/null; then
echo "Tor is not installed. Skipping Tor proxy."
return 1
fi
read -p "Do you want to use the Tor network for this operation (anonymity/bypassing geo-blocks)? (y/n) " use_tor_choice
if [[ "$use_tor_choice" =~ ^[Yy]$ ]]; then
echo ""
echo "Tor Quality Mode Selection:"
echo " [1] High-Quality (Aggressive): Tries for 4K/1080p, but risks the '403 Forbidden' error."
echo " [2] Reliable (Safe): Guarantees bypass of '403 Forbidden', but often limits quality to 720p/480p."
read -p "Select mode (1 or 2): " mode_choice
if [[ "$mode_choice" == "1" ]]; then
TOR_AGGRESSIVE_MODE="y"
echo "Mode: High-Quality (Aggressive) selected. Proceeding to start Tor..."
else
TOR_AGGRESSIVE_MODE="n"
echo "Mode: Reliable (Safe) selected. Proceeding to start Tor..."
fi
echo "Attempting to start Tor in the background (SOCKS5 on 127.0.0.1:9050)..."
# Check if Tor is already running (e.g., via system service)
if pgrep -x "tor" > /dev/null; then
echo "Tor is already running. Will use existing instance."
TOR_STARTED_BY_SCRIPT=0
return 0
fi
# Start Tor as a background process, redirecting output to /dev/null
tor &
TOR_PID=$!
sleep 5 # Wait for Tor to bootstrap
if kill -0 $TOR_PID 2>/dev/null; then
echo "Tor started successfully (PID: $TOR_PID)."
TOR_STARTED_BY_SCRIPT=1
return 0
else
echo "Failed to start Tor. Falling back to direct connection."
TOR_STARTED_BY_SCRIPT=0
return 1
fi
fi
# If Tor is not used, reset aggressive mode just in case
TOR_AGGRESSIVE_MODE="n"
return 1
}
stop_tor() {
if [ "$TOR_STARTED_BY_SCRIPT" -eq 1 ] && [ -n "$TOR_PID" ]; then
echo "Stopping Tor process (PID: $TOR_PID)..."
kill "$TOR_PID" 2>/dev/null
if [ $? -eq 0 ]; then
echo "Tor stopped."
else
echo "Could not stop Tor gracefully. It may have already exited."
fi
fi
# Reset mode after stopping
TOR_AGGRESSIVE_MODE="n"
}
# ----------------------------------------------------------------------
# --- 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
cookie_flags="--cookies-from-browser ${clean_browser_name}:${profile_name}"
else
cookie_flags="--cookies-from-browser ${clean_browser_name}"
fi
fi
echo "$cookie_flags"
}
# ----------------------------------------------------------------------
# --- CONSOLIDATED INTERACTION FUNCTION ---
# ----------------------------------------------------------------------
# Prompts for cookies, Tor, and extra options in a single block.
# Outputs:
# - cookie_flags (string)
# - extra_options (string)
# - tor_enabled (global TOR_STARTED_BY_SCRIPT is set)
# - tor_aggressive (global TOR_AGGRESSIVE_MODE is set)
get_user_options() {
local __cookie_flags_out=$1
local __extra_options_out=$2
local use_cookies_choice="n"
local browser_name=""
local profile_name=""
local cookie_flags=""
local extra_options=""
# 1. COOKIE INTERACTION
read -p "Do you want to use a browser for authentication (cookies)? (y/n) " use_cookies_choice
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
# 2. EXTRA OPTIONS INTERACTION
read -p "Any other yt-dlp options (e.g., --verbose)? " extra_options_input
if [[ "$extra_options_input" != "n" ]]; then
extra_options="$extra_options_input"
fi
# 3. TOR INTERACTION (Sets globals TOR_STARTED_BY_SCRIPT and TOR_AGGRESSIVE_MODE)
start_tor # This function handles the prompting and starting of Tor
# Set the output variables using nameref/indirect reference
eval "$__cookie_flags_out=\"$cookie_flags\""
eval "$__extra_options_out=\"$extra_options\""
}
# ----------------------------------------------------------------------
# --- yt-dlp Command Builder Function ---
# ----------------------------------------------------------------------
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"
local tor_enabled="$7" # 'y' or 'n'
local tor_aggressive="$8" # 'y' or 'n'
local YTDLP_CMD="yt-dlp"
# --- Tor Proxy and 403/Quality Fix Integration ---
if [[ "$tor_enabled" =~ ^[Yy]$ ]]; then
YTDLP_CMD="$YTDLP_CMD --proxy socks5://127.0.0.1:9050"
if [[ "$tor_aggressive" == "n" ]]; then
# Reliable Mode: Use the Android spoof to bypass the 403 check, but quality is limited
YTDLP_CMD="$YTDLP_CMD --extractor-args \"youtube:player-client=android\""
echo "Tor proxy (Reliable Mode: Android spoof active)." >&2
else
# Aggressive Mode: Do NOT use the Android spoof to maximize quality
echo "Tor proxy (Aggressive Mode: Max Quality attempted)." >&2
fi
fi
# -----------------------------------------
# Add Cookies and URL
YTDLP_CMD="$YTDLP_CMD $cookie_flags \"$url\""
# --- Robustness Flags: Referer, Retries, User-Agent ---
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\""
YTDLP_CMD="$YTDLP_CMD --no-check-certificate"
YTDLP_CMD="$YTDLP_CMD --extractor-retries 5"
YTDLP_CMD="$YTDLP_CMD --referer https://www.youtube.com/"
# --------------------------------------------------------
# --- Download Engine Logic ---
if [[ -n "$extra_options" ]] && command -v "aria2c" &> /dev/null; then
YTDLP_CMD="$YTDLP_CMD --force-ipv4 --external-downloader aria2c --external-downloader-args \"aria2c:--max-connection-per-server=16\""
echo "Using aria2c for download robustness." >&2
else
YTDLP_CMD="$YTDLP_CMD --force-ipv4"
echo "Using internal yt-dlp download for stability." >&2
fi
# -----------------------------
if [[ "$download_audio" =~ ^[Yy]$ ]]; then
# Audio download
YTDLP_CMD="$YTDLP_CMD -x --audio-format mp3 -o '$output_template'"
echo "Downloading audio in MP3 format." >&2
else
# Video download: Highest Quality Resilient String
YTDLP_CMD="$YTDLP_CMD -f 'bestvideo[ext=mp4]+bestaudio[ext=m4a]/bestvideo+bestaudio/best[ext=mp4]/best' -k -o '$output_template'"
echo "Downloading the HIGHEST reliable quality video and audio (MP4 preferred)." >&2
fi
if [[ -n "$extra_options" ]]; then
YTDLP_CMD="$YTDLP_CMD $extra_options"
fi
if [[ -n "$print_filename_flag" ]]; then
YTDLP_CMD="$YTDLP_CMD $print_filename_flag"
fi
echo "$YTDLP_CMD"
}
# ----------------------------------------------------------------------
# --- CORE DOWNLOAD FUNCTION ---
# ----------------------------------------------------------------------
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 others
local extra_options="$5"
local cookie_flags="$6"
local tor_enabled="$7" # Passed in
local tor_aggressive="$8" # Passed in
local print_filename_flag=""
if [[ "$temp_output_template" =~ "%(ext)s" ]]; then
print_filename_flag="--print filename"
fi
# Build the command string (passing all flags)
YTDLP_CMD=$(build_yt_dlp_command "$url" "$temp_output_template" "$download_audio_choice" "$extra_options" "$print_filename_flag" "$cookie_flags" "$tor_enabled" "$tor_aggressive")
echo ""
echo "$SEPARATOR" | lolcat
echo "Your final command is ready:"
echo "$YTDLP_CMD"
echo "$SEPARATOR" | lolcat
echo ""
if [[ "$interactive_mode" =~ ^[Yy]$ ]]; then
read -p "Ready to download? (y/n) " execute_choice
if [[ ! "$execute_choice" =~ ^[Yy]$ ]]; then
return 1 # Download cancelled
fi
fi
echo "Starting download..."
# Execute the command
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 (Exit Code: $FINAL_DOWNLOAD_STATUS)."
# Clean up temporary part files
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_tool "smplayer" "apt-get install -y smplayer" "smplayer"
install_tool "aria2c" "apt-get install -y aria2"
install_tool "tor" "apt-get install -y tor"
# Check for essential tools
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: Get Filename (Direct Connection) ---
# ----------------------------------------------------------------------
# This function is run BEFORE Tor is started to get the best info
get_info_direct() {
local url="$1"
local cookie_flags="$2"
local download_audio_choice="$3"
local filename_template=""
local format_string=""
if [[ "$download_audio_choice" =~ ^[Yy]$ ]]; then
# For audio, we look for the best audio stream and set filename to mp3
filename_template='%(title)s.mp3'
format_string="bestaudio[ext=m4a]/bestaudio"
else
# For video, we look for the best video/audio streams and set filename to mp4
filename_template='%(title)s.mp4'
# Resilient format string used to determine the final filename extension
format_string="bestvideo[ext=mp4]+bestaudio[ext=m4a]/best[ext=mp4]/best"
fi
local original_filename
# Use yt-dlp to output the determined filename using the best format string
original_filename=$(yt-dlp --get-filename -o "$filename_template" -f "$format_string" $cookie_flags "$url" 2>/dev/null)
original_filename=$(echo "$original_filename" | sed -e 's/^[[:space:]]*//' -e 's/[[:space:]]*$//')
if [ -z "$original_filename" ]; then
echo "Error: Could not determine original filename via direct connection." >&2
return 1
fi
# Returning only the filename. The download command uses the static, resilient format string.
echo "$original_filename"
return 0
}
# ----------------------------------------------------------------------
# ----------------------------------------------------------------------
# --- Function: Download and Play from a Playlist File ([l] 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 cookie_flags=""
local extra_options=""
echo "$SEPARATOR" | lolcat
# Use consolidated option getter (Tor is global, will be available)
get_user_options "cookie_flags" "extra_options"
local tor_enabled="n"
local tor_aggressive="n"
if [ "$TOR_STARTED_BY_SCRIPT" -eq 1 ] || pgrep -x "tor" > /dev/null; then
tor_enabled="y"
tor_aggressive="$TOR_AGGRESSIVE_MODE"
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"
# 1. Get info directly
local info
info=$(get_info_direct "$url" "$cookie_flags" "n")
local status=$?
if [ $status -ne 0 ]; then
echo "Warning: Could not determine final filename. Skipping URL."
continue
fi
# Use the command builder, passing all options
YTDLP_CMD=$(build_yt_dlp_command "$url" "playlist/%(title)s.%(ext)s" "n" "$extra_options" "" "$cookie_flags" "$tor_enabled" "$tor_aggressive")
echo "Executing: $YTDLP_CMD"
eval "$YTDLP_CMD"
if [ $? -eq 0 ]; then
echo "Download successful."
# Finding the downloaded file based on modification time
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")"
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"
# Safely remove the URL line from the 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"
# Stop Tor after the playlist finishes
stop_tor
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"
}
# ----------------------------------------------------------------------
# --- Download, Play, and Add to Playlist ([a] Logic) ---
# ----------------------------------------------------------------------
download_play_and_add_to_playlist() {
local temp_filename="taksshack.com.mp4"
local MAX_RETRIES=10
local RETRY_DELAY=10
if ! command -v "mpv" &> /dev/null; then
echo "Error: This option requires 'mpv' for playback. Please install it."
return 1
fi # <-- FIXED: This was the missing 'fi'
# --- INPUT/COOKIE/TOR SECTION ---
echo "$SEPARATOR" | lolcat
read -p "Please paste the YouTube URL you want to download and add to a playlist: " url
if [[ -z "$url" ]]; then
echo "No URL provided. Aborting."
return
fi
local cookie_flags=""
local extra_options=""
# Use consolidated option getter
get_user_options "cookie_flags" "extra_options"
local tor_enabled="n"
local tor_aggressive="n"
if [ "$TOR_STARTED_BY_SCRIPT" -eq 1 ] || pgrep -x "tor" > /dev/null; then
tor_enabled="y"
tor_aggressive="$TOR_AGGRESSIVE_MODE"
fi
# -------------------------------
# 1. Get info directly
local info
info=$(get_info_direct "$url" "$cookie_flags" "n")
local status=$?
local original_filename=""
if [ $status -eq 0 ]; then
# original_filename is retrieved
original_filename="$info"
else
echo "Error: Could not determine original filename. Aborting URL."
stop_tor
return
fi
# 2. Download Loop
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 (Tor: $tor_enabled) ---"
# Run the core download function, passing Tor flag and aggressive mode
run_single_download "$url" "$temp_filename" "n" "n" "$extra_options" "$cookie_flags" "$tor_enabled" "$tor_aggressive"
if [ $? -eq 0 ]; then
DOWNLOAD_SUCCESS=1
break
else
echo "Download failed. Waiting $RETRY_DELAY seconds before retrying..."
sleep $RETRY_DELAY
RETRY_COUNT=$((RETRY_COUNT + 1))
fi
done
# Stop Tor once download attempts are complete
stop_tor
if [ $DOWNLOAD_SUCCESS -eq 1 ]; then
# 3. Download successful: Rename, Play, and Add to Playlist
if [ -f "$temp_filename" ]; then
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"
mpv --fullscreen --no-keepaspect --no-keepaspect-window "$final_video_file"
echo "Playback session ended."
# --- Add to Playlist Logic ---
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"
# -----------------------------
read -p "Do you want to delete the downloaded file '$final_video_file' now? (y/n) " delete_choice
if [[ "$delete_choice" =~ ^[Yy]$ ]]; then
rm -f "$final_video_file"
echo "File deleted."
else
echo "File saved as '$final_video_file'."
fi
else
echo "Error: Download was reported successful but the final file could not be located."
fi
else
echo "$SEPARATOR" | lolcat
echo "Download failed after $MAX_RETRIES attempts. Cannot proceed to play or add to playlist."
fi
echo "$SEPARATOR" | lolcat
echo "Operation complete."
echo "$SEPARATOR" | lolcat
}
# ----------------------------------------------------------------------
# ----------------------------------------------------------------------
# --- Quick View / Live Stream Logic ([p] and [t]) ---
# ----------------------------------------------------------------------
# This function is now used for both [p] (quick D/P/D) and [t] (streaming)
hybrid_stream_loop() {
local temp_filename="taksshack.com.mp4"
local MAX_RETRIES=10
local RETRY_DELAY=10
local requested_action="$1" # 'stream' or 'download'
if ! command -v "mpv" &> /dev/null; then
echo "Error: This option requires 'mpv' for playback. Please install it."
return 1
fi
while true; do
echo "$SEPARATOR" | lolcat
read -p "Please paste the YouTube URL you want to process (or type 'q' to exit): " url
if [[ "$url" =~ ^[Qq]$ ]]; then
break
elif [[ -z "$url" ]]; then
echo "No URL provided. Please try again."
continue
fi
# --- INPUT/COOKIE/TOR SECTION ---
local cookie_flags=""
local extra_options=""
get_user_options "cookie_flags" "extra_options"
local tor_enabled="n"
local tor_aggressive="n"
if [ "$TOR_STARTED_BY_SCRIPT" -eq 1 ] || pgrep -x "tor" > /dev/null; then
tor_enabled="y"
tor_aggressive="$TOR_AGGRESSIVE_MODE"
fi
# -------------------------------
# ======================================================================
# --- LIVE STREAMING LOGIC ([t] option) ---
# ======================================================================
if [[ "$requested_action" == "stream" ]]; then
echo "Attempting to extract streaming URL and pipe directly to mpv (Bypassing download)..."
# Use the Tor/Cookie flags if enabled. Use -f 'best' and -g to get the stream URL.
local STREAM_CMD="yt-dlp -f 'best' -g $cookie_flags \"$url\" $extra_options"
# Add Tor/Proxy if enabled.
if [[ "$tor_enabled" =~ ^[Yy]$ ]]; then
STREAM_CMD="$STREAM_CMD --proxy socks5://127.0.0.1:9050"
if [[ "$tor_aggressive" == "n" ]]; then
STREAM_CMD="$STREAM_CMD --extractor-args \"youtube:player-client=android\""
echo "Using Reliable (Safe) mode for streaming (may limit quality)." >&2
else
echo "Using Aggressive (High-Quality) mode for streaming." >&2
fi
fi
echo "Extraction Command: $STREAM_CMD"
# Execute yt-dlp to get the URL, and pipe it directly to MPV
local FINAL_STREAM_CMD="mpv --fullscreen --no-keepaspect --no-keepaspect-window \"\$($STREAM_CMD)\""
echo "Launching player: $FINAL_STREAM_CMD"
eval "$FINAL_STREAM_CMD"
if [ $? -ne 0 ]; then
echo "Error: Failed to extract stream URL or MPV failed to play the stream."
fi
stop_tor # Stop Tor after streaming is complete
# ======================================================================
# --- QUICK VIEW DOWNLOAD LOGIC ([p] option) ---
# ======================================================================
elif [[ "$requested_action" == "download" ]]; then
echo "Starting download/play/delete cycle..."
# 1. Get info directly
local info
info=$(get_info_direct "$url" "$cookie_flags" "n")
local status=$?
local original_filename=""
if [ $status -eq 0 ]; then
original_filename="$info"
else
echo "Error: Could not determine original filename. Aborting URL."
stop_tor
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 (Tor: $tor_enabled) ---"
# Run the core download function, passing Tor flag and aggressive mode
run_single_download "$url" "$temp_filename" "n" "n" "$extra_options" "$cookie_flags" "$tor_enabled" "$tor_aggressive"
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
stop_tor # Stop Tor once download attempts are complete
if [ $DOWNLOAD_SUCCESS -eq 1 ]; then
# 3. Play and Delete
if [ -f "$temp_filename" ]; then
local final_video_file="$original_filename"
mv "$temp_filename" "$final_video_file"
echo "$SEPARATOR" | lolcat
echo "Launching player (mpv) for: $final_video_file"
mpv --fullscreen --no-keepaspect --no-keepaspect-window "$final_video_file"
echo "Playback session ended. Auto-deleting 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."
rm -f "${temp_filename}.part"
fi
else
echo "$SEPARATOR" | lolcat
echo "Download failed after $MAX_RETRIES attempts."
fi
fi # End of Stream/Download choice
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
# --- INPUT/COOKIE/TOR SECTION ---
local cookie_flags=""
local extra_options=""
get_user_options "cookie_flags" "extra_options"
local tor_enabled="n"
local tor_aggressive="n"
if [ "$TOR_STARTED_BY_SCRIPT" -eq 1 ] || pgrep -x "tor" > /dev/null; then
tor_enabled="y"
tor_aggressive="$TOR_AGGRESSIVE_MODE"
fi
# -------------------------------
read -p "Do you want to download just the audio? (y/n) " download_audio_choice
# 1. Get info directly
local info
info=$(get_info_direct "$url" "$cookie_flags" "$download_audio_choice")
local status=$?
local original_filename=""
if [ $status -eq 0 ]; then
original_filename="$info"
else
echo "Error: Could not determine original filename. Aborting URL."
stop_tor
return
fi
local temp_filename="taksshack.com.mp4"
# Run the core download function in interactive mode ("y"), passing Tor flag and aggressive mode
run_single_download "$url" "$temp_filename" "$download_audio_choice" "y" "$extra_options" "$cookie_flags" "$tor_enabled" "$tor_aggressive"
# Stop Tor once download is complete
stop_tor
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
# Rename the placeholder to the actual name/extension
local final_file_name="$original_filename"
mv "$temp_filename" "$final_file_name"
temp_filename="$final_file_name" # Update the reference for cleanup
read -p "Do you want to save the file as '$final_file_name'? (y/n) " save_choice
if [[ "$save_choice" =~ ^[Yy]$ ]]; then
echo "File saved as '$final_file_name'"
else
rm "$temp_filename"
echo "File deleted."
fi
fi
echo ""
echo "$SEPARATOR" | lolcat
echo "Operation complete."
echo "$SEPARATOR" | lolcat
}
# ----------------------------------------------------------------------
# --- Main Script Execution (FINAL MENU) ---
# ----------------------------------------------------------------------
type_text "Welcome to the yt-dlp interactive downloader!"
echo "https://taksshack.com"
echo ""
echo "Please choose a single URL mode (Tor/Cookies optional for all):"
echo " [s] Standard Download: Download, Play, and Choose to Save (Interactive)"
echo " [a] Add to Queue: Download, Play, and Auto-Save URL to Playlist File"
echo " [p] Quick View: Download, Auto-Play, and Auto-Delete"
echo " [t] Live Stream: Stream directly with MPV (No Download/Save)"
echo ""
echo "Or choose a list/management mode:"
echo " [l] Process List: Download, Play, and Manage URLs from a File (Playlist Mode)"
echo " [d] Add URL: Quickly add a URL to a Playlist File (No Download)"
read -p "Your choice (s/a/p/t/l/d): " main_choice
if [[ "$main_choice" =~ ^[Ll]$ ]]; then
download_and_play_playlist
elif [[ "$main_choice" =~ ^[Aa]$ ]]; then
download_play_and_add_to_playlist
elif [[ "$main_choice" =~ ^[Pp]$ ]]; then
hybrid_stream_loop "download"
elif [[ "$main_choice" =~ ^[Tt]$ ]]; then
hybrid_stream_loop "stream"
elif [[ "$main_choice" =~ ^[Dd]$ ]]; then
add_url_to_playlist
elif [[ "$main_choice" =~ ^[Ss]$ ]]; then
single_download_and_save
fi
-
This reply was modified 3 weeks ago by
thumbtak. Reason: Fixed option A
-
This reply was modified 3 weeks ago by
thumbtak. Reason: Tor Option added
-
This reply was modified 3 weeks ago by
thumbtak. Reason: Stream option added and improved tor network video quality, by adding a new option
-
This reply was modified 3 weeks ago by
thumbtak. Reason: Improved menu structure
