代码拉取完成,页面将自动刷新
#!/bin/bash
# 在线视频网站的下载工具
# author: yanjingtu
# date: 2020/3/17
# 用法:./get.sh [REFERER页面地址]
# 其中方括号中的内容为可选内容,有些网站会验证引用页是否为指定的URL,这时可以传递该参数
# ================ 全局变量定义区 ================
THISNAME=$0
SCRIPTNAME=$(basename $THISNAME)
# ================ 函数逻辑定义区 ================
############################################################
# echo输出颜色文本
#echo命令改变样式,以输出不同颜色的文本,必须有 -e 选项(开启echo中的转义)。
#文本终端的显示颜色可以使用“ANSI非常规字符序列”来生成。
#例如:echo -e "\033[44;37;5m ME\033[0m COOL"
#解释:"\033[44;37;5m ME "设置背景为蓝色,前景为白色,闪烁光标,输出字符“ME”;
# "\033[0m COOL"重新设置屏幕到缺省设置,输出字符 “COOL”。
# "e"是命令echo的一个可选项,它用于激活特殊字符的解析器。"\033"引导非常规字符序列(即"\033["表示终端转义字符开始,"\033"即退出键<ESC>的ASCII码)。"m"意味着设置属性然后结束非常规字符序列,这个例子里真正有效的字符是"44;37;5"和"0"。修改"44;37;5"可以生成不同颜色的组合,数值和编码的前后顺序没有关系。
#
# 可以选择的编码如下所示(这些颜色是ANSI标准颜色):
# 编码 颜色/动作
# 0 重新设置属性到缺省设置
# 1 设置粗体
# 2 设置一半亮度(模拟彩色显示器的颜色)
# 4 设置下划线(模拟彩色显示器的颜色)
# 5 设置闪烁
# 7 设置反向图象
# 22 设置一般密度
# 24 关闭下划线
# 25 关闭闪烁
# 27 关闭反向图象
# 30 设置黑色前景
# 31 设置红色前景
# 32 设置绿色前景
# 33 设置黄色前景
# 34 设置蓝色前景
# 35 设置紫色前景
# 36 设置青色前景
# 37 设置白色(灰色)前景
# 38 在缺省的前景颜色上设置下划线
# 39 在缺省的前景颜色上关闭下划线
# 40 设置黑色背景
# 41 设置红色背景
# 42 设置绿色背景
# 43 设置黄色背景
# 44 设置蓝色背景
# 45 设置紫色背景
# 46 设置青色背景
# 47 设置白色(灰色)背景
# 49 设置缺省黑色背景
# 其他有趣的代码还有:
# \033[2J 清除屏幕
# \033[0q 关闭所有的键盘指示灯
# \033[1q 设置"滚动锁定"指示灯(Scroll Lock)
# \033[2q 设置"数值锁定"指示灯(Num Lock)
# \033[3q 设置"大写锁定"指示灯(Caps Lock)
# \033[15:40H 把关闭移动到第15行,40列
# \007 发蜂鸣生beep
############################################################
# 向屏幕打印灰色文字
function EchoGray()
{
echo -e "\e[1;36m$@\e[0m"
}
# 向屏幕打印红色文字
function EchoRed()
{
echo -e "\e[1;31m$@\e[0m"
}
# 向屏幕打印蓝色文字
function EchoBlue()
{
echo -e "\e[1;34m$@\e[0m"
}
# 向屏幕打印绿色文字
function EchoGreen()
{
echo -e "\e[1;32m$@\e[0m"
}
# 向屏幕打印黄色背景的文字
function EchoYellow()
{
echo -e "\e[1;33m\e[1;42m$@\e[0m"
}
# 向日志文件中输出内容
function WriteLog()
{
logtype=$1
shift
if [ "$1" == "" ]; then
return
fi
curdate=$(date "+%Y%m%d")
tmhead=$(date "+%Y-%m-%d %H:%M:%S")
shortname=${SCRIPTNAME%.*}
logdir=/var/log/${shortname}
logfile=${logdir}/${shortname}_${curdate}.log
if ! [ -d ${logdir} ]; then
mkdir -p ${logdir}
fi
# 向日志的最后追加一行
echo -e "${tmhead}\t[${logtype}]$@" >> ${logfile}
# 最后用彩色在屏幕上打印一下
if [ "${logtype}" == "D" ]; then
EchoGray $@
elif [ "${logtype}" == "I" ]; then
echo $@
elif [ "${logtype}" == "N" ]; then
EchoGreen $@
elif [ "${logtype}" == "W" ]; then
EchoYellow $@
elif [ "${logtype}" == "E" ]; then
EchoRed $@
fi
}
# 记录日志并向屏幕打印灰色的文字(Debug类型)
function LogDebug()
{
WriteLog D $@
}
# 记录日志并向屏幕打印无颜色的文字(Info类型)
function LogInfo()
{
WriteLog I $@
}
# 记录日志并向屏幕打印绿色的文字(Notice类型)
function LogNotice()
{
WriteLog N $@
}
# 记录日志并向屏幕打印黄色背景的文字(Warning类型)
function LogWarning()
{
WriteLog W $@
}
# 记录日志并向屏幕打印红色的文字(Error类型)
function LogError()
{
WriteLog E $@
}
# 下载一个文件,可能是m3u8文件,也可能是ts文件。函数会自动根据内容决定保存的路径。
# 如果是m3u8,还会自动解析内容并进一步下载(输出文件名增加前缀)。
function download_one()
{
# 四个参数(后两个可选):要下载的URL、保存到的本地路径和文件名、下一层的文件名前缀、引用页
local url=$1
local localpath=$2
local prefix=$3
local referer=$4
# Debug信息
LogDebug "Url: ${url} LocalPath: ${localpath} Referer: ${referer} Prefix: ${prefix}"
# URL和本地路径都不能为空
if [ "${url}" == "" ]; then
LogError "url cannot be null"
return 0
fi
if [ "${localpath}" == "" ]; then
LogError "localpath cannot be null"
return 0
fi
# 如果本地已经有需要的文件了,则跳过下载该文件
if [ -f ${localpath} ]; then
LogWarning "skip ${localpath}"
#return 0
else
# 如果本地目录不存在,则先创建一下目录
pathname=$(dirname ${localpath})
if ! [ -d ${pathname} ]; then
LogNotice "create dir ${pathname}"
mkdir -p ${pathname}
fi
# 下载文件到本地
if [ "${referer}" == "" ]; then
wget -nv -O ${localpath} ${url}
else
wget -nv -O ${localpath} --referer=${referer} ${url}
fi
# 如果下载该文件失败了,打印报错,删掉可能存在的错误文件,跳过当前文件的下载
if [ $? -ne 0 ]; then
LogError "Download-Failed: ${url}"
rm -f ${localpath}
return 1
fi
fi
name=$(basename ${localpath})
suffix=${name#*.}
if [ "${suffix}" == "m3u8" ]; then
isEncrypted=0
# 如果文件中有加密秘钥,则下载该秘钥,并修改m3u8中的秘钥路径
if [ "$(cat ${localpath} | grep '#EXT-X-KEY:')" != "" ]; then
isEncrypted=1
# get key
# one line like: #EXT-X-KEY:METHOD=AES-128,URI="https://v2.91ceshi.com/res/72946866131566592/encrypt.key",IV=0x8d5c053547cc40349c4917cb433bfa63
keyUrl=$(cat ${localpath} | grep '#EXT-X-KEY:' | sed 's/^.\+,URI="\(.\+\)".*$/\1/')
# download key
keyPath=key
if ! [ -d ${keyPath} ]; then
mkdir -p ${keyPath}
fi
keyFile=${keyPath}/${prefix}key.key
download_one ${keyUrl} ${keyFile} ${prefix} ${referer}
if [ $? -ne 0 ]; then
LogError "下载m3u8的key文件失败,终止下载当前m3u8的后续内容: ${keyUrl}"
return 1
fi
# change key in local m3u8-file
sed -i "s\\${keyUrl}\\${keyFile}\\" ${localpath}
fi
# 依次下载m3u8中的每个文件
i=1
isVideo=0
for onesub in $(cat ${localpath} | grep -v '#'); do
# 针对不同类型的URL(完整URL、相对路径、绝对路径),分别做不同的处理(补全策略)
if [ "${onesub:0:4}" == "http" ]; then
suburl=${onesub}
elif [ "${onesub:0:1}" == "/" ]; then
protocol=$(echo ${url} | cut -d / -f 1)
host=$(echo ${url} | cut -d / -f 3)
suburl=${protocol}//${host}${onesub}
else
suburl=$(dirname ${url})/${onesub}
fi
subprefix="${prefix}${i}-"
subname=$(basename ${onesub})
subsuffix=${subname#*.}
if [ "${subsuffix}" == "ts" ]; then
path=video
isVideo=1
elif [ "${subsuffix}" == "m3u8" ]; then
path=
else
path=other
fi
if [ "${path}" != "" ]; then
if ! [ -d ${path} ]; then
mkdir -p ${path}
fi
path=${path}/
fi
k=$(printf %07d ${i})
localfile=${path}${prefix}${k}.${subsuffix}
download_one ${suburl} ${localfile} ${subprefix} ${referer}
if [ $? -ne 0 ]; then
LogError "下载m3u8的分片文件失败,终止下载当前m3u8的后续内容: ${suburl}"
return 1
fi
# 如果是从m3u8文件下载,则需要记得将m3u8中的文件URL修正成本地路径
sed -i "s\\${onesub}\\${localfile}\\" ${localpath}
let i=$i+1
done
# 合并一集结果文件
bigfile=${path}${prefix}all.mp4
if [ ${isEncrypted} -eq 1 ]; then
#echo "ffmpeg -allowed_extensions ALL -i ${localpath} -c copy -bsf:a aac_adtstoasc ${bigfile}"
ffmpeg -allowed_extensions ALL -i ${localpath} -c copy -bsf:a aac_adtstoasc ${bigfile}
else
#echo "ffmpeg -i ${localpath} -c copy ${bigfile}"
ffmpeg -allowed_extensions ALL -i ${localpath} -c copy ${bigfile}
fi
# 如果合并成功的话就可以删掉零碎文件了,否则保留着不要删除
if [ $? -eq 0 ]; then
# TODO 如果视频分块用的扩展名不是ts,下面这句会导致无法删除分块文件,需要考虑改进
rm -f ${path}${prefix}*.ts
else
LogError "合并视频片段失败!m3u8清单为${localpath}"
fi
fi
}
function download_by_list()
{
referer=$1
prefix=""
m3u8localpath=.
num=1
for i in `cat list.txt | grep -v '#'`; do
# 编号
#j=${i%.*}
j=`printf %02d ${num}`
prefix=${j}-
# 初始m3u8的完整URL
url=$i
# 下载到本地的m3u8的初始文件名
onename=$(basename ${i})
onesuffix=${onename#*.}
onelocal=${m3u8localpath}/${j}.${onesuffix}
# 下载
download_one ${url} ${onelocal} ${prefix} ${referer}
let num=$num+1
done
}
function main()
{
download_by_list $@
}
main $@
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。