dsh-classroom-mobile:手机浏览器录音 + 本地转写 + 课后整理的 DSH 工作流插件

前言

课堂场景里,录音容易,录音之后的整理难。一段一小时的课,手动整理成总结、思维导图、练习题,代价很高;直接丢给通用 Agent,又缺少「这节课讲了什么、错题有没有改完」这类上下文。dsh-classroom-mobile 针对的就是这一步:手机浏览器录音,本机 Whisper 转写,再由 DSH Agent 生成总结、导图和练习题,并用一个错题门控把复习闭合掉。

先说清楚它是什么:一个 DSH / cordis 插件,由 chengyu-xin1 维护,分类是工作流,当前 0 星。它不打包 APK,也不做原生 App。它的思路是 PC 端起一个 HTTP 服务,手机浏览器访问它。

这是什么

一句话定位:在 DSH 里加一个「课堂学习」工作流,覆盖录音、转写、总结、复习、专注报告这一整条链路。

它解决的是三个具体问题:

  • 录音之后没有结构化的整理产物;
  • 复习没有约束,错题改不改完都一样能继续录音;
  • 手机没有 DSH 的移动端,需要一个在手机浏览器里能用的入口。

README 里明确写了边界,值得先记住:DSH 是桌面应用、没有移动端;手机端等于手机浏览器访问 PC 上本插件启动的服务。专注功能只做检测、记录、报告,不会锁定手机或强制专注。插件零 npm 依赖,只用 node 内置模块,转写调用本机的 ffmpeg 和 python。

安装与启用

从 DSH 插件市场安装,审核通过后在命令行执行:

dsh plugin --profile desktop add github:chengyu-xin1/dsh-classroom-mobile

手动安装适合本机开发或离线环境。先把整个目录放到 D:\dsh-classroom-mobile,再复制到 DSH profile 的插件目录:

Copy-Item -Recurse -Force "D:\dsh-classroom-mobile" `
  "$env:USERPROFILE\.dsh\profiles\desktop\node_modules\dsh-classroom-mobile"

然后把包名加进 profile 的 package.json 的 dsh.profile.bundles 数组末尾,加 "dsh-classroom-mobile"。最后重启 DSH。插件 apply() 会自动在 0.0.0.0:8765 起服务,端口被占用时从 8766 起递增。

换电脑或给别人装,先跑环境准备脚本:

powershell -ExecutionPolicy Bypass -File scripts\setup.ps1

它依次检查并准备 Node、Python、ffmpeg,安装 faster-whisper(清华源),下载 Whisper small 模型(约 460 MB),下载 cloudflared。任何一步失败都不会影响插件可用,只是对应能力缺失:没有 faster-whisper 就手动粘贴文字,没有 cloudflared 就只用局域网。可以用 -SkipModel、-SkipCloudflared 跳过下载。

手机访问:公网隧道与局域网

插件启动时用 cloudflared 建一条临时 HTTPS 隧道,手机用流量或在别的 Wi-Fi 下都能打开:

https://xxxx-xxxx-xxxx.trycloudflare.com

HTTPS 还解决了手机浏览器「非安全上下文不能调用麦克风」的限制。cloudflared.exe 约 53 MB,仓库不打包,插件第一次启动会自动下载到 data\bin\cloudflared.exe,优先走 ghfast 镜像;下载失败时页面照常可用,只是没有公网地址。也可以手动放一份:

New-Item -ItemType Directory -Force D:\dsh-classroom-mobile\data\bin | Out-Null
Invoke-WebRequest -Uri https://github.com/cloudflare/cloudflared/releases/latest/download/cloudflared-windows-amd64.exe `
  -OutFile D:\dsh-classroom-mobile\data\bin\cloudflared.exe

非本机访问需要 6 位访问码,存在 data\access.json。首次打开手机端会弹输入框,也可以直接在 DSH 里问「手机访问码是多少」。quick tunnel 每次重启 DSH 可能换地址,随时问「手机访问地址」即可,工具 classroom_mobile_url 返回最新地址加访问码。关闭隧道用环境变量 DSH_CLASSROOM_MOBILE_TUNNEL=0,重启后只用局域网。

如果隧道没起来,电脑和手机连同一个 Wi-Fi 时可以用局域网地址:

http://<电脑局域网 IP>:8765

注意局域网 HTTP 下部分手机浏览器会拒绝录音(非安全上下文),此时优先用公网 HTTPS 地址。所有业务数据只写 D:\dsh-classroom-mobile\data,不上传云端。

录音转写与课后整理流程

