云盘转NAS,云盘转化为本地磁盘,跨平台跨设备同步-CarlZeng

背景

对软路由硬件J4125之类的关注,想要它虚拟出另外一个系统实现NAS本地云存储的功能,
可是碍于广大群众对这种集成方案的实用性、稳定性、低维护性产生实践中的顾虑和问题,更倾向于独立的NAS硬件。
我也一直在思考NAS在日常生活中除了备份旧文件用处的其他实用性考究。
(20231004更新:发现NAS收集展示15年+的个人所有照片后,赞赞赞)

音乐文件的跨平台同步需求越来越急切。各大平台对音乐版权的收紧,使得我不在寻找播放软件APP的解决方案,转而更希望保存我喜爱的歌曲。存储在网盘中不占用手机内存和电脑硬盘是个不错的选择(电影文件显然也是类似的)

介绍下载器Aria2c,开启无限制下载参数,为某网盘下载提速超6倍

20240129 新增 “最大尝试次数(max-tries)与重试等待时间(retry-wait)”

思路

  1. 将 阿里云盘 开放出 WebDAV 服务

  2. 将 rclone 用于同步 电脑中 和 阿里云盘 中的文件和目录

  3. 将 nplayer 用于播放 WebDAV中的音乐(电影也是一样)
      安卓手机手机都可以的,电脑上用Potplayer之类的。

技术步骤汇总

  1. 工具#1: https://github.com/messense/aliyundrive-webdav

