#!/usr/bin/env bash # --- Configuration --- # Version bumped to 2.1 VERSION="2.1" DOWNLOAD_DIR="$HOME/storage/downloads/termux" UPDATER_URL="https://raw.githubusercontent.com/haiueom/termux-url-opener/main/update.sh" # Ensure download directory exists mkdir -p "$DOWNLOAD_DIR" # --- Colors --- RED='\033[0;31m' GREEN='\033[0;32m' YELLOW='\033[1;33m' BLUE='\033[0;34m' NC='\033[0m' # No Color # --- Helper Functions --- print_header() { clear local bar="=========================================" echo -e "${BLUE}${bar}${NC}" echo -e "${GREEN}[#] Termux URL Downloader (v$VERSION)${NC}" echo -e "${GREEN}[#] Script by: haiueom${NC}" echo -e "${BLUE}${bar}${NC}" } log_message() { case "$1" in INFO) echo -e "${BLUE}[*] $2${NC}" ;; SUCCESS) echo -e "${GREEN}[✓] $2${NC}" ;; ERROR) echo -e "${RED}[!] $2${NC}" >&2 ;; WARN) echo -e "${YELLOW}[?] $2${NC}" ;; esac } check_dependencies() { local missing_deps=() for cmd in "$@"; do if ! command -v "$cmd" &> /dev/null; then missing_deps+=("$cmd") fi done if [ ${#missing_deps[@]} -ne 0 ]; then log_message WARN "Missing dependencies: ${missing_deps[*]}. Attempting to install..." for dep in "${missing_deps[@]}"; do if [[ "$dep" == "yt-dlp" ]]; then # yt-dlp must be installed without deps in Termux to avoid compilation errors log_message INFO "Installing python package: $dep (no-deps)" pip install --no-deps "$dep" || { log_message ERROR "Failed to install $dep."; exit 1; } elif [[ "$dep" == "spotdl" ]]; then log_message INFO "Installing python package: $dep" pip install "$dep" || { log_message ERROR "Failed to install $dep."; exit 1; } else log_message INFO "Installing system package: $dep" pkg install -y "$dep" || { log_message ERROR "Failed to install $dep."; exit 1; } fi done log_message SUCCESS "All dependencies installed." fi } # --- Update Function --- update_script() { log_message INFO "Checking for updates..." local updater_script updater_script=$(mktemp) if ! curl -fLo "$updater_script" "$UPDATER_URL"; then log_message ERROR "Could not download the updater script." rm -f "$updater_script" return 1 fi chmod +x "$updater_script" # Executing updater. It will replace this script. bash "$updater_script" rm -f "$updater_script" log_message INFO "Update check finished." } # --- Download Functions --- download_mp4_ytdlp() { local url="$1" local target_dir="${DOWNLOAD_DIR}/ytdlp_video" mkdir -p "$target_dir" log_message INFO "Downloading MP4 video to: $target_dir" # Added --restrict-filenames for safer file handling yt-dlp -f 'b[ext=mp4]/b' --restrict-filenames --output "$target_dir/%(title)s.%(ext)s" "$url" } download_mp3_ytdlp() { local url="$1" local target_dir="${DOWNLOAD_DIR}/ytdlp_audio" mkdir -p "$target_dir" log_message INFO "Downloading MP3 audio to: $target_dir" yt-dlp -f "ba[ext=m4a]/ba" -x --audio-format mp3 --audio-quality 0 --restrict-filenames --output "$target_dir/%(title)s.%(ext)s" "$url" } download_mp3_spotdl() { local url="$1" local target_dir="${DOWNLOAD_DIR}/spotdl" mkdir -p "$target_dir" log_message INFO "Downloading from Spotify to: $target_dir" spotdl download "$url" --output "$target_dir" } download_curl() { local url="$1" local target_dir="${DOWNLOAD_DIR}/curl" mkdir -p "$target_dir" log_message INFO "Downloading with curl to: $target_dir" # Use subshell to maintain directory context (cd "$target_dir" && curl -fO -L --remote-header-name "$url") } download_wget() { local url="$1" local target_dir="${DOWNLOAD_DIR}/wget" mkdir -p "$target_dir" log_message INFO "Downloading with wget to: $target_dir" wget --content-disposition -P "$target_dir" "$url" } # --- Main Logic --- # Auto-check and install dependencies check_dependencies yt-dlp spotdl curl wget url="$1" if [ -z "$url" ]; then print_header read -rp "$(echo -e "${YELLOW}Enter the URL to download: ${NC}")" url if [ -z "$url" ]; then log_message ERROR "No URL provided. Exiting." exit 1 fi fi while true; do print_header log_message INFO "Target URL: ${url}" echo -e "${BLUE}-----------------------------------------${NC}" echo " [1] Download mp4 (yt-dlp)" echo " [2] Download mp3 (yt-dlp)" echo " [3] Download mp3 (spotdl)" echo " [4] Download file (curl)" echo " [5] Download file (wget)" echo " [u] Check for Updates" echo -e " [${RED}x${NC}] Exit" echo -e "${BLUE}-----------------------------------------${NC}" read -rp "$(echo -e "${YELLOW}Choose an option: ${NC}")" option echo case $option in 1) download_mp4_ytdlp "$url" ;; 2) download_mp3_ytdlp "$url" ;; 3) download_mp3_spotdl "$url" ;; 4) download_curl "$url" ;; 5) download_wget "$url" ;; u|U) update_script ;; x|X) log_message INFO "Goodbye!" break ;; *) log_message ERROR "Invalid option '$option'." ;; esac echo log_message SUCCESS "Operation completed." read -n 1 -s -r -p "Press any key to return to the menu..." done