视频播放进度同步:Kazumi 多设备间进度共享实现
你是否遇到过这样的困扰:在手机上看番看到一半,切换到电脑端继续观看时,却发现播放进度需要重新查找?Kazumi 的视频播放进度同步功能彻底解决了这一问题,让你在多设备间无缝接续精彩剧情。本文将详细介绍 Kazumi 如何通过 WebDAV 协议实现播放进度的跨设备同步,以及背后的技术实现细节。
同步功能架构概述
Kazumi 的进度同步功能基于 WebDAV(Web-based Distributed Authoring and Versioning)协议实现,通过将本地播放历史数据加密存储到 WebDAV 服务器,实现多设备间的数据共享。核心实现涉及两个关键模块:
- WebDAV 客户端实现:lib/utils/webdav.dart
- 本地存储与数据处理:lib/utils/storage.dart
这两个模块协同工作,完成数据的备份、恢复和冲突解决,确保各设备间的播放进度保持一致。
数据同步实现原理
WebDAV 客户端核心实现
Kazumi 的 WebDAV 客户端封装在 WebDav 类中,位于 lib/utils/webdav.dart。该类实现了与 WebDAV 服务器的通信,包括初始化连接、数据上传、下载和同步等功能。
初始化连接的关键代码如下:
Future<void> init() async {
var directory = await getApplicationSupportDirectory();
webDavLocalTempDirectory = Directory('${directory.path}/webdavTemp');
Box setting = GStorage.setting;
webDavURL = setting.get(SettingBoxKey.webDavURL, defaultValue: '');
webDavUsername = setting.get(SettingBoxKey.webDavUsername, defaultValue: '');
webDavPassword = setting.get(SettingBoxKey.webDavPassword, defaultValue: '');
if (webDavURL.isEmpty) {
throw Exception('请先填写WebDAV URL');
}
client = webdav.newClient(
webDavURL,
user: webDavUsername,
password: webDavPassword,
debug: false,
);
client.setHeaders({'accept-charset': 'utf-8'});
try {
await client.ping();
try {
await client.mkdir('/kazumiSync');
if (!await webDavLocalTempDirectory.exists()) {
await webDavLocalTempDirectory.create(recursive: true);
}
initialized = true;
KazumiLogger().log(Level.info, 'webDav backup directory create success');
} catch (_) {
KazumiLogger().log(Level.error, 'webDav backup directory create failed');
rethrow;
}
} catch (e) {
KazumiLogger().log(Level.error, 'WebDAV ping failed: $e');
rethrow;
}
}
这段代码首先从本地存储中读取 WebDAV 服务器配置信息,然后创建 WebDAV 客户端并测试连接。成功连接后,会在服务器上创建一个名为 kazumiSync 的目录,用于存储同步数据。
播放历史数据同步流程
播放历史数据的同步主要通过 updateHistory 和 downloadAndPatchHistory 两个方法实现:
Future<void> updateHistory() async {
if (isHistorySyncing) {
KazumiLogger().log(Level.warning, 'History is currently syncing');
throw Exception('History is currently syncing');
}
isHistorySyncing = true;
try {
await update('histories');
} catch (e) {
KazumiLogger().log(Level.error, 'webDav update history failed $e');
rethrow;
} finally {
isHistorySyncing = false;
}
}
Future<void> downloadAndPatchHistory() async {
if (isHistorySyncing) {
KazumiLogger().log(Level.warning, 'History is currently syncing');
throw Exception('History is currently syncing');
}
isHistorySyncing = true;
String fileName = 'histories.tmp';
try {
final existingFile = File('${webDavLocalTempDirectory.path}/$fileName');
await download('histories');
await GStorage.patchHistory(existingFile.path);
} catch (e) {
KazumiLogger()
.log(Level.error, 'webDav download and patch history failed $e');
rethrow;
} finally {
isHistorySyncing = false;
}
}
updateHistory 方法负责将本地的播放历史数据上传到 WebDAV 服务器,而 downloadAndPatchHistory 方法则从服务器下载最新的历史数据,并与本地数据进行合并。
数据冲突解决策略
当多个设备同时修改播放进度时,可能会产生数据冲突。Kazumi 采用基于时间戳的冲突解决策略,总是保留最新的播放进度。这一逻辑在 lib/utils/storage.dart 的 patchHistory 方法中实现:
static Future<void> patchHistory(String backupFilePath) async {
final backupFile = File(backupFilePath);
final backupContent = await backupFile.readAsBytes();
final tempBox = await Hive.openBox('tempHistoryBox', bytes: backupContent);
final tempBoxItems = tempBox.toMap().entries;
for (var tempBoxItem in tempBoxItems) {
if (histories.get(tempBoxItem.key) != null) {
if (histories
.get(tempBoxItem.key)!
.lastWatchTime
.isBefore(tempBoxItem.value.lastWatchTime)) {
await histories.delete(tempBoxItem.key);
await histories.put(tempBoxItem.key, tempBoxItem.value);
}
} else {
await histories.put(tempBoxItem.key, tempBoxItem.value);
}
}
await tempBox.close();
}
这段代码会比较本地和远程历史记录的 lastWatchTime(最后观看时间),如果远程记录更新,则用远程记录覆盖本地记录,从而保证播放进度的准确性。
实际使用流程
配置 WebDAV 服务器
要使用 Kazumi 的进度同步功能,首先需要在设置中配置 WebDAV 服务器信息。这些配置项定义在 lib/utils/storage.dart 的 SettingBoxKey 类中:
static const String webDavEnable = 'webDavEnable',
webDavEnableHistory = 'webDavEnableHistory',
webDavEnableCollect = 'webDavEnableCollect',
webDavURL = 'webDavURL',
webDavUsername = 'webDavUsername',
webDavPassword = 'webDavPasswd',
用户需要提供 WebDAV 服务器的 URL、用户名和密码,Kazumi 会将这些信息安全存储在本地。
手动触发同步
除了自动同步外,用户还可以手动触发同步操作。同步功能的入口位于应用的设置页面,用户可以根据需要选择同步播放历史或收藏列表。
相关模块与文件
Kazumi 的进度同步功能涉及多个模块和文件,以下是核心组件的路径:
- WebDAV 客户端实现:lib/utils/webdav.dart
- 本地存储管理:lib/utils/storage.dart
- 历史记录数据模型:lib/modules/history/history_module.dart
- 收藏数据模型:lib/modules/collect/collect_module.dart
这些文件共同构成了 Kazumi 的多设备同步系统,确保用户在不同设备上都能获得一致的观看体验。
总结
Kazumi 通过 WebDAV 协议实现了播放进度的跨设备同步,解决了用户在多设备间切换时的播放进度接续问题。核心实现包括 WebDAV 客户端、数据同步逻辑和冲突解决策略,确保了数据的安全性和一致性。
通过本文的介绍,你已经了解了 Kazumi 进度同步功能的工作原理和实现细节。如果你对某个具体模块感兴趣,可以查看相应的源代码文件,深入了解其实现。
如果你在使用同步功能时遇到问题,可以参考项目的 README.md 或提交 issue 寻求帮助。Kazumi 作为一个开源项目,欢迎社区贡献代码和提出改进建议,共同完善这一功能。
GLM-5智谱 AI 正式发布 GLM-5,旨在应对复杂系统工程和长时域智能体任务。Jinja00
GLM-5-w4a8GLM-5-w4a8基于混合专家架构,专为复杂系统工程与长周期智能体任务设计。支持单/多节点部署,适配Atlas 800T A3,采用w4a8量化技术,结合vLLM推理优化,高效平衡性能与精度,助力智能应用开发Jinja00
请把这个活动推给顶尖程序员😎本次活动专为懂行的顶尖程序员量身打造,聚焦AtomGit首发开源模型的实际应用与深度测评,拒绝大众化浅层体验,邀请具备扎实技术功底、开源经验或模型测评能力的顶尖开发者,深度参与模型体验、性能测评,通过发布技术帖子、提交测评报告、上传实践项目成果等形式,挖掘模型核心价值,共建AtomGit开源模型生态,彰显顶尖程序员的技术洞察力与实践能力。00
Kimi-K2.5Kimi K2.5 是一款开源的原生多模态智能体模型,它在 Kimi-K2-Base 的基础上,通过对约 15 万亿混合视觉和文本 tokens 进行持续预训练构建而成。该模型将视觉与语言理解、高级智能体能力、即时模式与思考模式,以及对话式与智能体范式无缝融合。Python00
MiniMax-M2.5MiniMax-M2.5开源模型,经数十万复杂环境强化训练,在代码生成、工具调用、办公自动化等经济价值任务中表现卓越。SWE-Bench Verified得分80.2%,Multi-SWE-Bench达51.3%,BrowseComp获76.3%。推理速度比M2.1快37%,与Claude Opus 4.6相当,每小时仅需0.3-1美元,成本仅为同类模型1/10-1/20,为智能应用开发提供高效经济选择。【此简介由AI生成】Python00
Qwen3.5Qwen3.5 昇腾 vLLM 部署教程。Qwen3.5 是 Qwen 系列最新的旗舰多模态模型,采用 MoE(混合专家)架构,在保持强大模型能力的同时显著降低了推理成本。00- RRing-2.5-1TRing-2.5-1T:全球首个基于混合线性注意力架构的开源万亿参数思考模型。Python00