DSH Plugins Marketplace

DSH Plugins

Plugins

/

dsh-vidora

d

dsh-vidora

Identified

Vidora(DSH 插件)

本地优先的音视频知识文档化工具。 给 Vidora 一个本地 MP4/MKV/MP3/WAV,它会在本机完成 FFmpeg 解码、VAD 分段、Qwen3-ASR 转写、Qwen3-ForcedAligner 时间戳对齐,并调用 Harness 已配置的模型生成可追溯来源的 Markdown 讲义与译文。

DeepSeek Harness(DSH)是 Vidora 的交互入口,不是业务核心。Vidora Core 的 Transcript / Document JSON 不依赖 Harness 私有接口,可供未来的 Chrome 扩展和 GPUI 桌面端复用。

本地音视频
  → FFmpeg 解码 / 16kHz 单声道
  → VAD + 静音感知分段(不把完整长音频放进模型内存)
  → Qwen3-ASR-0.6B(可切换 1.7B)
  → Qwen3-ForcedAligner-0.6B(独立对齐阶段)
  → transcript.json(毫秒时间戳 / 稳定 segment id)
  → Harness 模型分窗口提取 → 全局合并 → 确定性 Markdown 渲染
  → notes.md + document.json + exports/

文档索引

当前状态

  • Phase 1–5 的最小可运行链路已经实现。
  • 已在 macOS Apple Silicon(M1 Pro,32GB,MPS)上完成真实推理测试:
    • 5 分钟中文教学音频:15 段,对齐 15 段,RTF 0.100,峰值内存约 3.4GB。
    • 10 分钟中英混合音频:31 段,RTF 0.096,峰值内存约 3.5GB。
    • 60 分钟中文长音频:157 段,RTF 0.092,峰值内存约 3.3GB。
    • 取消、检查点恢复、缓存命中、Harness 模型讲义生成均已实际执行。
  • 测试音频由 macOS say(Tingting)合成;这是真实语音推理,但不是人类课堂录音。CER 是按已知脚本计算的,不代表真实课堂准确率。详见 docs/test-report.md。
  • Linux / Windows 与 Intel Mac 尚未在本机验证;代码包含 CPU fallback 和跨平台路径处理,但请将它们视为兼容目标而不是已验证结果。

能力

工具功能
vidora_transcribe创建本地转写任务(本地 path 或 Bilibili/YouTube url);默认等待完成(wait=true),也可 wait=false 异步轮询
vidora_task_status查询阶段、真实已处理音频时长、总时长、片段数、错误
vidora_cancel_task取消任务;检查点保留,可恢复
vidora_get_transcript分页读取转写正文(默认可见;开启 blockHarnessContent 后仅受信任会话可见)
vidora_generate_notes用 Harness 模型生成精简/详细/可读转写/复习提纲
vidora_translate用 Harness 模型把转写或讲义逐句翻译成中文/英文/日文,保留片段与来源
vidora_get_document读取讲义正文(默认可见;开启 blockHarnessContent 后仅受信任会话可见)
vidora_export导出 Markdown / JSON / TXT / SRT(不返回正文)
vidora_list_models查询模型、设备、FFmpeg、Worker、Harness 模型和隐私状态

插件同时提供一个 Harness 输入框上方的图形面板:选择/拖入媒体或粘贴 Bilibili/YouTube 链接、查看真实进度、最近项目、转写预览、Harness 模型讲义生成、中/英/日翻译与 Markdown/SRT 导出。它只在 DSH Web/Desktop profile 中挂载;headless profile 只注册工具。

支持 MP3、WAV、FLAC、M4A、MP4、MKV、WebM、OGG、Opus、AAC、MOV、AVI、FLV、M4B。

还可以在界面里粘贴 Bilibili / YouTube 单视频链接,由本机 yt-dlp 下载后自动进入同一条本地转写链路。下载只使用你已有权访问的内容,不绕过 DRM、付费墙、登录或地区限制;不支持播放列表、直播和多 P 视频。

快速安装(macOS Apple Silicon)

前提:Node.js >= 22、Python >= 3.9、FFmpeg/ffprobe、DSH >= 0.2.2-rc.1 <0.3.0。要在界面/工具中导入 Bilibili 或 YouTube 链接,还需要本机安装 yt-dlp(例如 brew install yt-dlp 或 pipx install yt-dlp)。已在 DSH 0.2.2-rc.1 上实测。

