🎁 福利专区全网大模型免费应用 + 新用户福利 + 注册活动入口,低成本玩转 AI
DeepSeek Harness Hub

视频翻译配音 liuzhao1225/YouDub-webui

Cordis
liuzhao12251 天前有提交已提供中文文档扫描:含敏感能力

开源视频本地化工作台:导入视频,识别、翻译并逐句克隆原声,生成字幕和配音成片。

71.4/100
综合分
5,702
GitHub 星标
—
npm 周下载
—/5
用户评分

数据截至 2026/10/21 · 周下载取自 npm 全网(含 CI / 镜像),非本站安装数;综合分由星标、活跃度与兼容性检查合成。

安装命令 · 需先装 dsh CLI 引擎
dsh plugin --profile web add liuzhao1225/YouDub-webui
该包不可直接 npm 安装,改从 GitHub 源安装(原因见下方安装检查)

状态速览

判定依据:实装验证 · 静态安装检查 · 自动扫描 · 仓库维护状态
信任档位:需留意
是什么
dsh 原生插件 · platform
装得上吗
作者未把包发布到 npm,只能用源码安装
插件本身没问题,是分发方式不同
L4 · 真实安装等级说明 →
安全吗
本站尚未对该插件做风险分级
暂未覆盖,不等同于无风险
还在维护吗
活跃:最近一次提交在 1 天前
档位由哪些信号合成

本站实装验证(真实安装 L4 覆盖全站;L5 为运行时冒烟或实机截图,覆盖范围小于 L4) · 验证所用 dsh 版本 · 静态安装检查 · 风险分级 · 仓库维护状态。 下方各区块是它的证据明细。

验证判据与等级说明 →
社区实装还没有人打卡 · 装过的第一个就是你
安装兼容性检查需源码安装

缺少 main/exports/bin 入口声明;仓库 package.json 标记 private,未发布到 npm,需从源码安装

展开查看检查明细 ↓

以下结论由程序自动检查 npm 包、engines 声明与入口文件得出,未做人工实机验证——能装不等于用着没问题。

✗npm 包youdub-webui-fullstack(未发布到 npm,仅可源码安装)
✓Node 引擎要求 >=22.13.0 · 基线 Node 22.19 满足
✓dsh CLI 依赖未声明 dsh 版本约束
✗入口文件缺少入口声明

源码安装时若 pnpm 拦截 prepare 脚本,按其提示在 pnpm-workspace.yaml 的 allowBuilds 中放行后重跑。

验证方式:npm registry 存在性 + package.json 静态校验 · 最后检查 2026/10/16 02:43:58

安全扫描自动 · 静态分析源码
v2.7.0
🔵 扫描:含敏感能力尚无人工评估
展开查看扫描说明与证据 ↓

静态扫描发现插件具备触达本地系统的能力:执行外部命令、读写/删除本地文件、读取剪贴板或密钥类环境变量(至少其一)。这是能力清单,不是危险判定——具体能力项与证据见下方,安装前请自行判断是否需要。

