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

离线语音转写 anchoredship/dsh-audio-transcribe

DeepSeek Harness
anchoredship14 天前有提交已提供中文文档扫描:含敏感能力

本地把音频转成文字,还能录制系统播放的声音

29.9/100
综合分
0
GitHub 星标
—
npm 周下载
—/5
用户评分

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

安装命令 · 需先装 dsh CLI 引擎
dsh plugin --profile web add anchoredship/dsh-audio-transcribe
该包不可直接 npm 安装,改从 GitHub 源安装(明细见下方安装检查)

状态速览

判定依据:实装验证 · 静态安装检查 · 自动扫描 · 仓库维护状态
信任档位:仅索引
是什么
dsh 原生插件 · tool
装得上吗
本站尚未做安装检查
安全吗
本站尚未对该插件做风险分级
暂未覆盖,不等同于无风险
还在维护吗
活跃:最近一次提交在 14 天前
档位由哪些信号合成

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

验证判据与等级说明 →
社区实装还没有人打卡 · 装过的第一个就是你
安全扫描自动 · 静态分析源码
v2.7.0
🔵 扫描:含敏感能力尚无人工评估
展开查看扫描说明与证据 ↓

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

可执行外部命令读写/删除本地文件发起外部网络请求
查看扫描证据(共 6 处,展示前 6 条)
  • 读取本地文件
    src/index.js:263
    accessSync(flat)
  • 读取本地文件
    src/index.js:269
    accessSync(layered)
  • 发起网络请求
    src/index.js:655
    const res = await fetch(url, { redirect: 'follow', signal: exec?.signal })
  • 写入本地文件
    src/index.js:661
    await pipeline(Readable.fromWeb(res.body), createWriteStream(tmp))
  • 读取本地文件
    src/recorder.js:36
    return existsSync(exe)
  • 执行外部命令来自配置/变量
    src/recorder.js:80
    const child = spawn(exe, [binDir(packageRoot), file, String(maxSeconds)], {
扫描于 2026/11/4(0 天前) · 范围 入口闭包 + 发布文件清单 · 来源 GitHub 仓库

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

依赖的 DSH / Cordis 模块
@deepseek-ai/schemastery@deepseek-ai/cordis@deepseek-ai/dsh-tools
给这个插件打分还没有人投票↓
用户评分
还没有人投票,来当第一个

DeepSeek Harness 的离线音频转文字:用 SenseVoice 转写,录制系统播放的声音,全程本地运行。

README

由 DeepSeek 最新模型翻译生成
dsh-audio-transcribe 为 DeepSeek Harness 提供离线音频转文字,外加一个浮动小组件,用来录制机器正在播放的声音。 全部在本地运行:不需要 API key,不上传,转写时不联网。 仅支持 Windows x64。 录制器是随包附带的 WASAPI 回环二进制。 已针对 DSH Desktop 0.2.0-rc.2 测试。 本插件依赖两个 API,上游 harness 目前把它们标记为实验性:通过 dsh.bundle.patch 加载 bundle,以及通过 webserver/index-inject 注入索引。两者在 0.2.0-rc 系列中一直稳定,但未来的 DSH 版本可能改动它们。如果升级 DSH 后工具或小组件不再出现,先检查这里,不要急着认定插件坏了——见 TROUBLESHOOTING.md。 安装 推荐:克隆仓库,从本地检出安装 git clone https://github.com/Anchoredship/dsh-audio-transcribe dsh plugin --profile web add file:D:\path\to\dsh-audio-transcribe file: 安装直接从磁盘解析,完全跳过 registry 解析,所以 pnpm 的构建脚本门禁拦不到东西,也不依赖网络。
展开完整文档(README 剩余 1 节)
dsh-audio-transcribe

为 DeepSeek Harness 提供离线音频转文字,外加一个浮动小组件,用来录制机器正在播放的声音。

全部在本地运行:不需要 API key,不上传,转写时不联网。

仅支持 Windows x64。 录制器是随包附带的 WASAPI 回环二进制。

已针对 DSH Desktop 0.2.0-rc.2 测试。 本插件依赖两个 API,上游 harness 目前把它们标记为实验性:通过 dsh.bundle.patch 加载 bundle,以及通过 webserver/index-inject 注入索引。两者在 0.2.0-rc 系列中一直稳定,但未来的 DSH 版本可能改动它们。如果升级 DSH 后工具或小组件不再出现,先检查这里,不要急着认定插件坏了——见 TROUBLESHOOTING.md。

安装

推荐:克隆仓库,从本地检出安装

git clone https://github.com/Anchoredship/dsh-audio-transcribe
dsh plugin --profile web add file:D:\path\to\dsh-audio-transcribe

file: 安装直接从磁盘解析,完全跳过 registry 解析,所以 pnpm 的构建脚本门禁拦不到东西,也不依赖网络。用绝对路径,并保留 file: 前缀——只写 .\dir 会变成 link: 符号链接,Node 随后会从符号链接目标解析插件的 DSH peer 包,结果找不到。

备选:从 GitHub 安装

dsh plugin --profile web add github:Anchoredship/dsh-audio-transcribe

这条命令拉取源码,再通过 registry 安装。本插件没有 install / postinstall / prepare 脚本,也没有原生依赖,所以应该不会触发 pnpm 的构建脚本策略。如果 pnpm 确实以 ERR_PNPM_IGNORED_BUILDS 拒绝,它指的是作为传递依赖被拉进来的另一个包——按提示允许那个包,或者改用上面的 file: 方式。

然后

重启 DSH。转写无需额外下载即可使用,因为它复用 DSH 自带语音输入已经准备好的 SenseVoice 缓存——如果缓存不存在,运行一次 audio_model_download。

界面预览

展开后的小组件,正在录制,另有三条历史录音(其中两条已转写):

提供什么

三个模型工具

| 工具 | 用途 |
| audio_transcribe | 用本地 SenseVoice 模型把 WAV 文件转成文字 |
| audio_model | 报告模型所在位置,以及是否完整 |
| audio_model_download | 把模型(约 230 MB)下载到你指定的目录 |

录制小组件

Web/Desktop GUI 右下角一个可拖动的胶囊:

- 开始 / 停止捕获系统播放的声音(不是麦克风)
- 实时计时,面板关闭后仍继续计时
- 查看并修改录音的存放位置
- 列出最近的录音,并标出已有转写文本的那些
- 自动转写每段录音,在 WAV 旁边生成 .txt

为什么录音需要一个宿主进程

浏览器无法捕获机器正在播放的声音。因此这个小组件只是一个遥控器:按钮调用 /dsh-audio 下的宿主路由,宿主再启动 bin/LoopbackCap.exe(WASAPI 回环,基于 NAudio)完成采集。

widget (browser) ──HTTP──▶ host routes ──spawn──▶ LoopbackCap.exe
│
<dir>/system-audio-.wav
│
SenseVoice ──▶ .txt

不需要虚拟音频线:WASAPI 回环直接读取输出设备,既不切换默认设备,也不安装驱动。

存储

| 默认位置 | <dshHome>/audio-transcribe/recordings |
| 修改方式 | 选择… 按钮(打开系统文件夹选择器),或 POST /dsh-audio/dir.json |
| 持久化位置 | <dshHome>/audio-transcribe/config.json —— 重启后仍然有效 |
| 目录结构 | 每段录音一个带时间戳的文件夹(可在小组件里开关) |

目录结构

开启 每次录音新建独立文件夹(默认开启)后,每次录音都有自己的文件夹,音频和转写文本放在一起:

<recordDir>/
└── 2026-10-21_13-02-11/
├── system-audio.wav
└── system-audio.txt

关掉这个选项,录音会平铺在 <recordDir> 下,时间戳移进文件名(system-audio-2026-10-21_13-02-11.wav),这样也不会重名。

列表会读取两种目录结构,所以引入分组之前录的文件照样能显示出来。

为什么用配置文件,而不用设置服务

settings.mutate() 只持久化活动 profile entry* 的易失字段。这个插件是一个 bundle,没有自己的 entry id,所以通过那个 API 写入会被接受,然后被静默丢弃——早期版本每次重启都会重置所选目录,原因就在这里。因此插件自己维护一个小 JSON 文件,并以原子方式写入(临时文件 + 重命名)。

修改目录用的是 DSH 自带的目录选择器接口,而不是手写的文本框。这个接口暴露的是能力,不是一套固定的方法,因为不同后端的交互形态不一样:

const cap = ctx.directoryPicker.capability()
// { kind: 'native', pick(signal) } → OS folder chooser
// { kind: 'browse', list(path?), createDirectory } → in-app tree

所以插件先问宿主具备哪种能力(GET /dsh-audio/picker.json),再据此渲染:

| 能力 | 小组件行为 |
| native | 选择… 打开系统选择器;手动粘贴作为次要选项保留 |
| browse | 不绘制目录树;小组件会说明这一点,并提供手动输入 |
| none | 选择按钮隐藏,只能手动输入 |

最后一种情况是刻意设计的:组合里没有选择器后端时,必须隐藏入口,而不是报错。

这台主机拿到哪种?

dsh-base 组合了 dsh-host-directory-picker-auto,启动时解析一次:

if (bindHost !== '127.0.0.1') return 'browse' // remote browsers cannot reach an OS dialog
if (ssh) return 'browse' // the chooser would open on an unattended server
if (platform === 'darwin' || platform === 'win32') return 'native'

在这台机器上——Windows、回环绑定、本地启动——答案是 native,所以控件会打开真正的文件夹选择器。

选中的目录在接受前会校验是否可写,选错了立刻失败,不会拖到录制时才报错。

模型

默认复用 DSH 自带语音输入已经准备好的缓存:

<dshHome>/speech-to-text/sensevoice/models
├── sensevoice-onnx/model.int8.onnx
├── sensevoice-onnx/tokens.txt
└── silero/silero_vad.onnx

缓存不存在时,audio_model_download 可以把固定版本(按大小和 SHA-256 校验)下载到插件自己的目录。全新下载绝不会写入共享缓存。

定位文件时支持两种布局:上面这种分层布局,以及一个平铺目录,里面放全部三个文件。

解码模式

auto(默认)按文件逐个选择:

- ≤ 30 s → whole(一遍过,最快)
- \> 30 s 且静音 ≥ 15 % → segment(Silero VAD 切分语音)
- \> 30 s 其他情况 → 先 whole 到 120 s,再 segment

segment 输出带 [12.3s] 时间戳,处理长音频或停顿多的音频效果更好。用 audio_transcribe 的 mode 参数可以强制指定。

环境要求

| 平台 | Windows x64 |
| 运行时 | 复用 DSH Desktop 0.2.x 自带的 sherpa-onnx 构建 |
| .NET | 基于系统内置的 .NET Framework 4.x 构建 |
| 录制器 | bin/LoopbackCap.exe + NAudio,已打包(424 KB) |

不会在系统范围内安装任何东西。

HTTP 接口

所有路由归主机所有,挂载在 /dsh-audio 下:

| 路由 | 方法 | 用途 |
| /dsh-audio/status.json | GET | 录制状态、存储目录、最近文件 |
| /dsh-audio/start.json | POST | 开始录制({ maxSeconds },上限 7200) |
| /dsh-audio/stop.json | POST | 停止并完成 WAV |
| /dsh-audio/dir.json | GET/POST | 读取或修改存储目录 |
| /dsh-audio/settings.json | GET/POST | 按录制文件夹开关 |
| /dsh-audio/picker.json | GET | 主机具备哪种目录选择能力 |
| /dsh-audio/pick.json | POST | 打开系统选择器并采用结果 |
| /dsh-audio/ui.js | GET | 控件脚本 |

每条路由执行前都要过信任检查:Host 不是回环地址、Sec-Fetch-Site 是跨站、或 Origin 不匹配,一律返回 403。会修改状态的路由只接受上表列出的方法,其他方法返回 405。
少了这道防护,用户访问的任何页面都能偷偷开始录音,或者列出他们的录音。

小部件如何注入

在桌面端外壳里,index.html 由打包后的 dist 直接提供,从不经过 tapIndex,所以唯一可用的通道是 webserver/index-inject 上发出的结构化行:

root.on('webserver/index-inject', (table) => {
table.push({ kind: 'script', placement: 'body', text: INJECT_TEXT })
})

这里必须是内联 script 行,绝不能用 script-src:script-src 一旦失败,__DSH_BOOT_READY__ 就会被拒绝,整个应用都启动不了。注入的代码片段自己创建 script 标签,并吞掉 onerror,所以路由缺失时只会退化成「没有小部件」,而不会让应用崩溃。

干净地停止

LoopbackCap.exe 会监视 <file>.stop,由它自己把 WAV 收尾。直接杀掉进程则会让 RIFF 头没写完,所有解码器都会把它读成 0 秒 —— 一个 250 KB 的文件,转写出来什么都没有。

有两点让这件事可靠:

读取循环跑在自己的线程上。 在 WASAPI 回环里,静默的输出设备根本不送数据,Read 会一直阻塞到有数据为止。所以单线程的「先读再检查」循环永远走不到检查停止文件那一步,采集就一直跑到插件放弃、把它杀掉 —— 结果得到一个被截断的文件。现在读取线程独占缓冲区,主线程只负责轮询停止文件。

静默是正常结果,不是失败。 退出码 3(没有数据)和 4(采到了但全是静默)都会产出一个有效的 WAV,只是没有可听内容。小部件把这类录音标成无声,免得你打开文件后以为录音坏了;自动转写也会跳过它们。

许可证

MIT。bin/ 里打包的 NAudio 程序集同样是 MIT(署名见 LICENSE)。SenseVoice 模型在运行时下载,本仓库不分发它。

欢迎贡献 —— 见 CONTRIBUTING.md,提 issue 之前先看看 TROUBLESHOOTING.md。

退出行为

小部件会就地报告失败,不会闷声不响:

| 情况 | 你会看到 |
| 没有声音在播放 | 录音成功,WAV 近乎静默;转写结果为空 |
| 输出设备选错 | 转写结果为空 —— 检查默认播放设备 |
| 采集程序缺失 | 按钮禁用,显示 采集程序缺失 |
| 模型缺失 | 转写报错,指出缺哪些文件、怎么修 |

开发说明

宿主模块:

| 文件 | 作用 |
| src/index.js | 配置、模型解析、三个工具、小部件挂载 |
| src/recorder.js | 子进程生命周期、状态、文件列表 |
| src/ui-routes.js | HTTP 路由和 index 注入行 |
| assets/audio-ui.js | 浏览器小部件(纯脚本,无需构建步骤) |

audio_transcribe 和小部件共用 transcribeFile(),所以同一段音频无论走哪条路,出来的文字都一样。
改完 LoopbackCap.cs 后,重新构建录音器:

$csc = "C:\Windows\Microsoft.NET\Framework64\v4.0.30319\csc.exe"
$ns = "C:\Windows\Microsoft.NET\assembly\GAC_MSIL\netstandard\v4.0_2.0.0.0__cc7b13ffcd2ddd51\netstandard.dll"
& $csc /nologo /target:exe /out:"bin\LoopbackCap.exe"
/r:"bin\NAudio.Core.dll" /r:"bin\NAudio.Wasapi.dll" /r:"bin\NAudio.WinMM.dll" /r:"$ns"
"src\LoopbackCap.cs"

bin/LoopbackCap.exe.config 必须保留 loadFromRemoteSources enabled="true",否则 .NET 会拒绝从非 GAC 路径加载 NAudio。
预览分享卡片长什么样 ↓anchoredship/dsh-audio-transcribe
分享 · DeepSeek Harness Hub
anchoredship/dsh-audio-transcribe

本地把音频转成文字,还能录制系统播放的声音

这是你的仓库?认领条目

回到顶部