git clone <this-repo> dsh-vidora
cd dsh-vidora

# 1. 构建 TypeScript 插件
npm install
npm run build

# 2. 安装独立 Python Worker 虚拟环境(不会修改全局 Python)
node scripts/install-worker.mjs --yes

# 3. 显式确认后下载模型权重(默认写入 OS 用户数据目录)
node scripts/prepare-models.mjs --model qwen3-asr-0.6b --yes
node scripts/prepare-models.mjs --model qwen3-forced-aligner-0.6b --yes

模型来源、大小和目标目录会在下载前显示;prepare-models 也支持 --endpoint https://hf-mirror.com、--dest 和 --data-dir。Worker 自身始终以 HF_HUB_OFFLINE=1、local_files_only=True 运行,不会在推理时下载权重。

安装到 DSH profile:

dsh plugin --profile desktop add link:/absolute/path/to/dsh-vidora

然后编辑 ~/.dsh/profiles/desktop/cordis.patch.yml,为 vidora 行添加配置:

- id: vidora
  config:
    dataDir: /Users/you/Library/Application Support/Vidora
    worker:
      pythonPath: /absolute/path/to/dsh-vidora/python-worker/.venv/bin/python
    asr:
      modelsDir: /Users/you/Library/Application Support/Vidora/models
      device: auto
      align: true
    llm:
      mode: harness-current   # harness-current(默认)| off
    privacy:
      strictLocal: true
      blockHarnessContent: false  # 默认允许 Harness 模型读取正文
      trustedLocalProviders: []

重启 DSH(或让 profile HMR 重新加载)。在对话中输入:

请把 /Users/you/Videos/os-lecture.mp4 转换成文字,并整理成一份精简的 Markdown 教学讲义。

也可以只转写:

只转文字,不需要总结。

也可以直接给链接:

把这个 Bilibili/YouTube 链接下载下来并转成文字。

或者复用已有转写生成详细讲义:

使用刚才的 Transcript 重新生成一份详细讲义。

把这段英文转写翻译成中文,并导出中英双语 SRT。

Harness 模型

Vidora 不再自带 Ollama、OpenAI 兼容端点或任何独立推理服务,也不会请求用户自己的 LLM 服务端。讲义和翻译统一调用 Harness 已配置的模型:

  • 工具调用:使用当前 Agent 的模型(exec.agent.model.current())。
  • Web UI:使用 profile 的 agent-default-model 当前选择。
  • 模型可能是云端模型(例如 DeepSeek)。Vidora 不会偷偷换模型,也不会自动降级到其他服务。
  • llm.mode: "off":ASR、缓存、导出仍然可用;AI 讲义和翻译明确不可用。

因此不需要配置 baseUrl、apiKey、ollama 或 openai。只需要:

- id: vidora
  config:
    llm:
      mode: harness-current

如果 Web 面板要生成讲义/翻译,profile 还需要一个默认模型:

- id: agent-default-model
  config:
    provider: deepseek-account
    model: deepseek-flash

隐私与正文保护

这里的“严格本地”指 Vidora 不请求用户自己搭建的推理服务器,而不是禁止使用 Harness 模型。ASR/FFmpeg/VAD 始终本机执行;讲义和翻译使用 Harness 模型,因此如果该模型是云端的,转写正文会发送给该 provider。

默认 privacy.blockHarnessContent: false,即允许 Harness 模型读取正文:

  • vidora_get_transcript / vidora_get_document 默认可见。
  • vidora_generate_notes 和 vidora_translate 正常使用当前 Harness 模型。
  • 工具返回的标题、正文和警告按正常方式返回。

如果需要额外的正文保护,可显式开启:

privacy:
  blockHarnessContent: true
  trustedLocalProviders: [your-local-provider]
  trustedLocalModels: [your-local-model]

开启后:

  1. vidora_get_transcript / vidora_get_document 只对信任列表中的 provider/model 可见。
  2. 工具内部会用 exec.agent.model.current() 再检查一次。
  3. ctx.tools.guard() 会拦截非 Vidora 文件/Shell 工具对 Vidora 数据目录和已登记媒体路径的访问。untrustedFileToolPolicy 可为 block-data-path、block-all 或 off。
  4. 讲义/翻译结果在不可信会话中只返回元数据,隐藏标题、章节名和详细警告。