可执行外部命令读写/删除本地文件发起外部网络请求
查看扫描证据(共 77 处,展示前 52 条)
  • 写入本地文件
    apps/desktop/server.mjs:15
    await mkdir(data, { recursive: true })
  • 执行外部命令来自配置/变量
    apps/desktop/server.mjs:52
    web = spawn(process.execPath, [join(process.cwd(), 'web/apps/web/server.js')], {
  • 发起网络请求
    apps/desktop/server.mjs:69
    const response = await fetch(webURL, { signal: AbortSignal.timeout(5000) })
  • 写入本地文件
    apps/host/src/bootstrap.ts:19
    await writeFile(configuration, JSON.stringify(entries, null, 2), { mode: 0o600 })
  • 删除本地文件递归
    apps/host/src/bootstrap.ts:41
    await exportLog(); await rm(directory, { recursive: true })
  • 删除本地文件递归
    apps/host/src/bootstrap.ts:53
    await exportLog(); await rm(directory, { recursive: true })
  • 读取本地文件
    apps/host/src/main.ts:11
    const entries = configPath.endsWith('.json') ? JSON.parse(await readFile(configPath, 'utf8')) : await (await import(pathToFileURL(configPath).href)).d
  • 写入本地文件
    packages/builtin/src/extensions.ts:27
    await mkdir(this.config.root, { recursive: true, mode: 0o700 })
  • 读取本地文件
    packages/builtin/src/extensions.ts:28
    try { this.installed = JSON.parse(await readFile(join(this.config.root, 'installed.json'), 'utf8')) }
  • 读取本地文件
    packages/builtin/src/extensions.ts:33
    if (this.config.builtinClientManifest) this.builtin = JSON.parse(await readFile(this.config.builtinClientManifest, 'utf8'))
  • 写入本地文件
    packages/builtin/src/extensions.ts:48
    private save() { return writeFile(join(this.config.root, 'installed.json'), JSON.stringify(this.installed, null, 2) + '\n', { mode: 0o600 }) }
  • 读取本地文件
    packages/builtin/src/extensions.ts:53
    if (item.python) { await confined(item.directory, item.python.entry); await lstat(join(item.directory, process.platform === 'win32' ? '.venv/Scripts/p
  • 写入本地文件
    packages/builtin/src/extensions.ts:70
    await writeFile(join(this.config.root, 'installed.json'), JSON.stringify(next, null, 2) + '\n', { mode: 0o600 })
  • 删除本地文件递归
    packages/builtin/src/extensions.ts:80
    await rm(item.directory, { recursive: true })
  • 写入本地文件
    packages/builtin/src/extensions.ts:95
    log.push(result.stdout, result.stderr); await writeFile(join(staging, 'install.log'), log.join('\n'), { mode: 0o600 }); return result.stdout
  • 写入本地文件
    packages/builtin/src/extensions.ts:96
    } catch (error) { log.push(String(error)); await writeFile(join(staging, 'install.log'), log.join('\n'), { mode: 0o600 }); throw error }
  • 写入本地文件
    packages/builtin/src/extensions.ts:99
    await mkdir(staging, { mode: 0o700 })
  • 读取本地文件
    packages/builtin/src/extensions.ts:116
    const source = await realpath(resolve(request.source.replace(/^file:/, '')))
  • 读取本地文件
    packages/builtin/src/extensions.ts:119
    const manifest = JSON.parse(await readFile(join(directory, 'package.json'), 'utf8'))
  • 读取本地文件
    packages/builtin/src/extensions.ts:127
    const shared = new Map([['cordis', await realpath(dirname(require.resolve('cordis/package.json')))], ['@youdub/sdk', await realpath(resolve(dirname(re
  • 写入本地文件
    packages/builtin/src/files.ts:17
    async [Service.init]() { await mkdir(this.root, { recursive: true, mode: 0o700 }) }
  • 写入本地文件
    packages/builtin/src/files.ts:25
    await mkdir(path.dirname(root), { recursive: true, mode: 0o700 })
  • 写入本地文件
    packages/builtin/src/files.ts:26
    try { await mkdir(root, { mode: 0o700 }) }
  • 写入本地文件
    packages/builtin/src/files.ts:43
    const directory = path.join(this.taskRoot(id), 'input'); await mkdir(directory, { recursive: true, mode: 0o700 })
  • 写入本地文件
    packages/builtin/src/files.ts:49
    } }), createWriteStream(destination, { flags: 'wx', mode: 0o600 }))
  • 写入本地文件
    packages/builtin/src/files.ts:56
    await mkdir(work, { recursive: true, mode: 0o700 }); return work
  • 读取本地文件
    packages/builtin/src/files.ts:60
    const base = await realpath(workDir), file = await realpath(path.resolve(base, descriptor.path))
  • 读取本地文件
    packages/builtin/src/files.ts:61
    const taskRoot = await realpath(this.taskRoot(id))
  • 读取本地文件
    packages/builtin/src/files.ts:63
    const info = await stat(file)
  • 读取本地文件
    packages/builtin/src/files.ts:66
    if (descriptor.mimeType === 'application/json') JSON.parse(await readFile(file, 'utf8'))
  • 读取本地文件
    packages/builtin/src/files.ts:76
    const root = await realpath(this.taskRoot(id)), file = await realpath(path.resolve(root, artifact.path))
  • 读取本地文件
    packages/builtin/src/files.ts:78
    const info = await stat(file)
  • 删除本地文件
    packages/builtin/src/files.ts:117
    } finally { await rm(temporary, { force: true }) }
  • 删除本地文件递归
    packages/builtin/src/files.ts:123
    async remove(id: string) { await rm(this.taskRoot(id), { recursive: true, force: true }) }
  • 读取本地文件
    packages/builtin/src/http.ts:120
    const info = await stat(path)
  • 读取本地文件
    packages/builtin/src/http.ts:147
    await pipeline(createReadStream(path, { start, end }), request.response)
  • 执行外部命令来自配置/变量
    packages/builtin/src/process.ts:38
    const child = spawn(request.command, request.args, {
  • 读取本地文件
    packages/builtin/src/setup-download.ts:9
    try { const info = await stat(path); return info.isFile() ? info.size : 0 }
  • 读取本地文件
    packages/builtin/src/setup-download.ts:14
    for await (const chunk of createReadStream(path)) hash.update(chunk)
  • 发起网络请求
    packages/builtin/src/setup-download.ts:27
    private agent = new Agent({ connect: { timeout: 30_000 } })
  • 写入本地文件
    packages/builtin/src/setup-download.ts:31
    await mkdir(dirname(target), { recursive: true })
  • 发起网络请求
    packages/builtin/src/setup-download.ts:42
    const response = await fetch(file.url, { dispatcher: this.agent, signal, headers: { 'Accept-Encoding': 'identity', ...(received ? { Range: `bytes=${re
  • 发起网络请求
    packages/builtin/src/setup-download.ts:42
    const response = await fetch(file.url, { dispatcher: this.agent, signal, headers: { 'Accept-Encoding': 'identity', ...(received ? { Range: `bytes=${re
  • 写入本地文件
    packages/builtin/src/setup-download.ts:64
    await rename(partial, target)
  • 读取本地文件
    packages/builtin/src/setup-environment.ts:21
    try { await access(path, constants.X_OK); return path }
  • 写入本地文件
    packages/builtin/src/setup-environment.ts:92
    await mkdir(dirname(constraints), { recursive: true })
  • 写入本地文件
    packages/builtin/src/setup-environment.ts:93
    await writeFile(constraints, `torch==${plan.version}\ntorchaudio==${plan.version}\ntorchcodec==${plan.codec}\n`)
  • 读取本地文件
    packages/builtin/src/setup-environment.ts:117
    const shared = !windows || (await readdir(dirname(path))).some(file => /^av.*\.dll$/i.test(file))
  • 写入本地文件
    packages/builtin/src/setup-environment.ts:122
    await mkdir(directory, { recursive: true })
  • 写入本地文件
    packages/builtin/src/setup-environment.ts:133
    await chmod(managed, 0o700)
  • 发起网络请求
    site/downloads.js:5
    const response = await fetch('./releases.json', { cache: 'no-cache' })
  • 发起网络请求
    site/player.js:108
    const response = await fetch(`./assets/${this.id}-${video.dataset.language}.mp4`)
扫描于 2026/10/21(0 天前) · 范围 全包扫描 · 来源 GitHub 仓库

静态扫描只反映源码中出现的调用,不构成安全背书;人工评估与自动扫描相互独立、互不覆盖。

给这个插件打分还没有人投票↓
用户评分
还没有人投票,来当第一个

界面预览

3 张 · 点击查看大图

开源 AI 视频本地化与配音工具,面向 YouTube/Bilibili:语音识别、字幕翻译、声音克隆、混音与渲染。

README

由 DeepSeek 最新模型翻译生成
YouDub WebUI 开源视频本地化工作台:导入视频,识别、翻译并逐句克隆原声,生成字幕和配音成片。 English · 官网与试听 · 下载最新版 · 安装与升级 · 社区交流 效果示例 默认演示为 2026-10-09 生成的黄仁勋采访:逐句原声克隆、中文字幕与背景音保留,完整时长约 59 秒。源视频链接用于说明样例出处,工作台支持视频链接和本地文件导入。 1. 黄仁勋采访 · 最新效果 原视频链接 · YouTube Shorts · 英文 -> 中文 原始英文中文配音版 https://github.com/user-attachments/assets/befd11ca-e720-4faa-b4e0-d89bfe73df87 https://github.com/user-attachments/assets/60d5dbb0-f346-4c14-adad-2d0c481ac4fb 2. 历史样例:How much YT paid me for 129 million shorts views 原视频链接 · YouTube 横屏长视频 · 英文 -> 中文 · 下方为开头 40 秒切片,完整版可在 demo-assets Release 下载 原始英文中文配音版
展开完整文档(README 剩余 1 节)
YouDub WebUI

开源视频本地化工作台:导入视频,识别、翻译并逐句克隆原声,生成字幕和配音成片。

English · 官网与试听 · 下载最新版 · 安装与升级 · 社区交流

效果示例

默认演示为 2026-10-09 生成的黄仁勋采访:逐句原声克隆、中文字幕与背景音保留,完整时长约 59 秒。源视频链接用于说明样例出处,工作台支持视频链接和本地文件导入。

1. 黄仁勋采访 · 最新效果

原视频链接 · YouTube Shorts · 英文 -> 中文

原始英文中文配音版

https://github.com/user-attachments/assets/befd11ca-e720-4faa-b4e0-d89bfe73df87

https://github.com/user-attachments/assets/60d5dbb0-f346-4c14-adad-2d0c481ac4fb

2. 历史样例:How much YT paid me for 129 million shorts views

原视频链接 · YouTube 横屏长视频 · 英文 -> 中文 · 下方为开头 40 秒切片,完整版可在 demo-assets Release 下载

原始英文中文配音版

https://github.com/user-attachments/assets/bd02936f-cf3c-4e4b-85b5-0410d38f69f5

https://github.com/user-attachments/assets/158de60a-7de4-4ddf-b3d8-478d0423aee6

3. Me at the zoo

原视频 · 英文 → 中文 · 19 秒

在官网切换中英文试听。v0.0.2 起,安装包包含这三个示例,可从工作台或环境准备页的“查看内置示例”离线播放。

能做什么

| 输出模式 | 生成内容 |
| 原声 + 字幕 | 保留原始音轨,生成并烧录目标语言字幕 |
| 配音 | 生成目标语言配音,可保留分离后的背景音 |
| 字幕 + 配音 | 输出带字幕的配音视频,可选语音强制对齐 |

- 逐句原声克隆。 每句译文使用对应原文句子的音频片段作为参考,保留句子与参考音频的一一对应关系。
- 字幕显示。 按逗号、顿号、中文破折号等拆分显示,合并过短片段,隐藏字幕片段末尾的分隔标点。
- 任务管理。 查看封面、步骤进度、错误和产物,支持取消、重试、重新生成、播放及下载。

工作台保留视频、语言和输出模式等基本选项;模型、设备、声音、字幕对齐、背景音默认值及服务连接统一在设置中管理。

界面预览

工作台:导入视频,选择语言和输出内容。

YouDub 工作台:视频导入、原文与目标语言、配音与字幕选项

查看任务库与任务详情

任务库:视频封面、处理状态和历史任务。

YouDub 任务库:视频封面与已完成任务

任务详情:成片预览、处理步骤、配音音频和字幕下载。

YouDub 任务详情:带中文字幕的成片、八个已完成步骤与生成文件

下载与使用

Windows EXE 安装包 · macOS DMG · 版本说明与便携包

首次启动需要下载运行环境和模型;安装要求与升级方法见安装指南。

1. 在「设置」配置翻译连接,确认所需模型就绪,保存默认处理配置。
2. 在「工作台」导入视频,选择语言和输出模式,创建任务。
3. 在「任务库」查看进度,播放或下载结果。

社区交流

QQ 交流群:618246010

快速开始

运行与扩展指南 · 插件开发契约 · 版本发布以下是从源码运行的步骤,命令面向 macOS / Linux shell。真实模型流程已在 macOS arm64 / CPU 以及 Windows x64 / NVIDIA CUDA 验证;Windows 包的首次配置、完整视频任务和验收边界见验收记录,构建方法见桌面说明。应用自动检测 CUDA、MPS、AMD ROCm 并保留 CPU 回退,支持范围见设备说明;Linux、AMD 和 MPS 推理尚未完成本轮真机验收。

1. 安装依赖

准备 Node.js 22(至少 22.13.0)和 Git。首次启动会识别操作系统与架构,准备 Python 3.12、运行依赖、FFmpeg/ffprobe 和分句资源。会复用 YouDub 已准备的环境。

git clone --branch main --recurse-submodules https://github.com/liuzhao1225/YouDub-webui.git
cd YouDub-webui
npm ci --registry=https://registry.npmmirror.com
npm --prefix apps/web ci --registry=https://registry.npmmirror.com

已有 checkout 时直接启动即可检查缺失项。Python / FFmpeg 使用阿里 npmmirror,Python 依赖使用阿里 PyPI,模型使用 ModelScope;来源与例外见国内首次启动下载说明。安装、网络或校验失败会停在准备页显示原因,可修复后手动重试。

2. 创建本地配置

首次创建配置;已有 .env 时保留原文件:

cp .env.example .env
ln .env env.txt
test .env -ef env.txt

打开工作台即可使用,无需设置或输入访问密码。应用加载 .env,代理工具读取同 inode 的 env.txt;两者均忽略提交。

3. 准备模型

首次启动会并行下载 Whisper tiny、VoxCPM2、Demucs htdemucs 和 Qwen3 Aligner 0.6B;页面显示真实进度,支持单项或全部暂停、继续。完成 SHA-256 校验与运行环境检查后自动进入工作台。默认数据目录:macOS 为 ~/Library/Application Support/YouDub,Linux 为 ~/.local/share/youdub,Windows 为 %LOCALAPPDATA%/YouDub;可用 YOUDUB_DESKTOP_DATA_DIR 覆盖。

| 能力 | 默认提供者 | 模型路径(相对数据目录) |
| 语音识别 | Whisper | models/whisper/,如 tiny.pt;另需上面安装的 punkt_tab |
| 翻译 | OpenAI 兼容 API | 在设置页配置连接、密钥及模型 |
| 配音生成 | VoxCPM2 | models/voxcpm/VoxCPM2/ |
| 人声分离 | Demucs htdemucs | models/demucs/955717e8-8726e21a.th |
| 字幕对齐 | Qwen3 Forced Aligner | models/qwen3-forced-aligner/Qwen3-ForcedAligner-0.6B-hf/ |

Whisper、VoxCPM2、Demucs 和 Qwen 均从 ModelScope 获取固定版本;VoxCPM2 和 Qwen 包含 tokenizer/processor 配置。中断文件保留为 .part,继续下载需要下载源支持 Range。自定义模型路径和运行条件见运行指南。启动准备接口仅允许本机访问。

翻译密钥保存在系统 keyring。自定义翻译模型候选名单通过 .env 中的 YOUDUB_TRANSLATION_MODELS 配置,在设置页选择。默认翻译请求的最大输出 token 数至少为 65,535,连接的服务和模型需要接受该参数;不兼容时会明确报错。

4. 启动

确认 8000、3000 端口没有其他进程占用,然后在仓库根目录执行:

npm run build:plugins
npm start

另开一个终端,在同一目录启动前端:

npm --prefix apps/web run dev -- --hostname 127.0.0.1 --port 3000

打开 http://127.0.0.1:3000,首次使用显示环境与模型准备;资源已就绪时直接进入工作台。

需要运行构建后的前端时,用以下命令替代开发前端;Host 仍单独运行:

npm run build:web
npm --prefix apps/web start -- --hostname 127.0.0.1 --port 3000

一切皆插件

YouDub 使用 Cordis 装配服务。任务引擎、默认工作流、模型服务商、HTTP/API、认证和前端页面都以插件实现;默认组合见 youdub.config.ts。

Client 页面插件 → API / 认证插件 → 通用任务引擎插件 ↓ workflow 插件 ↓ provider 插件 ↓ Python 计算进程 / 远端服务 workflow 声明处理步骤和输入输出,provider 实现约定的 operation,文件通过 ArtifactRef 传递。Python 继续承担媒体处理与模型推理,每次 operation 通过受管进程和 stdio 协议调用;纯 Python 插件也可以直接接入。

替换 ASR、翻译或 TTS 时,提供符合契约的插件即可;新的处理流程可以注册自己的 workflow。架构和边界见架构说明,数据结构见插件契约。

安装与开发插件

先完成或取消活动任务,停止 Host,再管理插件:

npm run plugins -- list
npm run plugins -- install --source ./fixtures/plugins/file-transform
npm run plugins -- disable --id example.file-transform
npm run plugins -- enable --id example.file-transform

也支持从其他 GitHub 仓库或 npm 精确版本安装,下面的仓库、commit 和包名需替换为实际值:

npm run plugins -- install --source https://github.com/OWNER/REPO --ref FULL_COMMIT_SHA
npm run plugins -- install --source npm:PACKAGE_NAME@1.0.0

安装默认启用,重启 Host 后生效;带有预编译 Client 入口的扩展刷新页面即可加载。插件安装脚本与 Host 代码使用本机权限,安装前应信任其来源;Python 独立环境用于隔离依赖。

从两个最小示例开始:

- Host / workflow / Client 插件:注册处理流程、页面和导航。
- 纯 Python provider:通过 manifest 声明 operation,使用 stdio 输入输出协议。

包结构、文件契约、凭据与取消处理见插件开发契约;安装、启停与卸载见运行指南。当前 SDK 随仓库提供,尚未作为公共 npm 包发布。

当前范围

- 英文分句。 Whisper 识别后使用 NLTK Punkt 整理完整句子,并用词级时间戳确定原声范围;原始识别结果保留。
- 默认流程接收本地 mp4、mov、mkv、webm 视频;默认限制 4 GiB、10 分钟、宽高各不超过 1920、60 fps。
- 当前语言目录包含英文、中文、日文,具体能力取决于提供者;可选 Qwen 对齐支持英文、中文。
- MVP 使用单机单活跃任务;插件启停在重启后生效。DAG 编辑器、热替换、插件市场和分布式 worker 留待后续需求。
- 本地 workflow、Client 与 Python 插件已有验证;GitHub/npm 远端插件实装尚未验收。
- 当前 HTTP 接口为 /api/v2,支持从指定步骤重新生成任务。旧 FastAPI / v1 HTTP 入口已移除。链接下载通过 media.download/v1 接入现有任务流程,支持 YouTube、Shorts、B 站及 b23.tv 单视频链接;使用 yt-dlp、Node.js 与 FFmpeg,沿用 10 分钟和文件大小限制。

旧版本升级和数据迁移请先阅读运行指南。真实任务、迁移与未验证范围记录在迁移验收、逐句分句验收及字幕显示验收。

开发与测试

npm run typecheck
npm test
npm run test:backend
npm --prefix apps/web test
npm run lint:web
npm run build:web

youdub.config.ts 默认 Cordis 插件组合 apps/host/ Host 启动与插件管理 CLI packages/sdk/ 公共服务、workflow 与 operation 契约 packages/builtin/ 基础服务、通用任务引擎、workflow 和模型桥 backend/workers/ Python 计算与 SQLite 事务桥 backend/app/ 模型、媒体、凭据与历史数据格式 apps/web/ Next 引导、Client SDK 和页面插件 fixtures/plugins/ 独立 Host/Client/Python 插件示例 submodule/demucs/ Demucs 源码子模块

欢迎通过 Issue / PR 改进安装体验、适配模型、优化字幕与音画对齐,或提供独立来源/流程插件。docs/ 保留历史设计文档,当前入口以本文和 Cordis 运行指南为准。

开源许可

本项目使用 Apache License 2.0,详见 LICENSE。

国内镜像:AtomGit,由 GitHub 主仓库单向同步。Release、Issue 和 PR 在 GitHub 维护。

作者:刘朝 Zhao Liu · GitHub · Bilibili 黑纹白斑马 Star History
预览分享卡片长什么样 ↓liuzhao1225/YouDub-webui
分享 · DeepSeek Harness Hub
liuzhao1225/YouDub-webui

开源视频本地化工作台:导入视频,识别、翻译并逐句克隆原声,生成字幕和配音成片。

回到顶部