#!/bin/bash if [ "$EUID" -ne 0 ]; then sudo_cmd="sudo " fi declare -A -r APT_CMD=( ["update"]="${sudo_cmd}apt update" ["install"]="${sudo_cmd}apt install -y" ) declare -A -r DNF_CMD=( ["update"]="${sudo_cmd}dnf update -y" ["install"]="${sudo_cmd}dnf install -y" ) declare -A -r ZYPPER_CMD=( ["update"]="${sudo_cmd}zypper refresh" ["install"]="${sudo_cmd}zypper install -y" ) declare -A -r BREW_CMD=( ["update"]="${sudo_cmd}brew update" ["install"]="${sudo_cmd}brew install" ) declare -A -r PACMAN_CMD=( ["update"]="${sudo_cmd}pacman -Sy" ["install"]="${sudo_cmd}pacman -Sy --noconfirm" ) readonly YT_DLP_PATH="$HOME/.local/bin/yt-dlp" #### # Identify the system's distribution, version, and architecture. # # NOTE: # The 'os-release' file is used to determine the distribution and version. This file # is present on almost every distributions running systemd. # # NEW GLOBALS: # - DISTRO: The distribution name. # - VER: The distribution version. # - SVER: The distribution version without the minor version. # - ARCH: The system architecture. # - BITS: The system architecture in bits. detect_sys_info() { if [[ $(uname -s) == "Darwin" ]]; then DISTRO="darwin" VER=$(sw_vers -productVersion) elif [[ -f /etc/os-release ]]; then . /etc/os-release DISTRO="$ID" VER="$VERSION_ID" # Version: x.x.x... SVER=${VER//.*/} # Version: x else DISTRO=$(uname -s) VER=$(uname -r) fi case $(uname -m) in x86_64) BITS="64"; ARCH="x64" ;; aarch64) BITS="64"; ARCH="arm64" ;; armv*) BITS="32"; ARCH="arm32" ;; # Generic ARM 32-bit. i*86) BITS="32"; ARCH="x86" ;; *) BITS="?"; ARCH="$(uname -m)" ;; # Fallback to uname output. esac } #### # Install 'yt-dlp' at '~/.local/bin/yt-dlp'. # # EXITS: # - 1: Failed to download 'yt-dlp'. install_yt_dlp() { if command -v yt-dlp &>/dev/null; then echo "${BLUE}Updating 'yt-dlp'...${NC}" yt-dlp -U || { echo "${RED}Failed to update 'yt-dlp'${NC}" >&2 } return fi # get correct yt-dlp based on arch local yt_dlp_url="https://github.com/yt-dlp/yt-dlp/releases/latest/download/yt-dlp_linux" case $ARCH in x64) yt_dlp_url="${yt_dlp_url}" ;; arm64) yt_dlp_url="${yt_dlp_url}_aarch64" ;; arm32) yt_dlp_url="${yt_dlp_url}_armv7l" ;; *) echo "${RED}Unsupported architecture: $ARCH${NC}" >&2; return 1 ;; esac [[ ! -d "$HOME/.local/bin" ]] && mkdir -p "$HOME/.local/bin" if [[ ! -f $YT_DLP_PATH ]]; then echo "${BLUE}Installing 'yt-dlp'...${NC}" curl -L "$yt_dlp_url" -o "$YT_DLP_PATH" || { echo "${RED}Failed to download 'yt-dlp'${NC}" >&2 return 1 } fi echo "${BLUE}Modifying permissions for 'yt-dlp'...${NC}" chmod a+rx "$YT_DLP_PATH" } #### # Installs music prerequisites. # # PARAMETERS: # - $1: cmd_array (Required) # - The associative array containing the package manager commands. # - $2: pkg_list (Required) # - The array containing the list of packages to install. install_music_prereqs() { local -n cmd_array="$1" local -n pkg_list="$2" echo -e "${YELLOW}About to run: ${cmd_array["update"]}${NC}" read -p "${CYAN}Continue? [y/N]: ${NC}" -n 1 -r echo if [[ $REPLY =~ ^[Yy]$ ]]; then ${cmd_array["update"]} || { echo "${RED}Failed to update${NC}" >&2 exit 1 } else echo "${RED}Update skipped${NC}" fi echo -e "${YELLOW}About to run: ${cmd_array["install"]} ${pkg_list[*]}${NC}" read -p "${CYAN}Continue? [y/N]: ${NC}" -n 1 -r echo if [[ $REPLY =~ ^[Yy]$ ]]; then ${cmd_array["install"]} "${pkg_list[@]}" || { echo "${RED}Failed to install music prerequisites${NC}" >&2 exit 1 } else echo "${RED}Installation cancelled${NC}" exit 1 fi install_yt_dlp echo -e "\n${GREEN}Finished installing music prerequisites${NC}" } detect_sys_info if [[ $BITS == "32" ]]; then echo "${RED}Your system is 32-bit, which is unsupported${NC}" >&2 exit 1 fi case "$DISTRO" in ubuntu) readonly pkgs=(ffmpeg curl) case "$VER" in 22.04|24.04) install_music_prereqs APT_CMD pkgs ;; *) unsupported ;; esac ;; debian) readonly pkgs=(ffmpeg curl) case "$SVER" in 1[1-3]) install_music_prereqs APT_CMD pkgs ;; *) unsupported ;; esac ;; linuxmint) readonly pkgs=(ffmpeg curl) case "$SVER" in 2[0-3]) install_music_prereqs APT_CMD pkgs ;; *) unsupported ;; esac ;; fedora) readonly pkgs=(ffmpeg-free curl) case "$SVER" in 38|39|40|41|42|43) install_music_prereqs DNF_CMD pkgs ;; *) unsupported ;; esac ;; almalinux|rocky) el_ver=$(rpm -E %rhel) # add rpm fusion repo repo_cmd=( "${sudo_cmd}dnf install -y epel-release" "sudo dnf install --nogpgcheck https://mirrors.rpmfusion.org/free/el/rpmfusion-free-release-${el_ver}.noarch.rpm -y" ) if (( el_ver == 8 )); then repo_cmd+=("${sudo_cmd}dnf config-manager --set-enabled powertools") elif (( el_ver == 9 )); then repo_cmd+=("${sudo_cmd}dnf config-manager --set-enabled crb") fi echo "${YELLOW}In order to install ffmpeg, you need to enable the RPM Fusion repository.${NC}" echo "${YELLOW}The following commands will be run:${NC}" for cmd in "${repo_cmd[@]}"; do echo " ${YELLOW}-> $cmd${NC}" done # ask the user whether it's ok to run this command read -p "${CYAN}Do you want to continue with these commands? [y/N]: ${NC}" -n 1 -r echo "" if [[ $REPLY =~ ^[Yy]$ ]]; then for cmd in "${repo_cmd[@]}"; do echo "${BLUE}Running: $cmd${NC}" $cmd || { echo "${RED}Failed to run: $cmd${NC}" >&2 exit 1 } done else echo "${RED}User opted to cancel the command execution.${NC}" >&2 exit 1 fi readonly pkgs=(ffmpeg curl) install_music_prereqs DNF_CMD pkgs ;; opensuse-leap) readonly pkgs=(ffmpeg curl) case "$VER" in 15.5|15.6|15.7) install_music_prereqs ZYPPER_CMD pkgs ;; *) unsupported ;; esac ;; opensuse-tumbleweed) readonly pkgs=(ffmpeg curl) install_music_prereqs ZYPPER_CMD pkgs ;; arch|artix) readonly pkgs=(ffmpeg pipewire-jack curl) install_music_prereqs PACMAN_CMD pkgs ;; darwin) if ! command -v brew &>/dev/null; then echo "${RED}Homebrew is not installed. Please install Homebrew first.${NC}" >&2 exit 1 fi readonly pkgs=(ffmpeg python curl) install_music_prereqs BREW_CMD pkgs ;; *) echo "${RED}Unsupported distribution: $DISTRO${NC}" >&2 exit 1 ;; esac