这是运行时访问限制,不是 OS 文件系统沙箱。详见 docs/security.md。

数据目录

默认使用操作系统用户数据目录:

平台默认位置
macOS~/Library/Application Support/Vidora
Linux$XDG_DATA_HOME/vidora 或 ~/.local/share/vidora
Windows%APPDATA%\Vidora

可用 dataDir 或环境变量 VIDORA_DATA_DIR 覆盖。

Vidora/
├── meta.json
├── models/
├── projects/
│   └── prj-<source-hash>/
│       ├── source.json
│       ├── transcript.json          # 最近一次转写的便捷副本
│       ├── transcripts/<id>.json    # 规范转写文件
│       ├── document.json            # 最近一次讲义
│       ├── documents/<id>.json
│       ├── notes/<id>.md
│       └── exports/
├── uploads/                       # Web 面板上传的临时媒体
├── downloads/                     # 在线链接下载的媒体与 metadata.json
├── tasks/<task-id>/
│   ├── task.json
│   ├── checkpoint.json              # 中断/取消后可恢复
│   └── work/audio.wav
├── cache/index.json
└── logs/worker.log

同一个音视频按 SHA-256 + 模型 + 语言 + 对齐 + VAD 参数判断缓存;命中时不会重新执行 ASR。vidora cleanup --older-than 7 可清理旧任务的临时 WAV、检查点和失效缓存项。

Transcript / Document 契约

见 docs/data-format.md。核心约束:

  • 时间戳统一毫秒,对应原始媒体时间轴。
  • Segment ID 稳定且唯一。
  • timing_status 为 aligned / chunk / uncertain。
  • 原始 transcript.json 不会被 LLM 润色结果覆盖;讲义是独立的 document.json。
  • DocumentBlock 通过 source_segment_ids 关联转写片段;Markdown 渲染时由程序生成时间戳和相对链接,LLM 不能编造时间戳。

任务恢复与 Worker 生命周期

  • Python Worker 由 Node child_process.spawn() 启动,不在 Harness 主进程内做推理。
  • Worker 按需启动、复用已加载模型、空闲可卸载(默认 900 秒)。
  • 任务状态持久化在 tasks/<id>/task.json,Worker 在每个 ASR 片段后写 checkpoint.json。
  • 插件重启/Worker 崩溃/任务取消后,状态变为 interrupted 或 cancelled,resumable=true;用 vidora_transcribe 的 resumeTaskId 参数恢复。
  • 插件卸载时先标记未完成任务为 interrupted,再发送 worker.shutdown;超时后终止子进程。不会因为切换会话而取消转写。
  • 重复提交相同任务会返回已有 task 或已完成缓存,不会重复执行。

配置

完整字段与默认值见 docs/configuration.md。常用字段:

- id: vidora
  config:
    dataDir: /path/to/Vidora
    worker:
      pythonPath: /path/to/python-worker/.venv/bin/python
      idleUnloadSeconds: 900
    asr:
      defaultModel: qwen3-asr-0.6b
      modelsDir: /path/to/models
      device: auto              # auto | cpu | mps | cuda
      dtype: auto               # auto | float16 | bfloat16 | float32
      language: auto
      align: true
      diarize: false           # 实验性本地说话人聚类
      alignerModel: qwen3-forced-aligner-0.6b
      maxChunkSeconds: 30
      vad:
        thresholdDb: null       # null = 自适应
        minSilenceMs: 400
        minSpeechMs: 250
        paddingMs: 150
        frameMs: 20
    llm:
      mode: harness-current
    privacy:
      strictLocal: true
      blockHarnessContent: false                 # true = 只允许信任列表读取正文
      trustedLocalProviders: []
      trustedLocalModels: []
      untrustedFileToolPolicy: block-data-path   # block-data-path | block-all | off
    tasks:
      autoResume: false
      maxTaskHours: 8
      keepTempFiles: false
    paths:
      mode: explicit            # explicit | roots
      allowedRoots: []
      maxFileSizeBytes: 21474836480
      maxDurationMinutes: 480
    document:
      defaultMode: concise
      maxCharsPerWindow: 10000
      maxWindows: 300
    urlImport:
      enabled: true
      ytDlpPath: ""          # 空 = PATH 中的 yt-dlp
      cookiesFile: ""        # 可选;Netscape cookies.txt
      cookiesFromBrowser: "" # 或 chrome/safari/firefox/edge/brave
      timeoutMs: 1800000

