#!/bin/bash
# FFmpeg / Nginx / Openresty / V2ray / Xray / Cloudflare / IBM Cloud Foundry / Armbian / Proxmox VE / ...
# Copyright (C) 2019-2023
# Released under GPL Version 3 License
set -euo pipefail
sh_ver="1.87.9"
sh_debug=0
export LANGUAGE=
export LC_ALL=
export LANG=en_US.UTF-8
SH_LINK="https://woniuzfb.github.io/iptv/iptv.sh"
SH_FALLBACK="cn.epub.fun"
SH_FILE="/usr/local/bin/tv"
i18n_FILE="/usr/local/bin/tv-i18n"
OR_FILE="/usr/local/bin/or"
NX_FILE="/usr/local/bin/nx"
XC_FILE="/usr/local/bin/cx"
ARM_FILE="/usr/local/bin/arm"
PVE_FILE="/usr/local/bin/pve"
IPTV_ROOT="/usr/local/iptv"
JQ_FILE="$IPTV_ROOT/jq"
CURL_IMPERSONATE_FILE=/usr/local/bin/curl-impersonate
CHANNELS_FILE="$IPTV_ROOT/channels.json"
LOCK_FILE="$IPTV_ROOT/lock"
MONITOR_LOG="$IPTV_ROOT/monitor.log"
LOGROTATE_CONFIG="$IPTV_ROOT/logrotate"
CRON_FILE="$IPTV_ROOT/cron"
XTREAM_CODES="$IPTV_ROOT/xtream_codes"
XTREAM_CODES_EXAM="$IPTV_ROOT/xtream_codes_exam"
NODE_ROOT="$IPTV_ROOT/node"
IP_DENY="$IPTV_ROOT/ip.deny"
IP_LOG="$IPTV_ROOT/ip.log"
FFMPEG_LOG_ROOT="$IPTV_ROOT/ffmpeg"
# create your own mirror: tv ffmpeg
BACKUP_ROOT="$HOME"/iptv_sh_backup
FFMPEG_MIRROR_LINK="http://pngquant.com/ffmpeg"
V2_FILE="/usr/local/bin/v2"
V2_LINK="https://raw.githubusercontent.com/v2fly/fhs-install-v2ray/master/install-release.sh"
V2_LINK_FALLBACK="$FFMPEG_MIRROR_LINK/v2ray_install-release.sh"
V2CTL_FILE="/usr/local/bin/v2ctl"
V2_CONFIG="/usr/local/etc/v2ray/config.json"
X_FILE="/usr/local/bin/x"
X_CONFIG="/usr/local/etc/xray/config.json"
FFMPEG_MIRROR_ROOT="$IPTV_ROOT/ffmpeg"
LIVE_ROOT="$IPTV_ROOT/live"
SERVICES_FILE="$IPTV_ROOT/services.json"
VIP_FILE="$IPTV_ROOT/vip.json"
VIP_CHANNELS_LINK="$FFMPEG_MIRROR_LINK/vip_channels.json"
VIP_CHANNELS_FILE="$IPTV_ROOT/vip_channels.json"
VIP_ROOT="$IPTV_ROOT/vip"
VIP_USERS_ROOT="$VIP_ROOT/users"
C_ROOT="$IPTV_ROOT/c"
MD5SUM_FILE="$C_ROOT/md5sum"
MD5SUM_LINK="https://raw.githubusercontent.com/woniuzfb/iptv/master/scripts/md5sum.c"
MD5SUM_LINK_FALLBACK="$FFMPEG_MIRROR_LINK/md5sum.c"
CF_FILE="/usr/local/bin/cf"
CF_CONFIG="$HOME/cloudflare.json"
CF_WORKERS_ROOT="$HOME/workers"
CF_WORKERS_FILE="$CF_WORKERS_ROOT/cloudflare_workers.py"
CF_WORKERS_LINK="https://raw.githubusercontent.com/woniuzfb/iptv/master/scripts/cloudflare_workers.py"
CF_WORKERS_LINK_FALLBACK="$FFMPEG_MIRROR_LINK/cloudflare_workers.py"
STREAM_PROXY_LINK="https://raw.githubusercontent.com/woniuzfb/iptv/master/scripts/stream_proxy.js"
STREAM_PROXY_LINK_FALLBACK="$FFMPEG_MIRROR_LINK/stream_proxy.js"
XTREAM_CODES_PROXY_LINK="https://raw.githubusercontent.com/woniuzfb/iptv/master/scripts/xtream_codes_proxy.js"
XTREAM_CODES_PROXY_LINK_FALLBACK="$FFMPEG_MIRROR_LINK/xtream_codes_proxy.js"
IBM_FILE="/usr/local/bin/ibm"
IBM_APPS_ROOT="$HOME/ibm_apps"
IBM_CONFIG="$HOME/ibm.json"
DEFAULT_DEMOS="default.json"
TS_CHANNELS="channels.json"
XTREAM_CODES_CHANNELS="xtream_codes"
USER_AGENT_BROWSER="Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.55 Safari/537.36"
USER_AGENT_TV="Mozilla/5.0 (QtEmbedded; U; Linux; C) AppleWebKit/533.3 (KHTML, like Gecko) MAG200 stbapp ver: 2 rev: 250 Safari/533.3"
USER_AGENT_PHONE="iPhone; CPU iPhone OS 15_2 like Mac OS X"
monitor=false
red='\033[31m'
green='\033[32m'
yellow='\033[33m'
cyan='\033[36m'
white='\033[37m'
blue='\033[94m'
normal='\033[0m'
dim_underlined='\033[37;4;2m'
indent_6='\r\033[6C'
indent_20='\r\033[20C'
shopt -s extglob
Println()
{
printf '\n%b\n' "$1"
}
DistCheck()
{
[ -n "${dist:-}" ] && return 0
dist_files=( /etc/issue /etc/os-release /proc/version )
dist=""
for dist_file in "${dist_files[@]}"
do
if [ ! -s "$dist_file" ]
then
continue
fi
if grep -Eqi "Red Hat|redhat|CentOS|Fedora|Amazon" < "$dist_file"
then
dist="rpm"
break
elif grep -qi "Ubuntu" < "$dist_file"
then
dist="ubu"
break
elif grep -qi "Debian" < "$dist_file"
then
dist="deb"
break
fi
done
if [ -z "$dist" ]
then
Println "${red}[ERROR]${normal} not support yet...\n"
exit 1
fi
}
ArchCheck()
{
[ -n "${arch:-}" ] && return 0
arch=$(uname -m)
if grep -Eqi "x86_64|amd64" <<< "$arch"
then
arch="x86_64"
elif grep -Eqi "i386|i686|x86" <<< "$arch"
then
arch="i386"
elif grep -Eqi "aarch64|armv8|arm64" <<< "$arch"
then
arch="arm64"
elif grep -qi "armv7" <<< "$arch"
then
arch="armhf"
elif grep -qi "armv6" <<< "$arch"
then
arch="armv6l"
elif grep -qi "arm" <<< "$arch"
then
arch="armel"
elif grep -qi "s390" <<< "$arch"
then
arch="s390x"
fi
}
DebFixSources()
{
if [ "${deb_fix:-1}" -eq 1 ]
then
sed -i 's/^mozilla\/DST_Root_CA_X3.crt/!mozilla\/DST_Root_CA_X3.crt/g' /etc/ca-certificates.conf
update-ca-certificates -f >/dev/null 2>&1 || true
if [ -f /etc/apt/sources.list.d/sources-aliyun-0.list ]
then
deb_list=$(< /etc/apt/sources.list.d/sources-aliyun-0.list)
rm -f /etc/apt/sources.list.d/sources-aliyun-0.list
rm -rf /var/lib/apt/lists/*
else
deb_list=$(< /etc/apt/sources.list)
fi
if grep -q "jessie" <<< "$deb_list"
then
printf '%s' "
deb http://archive.debian.org/debian/ jessie main
deb-src http://archive.debian.org/debian/ jessie main
deb http://security.debian.org jessie/updates main
deb-src http://security.debian.org jessie/updates main
" > "/etc/apt/sources.list"
apt-get clean >/dev/null 2>&1
elif grep -q "wheezy" <<< "$deb_list"
then
printf '%s' "
deb http://archive.debian.org/debian/ wheezy main
deb-src http://archive.debian.org/debian/ wheezy main
deb http://security.debian.org wheezy/updates main
deb-src http://security.debian.org wheezy/updates main
" > "/etc/apt/sources.list"
apt-get clean >/dev/null 2>&1
fi
deb_fix=0
sed -i '/deb_fix=/d' "$i18n_FILE"
printf "deb_fix=%s" "$deb_fix" >> "$i18n_FILE"
fi
}
AptUpdate()
{
if [ "${apt_updated:-false}" = false ]
then
Println "$info 更新软件包列表..."
apt-get update --allow-releaseinfo-change >/dev/null
apt_updated=true
fi
}
DepInstall()
{
dependency=$1
[[ -x $(command -v $dependency) ]] && return 0
if [ "$dependency" == "gettext" ] || [ "$dependency" == "wget" ]
then
Println "${green}[INFO]${normal} Installing $dependency, it takes awhile..."
if [ "$dist" == "rpm" ]
then
if [[ -x $(command -v getenforce) ]] && [ "$(getenforce)" != "Disabled" ]
then
setenforce 0
fi
if ! rpm -q $dependency &>/dev/null
then
if yum -y install $dependency &>/dev/null
then
Println "${green}[INFO]${normal} $dependency installation succeed..."
else
Println "${green}[ERROR]${normal} $dependency installation failed...\n"
return 1
fi
fi
else
if [ "$dist" == "deb" ]
then
DebFixSources
fi
if ! dpkg -s $dependency &>/dev/null
then
AptUpdate
if apt-get -y install $dependency &>/dev/null
then
Println "${green}[INFO]${normal} $dependency installation succeed..."
else
Println "${green}[ERROR]${normal} $dependency installation failed...\n"
return 1
fi
fi
fi
return 0
fi
if [ "$dist" == "rpm" ]
then
if [[ -x $(command -v getenforce) ]] && [ "$(getenforce)" != "Disabled" ]
then
setenforce 0
fi
if [ "$dependency" == "dig" ]
then
dependency="bind-utils"
elif [ "$dependency" == "hexdump" ]
then
dependency="util-linux"
elif [ "$dependency" == "ss" ]
then
dependency="iproute"
elif [ "$dependency" == "tput" ]
then
dependency="ncurses"
fi
if ! rpm -q $dependency &>/dev/null
then
Println "`eval_gettext \"\\\$info 安装 \\\$dependency, 请稍等...\"`"
if yum -y install $dependency >/dev/null 2>&1
then
Println "`eval_gettext \"\\\$info \\\$dependency 安装成功\"`"
else
Println "`eval_gettext \"\\\$error \\\$dependency 安装失败\"`\n"
return 1
fi
fi
else
if [ "$dist" == "deb" ]
then
DebFixSources
fi
if [ "$dependency" == "dig" ]
then
dependency="dnsutils"
elif [ "$dependency" == "hexdump" ]
then
dependency="bsdmainutils"
elif [ "$dependency" == "ss" ]
then
dependency="iproute2"
elif [ "$dependency" == "tput" ]
then
dependency="ncurses-bin"
fi
if ! dpkg -s $dependency &>/dev/null
then
AptUpdate
Println "`eval_gettext \"\\\$info 安装 \\\$dependency, 请稍等...\"`"
if apt-get -y install $1 >/dev/null 2>&1
then
Println "`eval_gettext \"\\\$info \\\$dependency 安装成功\"`"
else
Println "`eval_gettext \"\\\$error \\\$dependency 安装失败\"`\n"
return 1
fi
fi
fi
}
i18nInstall()
{
local sh_locale=${1:-zh_CN}
Println "$info You can always use command ${green}tv c 上下移动)\"`${normal}\n"
for i in "${!sort_options[@]}"
do
if [ $i = 0 ]
then
inquirer:print "${cyan}${arrow} ${sort_options[i]} ${normal}\n"
else
inquirer:print " ${sort_options[i]}\n"
fi
done
tput cuu ${#sort_options[@]}
inquirer:on_keypress inquirer:on_sort_up inquirer:on_sort_down inquirer:on_sort_enter_space inquirer:on_sort_enter_space inquirer:on_default inquirer:on_default inquirer:on_sort_ascii
}
inquirer:sort_input() {
var_name=$3
inquirer:_sort_input "$1" "$2"
read -r -a ${var_name?} <<< "${sort_options[@]}"
inquirer:cleanup
trap - EXIT
}
inquirer:sort_input_indices() {
var_name=$3
inquirer:_sort_input "$1" "$2"
read -r -a ${var_name?} <<< "${sort_indices[@]}"
inquirer:cleanup
trap - EXIT
}
inquirer:on_list_input_up() {
if [ "$input_search" = true ]
then
tput cub "$(tput cols)"
tput el
tput cuu1
tput el
tput cuu1
tput el
stty -echo
tput civis
local i
for((i=0;i