Syncs YouTube channels and playlists to a locally hosted media server
TubeSync
TubeSync 是一款面向 YouTube 的 PVR(个人视频录像机)。或者,把它理解成 YouTube 版的 Sonarr(内置下载客户端)。它旨在将 YouTube 上的频道和播放列表同步到本地目录,并在媒体下载完成后更新您的媒体服务器。
如果您希望从本地媒体服务器以特定画质或设置观看 YouTube 视频,那么 TubeSync 正适合您。在内部实现上,TubeSync 是在 yt-dlp 和 ffmpeg 之上构建的 Web 界面封装,并带有任务调度器。
目前还有多个面向 YouTube 和 yt-dlp 的 Web 界面,功能和实现方式各不相同。TubeSync 最大的不同在于提供完整的 PVR 体验,包括更新媒体服务器以及更优的媒体格式选择。此外,为了尽可能无人值守,TubeSync 会针对失败任务采用渐进式重试,并配合退避定时器,使下载失败的媒体在较长时间内持续重试,从而有望保持相当高的可靠性。
最新容器镜像
ghcr.io/meeb/tubesync:latest
截图
系统要求
为了获得最简便的安装体验,你需要一个可以运行容器的环境,例如 Docker 或 Podman。你还需要为下载的媒体和缩略图分配足够的空间。如果你下载大量高清媒体, 所需空间可能会非常大。
预期效果
启动后,TubeSync 会将媒体下载到指定目录中。该目录内将包含 video 和 audio
两个子目录。所有仅包含音频流的媒体(例如音乐)都会下载到 audio 目录。所有包含
视频流的媒体都会下载到 video 目录。TubeSync 的所有管理操作都通过网页界面完成。你还可以
可选地添加一个媒体服务器,目前仅支持 Jellyfin 或 Plex,以获得完整的 PVR 体验。
安装
TubeSync 设计为在容器中运行,例如通过 Docker 或 Podman 运行。它也
适用于 Docker Compose 部署栈。支持 amd64(大多数桌面电脑和服务器)和 arm64
(现代 ARM 设备,例如 Raspberry Pi 3 及更高版本)。
示例(在 *nix 系统上使用 Docker):
首先找到你希望用于运行 TubeSync 的用户 ID 和组 ID。如果不确定,通常使用你当前的 用户 ID 和组 ID 即可:
$ id
# Example output, in this example, user ID = 1000, group ID = 1000
# id uid=1000(username) gid=1000(username) groups=1000(username),129(docker)
你可以在此处找到你的本地时区名称:
https://en.wikipedia.org/wiki/List_of_tz_database_time_zones
如果未设置,TZ 默认为 UTC。
接下来,创建将用于存放配置数据和下载内容的目录:
$ mkdir /some/directory/tubesync-config
$ mkdir /some/directory/tubesync-downloads
最后,下载并运行容器:
# Pull image
$ docker pull ghcr.io/meeb/tubesync:latest
# Start the container using your user ID and group ID
$ docker run \
-d \
--name tubesync \
-e PUID=1000 \
-e PGID=1000 \
-e TZ=Europe/London \
-v /some/directory/tubesync-config:/config \
-v /some/directory/tubesync-downloads:/downloads \
-p 4848:4848 \
--stop-timeout 1800 \
ghcr.io/meeb/tubesync:latest
服务启动后,在浏览器中打开 http://localhost:4848,你应该就能看到 TubeSync 仪表盘。如果成功,你可以继续添加一些来源(YouTube 频道和播放列表)。如果未看到,请检查 docker logs tubesync,查看可能出现的错误,常见的是文件权限问题。
或者,对于 Docker Compose,你可以使用类似:
services:
tubesync:
image: ghcr.io/meeb/tubesync:latest
container_name: tubesync
restart: unless-stopped
stop_grace_period: 30m
ports:
- 4848:4848
volumes:
- /some/directory/tubesync-config:/config
- /some/directory/tubesync-downloads:/downloads
environment:
- TZ=Europe/London
- PUID=1000
- PGID=1000
Important
如果 /downloads 目录是从 Samba 卷 挂载的,请务必在驱动选项中也提供 uid 和 gid 挂载参数。
这些参数必须与环境变量中指定的 PUID 和 PGID 值保持一致。
将这些用户 ID 和组 ID 正确匹配,可避免在执行文件操作(例如写入元数据)时出现问题。详细信息请参见 此问题。
可选身份验证
通过设置 HTTP_USER 和 HTTP_PASS
环境变量,可以启用基本 HTTP 身份验证。详细信息请参见环境变量参考。
更新
版本发布后,只需拉取新的容器镜像即可完成更新。
$ docker pull ghcr.io/meeb/tubesync:v[number]
后端更新(例如数据库迁移)应当是自动执行的。
Important
MariaDB 未针对 UUID 列类型自动完成升级。
若想了解需要执行哪些更改,你可以运行:
docker exec -it tubesync python3 /app/manage.py fix-mariadb --dry-run --uuid-columns
移除 --dry-run 后,将尝试使用已配置的数据库连接执行这些语句。
移动、备份等
当 TubeSync 在默认容器中运行时,它会将缩略图、缓存以及 SQLite 数据库存储到 /config 目录,也就是你在文件系统中映射到的目录。只需复制或移动该目录,并确保权限正确,就足以完成 TubeSync 安装的移动、备份或迁移。
使用 TubeSync
1. 添加一些来源
选择你喜欢的 YouTube 频道或播放列表,打开“来源”标签页,点击适合你的添加按钮,输入 URL 并验证。该过程会从 URL 中提取关键信息,并确认它是有效的 URL。对于 YouTube 频道,这是频道名称;对于 YouTube 播放列表,这是播放列表 ID。
随后会显示“添加来源”初始表单,你可以在其中选择所有需要的功能,例如多久索引一次你的来源,以及要下载的媒体质量。确认无误后,点击“添加来源”。
2. 等待
基本就是这些。其他所有操作都是自动执行的,由计划任务按定时器触发。你可以在“任务”标签页中查看当前 TubeSync 实例正在执行什么。
媒体被索引和下载后,会出现在“媒体”标签页中。
3. 更新媒体服务器
目前,TubeSync 支持 Plex 和 Jellyfin 作为媒体服务器。你可以在“媒体服务器”标签页中添加本地的 Jellyfin 或 Plex 服务器。
日志与调试
已移至 wiki。
高级使用指南
已移至 wiki。
警告
1. 索引频率
添加来源时,最好尽可能将索引频率设置得尽量长。
这是该来源两次索引之间的时长。索引是指 TubeSync 检查频道或播放列表上有哪些可用视频,以发现新的媒体内容。请尽可能将其设置得长一些,最长可达 24 小时。
2. 索引超大型频道
如果你将一个超大型频道(拥有数千个视频的频道)添加到 TubeSync,并选择“每小时索引一次”或类似的较短间隔,那么你的 TubeSync 安装很可能会把全部时间都用来反复索引该频道,而不会下载任何媒体。请通过任务检查你的 TubeSync 安装状态。
请保持礼貌。 如果你尝试快速抓取大量内容,你的 IP 地址完全有可能被来源限流和/或封禁。请在满足需求的前提下,尽量减少索引量和并发下载量,保持克制。
常见问题
已移至 wiki。
高级配置
你还可以设置一些其他环境变量。它们大多数并非默认容器安装所必需,通常只在你于其他环境中手动安装 TubeSync 时才有用。这些变量如下:
| 名称 | 说明 | 示例 |
|---|---|---|
| DJANGO_SECRET_KEY | Django 的 SECRET_KEY | YJySXnQLB7UVZw2dXKDWxI5lEZaImK6l |
| DJANGO_URL_PREFIX | 在 Web 服务器上以子路径运行 TubeSync | /somepath/ |
| TUBESYNC_DEBUG | 启用调试 | True |
| TUBESYNC_HOSTS | Django 的 ALLOWED_HOSTS,默认为 * |
tubesync.example.com,otherhost.com |
| TUBESYNC_RESET_DOWNLOAD_DIR | 切换是否重置 /downloads 权限,默认为 True |
True |
| TUBESYNC_VIDEO_HEIGHT_CUTOFF | 允许下载的最小视频高度(像素) | 240 |
| TUBESYNC_RENAME_SOURCES | 重命名所选来源的媒体文件 | Source1_directory,Source2_directory |
| TUBESYNC_RENAME_ALL_SOURCES | 重命名所有来源的媒体文件 | True |
| TUBESYNC_DIRECTORY_PREFIX | 启用 /downloads 中的 video 和 audio 目录前缀 |
True |
| TUBESYNC_SHRINK_NEW | 过滤新获取元数据中无用的信息 | True |
| TUBESYNC_SHRINK_OLD | 过滤从数据库加载的元数据中无用的信息 | True |
| GUNICORN_WORKERS | 要启动的 gunicorn(Web 请求)工作进程数量 |
3 |
| LISTEN_HOST | gunicorn 监听的 IP 地址 |
127.0.0.1 |
| LISTEN_PORT | gunicorn 监听的端口号 |
8080 |
| HTTP_USER | 设置 HTTP 基本身份验证的用户名 | some-username |
| HTTP_PASS | 设置 HTTP 基本身份验证的密码 | some-secure-password |
| DATABASE_CONNECTION | 可选的外部数据库连接信息 | postgresql://user:pass@host:port/database |
手动非容器化安装
TubeSync 是一个相对常规的 Django 应用,你可以不使用容器来运行它。除按这份粗略指南操作外,后续需要自行处理。在尝试这种方式之前,建议熟悉基于 WSGI 的 Python Web 应用的安装与运行方法。
- 克隆或下载本仓库
- 确保你正在使用较新版本的 Python(>=3.12),并且已安装 Pipenv
- 使用
pipenv install配置环境 - 将
tubesync/tubesync/local_settings.py.example复制为tubesync/tubesync/local_settings.py,并按需修改 - 使用
./manage.py migrate执行数据库迁移 - 使用
./manage.py collectstatic收集静态文件 - 配置你偏好的 WSGI 服务器,例如
gunicorn,并将其指向tubesync/tubesync/wsgi.py中的应用 - 配置代理服务器,例如
nginx,并将请求转发到 WSGI 服务器 - 确认 Web 界面可正常工作
- 运行
./manage.py process_tasks作为后台任务工作进程,用于建立媒体索引并下载媒体。这是一个不会自动转入后台的进程,日志会写入控制台。若需长期运行,可以使用tmux等终端复用器,或创建systemd单元来运行它。
测试
这里提供了一套较为全面的测试套件,主要覆盖自定义媒体格式匹配逻辑,并验证前端界面是否正常工作。你可以通过 Django 运行它:
$ ./manage.py test --verbosity=2
参与贡献
欢迎提交所有格式规范且合理的拉取请求、议题与评论。