Harness 内界面

安装到 Web/Desktop profile 后,输入框上方会出现 Vidora 面板。它支持本机文件选择、拖入/上传、路径输入、Bilibili/YouTube 链接、模型与语言选择、真实进度、最近项目、转写预览、Harness 模型讲义生成、项目问答、逐句翻译、媒体播放与时间戳跳转、全文搜索/讲义目录、环境初始化、批量导入队列、项目/术语表管理、说话人分离(实验)和多格式导出。转写完成后,来源选择会自动收起,结果横幅提供“模式 + 一键生成讲义”;转写结果里可直接播放源音视频、点击时间戳跳转,当前句自动高亮;也可选择目标语言并“逐句翻译”,译文显示在每句转写下方。顶部有“搜索”“问答”“环境”页,分别用于全文检索/讲义目录、基于转写的引用问答、环境初始化。在线链接支持播放列表/多 P 展开和批量队列;项目可重命名、打标签、收藏、归档、删除,并查看/清理存储占用。讲义页只保留一个主按钮和四个模式切换,不再需要在多个表单之间来回操作。浏览器只调用 DSH 自己的 /vidora 回环路由;详细路由和限制见 docs/ui.md。

开发与测试

npm run build          # TypeScript -> dist
npm test               # Node 单元/集成测试(64 项)
npm run test:python    # Python Worker 单元测试(需先安装 venv)
npm run check          # build + node --check + tests

# 真实推理(需要模型和 venv)
node scripts/real-asr-test.mjs testdata/audio/lecture-5m-zh.m4a --device mps

# 生成真实测试语音(macOS say;仅用于可重复测试)
node scripts/generate-test-audio.mjs --minutes 5 --name lecture-5m-zh

详细测试方法、CER 结果、取消/恢复结果见 docs/test-report.md。

已知限制

  • 支持本地文件与 Bilibili/YouTube 链接;播放列表/多 P 可展开为批量队列,不支持直播、DRM/付费墙/登录绕过。
  • 第一版以 片段级 时间戳为可靠交付;字符/词级时间戳来自 ForcedAligner,作为增强字段 words。对齐失败时标记为 chunk 或 uncertain,不会伪造精确时间。
  • 在线导入对播放列表/多 P 先展开成独立视频队列;不支持直播、DRM/付费墙/登录绕过。部分视频会触发 YouTube 人机验证,需要在界面选择已登录浏览器的 Cookies,或配置 cookiesFile。
  • 在线导入依赖本机 yt-dlp 和目标站点可访问性;网络被阻断时会失败,不会改用云端下载服务。
  • 说话人分离是实验性的 MFCC + KMeans 聚类,只适合双人/少数说话人场景;不是 pyannote 级别的 diarization。
  • Web 面板使用安全 Markdown 渲染(标题、列表、表格、代码块、讲义目录),支持预览/源码切换,不注入 HTML。
  • Windows 原生文件选择已接入 PowerShell;仍需在真实 Windows 上验证。媒体播放依赖浏览器支持的容器/编码。
  • MPS 已在 M1 Pro 上实测可用;CUDA 未在本机验证;CPU fallback 可用但更慢。
  • Linux/Windows 的路径、进程和安装流程已做代码适配,但未在本机实测;详见 docs/cross-platform.md。
  • 1.7B ASR 模型、真实 GPU、Intel Mac 未实测。
  • 讲义/翻译质量取决于当前 Harness 模型。历史测试使用过 1.5B/3B 本地模型;小模型的章节合并和术语解释质量明显更弱。
  • 长音频的 ASR 片段是 VAD 边界;跨边界句子采用静音感知切分 + 边界重复抑制,但不做强制重切/全文重对齐。
  • 首次使用可在“环境”页安装 Python Worker、下载 ASR/对齐模型;模型权重下载需要网络和用户显式确认。
  • 环境初始化任务使用本机脚本,不会自动安装 FFmpeg 或 yt-dlp,缺项会在“环境”页给出命令提示。

许可证

插件代码:MIT。第三方模型、Python 包、FFmpeg 的许可证与来源见 THIRD_PARTY_NOTICES.md。Qwen3-ASR / ForcedAligner 权重为 Apache-2.0。

Comments

Loading…