拓冰建站拓冰建站
首页 / 资讯中心 / 正文

OmniGet架构解析:如何用Tauri 2 + Rust + SvelteKit构建跨平台下载应用

OmniGet架构解析如何用Tauri 2 Rust SvelteKit构建跨平台下载应用【免费下载链接】omnigetDownload Udemy and Hotmart courses, YouTube videos, music and books — 1,800 sites, no terminal. Free open-source desktop app for Windows, macOS and Linux, with a built-in course player, PDF/EPUB reader and music library. Powered by yt-dlp. Your files stay on your computer.项目地址: https://gitcode.com/GitHub_Trending/om/omnigetOmniGet 是一款免费的开源跨平台下载应用支持 Windows、macOS 和 Linux能下载 YouTube 视频、Udemy/Hotmart 在线课程、音乐和电子书覆盖 1,800 网站且无需终端。它底层由 yt-dlp 驱动用Tauri 2 Rust 后端 SvelteKit 前端三层架构构建。本文将带你拆解这套架构它为什么比 Electron 更轻前后端如何分工下载引擎又是怎么调度上千个网站的一、技术栈全景一个应用三个大脑OmniGet 的仓库是一个Cargo Workspace pnpm Monorepo的混合结构前后端在同仓内协同开发层技术职责位置前端SvelteKit 2 Svelte 5 Vite界面、路由、状态管理src/routes/后端RustTauri 2 tokio 异步运行时下载引擎、队列、系统能力src-tauri/src/引擎打包托管的 yt-dlp FFmpeg1,800 站点的协议解析与合并自更新管理┌─────────────────────────────────────────────┐ │ 前端 SvelteKitWebView 渲染 │ │ 粘贴链接 → 预览卡片 → 质量选择 → 下载队列 UI │ └──────────────────┬──────────────────────────┘ │ invoke() 命令 / emit() 事件 ┌──────────────────▼──────────────────────────┐ │ Rust 后端Tauri 主进程tokio 异步 │ │ PlatformRegistry 路由 → 平台下载器 → 队列 │ └──────────────────┬──────────────────────────┘ │ 子进程调用 ┌──────────────────▼──────────────────────────┐ │ yt-dlp FFmpeg自更新、SHA256 校验 │ └─────────────────────────────────────────────┘为什么选 Tauri 2 而不是 Electron核心原因有三个体积小Tauri 复用系统的 WebViewWindows 用 WebView2、macOS 用 WKWebView不需要打包整个 Chromium安装包显著小于同类 Electron 下载器内存占用低Rust 主进程没有 V8 垃圾回收的开销常驻后台的下载队列更稳系统级能力原生全局热键、系统托盘、剪贴板、自启动都是 Tauri 插件一行初始化搞定见 src-tauri/src/lib.rs#L301-L326。整个应用的窗口配置、自动更新签名、omniget://协议注册等都在 src-tauri/tauri.conf.json 中声明。二、前端架构SvelteKit 如何组织界面前端是标准的 SvelteKit 项目路由即目录src/routes/page.svelte首页包含全知输入框Omnibox粘贴链接自动识别站点src/routes/downloads/page.svelte下载队列页展示实时速度、ETA 与合并阶段src/routes/settings/page.svelte分组式设置支持跨类别搜索。Svelte 5 响应式状态 Svelte Store界面状态没有用重型框架而是Svelte 5 的runes响应式 官方 Store管理。以下 Svelte Store 各自负责一块领域状态src/lib/stores/download-store.svelte.ts下载队列状态监听后端推送的进度事件src/lib/stores/settings-store.svelte.ts设置项的读写缓存src/lib/stores/media-preview-store.svelte.ts链接预览标题、封面、清晰度列表。组件按功能分子目录例如src/components/omnibox/里放输入框全家桶质量选择器 QualityPicker.svelte、批量下载 BatchDownload.svelte。前后端通信命令与事件前端不直接碰文件系统一切通过invoke()调用 Rust 命令反向数据则由后端emit()事件推给前端。例如 src/lib/rpc.ts 中前端调用rpc_set_source命令让 Rust 端更新正在播放信息进而驱动 Discord 在线状态。这个请求-响应 事件推送的双向模型是 Tauri 应用的标准骨架。三、核心架构平台注册表模式 ⭐这是 OmniGet 最值得学习的部分。面对 YouTube、Bilibili、Instagram、磁链等几十种下载逻辑完全不同的源它没有写一个巨大的if-else而是用了Trait 抽象 注册表路由。统一的平台下载器契约所有平台实现同一个异步 TraitPlatformDownloader定义在 src-tauri/omniget-core/src/platforms/traits.rs#L6-L17pub trait PlatformDownloader: Send Sync { fn name(self) - str; fn can_handle(self, url: str) - bool; // 我能处理这个 URL 吗 async fn get_media_info(self, url) - ResultMediaInfo; // 探测标题/格式/大小 async fn download(self, info, opts, progress) - ResultDownloadResult; }每个平台如 youtube.rs、tiktok.rs只需回答能否处理该 URL并实现下载彼此完全解耦。注册表按顺序匹配先注册者优先启动时主程序把全部下载器依次注册进 PlatformRegistry并注入全局AppState// src-tauri/src/lib.rs节选 let mut registry PlatformRegistry::new(); registry.register(Arc::new(platforms::gallerydl::GalleryDlDownloader::new())); registry.register(Arc::new(omniget_core::platforms::InstagramDownloader::new())); registry.register(Arc::new(omniget_core::platforms::YouTubeDownloader::new())); // …共 16 个下载器 registry.register(Arc::new( platforms::generic_ytdlp::GenericYtdlpDownloader::new(), // 兜底1800 站点 ));注意注册顺序是有讲究的见 src-tauri/src/lib.rs#L226-L255批量列表抓取器Gallery-DL必须排最前否则会抢走 Twitter 主页、Reddit 子版块这类单帖下载器也能匹配的 URL最后的GenericYtdlpDownloader是兜底任何前面都没认领的 URL 直接交给 yt-dlp这正是1,800 站点能力的来源——OmniGet 自己只精写了头部平台的原生解析器长尾站点全部由 yt-dlp 承接。下载队列断点续传 指数退避下载任务进入 DownloadQueue它负责并发控制默认同时下载 2 个任务见 src-tauri/src/lib.rs#L261断点续传队列状态持久化到磁盘WAL重启后hydrate_from_history()恢复未完成任务重试退避站点限流429时自动退避重试而不是直接报错真实速度/ETA数据直接来自下载器即使文件大小未知或直播流也能准确显示停滞就显示为停滞不会假装还剩 3 秒。四、yt-dlp 引擎管理自更新 自适应并发OmniGet 把 yt-dlp 当作托管二进制来管理逻辑集中在 src-tauri/omniget-core/src/core/ytdlp.rs首次启动自动安装之后后台检查更新SHA256 校验后才允许执行保证供应链安全所有用户设置字幕语言、SponsorBlock、限速、User-Agent…通过一组闭包注入到 yt-dlp 参数构造中见 src-tauri/src/lib.rs#L439-L581Rust 端完全掌握调用时机。一个精妙的设计是自适应并发实现在 src-tauri/omniget-core/src/core/adaptive_concurrency.rs。它不让你手工填并发数而是按 CDN 拥塞控制思路慢起步、快回退实测每个域名的吞吐来动态调整并发参数上限 16、下限 1避免盲目高并发触发 429。五、插件系统Rust 动态库热加载 课程下载、Telegram 浏览器、格式转换这些大功能其实都不是主程序写的而是插件——独立的 Rust 动态库基于 omniget-plugin-sdk 开发。加载机制主程序用libloading在运行时加载.dylib/.so/.dll由 plugin_loader.rs 管理生命周期宿主接口实现在 plugin_host.rs零配置体验插件随应用首次启动自动安装、有新版自动更新用户可在设置里开关或卸载且删掉的不会再回来第三方生态官方提供插件开发指南 docs/plugin-development.md覆盖清单格式、宿主 API 和 ABI 兼容性注意事项。六、Cargo Workspace把下载引擎编译给多个宿主注意 src-tauri/Cargo.toml#L1-L3 中的 Workspace 成员——这套 Rust 代码不只服务于桌面应用Crate作用omniget-core平台无关的下载核心平台下载器 引擎封装被桌面 App 与 CLI 复用omniget-plugin-sdk插件开发用的 Trait 与宿主 API 定义omniget-cli命令行工具让 OmniGet 可被脚本/定时任务调用omnidisc-proto/omnidisc-media/omnidisc-mls内置Omnidisc社交模块的协议、媒体与端到端加密层这种核心引擎独立成 Crate的分层让 omniget-cli支持omniget download url -q 1080、批量下载等几乎零成本地复用了与 GUI 完全相同的下载逻辑。七、本地开发与构建 开发环境需要 Rust、Node.js 18 和 pnpmgit clone https://gitcode.com/gh_mirrors/om/omniget cd omniget pnpm install pnpm tauri dev # 前端热更新 Rust 自动重编译 pnpm tauri build # 产出各平台安装包几个工程细节值得借鉴单实例锁第二次启动时命令行里的 URL 会被转发给已运行的实例src-tauri/src/lib.rs#L274-L292便携模式在 exe 旁创建portable.txt全部数据含 WebView 数据目录都收敛到应用旁边U 盘即走即用CI 冒烟测试OMNIGET_SMOKE_EXIT_MS环境变量让应用在 CI 中打开窗口即自退验证能启动这件编译无法证明的事。八、总结这套架构能学到什么Tauri 2 SvelteKit 是轻量级跨平台桌面应用的务实组合系统 WebView Rust 主进程安装包小、内存低系统能力靠插件生态补齐注册表模式驯服多源下载一个can_handle(url)契约 有序注册新增平台零改动主流程兜底下载器让长尾站点白嫖 yt-dlp引擎托管而非捆绑yt-dlp/FFmpeg 自更新 哈希校验把网站更新导致脚本失效的痛点变成后台静默自愈Cargo Workspace 一份核心多宿主复用GUI 和 CLI 共享同一套omniget-core插件通过 SDK 与宿主解耦。如果你想给 OmniGet 贡献一个新平台下载器只需要在 src-tauri/omniget-core/src/platforms/ 里新建一个文件实现PlatformDownloader再注册进PlatformRegistry——这就是这套架构留给你的第一个入口。【免费下载链接】omnigetDownload Udemy and Hotmart courses, YouTube videos, music and books — 1,800 sites, no terminal. Free open-source desktop app for Windows, macOS and Linux, with a built-in course player, PDF/EPUB reader and music library. Powered by yt-dlp. Your files stay on your computer.项目地址: https://gitcode.com/GitHub_Trending/om/omniget创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
分享:

看完干货,该让你的企业上线了

免费需求沟通 · 48 小时内出具建站方案 · 河南本地可上门