断点续传与智能去重
任务被手动停止后,重新启动队列即可继续发送:已发送的弹幕不会重复发送,其余弹幕按原顺序继续。网络中断与程序退出不属于这种情况,需要重新创建任务,见下文「使用场景」。
工作原理
程序在本地 SQLite 数据库中记录每条弹幕的发送结果。发送前查询数据库,判断该弹幕是否已发送:
待发送弹幕 → 生成五维指纹
│
▼
查询本地数据库 (history.db)
│
┌───────────┼───────────┐
▼ ▼
已存在记录 无记录
(指纹+视频匹配) │
│ ▼
▼ 正常发送
跳过
不消耗延时等待
被跳过的弹幕不消耗发送间隔,因此中断位置越靠后,重新启动后前段的处理速度越快。
匹配规则(五维指纹)
程序通过「五维指纹」判断两条弹幕是否完全一致,而非仅比对文本:
| 维度 | 字段 | 说明 |
|---|---|---|
| 1 | msg |
弹幕文本内容 |
| 2 | progress |
出现时间(毫秒级精度) |
| 3 | mode |
弹幕模式(滚动/底部/顶部) |
| 4 | fontsize |
字号大小 |
| 5 | color |
颜色值 |
仅当五维指纹完全相同,且目标视频(BV 号 + 分 P 的 cid)也相同时,才判定为重复。
因此「同一时间、同一内容但样式不同」的弹幕不会被误判为重复。例如一条白色滚动弹幕与一条彩色顶部弹幕属于两条独立弹幕,均会正常发送。
限制
不防止漏发。 该机制仅拦截重复发送。若删除了尚未发送的弹幕,或中途更换 XML 文件,程序不会自动补发。
不保存队列。 程序退出后,队列、进度与任务列表一并丢失,因此无法直接重新启动队列。此时需使用同一个 XML 文件重新创建任务,由上述查重机制跳过已发送部分。崩溃恢复暂未提供,队列落盘与崩溃恢复计划在 2.7.0 实现。
不自动重试发送失败的弹幕。 失败的弹幕会保留,等待用户修正或删除——它们可能本身存在问题,重发仍会失败。
需要重复发送时
默认情况下,已发送的弹幕会被跳过。若确实需要重复发送同一批弹幕:
- 打开「全局设置」,进入页面底部的危险区
- 勾选允许重复发送
启用后发送前不再比对数据库,已发送的弹幕会被再次发送到同一视频,视频中会出现重复弹幕。使用完毕后请关闭该选项。
使用场景
场景 1:手动停止后继续
发送 500 条弹幕至第 200 条时点击了「停止队列」。
操作:再次点击「启动队列」。
结果:前 200 条已在数据库中记录,被跳过;从第 201 条继续发送,视频中不会出现重复弹幕。
场景 2:网络中断
发送至第 200 条时网络中断。程序会继续处理剩余弹幕,无法发出的逐条记为未发送成功;该任务不会留在待发状态,重新启动队列不会再处理它。
操作:使用同一个 XML 文件重新创建任务,然后启动队列。若只需补发缺失的部分,可先导出未发送成功的弹幕,修改后另建任务。
结果:与场景 1 相同,已发送的 200 条被跳过。
场景 3:程序异常退出
发送至第 200 条时程序异常退出。队列不会保存,任务列表为空。
操作:使用同一个 XML 文件重新创建任务,然后启动队列。
结果:与场景 1 相同,已发送的 200 条被跳过。
场景 4:重复导入同一 XML
此前已在某个视频上发送过一批弹幕,现在使用同一个 XML 文件再次创建任务。
操作:正常启动队列。
结果:与已有记录匹配的弹幕被跳过,仅发送尚未发送的部分。
查看跳过记录
发送过程中,日志面板会为每条被跳过的弹幕记录一行:
⏭️ [跳过] 已发送 (1/2): 今天天气不错
括号内为「本次发送序列中的出现次序 / 数据库中已有条数」。
任务结束时日志输出汇总:
--- 发送任务结束 ---
总计: 500 | 成功: 180 | 跳过: 17 | 失败: 3
「总计」为该任务的弹幕总数,其余三项只统计已处理的弹幕——本例处理到第 200 条(180 + 17 + 3)。未轮到发送的弹幕不计入这几项,归入「未发送成功」,见下文。
导出未发送成功的弹幕
被跳过的弹幕不在导出范围内,它们已成功发送。导出包含两类:发送失败的弹幕,以及未轮到发送的弹幕(因手动停止)。二者合称「未发送成功」。
队列执行结束后,若存在未发送成功的弹幕,程序会弹出确认对话框:
有 N 条未发送成功,分布在 M 个任务。要导出吗? 每个任务导出一个 XML,可修改后重新导入。
- 是:选择导出目录,每个任务生成一个
{原文件名}_Unsent.xml,仅含该任务未发送成功的弹幕。 - 否:不执行导出。
导出的 XML 可修改后重新导入以创建新任务。也可在队列表格中右键单个任务,仅导出该任务的未发送弹幕。