使用流程按顺序是:

  1. 手机打开页面,在「录音」页填课程标题,点「开始上课」。浏览器请求麦克风权限;录音过程中每 30 秒自动切一个分片上传,服务端逐片转写。
  2. 录音页字幕区每 3 秒刷新最近 5 段转写。转写引擎未就绪时页面提示「转写引擎未就绪,可手动粘贴文字」,并给粘贴框兜底,音频仍然照常保存。
  3. 点「结束并整理」停止录音,结束专注计时。
  4. 在 DSH 对话框里说「生成这节课的总结和导图」,Agent 调用 classroom_mobile_digest,生成 5 条带时间戳要点、mermaid 思维导图、3 条知识拓展、5 道由易到难的题并写入题目文件。
  5. 手机切到「总结 / 导图 / 复习」页刷新即可看到。
  6. 复习页作答后,在 DSH 里让 Agent 批改(classroom_mobile_grade)。未改正的错题大于 0 时,手机端不允许开始新录音,服务端也会返回 409。
  7. 课后在 DSH 里说「结束专注/看看专注报告」,classroom_mobile_focus 输出总时长、切走次数与累计离开时长、最长连续专注、番茄数。

转写引擎按顺序降级。先安装依赖:

python -m pip install faster-whisper

校园网建议加清华源。首次转写会把 small 模型(int8,约 460 MB)下载到 data\models,脚本默认走 HF_ENDPOINT=https://hf-mirror.com。pip 安装失败、模型下载失败、python/ffmpeg 不可用时,音频照存,transcript.md 写入「[此段待转写]」,/api/state 返回 asrAvailable=false。任何情况下都不会伪造转写文字。

HTTP 接口与数据目录

插件自带一组 HTTP 接口,手机页面就是它的客户端:

方法 路径 说明
GET / 单文件手机页面(内嵌 CSS/JS,中文,四页签)
GET /api/state 当前会话、录音时长、待改正错题数、ASR 状态、端口
POST /api/session/start {title} 新建会话;有未改正错题时 409
POST /api/audio 二进制音频分片,落盘后异步转写
GET /api/live 最近 5 段转写(页面 3 秒轮询)
GET /api/summary summary.md / mindmap.md 内容
POST /api/quiz/answer {index, answer} 手机端作答
GET /api/quiz/pending 未改正错题(同题以最新一条为准,correct=true 出队)
GET /api/quiz/questions 题目列表与作答状态
POST /api/focus/event {type: start\|leave\|return\|stop} 专注事件
POST /api/transcript/manual {text} ASR 不可用时手动补录

数据目录结构固定:

D:\dsh-classroom-mobile\data\
  current.json                     # 当前会话指针
  models\                          # faster-whisper 模型缓存
  sessions\<yyyy-mm-dd>-<标题>\
    meta.json                      # 录音起止时间、分片状态
    audio\chunk-000.webm ...       # 原始录音分片
    transcript.md                  # 增量转写,每段 "[mm:ss] 文本"
    summary.md                     # Agent 生成的总结
    mindmap.md                     # Agent 生成的 mermaid 思维导图
    quiz.jsonl                     # 出题 / 作答 / 批改记录
    focus.jsonl                    # 专注事件(start/leave/return/stop)

想不起 DSH 也能验服务时,用内置脚本:

node --check src\index.js
node scripts\dev-server.js    # 不起 DSH,直接起服务
node test\e2e.mjs              # 端到端:上传→转写→总结→错题门控→专注报告

test\e2e.mjs 会往真实数据目录写一个「自动验收测试」会话,运行结束会清理。

适用场景与注意

适合想在课堂里用上 DSH,并且愿意自己搭录音转写链路的开发者或研究者:录一节课,课后自动拿到总结、导图、练习题和专注报告,复习闭环由错题门控强制。

需要留意的地方:

  • 插件以当前 DSH 进程权限运行,安装前应检查源码与许可证(MIT),不要在未审阅的情况下直接装到生产环境。
  • 服务只在局域网内使用,没有登录鉴权,不要把端口暴露到公网;隧道地址有访问码兜底,但不要公开发布。
  • 全屏 API 在手机上常被拒绝,失败会静默忽略,不影响录音。
  • 浏览器切后台可能被系统暂停录音,项目只记录 visibilitychange,不保证后台录音连续。
  • 真机(iOS Safari / 安卓 Chrome / 微信内置)的录音编码和后台行为未被自动化测试覆盖,需要真机验证。
  • 专注报告只反映页面可见性变化,不能证明「没有分心」,也不是防沉迷工具。

结尾

这个插件的价值不在录音本身,而在把「录完」到「复习完」之间的链路打通:本地转写不经过第三方,总结和导图交给 DSH Agent,错题没改完就不允许开始下一节课的录音。对做课堂场景的人来看,这是一个可以直接组装进 DSH 的工作流。目录页在 https://www.skillhub.cn/plugins/chengyu-xin1/dsh-classroom-mobile ,源码在 https://github.com/chengyu-xin1/dsh-classroom-mobile 。

羽毛球分组比赛记分
小程序二维码

欢迎使用《羽毛球分组比赛记分》微信小程序

小夜