斌斌yubinalice · 2019年09月12日

使用you-get下载并转码优酷影片

you-get是一个可以用来下载各大视频网站影视的软件,然而最近you-get软件出了问题,

2019-09-12 06-57-40 的屏幕截图.png

目前已经更新到最新了。不知道什么时候会恢复正常。

那么我们这里写几个使用you-get的脚本来下载大量的影像。

为了批量的获取urls,我们需要Chrome的link grabber插件。

QQ截图20190912150920.png

解压缩之后,

QQ截图20190912151128.png

介绍网页,

QQ截图20190912151036.png

然而,不知道什么原因,导致插件安装失败,在这里就不展示使用插件的方法,异常的简单。

下面我们记录一些使用you-get批量下载的代码。

#!/bin/bash
read -p "files:" files
read -p "source:" source
read -p "destation:" destation
for i in `seq 1 $files`
do
for j in {1..10}
do
echo $i files
echo $j times
~/you-get/you-get `sed -n "$i"p "$source"`
if [ $? == 0]
then
mv *mp4 "$destation"    
break
fi
done
done

如此可以批量下载大量优酷的影像,一般来讲我都是一批下载一部电视剧或者一年的纪录片的。

话说程序运行的那个目录是高速设备地址,比如SSD,读写可以达到500MB以上,然而几年前的HDD用来存储,写入速度可能50MB左右,速度差10倍。那么合并过程都在高速设备上面读写。

经过观察程序运行可知道,这个程序下载的视频都是一段一段的,然后在进行合成,他合成的时候会出现一个ts格式的中间文件,如此,比如1GB的视频,他总共要写入3GB,然后在mv到目的地去,于是在经过对于ffmpeg的研究之后我自己写了一个ffmpeg合并代码,这个合并代码只要写入1GB在缓存地址就可以了。

代码如下:

#!/bin/bash
for f in {96..127}
do
for t in {1..6}
do
echo $f file
echo $t time
~/Desktop/you-get/you-get -n `sed -n "$f"p dl.txt `
if [ $? == 0 ]
then
for n in *00*
do
for l in "${n%[*}"*
do
echo "file '$l'" >>merge.lis
done
ffmpeg -f concat -safe 0 -i    mearge.lis -c copy "/media/pi/Data/BTVDang'an2017/${n%[*}.mp4"
rm merge.lis
rm "${n%[*}"*
done
break
fi
done
done

这里you-get那行
-n就是说只下载不合并。

然后ffmpeg是直接合并到目标地址,不在高速缓存上面合并。

话说我在看到开发板的说明上写着开发板支持h265硬件编码。
那么我们可以把-c copy那行改成
-c:v hevc_mpp -c:a copy
这样就能够变成下载后转码到目的地,转码完成后下载下一个。

话说,我们的缓存盘空间很大,一般SSD现在最小也128GB的,那么我们可以考虑并行下载,就是同时下载多个,这样当一个文件在合成时也仍然有其他的下载线程占用网速,提高网络的利用率,单文件下载当合并的时候网络就没有下载速度了。

这个多线程的代码我写了很长时间都没写出来,有个高手给了我一个带注释的代码,由于you-get现在无法使用,我也不知道他的代码到底能用不能。现在粘贴下头大家看看。

#!/bin/bash
trap "exec 1000>&-;exec 1000<&-;exit 0" 2

# 分别为 创建管道文件,文件操作符绑定,删除管道文件
# 可能会有疑问,为什么不能直接使用管道文件呢? 
# 事实上,这并非多此一举,刚才已经说明了管道文件的一个重要特性了,那就是读写必须同时存在
# 缺少某一种操作,另一种操作就是滞留,而绑定文件操作符 正好解决了这个问题。
mkfifo testfifo
exec 1000<>testfifo
rm -rf testfifo

# 对文件操作符进行写入操作。 
# 通过一个for循环写入10个空行,这个10就是我们要定义的后台线程数量。
for ((n=1; n<=10; n++))
do
    echo >&1000
done

# 创建一个备份目录
if [[ ! -d back ]]; then
mkdir back
fi

# 开始时间记录
start=`date "+%s"`
# 获取URL总数,如果总数为0,直接退出
total=`cat urls | wc -l`
if [[ $total == 0 ]]; then
    echo 'urls总数为空'
exit 0
fi 

# 遍历URLS文件,开始执行下载
for ((i=1;i<=$total;i++))
do {
# 从testfifo中读取一行
read -u1000
{    
    # 增加尝试次数,最大5次
    for j in {1..5}
    do 
        # 判断单独进程文件目录是否存在,不存在则创建目录
        download_dir=audio"$i"
        if [[ ! -d $download_dir ]]; then
            mkdir -p $download_dir
        fi
        echo "往目录${download_dir}中开始下载文件,尝试次数:${j}"
        # 读取URLS中的一行,下载文件
        you-get -o $download_dir `sed -n "$i"p urls | tr -d '\r'`

        # 校验是否有异常,如果没有异常,则跳出循环,执行外下一条,如果有异常,再次尝试下载
        if [[ $? != 0 ]]; then
            mv $download_dir/* back
            rm -rf $download_dir
        else
            break
        fi
    done
    # 往testfifo中写入一行
    echo >&1000
}&
}
done

wait
end=`date "+%s"`
echo "time: `expr $end - $start`"

exec 1000>&-
exec 1000<&-

由于现在许多的地方网速仍然很慢,因此要下载大量的高清的节目仍然需要很长时间(通宵挂机),因此比较适合在开发板一类的低耗电设备上面使用you-get下载。

我自己写的那个失败的并行下载代码也粘贴下面,谁懂帮忙指点下。

#!/bin/bash
mkfifo fifo && exec 7<>fifo && rm fifo
for n in {1..3}
do
echo >&7
done

for i in {1..39}
do
{
read -u7

for j in {1..5}
do
echo $i file $j time
mkdir $i
./you-get/you-get `sed -n "$i"p urls` -o $i 
if [ $? == 0 ]
then
break
mv $i/*mp4 ./
#rmdir $i
fi
done
echo >&7
}&
done

wait
exec 7>&-
exec 7<&-

最近发现优酷开始有50fps的HDR影视资源了,估计体积比起1080p30fps的SDR视频体积大不少。

事实上我听说还有一个更好的写法,据说是使用管道,不必完全下载完所有的片段,随着下载就写入目的地,然而我的能力弱,不知道这种代码应该怎么写。

OK,等到哪天you-get可以正常使用的时候,大家可以试试看,这样很适合一次性下载一个系列的影像节目。

推荐阅读
关注数
3507
内容数
57
目录
极术微信服务号
关注极术微信号
实时接收点赞提醒和评论通知
安谋科技学堂公众号
关注安谋科技学堂
实时获取安谋科技及 Arm 教学资源
安谋科技招聘公众号
关注安谋科技招聘
实时获取安谋科技中国职位信息