Releases: davidchiu66/Tube_Ultimate_Player
Release list
Tube_Ultimate_Player 0.2.31
v0.2.31
0.2.31 聚焦 Instagram 接入、评论体验、播放队列导航、YouTube 清晰度显示和 macOS 发布能力。
Instagram 支持
- 新增 Instagram 首页和搜索浏览器服务,支持 Firefox 登录 Cookie 和 Qt WebEngine 安全上下文
- 从 Instagram 主首页采集动态 Relay/ServerJS 视频节点,支持滚动加载并按 20 条分页
- 支持 Instagram Reel 视频卡片识别、播放、下载、收藏、历史和播放记忆
- 增加登录页、Challenge、Checkpoint 和安全验证状态识别
- 采集日志不记录 Cookie 值,只记录来源和必要诊断信息
评论体验
- 播放器右侧播放列表增加结构化评论 Tab
- Bilibili 评论改用官方分页接口,加载更快并支持“加载更多”
- YouTube 评论支持 yt-dlp 分页参数和继续加载
- 播放开始后后台预取首批评论
- 评论首次显示、面板首次滑入和窗口尺寸变化时自动重新计算换行高度
- 加载更多后保持旧评论页末尾锚点,并按评论 ID 去重
- 鼠标停留或滚动评论面板时不会被播放器空闲计时器自动收起
播放控制与清晰度
- 播放控制器增加“上一个”“下一个”文字按钮,位于停止按钮之后
- 新增
P/N快捷键,保留原有PgUp/PgDown配置 - 播放列表、合集和首页/搜索结果支持统一的上一个/下一个导航
- 队列边界禁用,不循环播放
- 普通窗口音量改为悬浮竖向滑条,默认隐藏,悬停音量按钮时显示
- 投屏、全屏和小窗按钮收窄,改善普通窗口控制器拥挤问题
- YouTube 使用
default,web_safariclient 组合,保留完整格式梯度 - 超宽 YouTube 视频按标准画质档位显示,避免出现
886p/590p/394p等误导标签 - 同一分辨率多个帧率只保留最高质量版本
macOS 发布
- 新增
release-macos.yml工作流 - 支持 macOS Intel 与 Apple Silicon runner
- 生成
.app、.dmg和.zip发布资产 - 内置 macOS 版 yt-dlp、Deno 和 libmpv
- 自动打包 libmpv 的动态库依赖,检查并拒绝 Homebrew 本地路径泄漏
- 主发布工作流会将 macOS 资产与 Windows 资产一起上传到 GitHub Release
稳定性与验证
- 保留既有抖音、TikTok、小红书浏览器签名、Cookie、风控恢复和站点隔离能力
- 更新 README、macOS 构建文档和相关回归测试
pyproject.toml与app_version.txt统一为0.2.31- 全量自动化测试:892 passed
- Python 编译检查、Ruff 和
git diff --check通过
升级说明
首次使用 Instagram 时,建议在 Firefox 中登录 Instagram,再在设置页为 Instagram 配置自动检测 Cookie。macOS 发布资产分为 Intel (mac_x86_64) 和 Apple Silicon (mac_arm64) 两种架构,请按设备选择。
Tube_Ultimate_Player 0.2.30
v0.2.30
0.2.30 在抖音与 TikTok 支持的基础上接入小红书视频能力,并继续增强小窗播放、播放列表和多站点稳定性。
小红书支持
- 新增小红书视频首页(
https://www.xiaohongshu.com/red_video)和关键词搜索 - 支持小红书视频笔记 URL 播放、清晰度选择、下载、收藏、历史和播放记忆点
- 新增小红书作者昵称识别与作者其它视频播放列表
- 新增小红书独立浏览器服务,复用浏览器 Cookie、页面安全上下文和媒体请求头
- 新增小红书安全验证窗口;遇到平台验证时可在应用内完成后重试
- 小红书站点与其它站点的 Cookie、默认画质、浏览器和请求缓存相互隔离
- 图文笔记、直播、评论、私信和商城等非视频内容仍不在支持范围内
播放列表与播放器体验
- 单视频播放后在后台生成作者播放列表,不阻塞当前视频首帧播放
- 作者播放列表尚未解析完成时,将鼠标移入播放器右侧热点会提示“播放列表加载中,请稍候”
- 加载提示按一次热点进入节流,离开后再次进入才重新提示
- 作者列表成功、失败、无作者信息、切换视频和请求失效时正确清理加载状态
- 小窗模式、左侧合集列表和已有保存列表不受右侧加载提示影响
- 继续保持小窗播放的拖动、等比缩放、置顶、迷你控制条和多风格图标能力
多站点与稳定性
- 首页、搜索、URL 播放、下载、收藏、历史、设置和工具栏全面补齐小红书适配
- 加强抖音首页与搜索的浏览器签名、风控验证恢复和请求取消处理
- 改进小红书媒体 URL、Referer、Origin、编码和清晰度兼容处理
- 首页或搜索加载期间启动播放时,取消旧浏览任务,避免迟到回调覆盖当前页面
- 站点切换期间冻结重复切换操作,待当前加载完成后自动恢复
- 首次启动增加 Cookie 配置操作指南,可勾选后不再显示
- 完善作者列表异步 worker 的 generation 校验,避免旧视频结果污染当前播放
文档与测试
- README 更新为五站点能力说明,补充小红书配置、运行目录和使用说明
pyproject.toml与app_version.txt版本号统一为0.2.30- 新增小红书、浏览器验证、播放列表加载提示等回归测试
- 全量自动化测试:862 passed
- Python 编译检查和
git diff --check通过
升级说明
升级后建议在设置页为小红书单独配置 Firefox Cookie。首次打开小红书首页或搜索时需要初始化浏览器安全环境,加载时间可能明显长于 Bilibili 和 YouTube,请耐心等待。
Tube_Ultimate_Player 0.2.29
v0.2.29
0.2.29 新增抖音(Douyin)与 TikTok 支持,并将两个短视频站点完整接入首页、搜索、URL 播放、作者播放列表、下载、收藏、历史、播放记忆和设置体系。本版本同时为抖音首页与搜索引入页面动态签名请求,降低直接调用接口时频繁触发安全验证的问题。
抖音与 TikTok
- 工具栏和默认首页增加抖音、TikTok,四站点可独立切换并保留各自缓存
- 支持抖音和 TikTok 视频 URL、常见分享短链、首页卡片和搜索结果播放
- 使用带站点前缀的稳定视频 ID,避免下载、收藏、历史和播放记忆串站
- 播放器显示短视频作者昵称、时长和可用清晰度
- 支持按作者生成播放列表,并可选择其它作品继续播放
- TikTok 用户主页和平台可解析列表沿用通用播放列表能力
- 不支持直播、标签、音效和特效页;地区、私密内容和登录限制会显示明确错误
首页与搜索
- 抖音搜索在内置 Qt WebEngine 页面中调用站点自身的动态签名函数,再由 Chromium 发起同源请求
- 导入设置中选择的 Firefox Cookie,不在日志中记录 Cookie、签名值或完整媒体 URL
- 搜索每个 UI 页只对应一个平台原生批次,下一页复用
search_id和游标 - 抖音首页复用精选页自动加载的视频数据,并补充多个签名推荐窗口后统一去重
- 浏览器请求使用线程安全队列,后台 worker 不阻塞 Qt 主线程
- 刷新或后续请求被平台限制时保留已有有效结果,不把部分结果误判为搜索结束
- TikTok 首页与搜索使用登录 Cookie、平台接口和推荐流过滤降级,不回退到其它站点
- 平台推荐流本身可能返回重复或较少内容,因此抖音首页单页数量以当次去重结果为准
播放与画质
- 首页、搜索和作者列表缓存短视频原始条目,播放时可直接复用带签名媒体地址
- 抖音详情接口补充登录后可用的高分辨率格式,支持 1080p 等清晰度
- 竖屏视频按短边生成清晰度标签,避免将 1080 x 1920 错标为 1920p
- 抖音与 TikTok 各自支持智能、高、中、低默认画质配置
- 播放请求保留站点所需 User-Agent、Referer、Origin 和精简 Cookie
- 收藏、历史、首页、搜索、URL 和播放列表入口共用现有播放记忆逻辑
下载
- 抖音与 TikTok 使用专用直链下载路径,支持断点续传和
.part临时文件 - 下载任务保存实际媒体 URL、请求头、来源站点和原始视频 URL
- 媒体直链过期或旧任务缺少上下文时,自动重新解析并迁移任务
- 修复下载完成后文件存在但记录仍提示本地文件不存在的问题
- 修复重启后抖音下载记录被误识别为 YouTube 的问题
- 文件名和任务导入支持
douyin:<id>、tiktok:<id>以及无前缀原始 ID - 日志会清理短视频媒体 URL 中的签名参数,避免泄露临时访问凭据
设置与数据兼容
- 新增集中式站点注册表,统一四站点名称、紧凑标签、URL 识别和 Cookie 域
- 默认首页、默认画质、Cookie 文件、浏览器及 Profile 按四站点独立保存
- Cookie 自动检测增加抖音和 TikTok 登录域识别
- 工具栏在较窄窗口使用
B站 / YT / DY / TT紧凑标签 - 备份与恢复包含
cookie_douyin.txt和cookie_tiktok.txt - 旧版下载任务、收藏、历史、播放列表和配置继续兼容
真实环境验证
- Firefox 已登录抖音和 TikTok,应用能够读取对应 Cookie
- 抖音、TikTok 首页、搜索结果和视频播放已在真实网络环境验证
- 抖音搜索连续分页可返回有效结果且不再立即触发
verify_check - 抖音首页签名推荐流可返回去重后的可播放内容;数量受平台当次推荐结果影响
- 抖音 1080p 直链下载成功,验证文件大小约 70.2 MiB
- TikTok 1080p 直链下载成功,验证文件大小约 41.3 MiB
- 旧 TikTok 下载任务重新解析和迁移成功,验证文件大小约 10.5 MiB
测试
- 新增站点识别、设置隔离、Cookie 路由、首页/搜索分页、作者列表、播放格式、下载迁移和签名请求回归测试
- 全量自动化测试:803 passed
- 抖音/TikTok 定向测试:26 passed
- Python 编译检查和
git diff --check通过
升级说明
升级后可在设置页分别为抖音和 TikTok 选择已登录浏览器、Cookie 文件及默认画质。抖音首页和搜索首次使用时需要初始化内置浏览器签名运行时,首轮加载会比后续请求慢;TikTok 内容仍可能受账号地区和网络出口地区限制。
Tube_Ultimate_Player 0.2.28
v0.2.28
0.2.28 完善了播放连续性和小窗发布质量:在线视频、本地视频和收藏入口现在支持播放记忆点;下载列表播放本地文件时会自动加载同目录视频;同时修复了安装版小窗 SVG 图标缺失和结束播放返回后普通控制器不显示的问题。
播放记忆点
- 在线视频从首页、播放历史、收藏或 URL 播放时,统一保存和恢复播放位置
- 播放位置按视频 ID 和规范化网页 URL 双重匹配,兼容重新解析后 ID 变化的情况
- 播放过程中节流保存位置,暂停、停止、切换媒体和关闭应用时强制保存
- 修复 mpv 在停止/切换瞬间回报起始位置导致记忆点被覆盖的问题
- 使用最后一次有效位置、播放器页面位置和 mpv 位置进行保护,避免实际播放 30 秒后只保存 0~1 秒
- 记忆点小于 5 秒时不恢复,播放达到总时长 95% 或自然结束后从头播放
- 点击重新播放会清除当前记忆点并从 0 秒开始
- 播放记忆位置更新不会增加播放次数
下载列表本地视频
- 从下载列表播放本地视频时自动保存和恢复记忆点
- 记忆点按规范化绝对路径保存,并校验文件大小和修改时间
- 文件发生变化、失效或不存在时自动忽略旧记忆点
- 关闭应用后重新打开仍可恢复本地视频位置
同目录本地播放列表
- 从下载列表播放本地视频后,自动扫描当前文件所在目录的直接子视频文件
- 支持
mp4、mkv、webm、m4v、mov、avi、flv、wmv、ts、m2ts - 过滤隐藏文件、子目录和
.part、.ytdl、.tmp、.temp临时文件 - 使用自然排序,确保“第2集”排在“第10集”之前
- 当前文件自动定位,上一集、下一集和自动连播直接加载本地文件,不经过 yt-dlp
- 本地播放列表仅在当前播放会话中存在,不写入站点播放列表数据库
- 本地文件不允许重复下载或保存为站点播放列表
小窗播放稳定性修复
- 安装版显式打包并安装
docs/assets/pip下的 SVG 图标资源 - 资源目录选择增加实际 SVG 文件校验,避免不完整安装目录遮蔽 PyInstaller 内部资源
- 修复播放结束后点击「返回播放器」时,普通播放器控制面板无法重新滑入的问题
- 保持既有小窗标题栏、迷你控制器、全屏/窗口恢复和窗口几何修复能力
数据库与兼容性
- 新增本地播放记忆表,应用启动时自动创建,不需要手工迁移
- 既有在线历史、收藏、播放列表和下载任务数据保持兼容
- 本地记忆不写入在线历史,避免历史页出现无法解析的本地文件记录
测试与验证
- 新增播放记忆仓储、在线 URL 回退、本地目录扫描、停止位置回退和小窗返回控制器测试
- 全量测试:773 passed
- 相关回归测试:43 passed
- Python 编译检查和
git diff --check通过 - 已在真实环境验证首页/历史/收藏在线视频续播、下载列表本地视频续播、停止后再次播放以及同目录本地播放列表
升级说明
升级后已有在线视频会沿用现有历史记录;本地视频从下载列表播放后开始建立本地记忆。若文件被替换或修改,程序会自动丢弃旧记忆点并从头播放。
Tube_Ultimate_Player 0.2.27
v0.2.27
0.2.27 新增完整的小窗播放体验:播放器可在不打断当前播放的情况下切换为置顶小窗,支持拖动、等比例缩放、锁定、快捷键操作和迷你控制条。本版本同时统一了小窗播放反馈图标,并修复了全屏、小窗与停止播放之间的窗口状态恢复问题。
小窗播放
- 播放控制器新增「小窗」按钮,位于全屏按钮之后,快捷键为
W - 小窗仅保留视频播放区域和轻量自绘标题栏、迷你控制条,不显示播放列表与合集列表
- 支持拖拽移动窗口,靠近屏幕边缘时自动吸附
- 支持四角和四边缩放,始终保持视频画面比例
- 窗口尺寸限制为最小
320 × 180,最大不超过当前屏幕工作区允许的尺寸 - 小窗默认置顶,支持锁定位置和尺寸;锁定后仍可操作播放控制、进度和音量
- 单击视频区域切换暂停/播放,双击退出小窗;
W和Esc可退出小窗 - 播放结束时提供轻量的重新播放和返回播放器操作
- 小窗位置、尺寸和静音状态按要求持久化,并在多屏、分辨率或 DPI 变化后进行有效性校验
迷你控制器风格
- 增加三套自绘 SVG 迷你控制器风格:简约线性、圆润胶囊、深色实体
- 设置页新增中文风格选项,默认使用「随机」
- 随机模式会在每个新视频开始播放时重新选择风格,并避免连续视频重复使用同一风格
- 播放/暂停中屏提示图标与当前迷你控制器风格保持一致
- 所有 SVG 资源统一归档到
assets资源目录并纳入构建包
窗口状态与停止播放修复
- 修复全屏进入小窗后返回普通窗口时标题栏丢失或关闭按钮无法点击的问题
- 修复从全屏进入小窗后按
S停止播放,主工具栏消失的问题 - 修复小窗尺寸和位置污染主窗口的问题:停止播放返回主界面时恢复进入全屏前的正常窗口位置和尺寸
- 增加 Windows 原生窗口 frame 刷新和延迟几何恢复,覆盖 Qt/Windows 异步状态回写场景
- 保持 mpv 视频窗口句柄稳定,避免切换小窗时重建播放窗口导致黑屏或控件失效
文档与测试
- 补充小窗播放需求分析、裁定结果、实施方案和验收标准文档
- 新增小窗配置、控制器、几何约束和窗口状态回归测试
- 本版本收集到 765 项自动化测试用例
- 小窗相关测试:
31 passed - 主窗口硬化测试:
13 passed - Python 编译检查和
git diff --check通过
升级说明
升级后可在设置页选择迷你窗口播放器风格。默认「随机」会在不同视频之间自动切换;如需固定视觉效果,可选择对应的中文风格。
小窗的位置、尺寸和静音状态会保存到本地配置。更换显示器或分辨率后,应用会自动将小窗调整到当前屏幕的有效工作区内。
Tube_Ultimate_Player 0.2.26
v0.2.26
0.2.26 重点增强了多站点播放体验:默认画质和 Cookie 设置现在按视频网站独立保存,并新增基于目标视频 CDN 实测带宽的「智能选择」。合集播放能够继承用户当前实际使用的清晰度,Bilibili 合集则进一步支持「合集 → 专辑 → 分集」层级和多 P 视频展开。本轮自动化测试增至 732 项,全部通过。
分站点画质与 Cookie 设置
- Bilibili 与 YouTube 可分别配置默认画质,互不覆盖
- Cookie 浏览器和 Profile 同样按站点独立保存,切换站点时自动使用对应配置
- 设置页会跟随当前站点展示和保存配置,并兼容迁移旧版全局设置
- 默认首页配置现在会真实决定应用启动后加载 Bilibili 还是 YouTube
- 同时修改多个站点画质时,旧版全局画质兼容值会稳定跟随默认首页站点
智能画质选择
- 默认画质新增「智能选择」,播放前通过目标视频 CDN 的 Range 请求测量实际下载带宽
- 测速复用视频请求头、代理和 Cookie 上下文,使结果更接近真实播放链路
- 带宽结果按站点和网络环境短期缓存,减少重复探测与起播等待
- 根据实测带宽、格式码率和安全余量选择可稳定播放的最高画质
- 部分格式缺少码率时,会结合分辨率估算所需带宽,不会无故排除高画质
- 测速失败、数据不足或格式信息异常时会可靠回退到可播放画质,不再出现「没有可播放的清晰度」错误
- 异步解析和测速使用请求代次隔离,旧请求的迟到结果不会覆盖当前视频
默认画质档位
- 高、中、低档位统一基于实际可选画质集合计算
- 「中」在奇数个选项时取正中间;偶数个选项时取半数后的第一项,即偏高的一档
- 选择过程不依赖解析器返回顺序,并继续兼容旧版精确画质标签
连播与手动切集画质继承
- 同一播放列表、合集或专辑内切换条目时,继承上一个视频实际播放的清晰度
- 自动连播和手动点击下一集均采用相同规则
- 用户播放期间临时切换到 1080p 等画质后,下一条会优先保持该画质,而非重新套用设置页默认值
- 目标视频缺少完全相同的清晰度时,会选择最合理的可用替代项
Bilibili 合集、专辑与多 P 分集
- 支持解析 Bilibili
ugc_season.sections合集层级,展示合集下的专辑及其分集 - 支持通过
episode.pages展开多 P 视频,一个专辑内的所有分集均可直接选择播放 - 播放合集中的视频时会自动定位并展开当前专辑
- 专辑内自动连播按本专辑顺序进行,并保持当前实际清晰度
- 合集与专辑层级写入 SQLite 缓存,减少重复解析并改善再次打开速度
- 层级导航统一使用「返回合集」,明确返回目标
- 已用 Bilibili《纪录片》合集中的《钱学森》专辑验证,6 集均可完整展开和播放
稳定性与兼容性
- 加强站点切换、设置保存、解析器重建和播放请求之间的状态同步
- 防止旧的视频解析或网络探测结果覆盖用户后来选择的条目
- 数据库升级自动创建合集层级所需结构,现有播放历史、收藏和播放列表不受影响
- 旧版全局默认画质与 Cookie 配置会继续读取并迁移,无需重新设置全部站点
测试与验证
- 新增分站点画质、Cookie、智能测速、画质继承、合集层级和多 P 展开测试
- 全量结果:732 tests,全部通过
compileall与git diff --check通过- 已在真实 Bilibili 与 YouTube 环境验证默认首页、智能画质、手动切集、自动连播和合集专辑展开
升级说明
Windows 安装版与便携版可直接在「关于」页检查更新。升级后,原有全局默认画质和 Cookie 设置会作为兼容配置保留;可进入设置页分别调整 Bilibili 与 YouTube 的选项。
首次使用「智能选择」时,起播前可能发生一次短暂的目标 CDN 测速;后续会复用缓存结果。测速仅请求少量视频数据,不会下载完整视频。
Fedora 用户通过 COPR 升级:
sudo dnf upgrade tube-ultimate-playerTube_Ultimate_Player 0.2.25
v0.2.25
0.2.25 的重点是数据备份与恢复:设置页新增完整的 WebDAV 备份方案,可管理多个服务器、创建带校验清单的备份包、查看远端备份并安全恢复。同时补齐默认画质档位、首页/搜索切站点状态和播放历史批量操作。本轮全量自动化测试由 661 项增至 719 项,并已通过真实 WebDAV 环境的完整备份、恢复和重启验收。
WebDAV 备份与恢复
设置页新增「备份/恢复」Tab:
- 支持添加、编辑、删除和测试多个 WebDAV 账号;选中项就是当前使用的服务器
- 支持自定义服务器地址、用户名、密码和远程目录,默认目录为
Tube_Ultimate_Player/backups - 备份内容包括用户配置、播放历史、收藏、播放列表数据库和下载任务
- Cookie 默认不进入备份;需要时可手动勾选,并会显示登录凭据风险提示
- 已下载的视频、日志、缓存、升级包和第三方二进制不会进入备份
- 远端只保留最近 20 个本程序生成的备份,不会误删其他文件
- 网络与压缩操作全部在后台线程执行,备份、恢复和连接测试不会阻塞界面
备份完整性与安全
- SQLite 使用在线备份接口生成一致性快照,避免直接复制活动数据库或 WAL 中间状态
- 每个 ZIP 都包含
manifest.json,记录应用版本、创建时间、平台、文件大小及 SHA256 - 恢复前严格校验应用标识、schema、文件集合、大小和 SHA256;任何异常都在覆盖现有数据前中止
- 拒绝重复路径、路径穿越、绝对路径、未在清单中声明的文件以及不安全的压缩包条目
- WebDAV 账号文件不会进入备份包;密码在 Windows 上使用 DPAPI,在其他平台使用 Fernet 加密保存
- 无法解密或遇到明文降级凭据时会明确提示,不会静默当作正常配置使用
网络与代理
- WebDAV 默认强制直连,避免无意继承系统环境代理
- 网络层连续 3 次直连失败后,自动尝试应用当前有效代理
- 一旦某账号经代理成功,本次会话后续操作直接复用代理,不再重复等待三次直连超时
- 401/403/404/405 等 HTTP 响应说明服务器可达,会立即转换为可读错误,不会错误地重试或切换代理
- 上传中断时会清理可能残留的远端半成品;正常 HTTP 错误不会误删服务器已有文件
恢复与重启
- 恢复前自动在本地生成
pre-restore-<时间戳>.zip快照,便于意外情况下回退 - 备份来自更高版本时会再次确认,避免无提示地进行不兼容恢复
- 恢复完成后可选择「立即重启」或「稍后重启」
- 选择稍后重启时会保留状态提示,并暂停旧进程的配置和下载任务持久化,防止退出时把恢复结果覆盖回去
- 自动重启同时支持安装版、便携版和
python main.py源码运行形态
默认画质:高 / 中 / 低
- 设置页新增「默认画质」,提供高、中、低三个档位,默认保持原来的最高画质行为
- 「中」按去重后的分辨率高度取中位,同高度优先较高帧率;偶数档位时取偏低的一档
- 选择过程不依赖解析器返回顺序,并会忽略无效或异常的分辨率数据
- 旧配置中的
Auto继续按最高画质处理;1080p等精确标签仍可精确命中 - 保存其他设置时不会擅自把旧的精确画质标签改写成
high
首页与搜索切换站点
- 主窗口显式记录当前浏览动作是「首页」还是「搜索」
- 首页状态下切换 Bilibili / YouTube 时始终加载新站点首页,即使搜索框仍保留旧文字
- 搜索状态下直接切站点时,仍会使用当前关键词在新站点重新搜索
- 搜索框清空后切站点会回到首页;重复选择当前站点不会触发无效刷新
- 首页缓存命中同样会推进请求代次,旧站点迟到的异步结果不会覆盖当前页面
- 保存设置并重建解析器后会同时重置浏览状态,避免残留文本再次误触发搜索
播放历史批量操作
- 历史页新增「下载选中 / 下载全部 / 删除选中 / 删除全部」
- 表格支持多选,每行新增独立删除按钮
- 「全部」始终指当前搜索筛选后可见的记录,按钮提示会显示实际数量
- 历史页展示上限由 50 提升到 200;仓储接口的默认读取数量保持兼容
- 删除前明确提示只删除播放历史,不会删除本地视频文件
- 批量下载统一汇总新建和跳过数量,单条或批量仓储异常会被记录并显示友好提示
- 收藏页与历史页共用批量操作逻辑,收藏批量删除同时加强了 ID 清理、去重和异常处理
测试与兼容性
- 新增默认画质、站点切换、历史批量、WebDAV、备份包、凭据存储和应用重启测试
- 全量结果:719 tests,全部通过
compileall与git diff --check通过- 已在真实 WebDAV 环境验证连接测试、备份、远端保留、恢复、立即重启以及直连失败后的代理回退
升级说明
Windows 安装版与便携版可直接在「关于」页检查更新。升级不会自动创建远端备份;如需使用该功能,请在设置页的「备份/恢复」中先添加 WebDAV 账号。
恢复操作不会恢复或删除已下载的视频文件。恢复完成后必须重启应用,新的配置和数据库状态才会完整生效。
Fedora 用户通过 COPR 升级:
sudo dnf upgrade tube-ultimate-playerTube_Ultimate_Player 0.2.24
v0.2.24
0.2.24 的重点是播放体验:控制面板新增「音轨」选择、左侧可滑出「合集列表」、播放界面显示收藏与下载状态、播放列表切换即加载、收藏页支持批量操作。其中音轨一项的起因是个既有缺陷——多语言配音视频此前播出的是随机语言。另修掉 Cookie 读取上一批「明明登录了却读不出来」的问题。本轮全量单测从 442 项增至 661 项。
音轨:修掉多语言配音视频播出随机语言
需求原本只是「控制面板加一个音轨下拉」,取证时发现的却是个既有缺陷:多语言视频当前播的是一条随机语言的音频(实测某视频默认俄语),用户不但不能选,连「现在放的是哪条」都不知道。根因是选轨只按码率打分(score_audio),从不看语言。所以这一版真正交付的是修掉它,下拉框只是它的出口。
- 控制面板「清晰度」之后新增音轨下拉。多语言视频列出各语言,标注「原声」/「站点默认」
- 默认轨的挑选链条:本机系统语言 → 站点默认轨 → 原声轨 → 其余按可读语言名。这条链条只存在于
select_audio_tracks()的排序 key 一处,界面显示的默认项就是排序首条,不会出现「下拉里选中的」与「实际在播的」错位 - 设置页新增默认音轨语言,首项形如
跟随系统(zh-Hans-CN),括号里是探测结果——「默认语言不对」时先看这里 - 同语言的 DRC 轨在组内剔除:DRC 的码率常略高于原轨,按码率挑会盖过它;整组都是 DRC 时才保留,不会让一种语言凭空消失
- 下载与投屏跟随所选音轨,不再各自另挑一条
- 新增「随画面(免转码)」选项:切到它会把画面也换回同档的已混音单流,用于没装 FFmpeg 时直投。无 FFmpeg 的投屏提示改为条件文案——本档位没有已混音变体时(如只有纯视频轨的 2160p)不指路到一个当前选不出来的选项
- 单语言视频与 Bilibili 显示占位项且不可点,与「切换清晰度」的启用判据同源,不会出现「显示了一个能读的语言名却点不动」
- 切轨失败先回滚再报错,下拉不会停在一条并没有在播的轨上
播放:左侧滑出「合集列表」
-
左边缘热区滑出合集列表,与右侧播放列表对称(
PlaylistOverlay参数化左右方向复用) -
合集与播放列表是两套独立状态,自动连播由
_active_queue仲裁,不会互相抢 -
当前视频不属于任何合集时显示空态,而不是留一个空列表
-
修复合集列表没有上传日期(右侧播放列表一直有)。根因是数据缺失不是渲染问题:
--flat-playlist默认不返回任何日期字段,必须显式加--extractor-args youtubetab:approximate_date;_build_home_command()一直带着它,_build_playlist_command()漏了。两侧共用同一个PlaylistItemWidget,有数据就会显示。实测某频道 1546 条上传,修复后 1546/1546 都有日期一处需知情的性质:该参数名为 approximate 并非修辞——YouTube 的 tab 页只给相对时长(「3 天前」),最新几条会 collapse 到同一天,越老的越粗。首页与创作者列表一直是这个精度,此改动只是让合集列表与它们一致
播放:显示「已收藏」/「已下载」
- 「已收藏」补齐了此前失效的场景
- 新增下载态六档文案(
已加入下载队列/下载中 N%/下载中/下载已暂停/下载失败/已下载),随task_changed实时联动 - 字幕数量改为
字幕 N 个,为 0 时显示无字幕
播放:进入播放时的窗口状态
- 新增配置项进入播放(窗口 / 全屏),默认「窗口」保持现有行为
- 全屏在
mpv.load()成功之后才切换——加载失败时不会把用户丢在一个全屏的黑屏里
字幕
修复:中文字幕报 HTTP 429
选 English 正常,选中文报「字幕加载失败:HTTP Error 429」,换其他中文轨同样失败。根因是 YouTube 的中文轨大多是机器翻译轨(地址形如 …&kind=asr&lang=en&tlang=zh-Hans),由翻译接口按请求现场生成,配额按 IP 计且远紧于原文轨;原文轨走的是另一条已缓存的路径,所以英文永远正常。实测去掉地址里的 &tlang= 即返回 200,yt-dlp 自己取同一条轨也是 429——不是本程序的请求头、代理或 Cookie 问题。
- 字幕下载套一层重试:429 与 5xx 最多 3 次,退避优先听服务端
Retry-After,否则 1.5s × 次数并加抖动,以 8s 封顶——服务端给几百秒时不陪它死等 - 401/403/404 不重试,直接换成「签名可能过期,请重新解析该视频」
- 重试仍失败时给的是能照着做的一句话:点名「这条是机器翻译字幕」「建议改选原文字幕(如 English),或等一两分钟再试」
- 轨道标签加「机翻」后缀,让用户在点之前就能看出哪几条走的是紧配额通道
- 明确不做:不在 429 时静默回退到原文轨。用户要的是中文,给英文属于答非所问
排查:YouTube 视频取不到字幕
用户报「YouTube 没有字幕」,实测取证结论是主因不在程序——那几个视频在 YouTube 侧确实没有任何字幕轨。但排查暴露了一个 UX 缺口和几处真实缺陷:
- 无字幕时下拉框只剩一个「关闭」,用户无法区分「这个视频没字幕」与「程序坏了」。现在改为**「无可用字幕」并置灰**,meta 行显示「无字幕」。只做静默的可见性改善,不弹提示——绝大多数视频没字幕是常态
--write-subs/--write-auto-subs/--sub-langs/--sub-format四个参数在--dump-single-json下全是空转:它们只影响requested_subtitles与实际下载文件,对subtitles/automatic_captions两个原始字典没有任何过滤作用(实测--sub-langs zh-Hans,zh-Hant,zh,en之下automatic_captions依然返回全部 940 种语言)。也就是说youtube.subtitle_languages此前完全不起作用,还制造了「字幕已经配置好了」的假象。现已删掉这四个参数,并让该配置项真正决定字幕下拉的排序(未配置时回落到内置的中英文优先)SubtitleParser.PREFERRED_EXTS过窄是颗定时炸弹:只认srt/vtt/ass/ssa四种,_select_entry()没命中就返回None。当前 YouTube 必定提供 srt 所以安全,但一旦停供,全部字幕会在解析层被静默丢光,表现与本次一模一样且极难排查。现在按 mpv 兼容度把ttml/srv3/srv2/srv1/json3接在四种之后作回退,且格式完全没见过时也不再返回None——有内容就交给 mpv,最坏是它报一句加载失败,比字幕凭空消失好排查得多- 补「原始轨道数」的 debug 日志(
raw_manual/raw_auto/parsed):此前「站点没给」与「解析器全丢了」两种截然不同的故障产生完全相同的日志,本次是靠「某条日志不存在」这种反证才定位的
修复:多行提示框文字被裁掉
Toast.show_message() 把宽度夹到 420px 后仍按未换行的 sizeHint() 高度 resize,多行文案会被裁掉(实测长文案需 74px 只给了 60px)——上面那些「能照着做的一句话」写了也看不全。改为按夹取后的宽度用 heightForWidth() 重算;长文案(>40 字)显示时长从 3s 放宽到 8s。
Cookie:修掉「必须把 Firefox 设为默认浏览器才能读出」
用户报:能识别到 Firefox 但读不出来,只有把 Firefox 设为默认浏览器才行;手工指定非默认的 Firefox(已登录 YouTube)也失败。确认存在,且不止一个成因。
根因(config_service.detect_browser_cookie_source()):兜底直接取 detect_browser_cookie_sources()[0]。那份列表是排给用户看的,按「默认浏览器优先」排序。而 Chromium 系从 Chrome 127 起给 Cookie 库套了 App-Bound Encryption,yt-dlp 多半只报 Failed to decrypt with DPAPI;Firefox 的 moz_cookies.value 是明文,一向读得出来。于是默认浏览器是 Chromium 系时,兜底必然选中一个读不出 Cookie 的源——把 Firefox 设为默认就是把它挪到了 [0],这正是用户观察到的现象。本机取证:5 个候选逐个用 yt-dlp 抽取,只有 Firefox 成功(308 条),两条 Chrome 报无法复制库、brave/edge 报 DPAPI 解密失败。
这条兜底的覆盖面比看起来大:首次启动(异步探测还没回)、探测失败、站点未命中三种情况都落到它。启动探测本身工作正常,所以平时看不出毛病,只在探测尚未落地的窗口期暴露。
- 新增
rank_cookie_sources(),按内核分档、档内保持原顺序,Firefox 优先。给用户看的下拉列表顺序一个字没动,改的只是程序自动挑选时的口径;已存的探测结果优先级不变,仍然压过排序 - 对齐三处「换浏览器重试」的候选顺序,它们此前都按发现顺序试,把可用的 Firefox 压在几个读不出来的 Chromium 后面。其中
youtube_resolver._alternate_cookie_browsers()另有一处独立缺陷:current用auto_cookie_browser()(默认浏览器)算,而自动模式下真正用出去的是auto_cookie_browser_for_site()(按站点探测的结果),两者不一致时已经失败过的那个源会被当成新候选再试一遍
连带修复:WAL 与 profile 发现范围
Cookie 库是 WAL 模式,读法不对会读到旧快照。 探测与读取两处都只复制主库,前者还用 immutable=1 打开。构造「写入未 checkpoint」的库实测:
| 复制方式 | 打开方式 | 结果 |
|---|---|---|
| 只拷主库 | mode=ro&immutable=1 |
连表都不存在 |
| 只拷主库 | mode=ro |
连表都不存在 |
连 -wal/-shm 一起拷 |
mode=ro&immutable=1 |
连表都不存在(immutable 直接无视 WAL) |
连 -wal/-shm 一起拷 |
mode=ro |
正常读到 |
即两处必须同时改才有效。Firefox 正在运行时,刚登录的 Cookie 就在 -wal 里——这是常态,不是边角情况。直接打开源库那条兜底路径仍保留 immutable=1:此时库多半正被独占,那是唯一还能读出点东西的方式。
profile 发现只扫 %APPDATA%\Mozilla\Firefox\Profiles,三处各写了一遍同样的逻辑,都有两个洞:Microsoft Store 版 Firefox 的数据被重定向到 %LOCALAPPDATA%\Packages\Mozilla.Firefox_*\...,完全看不见;多 profile 时顺序随 iterdir() 波动,而「哪个 profile 在用」只有 profiles.ini 知道([Install*] 段的 Default= 比 [Profile*] 的 Default=1 可靠——后者是传统标记,装过多个版本后常已不是实际在用的那个)。
- 抽出
services/firefox_profiles.py(仅依赖标准库),三处共用;Store 版的 profile 以绝对路径下发(yt-dlp 会把裸目录名拼到%APPDATA%下扑空)。这也是「指定非默认 Firefox 失败」最可能的成因
列表与收藏
- 播放列表页与两侧播放器浮层去掉「加载」按钮,切换下拉即加载;浮层加载不再跳页
- 随之新增
NoScrollComboBox:未聚焦时忽略滚轮。原本滚错了再点一次就好,现在滚一下就直接换掉整个列表,而浮层里的下拉紧邻可滚动的长列表,用户滚列表时极易扫到它——这层防护是「切换即加载」的前置条件 - 收藏页新增下载选中 / 下载全部 / 删除选中 / 删除全部。「全部」的口径是当前搜索筛选后可见的行(与下载页一致),按钮提示会点明数量;删除前确认并说明已下载的本地文件不会被删除
其他
- 设置页「默认首页」改名「网站选择」,两个站点后补一条备注说明。配置键
content.default_home未变
已知遗留
- 系统语言探测错误时的自查入口只有设置页「默认音轨语言」首项括号里的探测结果
- 以下不做:本地文件内部音轨选择、无缝切轨(仍走重载)、把码率变体当音轨、DRC 单列、按视频记忆音轨选择
升级说明
Windows 安装版与便携版可直接在「关于」页检查更新。Fedora 用户通过 COPR 升级:
sudo dnf upgrade tube-ultimate-playerTube_Ultimate_Player 0.2.23
v0.2.23
0.2.23 的重点是浏览体验与稳定性:工具栏可直接切换视频网站并复用首页结果,修掉了启动与切站时的闪退,并补上 Chrome/Edge 新版 Cookie 加密的解法。发布侧新增 Windows ARM64 产物。本轮全量单测从 366 项增至 442 项。
浏览:站点切换与首页缓存
- 工具栏搜索框前新增 BiliBili / YouTube 单选,默认 BiliBili。切换即跳转对应站点首页;搜索框里有关键词时则按新站点重新搜索
- 这里选的站点只作用于当前会话的浏览行为,不再受「默认首页」配置项影响,也不写回配置
- 首页结果按站点留档(TTL 5 分钟,含页码与「还有下一页」状态),来回切站直接从内存重绘,不再每次重新拉取。显式「刷新」以及保存设置(Cookie/代理可能已变)会作废留档
HomeWorker/SearchWorker的目标站点在提交任务时就固定下来。此前 worker 自己去读当前选择,用户在加载途中切站就会拿到切换后的值,结果与发起时的意图对不上- 修复解析层缓存串站:缓存指纹此前固定取「默认首页」站点,而两个站点的 Cookie 文件并不相同;现在指纹跟随实际请求的站点
- 修复 YouTube 首页与搜索卡片没有日期:
--flat-playlist的条目默认不带日期,现在附带youtubetab:approximate_date,把页面上的「N 天前」折算回时间戳(天级精度,够卡片展示)
稳定性:修复启动与切站闪退
根因是线程池任务在信号送达前就被回收。QThreadPool.start() 之后 C++ 侧接管 worker 的销毁,但 Python 包装对象和它持有的 signals(QObject)没有别的引用。跨线程排队的信号还没投递,发送者就先没了。
日志里对应两种症状:一是静默丢结果——只有 home worker success / search worker success,却没有配套的界面刷新记录;二是进程直接消失——日志在会话中途截断,没有正常的关闭记录。
- 统一改由
_start_worker()提交任务,登记引用直到finished回到主线程才释放,13 处任务提交点全部走它 - 实测连接方式决定存活率(200 次提交、不保留引用):绑定方法 200/200,
partial7/200,lambda2/200。首页与搜索恰好用的是partial,所以偏偏是它们最容易掉 - 5 处
finished的 lambda 连接改成带关闭守卫的具名槽,退出流程中不再被派发 - 修复首页/搜索缓存被多个 worker 线程无锁读写(作者列表缓存一直是有锁的),补上独立的锁
Cookie:支持 Chrome 127+ / 新版 Edge 的 App-Bound 加密
Chrome 127+ 与新版 Edge 用 App-Bound Encryption 存 Cookie(值以 v20 打头),密钥被浏览器的 IElevator 提权服务包了一层,yt-dlp 走 DPAPI 必然报 Failed to decrypt with DPAPI。换浏览器、退回 Cookie 文件都救不了纯 v20 的浏览器。
- 新增 Cookie 解密回退:自行走 IElevator 解出 Cookie,导出成 Netscape
cookies.txt交给 yt-dlp - 解密永远在独立子进程里做:这个 COM 调用有可能直接让解释器崩溃,隔离后崩了也不影响主程序。超时、非零退出、缺依赖等任何异常都回退空结果,继续走原有的 Firefox / Cookie 文件链路,不会比原先更差
- 绝不强行关闭用户的浏览器进程:Cookie 库被独占时只尝试读副本,失败即放弃
- 播放解析、播放列表、首页、搜索、作者视频列表与下载链路都接上了这条兜底
- 冻结后的 exe 没有独立解释器,子进程通过
--extract-chromium-cookies哨兵参数复用自身,在导入 Qt 之前就拦下,不会拉起第二个界面 - 新增依赖
cryptography>=42.0
Cookie:识别被设为系统默认的便携版浏览器
此前候选列表只来自标准安装路径,系统默认浏览器仅用于排序和挂「默认浏览器」标签,不参与找库。便携版因此贡献不了任何候选,结果是静默指错人:默认浏览器若是便携版 CentBrowser,其 ProgId 里含 chrome,「默认浏览器」标签就被贴到几乎没用过的安装版 Chrome 上,用户照着选,yt-dlp 去读那个空 profile,返回空结果还不报错。
- 顺着
HKCR\<ProgId>\shell\open\command取默认浏览器的真实 exe 路径(纯注册表读,不需提权),按 exe 名判内核,再按 5 种常见便携布局反推 profile 目录(exe 同级/上级的User Data、PortableApps 的Data\profile,Firefox 另有一套) - 命中的便携版以绝对路径下发并排在候选最前;同内核的安装版仍会列出,但不再冒充「默认浏览器」
- Cookie 解密子进程支持绝对路径 profile。密钥必须从该 profile 自己的
Local State读——混用安装版的 AES 密钥会导致整批解不开
已知限制:设置页还没有「手动指定 profile 目录」的入口,便携布局千奇百怪,启发式规则总有漏网;纯便携 Chromium 若用 v20 加密又没注册 elevation service,这条链路仍救不了。
下载
- 下载改用专用线程池,容量跟随「同时下载数」设置并可运行时调整。此前下载与解析/搜索/投屏共用全局线程池(容量等于 CPU 核数),下载 worker 会长时间占线程,把「同时下载数」设得比核数大时,后续任务永远排不到线程
- 退出时下载池自行等待收敛,避免子进程终止前就继续往下走
发布与更新
- 新增 Windows ARM64 安装版与便携版产物。ARM 上以 x64 模拟方式运行(aarch64 的 mpv 缺 OpenGL/ANGLE,本应用的 gpu-next 渲染暂时无法原生跑在 ARM64)
- 所有 Windows 产物文件名带架构后缀:
win_x86_64/win_arm64
升级前先探测运行环境,并在「关于」页展示
同一个发布里第一次同时存在两种架构的安装包,挑错包的代价是安装程序直接拒绝执行,弹出 This program does not support the version of Windows your computer is running——这句提示指向系统版本,与真正的病因(架构不符)毫无关系,很容易把人带偏。所以这一版把架构探测提到台面上:
- 「关于」页新增系统环境一行,进页面即显示,形如
Windows 11 (10.0.26100) · CPU arm64 · 本程序 x86_64(模拟运行)。升级包就按这里显示的架构挑,用户能先看到判断依据,再决定要不要升 - 宿主机架构优先问
kernel32!IsWow64Process2——它是唯一能如实报出宿主机型号的接口,ARM64 机器上跑 x64 进程时会明确返回 ARM64;取不到再退回PROCESSOR_ARCHITEW6432/PROCESSOR_ARCHITECTURE与platform.machine() - 展示与挑包用的是两个值:展示的是本机 CPU,挑包用的是当前进程架构。x86_64 版在 ARM 机器上模拟运行时应继续更新到 x86_64 版,换过去会把用户挪到另一套安装体系上。两者不同即标注「模拟运行」
- Windows 11 的
platform.release()仍可能报10,按内部版本号(≥ 22000)纠正后再显示
修复:本机架构没有对应包时会装上另一架构的包
- 资产筛选此前写成「按架构过滤,过滤空了就退回全量」。GitHub Releases API 返回的资产按文件名排序而非上传顺序,
arm64排在x86_64前面,于是本机架构缺包时,x64 机器稳定拿到 ARM64 安装包 - 现在过滤空了只退回无架构标记的旧资产,绝不跨架构退回。一个都匹配不上时如实告知「该版本没有提供 <架构> 架构的升级包,已停止升级」,而不是含糊地报「已是最新」
- Linux 的
.deb/.appimage同样按本机架构收紧:宁可不给包,也不给一个跑不起来的异架构包 - 加一道兜底:安装包启动前先核对架构,不符就中止并说明真实原因,而不是让安装程序弹那句与病因无关的系统版本提示。判定看两处——文件名的架构标记与 PE 头机器类型,任一不符即拦。ARM64 机器可模拟跑 x86_64/x86 包,反向不成立,判定按此放行;两处都读不出(无架构标记的旧资产、非 PE 文件)时放行,不给正常升级添堵
- 这里必须看文件名而非只看 PE 头:本项目的 Inno Setup 安装程序外层是 32 位 x86 引导壳,两种架构的包 PE 机器类型都是
x86,真正拒绝执行的是.iss里的ArchitecturesAllowed=arm64,这一层从 PE 头看不出来。只读机器类型会原样放行 ARM64 包 - 补 17 项单测,其中
test_missing_arch_never_falls_back_to_the_other_arch钉住资产挑选的回归点,test_arm64_installer_is_rejected_on_x64_despite_a_32bit_stub钉住 32 位引导壳这个坑
其他
- 播放列表的自动连播改为默认不勾选(此前默认勾选):新建播放列表、数据库默认值与播放器面板一致,自动识别的作者播放列表沿用用户当前的勾选状态
- 修复设置页「安装 FFmpeg」失效:gyan.dev 只保留当前版本,原先钉住的 8.0.1 归档已被上游清掉,点安装必然 404。现改为 9.0(校验值经本机下载复算确认)。发布流程里取 FFmpeg 改用版本无关的 release 别名,不会再随上游发版而断
升级说明
Windows 安装版与便携版可直接在「关于」页检查更新。Fedora 用户通过 COPR 升级:
sudo dnf upgrade tube-ultimate-playerTube_Ultimate_Player 0.2.22
v0.2.22
0.2.22 修掉了投屏与 Cookie 两条链路上一批真实可复现的缺陷,并新增六项日常功能增强。本轮全量单测从 213 项增至 366 项。
DLNA 投屏
- 修复投屏时进度条在「投屏起始点」与「真实位置」之间反复跳动 —— 投屏期间本地 mpv 只是被暂停,属性轮询仍在无条件上报被冻结的位置,与远端轮询同时驱动面板
- 修复投屏中途未播完就中断、以及后段只有画面没有声音:两者是同一根因的两面。分离音视频投屏时 FFmpeg 开两路独立 HTTP 输入,视频路提前结束就是整个流结束,音频路提前结束则只剩画面。现在两路输入都带重连与读超时,并加上
-max_muxing_queue_size避免缓冲溢出导致的退出 - 单文件直投路径新增按
Range续传(最多 3 次) - 三条取流路径统一发送
contentFeatures.dlna.org,DIDL 元数据补上 DLNA 标志位与视频时长 - 取流令牌改为滑动续期、基础有效期提到 2 小时 —— 原本 30 分钟一到,电视重新发起请求就会拿到 404,长视频必然中断
- 转封装结束无条件记录一条摘要:收尾原因(电视断开 / FFmpeg 正常结束 / FFmpeg 报错)、退出码、已转发字节、耗时、最后的
out_time与 FFmpeg 输出
字幕
- 修复 Bilibili 字幕全部拿不到:yt-dlp 把 B 站 AI 字幕的 SRT 正文内联在
data字段而不给 URL,原实现只收带 URL 的条目,六条 AI 字幕因此全被丢弃,只剩弹幕能通过筛选,选中后又报「不支持的 XML 字幕」 - 弹幕轨在解析阶段就被排除,不再出现在字幕列表里
- YouTube 支持全量枚举:手动字幕与自动字幕(含机翻到各语言)全部可选
- 字幕标签改为可读形式(
中文(台湾)[zh-TW] · 字幕、中文 [ai-zh] · AI 字幕),按「手动优先 → 中英文优先」排序 - 下拉框列出常用的前 12 条,其余通过「更多字幕…」打开完整列表,可按语言名或语言代码搜索
- 字幕改为先下载到本地再交给 mpv:B 站字幕没有 URL 只能这样用,YouTube 的签名地址与 B 站 aisubtitle 地址交给 mpv 内部 HTTP 容易被拒,本地下载可复用应用的代理与请求头
Cookie
- 修复空 Cookie 文件导致首页整体失败:0 字节的 Cookie 文件被当作已配置,排在浏览器 Cookie 之前,并抛出「Cookie 文件格式不正确」。现在文件不存在、空、只有空白或只有注释都视为未配置,请求自然回退到浏览器 Cookie
- 「自动检测」改为按站点挑选确实登录过该站点的浏览器,Bilibili 与 YouTube 可以分别落在不同浏览器上。判断登录态只读 Cookie 的 host 与 name 列(明文),不读也不解密 value
- 运行中的 Chromium 会独占 Cookie 库,读不到不等于没登录 —— 现在会明确提示「浏览器正在运行,关闭后可重新检测」,设置页也新增「重新检测」按钮
- 探测优先选择 Firefox:Chrome 127+ / Brave / Edge 的 App-Bound Encryption 会让 yt-dlp 解不出 Cookie 值,而 Firefox 的值是明文
- 下载遇到
Failed to decrypt with DPAPI时自动换其它浏览器重试 —— 解析链路早有这个兜底,下载链路一直没有,于是出现「能播放但下载失败」 - 修复设置页保存时 Cookie 写入路径可能解析成当前目录(
PermissionError: '.'),并且一个文件写失败不再连带丢掉默认首页、代理等其余设置 - YouTube 返回空结果时不再静默:yt-dlp 对无效 Cookie 并不报错(退出码 0、条目为空),现在会换 Cookie 源重试,仍为空则给出指名 Cookie 来源的中文提示
功能增强
- 首页 / 搜索 / 播放列表 / 播放器显示视频更新时间(Bilibili 可得;YouTube 扁平列表常不返回日期,此时留空)
- 下载列表最新任务置顶
- 下载列表新增批量操作:暂停/启动/删除 × 选中/全部,「全部」按当前搜索筛选范围计算,删除前确认并说明本地文件不会被删除
- 鼠标滚轮可在视频区与控制面板背景上调节音量,复用键盘那套音量提示;音量滑块、下拉框与播放列表面板保留原生滚轮行为
- 「播放 URL」面板新增最近播放历史(上限 20 条),可单击填入、双击直接播放、右键删除或清空
- 下载进度条不再每秒回跳:yt-dlp 的进度模板给的是单文件百分比,与按字节算的整体进度交替上报导致来回跳,现在统一为单调递增的整体进度
其他
- 封面请求关闭 HTTP/2,消除控制台里的
qt.network.http2: stream N error—— 一屏几十张封面复用到一条连接时图片 CDN 会重置流 - Qt 自身的分类日志改为收进
logs/app.log,不再只打到控制台 - 修复单元测试会写入真实运行目录(配置、Cookie、下载任务),并加了守卫用例
升级说明
Windows 安装版与便携版可直接在「关于」页检查更新。Fedora 用户通过 COPR 升级:
sudo dnf upgrade tube-ultimate-player