最近换了iphone,发现缺乏下载网页视频的软件,于是想办法在群晖NAS上部署了github上的yt-dlp项目。
功能:使用iOS的分享表单将网页链接整理为json格式的api请求,并发送到运行在NAS上的yt-dlp来进行远程下载视频。
- 首先开启NAS的SSH连接。
2. 安装python3.9及其以上版本。
2.1 可以选择在套件中心通过第三方源进行安装。或者在SSH下通过命令行进行安装,具体请网络搜索教程。
2.2 安装后在SSH内使用命令行 python3.11 --version
查看是否安装成功。
2.3 通过命令行 which python3.11
查看路径并记录下来。
3. 安装yt-dlp。
3.1 在SSH中可以直接通过pip管理器来安装,运行命令 pip install yt-dlp
3.2 使用Shebang行来检查其解释器,运行命令 head -n l $(which yt-dlp)
3.3 使用vim或者nano来将第一行的python更改为需要的python版本。
4. 保存具有登录信息的浏览器的Cookies(可选,可用chrome插件”get cookies”来导出netscape格式的Cookies文件,具体查看yt-dlp的github说明)。
5. 如果你的域名商允许你下载安全证书,万岁!
如果像我一样是域名商是Squarespace或者不允许你下载安全证书,那么就要导出安全证书给flask使用。
5.1 使用root登录SSH,找到目录/usr/syno/etc/certificate/system/default/
5.2 导出其中的fullchain和privetkey证书
6. 安装flask以建立api服务。
6.1 在SSH中运行命令 pip install flask
7. 创建flask脚本。
脚本内容大致如下:
# flask-yt-dlp.py 开通api服务
from flask import Flask, request, jsonify
import subprocess
import threading
import uuid
import logging
from logging.handlers import RotatingFileHandler
app = Flask(__name__)
# 设置日志记录器
logger = logging.getLogger('werkzeug')
logger.setLevel(logging.INFO)
# 创建日志处理器
handler = RotatingFileHandler('/volume1/video/Download/临时/logs/flask_app.log', maxBytes=10*1024*1024, backupCount=5)
handler.setLevel(logging.INFO)
# 设置日志格式
formatter = logging.Formatter(
'[%(asctime)s] %(levelname)s in %(module)s: %(message)s'
)
handler.setFormatter(formatter)
# 将处理器添加到日志记录器
logger.addHandler(handler)
app.logger.addHandler(handler)
tasks_lock = threading.Lock()
# 下载任务的字典,用于存储任务状态
tasks = {}
# 下载视频的函数
def download_video(url, task_id):
try:
app.logger.info(f"开始下载任务 {task_id}: {url}")
command = [
'/var/services/homes/myname/.local/bin/yt-dlp',
#'--cookies',
#'/volume1/homes/myname/services/login-cookies.txt', # 替换为实际的Cookie文件路径
'--add-header', 'User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/18.0.1 Safari/605.1.15',
#'-f', 'bestvideo+bestaudio/best',
url,
'-o',
'/volume1/video/Download/临时/%(title)s.%(ext)s'
]
# 执行下载命令
process = subprocess.Popen(
command,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
text=True # 如果Python版本低于3.7,使用universal_newlines=True
)
stdout, stderr = process.communicate()
app.logger.info(f"任务 {task_id} 的下载进程返回码:{process.returncode}")
# 使用锁来同步对tasks字典的访问
with tasks_lock:
if process.returncode == 0:
tasks[task_id]['status'] = 'completed'
tasks[task_id]['output'] = stdout
app.logger.info(f"任务 {task_id} 下载完成")
else:
tasks[task_id]['status'] = 'failed'
tasks[task_id]['error'] = stderr
app.logger.error(f"任务 {task_id} 下载失败,错误信息:{stderr}")
except Exception as e:
with tasks_lock:
tasks[task_id]['status'] = 'failed'
tasks[task_id]['error'] = str(e)
app.logger.exception(f"任务 {task_id} 发生异常")
# 定义API路由
@app.route('/download', methods=['POST'])
def download():
# 获取请求头中的API密钥
api_key = request.headers.get('API-Key')
if api_key != '***************': # 请替换为自己设定的API密钥
app.logger.warning("未经授权的访问尝试")
return jsonify({'error': 'Unauthorized'}), 401
# 获取请求体中的视频URL
data = request.get_json()
if not data:
return jsonify({'error': 'Invalid JSON data'}), 400
video_url = data.get('url')
if not video_url:
return jsonify({'error': 'No URL provided'}), 400
# 生成任务ID
task_id = str(uuid.uuid4())
app.logger.info(f"收到下载请求,任务ID:{task_id}")
# 使用锁来同步对tasks字典的访问
with tasks_lock:
tasks[task_id] = {'status': 'in_progress'}
# 启动异步线程进行下载
threading.Thread(target=download_video, args=(video_url, task_id)).start()
return jsonify({'status': 'Download started', 'task_id': task_id}), 200
@app.route('/status/<task_id>', methods=['GET'])
def status(task_id):
app.logger.info(f"查询任务状态,任务ID:{task_id}")
with tasks_lock:
task = tasks.get(task_id)
if task:
return jsonify(task), 200
else:
return jsonify({'error': 'Task not found'}), 404
if __name__ == '__main__':
app.run(
host='0.0.0.0',
port=1234, # 设定一个监听的端口号
ssl_context=(
'/volume1/homes/myname/services/cer/f.pem', # 证书位置
'/volume1/homes/myname/services/cer/p.pem'
)
)
注意修改脚本中的个别信息以符合你的配置,包括建立日志储存的目录。其中Cookies我添加了注释,因为我还没搞懂怎么弄。如果你有这方面的需要的话可以自己修改。除了使用netscape格式的cookies文件之外还可以使用wget命令,或者创建~/.netrc文件来储存凭据(记得给600权限),这些进阶操作这里就不展开说明了。
8. 建立NAS的开机自启动脚本,在群晖DSM的控制面板中找到任务计划,点击新增,触发的任务,用户自定义的脚本,设定为开机启动。在任务设置选项卡下的运行命令中输入 nohup python3 /volume1/homes/yourname/flask-yt-dlp.py &
(调整你的脚本位置,最后的&符号不要漏掉)
9. 重启NAS。
10. 检查端口是否在被监听,在SSH中输入命令 netstat -tulnp | grep 你设定的端口号
11. 在路由器中设定端口转发。
12. 在iOS中建立一个快捷指令:
13. 可以通过iOS的共享到快捷指令进行远程下载视频了,如果下载失败的话请检查你的文件下载目录是否有访问权限,或者查看日志来调试。
谢谢你的阅读,希望对你有帮助!