根据您平台的构架来选择不同的可执行文件(以我的MAC为例,下载:aliyundrive-webdav-v2.3.2.apple-darwin.tar.gz

1.1 解压缩后得到文件:aliyundrive-webdav

1.2 Terimal运行:

1
aliyundrive-webdav -r eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9.eyJzdWIiOiIzYjg0YzM0OTczNjA0OTk4OTRjYjI3OWUzOTM1ZTA0OSIsImF1ZCI6IjczZTYxMTgzMWE3YzRkODdhYzQ5Yzg0ODFiZjlmMmM0IiwiZXhwIjoxNzAwNzI5MTM4LCJpYXQiOjE2OTI5NTMxMzgsImp0aSI6IjJjNDVlZDdhNWUyZjQxOTg5ZTk2NDA4NmQ1OTE1MzhiIn0.LcDVLaeqaQWpvE7eBbEv-KnA27JP6bmk7Rxw1vK6ZD3EqSGQuaH-DVE6lU8NneiN1h0z8mW1ImrkjFQ1234

如何获取这个refresh-token,作者在页面做了详细的说明:https://github.com/messense/aliyundrive-webdav。
实测也可以使用Chrome登录云盘后https://www.aliyundrive.com/drive/file/backup,
在Chrome > Application > Local Storage > share_token 中复制。

成功运行后的日志类似:

    2023-08-25T21:10:27.769474+08:00 INFO aliyundrive\_webdav::drive: refresh token succeed
    
    2023-08-25T21:10:30.984144+08:00 INFO aliyundrive\_webdav::drive: found default drive _drive\_id_\=71999\*\*\*\*
    
    2023-08-25T21:10:30.985527+08:00 INFO aliyundrive\_webdav::webdav: listening on http://0.0.0.0:8080

1.3 运行后WebDAV就启用了,可以通过Mac的Finder来验证:Finder > Go > Connect to Server

输入http://127.0.0.1:8080

在提示的用户名密码都输入:admin

  1. 工具#2:https://github.com/rclone/rclone

获取:根据您平台的构架来选择不同的可执行文件(以我的MAC为例,下载:rclone-v1.63.1-osx-arm64.zip)

2.1 解压缩后得到文件:rclone

2.2 Terimal运行配置(一次性):

1
2
3
4
5
rclone config
name\> webdav
Storage\> 47 url\> http://127.0.0.1:8080
vendor> 6 user\> admin
password: admin

其他的参数都直接回车,默认即可。
第二步中的47指向webdav

47 / WebDAV
\ (webdav)

2.3 Terimal运行配置(日常同步):

    rclone lsd webdav:
            列出目录
    
    rclone ls webdav:
            列出根目录下所有文件
    
    rclone copy /Users/\*\*\*/MusicSyncCar webdav:MusicSyncCar


​ rclone sync --interactive /Users/***/MusicSyncCar webdav:MusicSyncCar
​ works great, will ask for new files to sync

​ rclone sync /Users/***/MusicSyncCar webdav:MusicSyncCar
​ works great too, without any question, but minor error.

详细的说明:https://rclone.org/docs/
如下(注意下面列子的remote就是webdav的创建时的名称)

rclone uses a system of subcommands. For example

1
2
3
rclone ls remote:path                                   # lists a remote
rclone copy /local/path remote:path # copies /local/path to the remote
rclone sync --interactive /local/path remote:path # syncs /local/path to the remote
  1. 工具#3:Nplayer安卓版

直接把链接中的apk下载后,在手机中安装添加WebDAV, 主要的参数:

主机:选择运行aliyundrive-webdav的电脑的局域网IP地址(http://192.168.6.221:8080)

用户名/密码:admin

端口:8080

如何获取这个阿里云盘refresh-token

可以用于影视或TVBOX中提示时的Refresh_Token

  1. 浏览器打开并登录阿里云https://www.aliyundrive.com/drive/
  2. 在Chrome > Application > Local Storage > share_token 中复制
    或者打开console(开发者工具中)运行下面的JS
    1
    JSON.parse(localStorage.getItem('share_token')).access_token
    此方法已失效,最新的必须扫码登录或短信验证,后用工具显示:
    方法一
    https://aliyundriver-refresh-token.vercel.app/

具体的项目地址:https://github.com/itxve/aliyundriver-refresh-token

方法二:
用Webdav那个安卓APP,登录阿里云盘;设置里面有可以复制Refresh_Token的地方

二者都是通过API的方式获取的Refresh_Token

背景知识

NAS是网络接入存储(Network Attached Storage)的简称,也就是存储系统直接接入网络,通过网络交换机,将服务器与存储连接在一起,用户可以通过TCPIP协议访问数据,并通过标准的业界文件共享协议,如CIFS、NFS来实现目录级的共享。

感谢

感谢所有以上工具的作者与参与者,感恩。

后续

文章分享没有几天,聪明的朋友就寻出了不便之处:上面这个方案,需要电脑上开启WebDAV服务然后手机才能连接上去播放媒体文件等访问网盘的内容。

那么有没有办法直接把WebDAV架设在手机上呢?这样就不需要一台‘服务器’开着。答案是有的:

https://github.com/eritpchy/aliyundrive-webdav/releases

下载这个apk文件net.xdow.webdavaliyundriver.3.1.0.release.apk

(视频介绍:通过安卓手机启用阿里云盘webdav服务,实现把云盘资料挂载为本地硬盘使用,无压缩播放原画质视频

安装到安卓手机上,打开这个APP,设置好Refresh_token(扫码获取),手机上点击启动WebDAV服务。

在切换到手机上nplayer,同理,建立新的连接到手机本机(127.0.0.1)8080端口上的WebDAV即可。



NAS安装Aria2下载服务器

J4125的下载器?如何提交远程下载任务?应用baidu网盘下载
https://p3terx.com/archives/aria2-frontend-ariang-tutorial.html

[Aria2 Pro Docker](https://hub.docker.com/r/p3terx/aria2-pro)
会在Mac的docker中开启两个container,可是6800怎么也无法映射出来。
各种尝试以后还是最终放弃。

http://127.0.0.1:8080/#!/downloading    
终于找打一个可用的+运行在docker里面的[aria2](https://hub.docker.com/r/wahyd4/aria2-ui)

为了方便映射到NAS中目录,在NAS的docker中安装

1
2
3
4
5
6
7
8
9

docker run -d --restart=always --name aria2-webui -p 8080:80 -p 6800:6800 -v /volume2/KingchuxingSSD512G/Download:/data onisuly/aria2-with-webui

#这样运行后
#Aria2: http://yourip/ui/
#FileManger: http://yourip
#Rclone: http://yourip/rclone
#Please use admin/admin as username and password to login for the first time.

考虑到大文件下载还是放到NAS的大容量固态硬盘中存储,还是把这个aria2安装到docker中去,
用web的形式打开管理界面,查询或者提交下载任务。

更改 User Agent from
aria2/1.36.0
to
pan.baidu.com


首先在控制面板——终端机和SNMP里面启用SSH功能

紧接着输入sudo -i回车,获取root权限,这一步还要再一次输入密码,也是不显示

接下来输入docker pull XXX/XXX(X代表的就是你索要拉取的镜像名称),例如我要拉取jellyfin的docker镜像,就输入docker pull jellyfin/jellyfin即可,然后回车,接下来你会发现镜像开始下载了

https://www.moewah.com/archives/3147.html
docker run -d –name aria2-webui -p 8080:80 -p 6800:6800 -v /volume2/KingchuxingSSD512G/Download:/data onisuly/aria2-with-webui

成功了 http://192.168.6.203:8080/#!/downloading 测试提交某度网盘的5G+文件下载,正常龟速90+KB/s
总结:
    请忽略上面的其他的docker镜像, NAS的SSH中用 
sudo docker pull onisuly/aria2-with-webui
    然后
sudo docker run -d --name aria2-webui -p 8080:80 -p 6800:6800 -v /volume2/KingchuxingSSD512G/Download:/data onisuly/aria2-with-webui

实践多任务从某度网盘下载NS大游戏文件,下载列表惊讶的发现(与默认的龟速相比),持续地平均速度竟然达到了860KB/s
1. 用浏览器插件中的API下载(适用于 IDM,NDM 以及浏览器自带下载)获取网盘中的链接
2. 设置(Settings)》Aria2 Setting 〉 Http/FTP/SFTP Settings 》 Max Connection Per Server
设置为10,单个server10个链接;正在测试调整为15,持续观察新任务的下载速度。

改进这个NAS中的docker aria2-webui

1
2
3
4
5
6
7
8
9
#设置了自动重启
docker update --restart=always aria2-webui

docker start aria2-webui
#发现端口映射并没有映射出期待的端口

#继续设置保存到docker中,下次自动就映射出来
root@DS918:~# docker update -p 8080:80 -p 6800:6800 aria2-webui
aria2-webui

远程提交下载任务至NAS

Nginx Proxy Manager(NPM)反代aria2的下载工具至外网管理
人在宽带的外网时候可以提交下载任务至NAS,这样可以不受地理位置限制的下载,充当下载服务器的目的。
通过Nginx Proxy Manager来反代两个地址

  1. http://192.168.*.*:8080
    这是aria2的web面板UI(AriaNg)的本地管理地址,把这个地址反代到外网比如 https://@.@@@@@.com:port
    这样就可以带SSL证书的情况下原创访问aria2面板。
    NPM中新增上面这样一条的反代记录
    http://192.168.*.*:8080 -> https://@aria@.@@@@@.com:port
    Note: 这个8080端口是从docker中映射出来的, 下面的6800端口也是同样道理
    这个面板也可以使用网络上公开的公共的面板,因为它只是一个UI。
    真正的下载服务器服务是RPC的服务信息。
  2. http://192.168.*.*:6800/jsonrpc
    这是aria2后台服务的地址,Aria2 PRC Address,协议http,Aria2 RPC Http Request Method POST(默认)
    在第一步的外网面板地址(https://@.@@@@@.com:port)中配置Aria2 RPC信息,也必须是https协议(已被默认强制)
    NPM中新增上面这样一条的反代记录
    http://192.168.*.*:6800/jsonrpc -> https://rpc@.@@@@@.com:port

这样2条反代配置以后,返回第一步的Aria2面板(AriaNg)设置RPC地信息为反代以后的https信息(地址和端口), 即可
实现外网时也可提交下载任务至NAS。

RPC下载的’保存路径’

油猴插件的发送至RPC非常方便,然后速度也快也稳定不断流(夸克480KB/s),可是发现RPC的文件下载后在docker的映射目录找不到。
检查PRC的详细信息才知道,原来文件信息携带了Windows的目录信息 D:@@@.nsp,这直接导致NAS的docker下载成功后,文件根本找不到。
估计停留在了内存里面了,也不知道怎么取下来 :-)

测试尝试解决(SSH中):

1
2
3
4
5
6
7
sudo docker run -d --name aria2-webui -p 8080:80 -p 6800:6800 -v /volume2/KingchuxingSSD512G/Download:/data onisuly/aria2-with-webui

docker: Error response from daemon: Conflict. The container name "/aria2-webui" is already in use by container "3878b3e6c566c395ee8ffe2538a4ee3de892458facd72c5c6eb7a0995545deef". You have to remove (or rename) that container to be able to reuse that name.

#进入docker里面的命令行
sudo docker exec -it aria2-webui /bin/bash

最后还是到Docker的UI界面,操作》重置,操作》启动。这才重启成功

最后竟然在插件助手的PRC配置中找到一个'保存路径'的设置, 就是这个配置告知了aria2c应该保存文件到那个目录。 在个人的配置环境,我要配置到docker里面的目录/data,然后就能看到映射出来的目录中看到下载的文件了。

最大尝试次数(max-tries)与重试等待时间(retry-wait)

下载某度网盘的单文件大于10G时(速度一般在800 - 900KB/s,实际下载过程要超过24h),无人值守的下载过程中经常遇到错误(比如status 403,或者链接被某度网盘重置)

​ 手动重试:

  1. 点击AriaNg的左侧菜单 > 已完成/已停止 > 点击 重试。即可有一次开始断点续传继续下载。
  2. 有时即便重试仍然无法正常继续下载(这是往往是链接地址自动无效了),需要手动去网盘页面重新获取新的“API下载”下载地址,然后新建下载(系统自动判断后会断电续传)

尝试通过设置一下设置缓解这种手动重试的动作:

  1. 最大尝试次数(max-tries) 从 5 修改为:8
  2. 重试等待时间(retry-wait) 从 0 修改为:120秒

20240129 等待验证是否能有效减少人工干预重试的次数….

突破aria2c的16连接数限制

max-connection-per-server,如上图所示某度下载默认的下载92KB/s,只打开了5个链接数。
目标:突破aria2的16连接数限制,这个16是aria2原作者做的默认。
网上出现很多关于这样设置默认的讨论(有的说是为了防止DOS)
同时也出现各种解决方法,比如:
Linux
https://aur.archlinux.org/packages/aria2-unlimited
https://github.com/P3TERX/Aria2-Pro-Core
增强版安装(适用于旁路由已经@墙的情况下)
curl -fsSL git.io/aria2c.sh | bash

Windows 用法
aria2c.exe –max-connection-per-server=64 –split=64

下面讲解如何在以上的NAS中,NAS内docker环境来利用Aria2-Pro-Core来突破链接数限制

步骤1: SSH进NAS

然后进docker的bash:
sudo docker exec -it aria2-webui /bin/bash

其实程序的部署都写在docker的start.sh文件中了,观察docker的进程主要有:

  1. aria2c –conf-path=$conf –log=/conf/aria2.log >/dev/null 2>&1
  2. darkhttpd /aria2-ng –port 80 –daemon –no-listing –no-server-id $ipv6

升级aria2c主程序

由于只有一个docker,直接(适用于旁路由已经@墙的情况下)
curl -fsSL git.io/aria2c.sh | bash
我的情况无法链接(下载超时),直接下载好aria2c.sh文件,之后放到/data(这个文件夹已经映射到NAS的某个文件目录),
在NAS中这很容易操作(比如分享到其他电脑为局域网内共享文件夹,从其他的系统中传入文件)

1
2
3
4
5
6
7
8
在docker的 /bin/bash 中运行
./aria2c.sh
[INFO] Get CPU architecture ...
[INFO] Architecture: x86_64 (apk)
[INFO] Get Aria2 Pro Core download URL ...
[INFO] Download URL: https://github.com/P3TERX/Aria2-Pro-Core/releases/download/1.36.0_2021.08.22/aria2-1.36.0-static-linux-amd64.tar.gz
[INFO] Installing Aria2 Pro Core ...
...

更改aria2c主程序配置文件

vi /conf/aria2.conf
修改
max-connection-per-server=1024
split=100

修改后aria2.conf文件内容

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
dir=/data
input-file=/conf/aria2.session
save-session=/conf/aria2.session
dht-file-path=/conf/dht.dat
dht-file-path6=/conf/dht6.dat
netrc-path=/conf/.netrc

log-level=notice

enable-http-pipelining=true
max-concurrent-downloads=3
max-connection-per-server=1024
min-split-size=10M
split=100
continue=true
max-overall-download-limit=0
max-overall-upload-limit=1K

disable-ipv6=true

enable-rpc=true
rpc-listen-all=true
rpc-allow-origin-all=true
rpc-listen-port=6800

seed-ratio=0
seed-time=0

如何测试这个Aria2新版可以把连接数提高到64(或更高)呢?
pkill aria2c
aria2c –conf-path=/conf/aria2.conf –log=/conf/aria2.log
这个kill aria2c的操作,直接导致docker的整个容器下线了,说明有守护进程:一发现aria2c进程挂了,就直接停掉整个docker容器

安装后依然无效,
发现默认的aria2c.sh把程序安装到了/usr/local/bin目录,这个不是docker中aria2c默认的目录
解决办法:

1
2
cd /usr/bin
cp /usr/local/bin/aria2c aria2c

修改Aria2c的面板AriaNg

修改了cp /data/aria-ng-2d4f618b32.min.js /aria2-ng/js/
让面板的验证可以调节最大链接数
darkhttpd 无法重启, 等待目前的2个下载数结束以后,可以安全地重启docker
/preset-conf/start.sh

s6-setuidgid $PUID:$PGID darkhttpd /aria2-ng –port 80 –daemon –no-listing –no-server-id $ipv6

正在测试并熟悉:修改了docker中的文件(未映射出来)后,重启docker会不会保留修改后的版本,还是重新从pull来的docker映像中获取默认版本?
结果:好像是会保留修改了配置文件的docker中的所有内容。

通过直接修改aria-ng-2d4f618b32.min.js的方式把max-connection-per-server改到64后,UI操作可以修改超过16,
可是UI报错:We encounter a problem while processing the option: max-connection-per-server
说明我先要去升级aria2c,改到新的无限制版,再来测试UI传递情况。

最新发现:不需要这么麻烦,直接在浏览器的开发者模式,通过覆盖js的办法,可以绕过这个AriaNg面板的Max Connection Limit为16的限制

1
2
3
4
5
6
7
8
搜索"max: 16"后修改文件:aria-ng-2d4f618b32.min.js
"max-connection-per-server": {
type: "integer",
defaultValue: "1",
required: !0,
min: 1,
max: 164
},

就是这个164,原来的内容是16. 是darkhttpd给开放的80端口并把/aria2-ng文件夹的内容作为web服务的内容。

实测效果

设置多线程下载的关键在于:

  1. 连接数(max-connection-per-server):
  2. 分块数(split-count):
    二者相辅相成,如果连接数64,但是分块40;那么也就只会进行40个网络链接。
    最大连接数与速度的对应关系(夸克举例)
    连接数,分块数 下载速度 感受
    10 90KB/s 大文件下载超过24h被某度虐晕
    46 1.45MB/s nice
    160 5.4MB/s 大约15分钟下载完4.7GB的文件
    360 12.4MB/s 大约25分钟下载完16.3GB的文件

不要太贪心,其实服务器升级一下就可以实现底层检测这种单IP链接过来线程数太多的情况,然后大数据join一下那些用户,直接封号,芭比Q了
适可而止,适度适量。
持续实践中:某度网盘太坏了,即便是如上修改后,最大链接数也只能到11个,真是让人又爱又恨。

今天发现用160个连接数去下载普通的网站上的资源(链接类型简单,比如软件等),它的速度十分惊人。赞!

当开启了Max Connection Per Server 为1024后(这个默认值最大值是16),大文件的下载(比如超过4G),真正限制速度的变成:分块数多少的值;当我把分块数调整到360时,我发现aria2会开启360个链接到服务器,这时多线程下载速度达到了每秒12兆左右。
感受:这个速度我在局域网拷贝文件的速度差不多了,跟U盘拷贝,机械硬盘拷贝的速度差不多了;网盘变成了本地机械硬盘。

小文件的下载(比如280M),即便我们把分块数调整到360时,我发现aria2仅会开启32个链接到服务器,这时多线程下载速度在每秒1.1兆左右。

Next:go的并发下载器

学习Go的好项目

写一个简单的go的并发下载器

代码:https://github.com/zmisgod/gofun/blob/master/downloader/downloader_test.go

直接在IDEA里面执行

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
text := "https://qdall01.baidupcs.com/file/7d19b9b918aa2a8378fbc97e09546d8b?bkt=en-24c643f198a62f889617b178e5cec2bac5c80cde035646474703157dcd274bbba0dd05b567b466d1&fid=1996670861-309847-954183442172954&time=1615470389&sign=FDTAXUGERLQlBHSKfWaqir-DCb740ccc5511e5e8fedcff06b081203-DLIjwClp8jhvTCtezZG1c5EB%2BoI%3D&to=92&size=274395838&sta_dx=274395838&sta_cs=21142&sta_ft=mkv&sta_ct=7&sta_mt=7&fm2=MH%2CQingdao%2CAnywhere%2C%2Cshanghai%2Cct&ctime=1424274646&mtime=1486178443&resv0=-1&resv1=0&resv2=rlim&resv3=5&resv4=274395838&vuk=1996670861&iv=0&htype=&randtype=em&newver=1&newfm=1&secfm=1&flow_ver=3&pkey=en-d27c932c79071079b1c5ce8ca7087ee0a722bf4bee97d0e7e8d5cba91bd5389e8bd962717a694c4d&sl=76480590&expires=8h&rt=pr&r=199868329&mlogid=1621347232376378602&vbdid=3403188840&fin=%E6%80%AA%E8%AF%9E%E5%B0%8F%E9%95%87.Gravity.Falls.S01E11.HR-HDTV.x264.AAC.Chs.Eng-Deefun%E8%BF%AA%E5%B9%BB%E5%AD%97%E5%B9%95%E7%BB%84.mkv&fn=%E6%80%AA%E8%AF%9E%E5%B0%8F%E9%95%87.Gravity.Falls.S01E11.HR-HDTV.x264.AAC.Chs.Eng-Deefun%E8%BF%AA%E5%B9%BB%E5%AD%97%E5%B9%95%E7%BB%84.mkv&rtype=1&dp-logid=1621347232376378602&dp-callid=0.1.1&hps=1&tsl=80&csl=80&fsl=-1&csign=dVYKgEit045y%2FYZnjUaT3WXZHfA%3D&so=0&ut=6&uter=4&serv=1&uc=1133405546&ti=5ab0bd4e07f1f550038acada5d35496b1dc2deaff0533f8e&hflag=30&from_type=0&adg=c_edc0108e9fa1ea2bf75676e893bdf053&reqlabel=309847_d_542374c7794461b783501a9d00e48223_-1_18e87ecb8b58d3c5a256ffa3f09e85da&by=themis"
down, err := NewDownloader(text,
SetTimeout(222601),
SetDownloadRoutine(20),
SetStrategyWait(true),
SetTryTimes(400),
)
if err != nil {
log.Println(err)
} else {
err = down.SaveFile(context.Background())
if err != nil {
fmt.Println(err)
} else {
fmt.Println(down.option.SaveName)
}
}

状态:待测试