dsh-daily-transcription
v0.1.0
Published
dsh plugin: transcription (developer preview)
Downloads
52
Readme
transcription
dsh(DeepSeek Harness)插件:音/视频文件转录 + 章节与待办提取。双引擎——openai-compatible(默认,OpenAI 兼容 /audio/transcriptions 云端端点)与 local-whisper(本地 whisper.cpp 子进程,全离线)——输出统一的结构化 Transcript(带起止时间的分段),再用本地启发式(无模型调用、零额外配置)给出章节(静音间隔/时长窗口分章)与待办(关键词命中句)。可导出 plain/srt/vtt 三种可读格式。
状态:developer preview。尚未在真实 dsh 运行时中验证,手动验证步骤见下文。
安装与配置
# dsh 配置示例
- id: transcription
name: dsh-daily-transcription
config:
enabled: true
provider: openai-compatible # 或 local-whisper(全离线)
language: '' # 语言提示(ISO-639-1,如 zh/en);空 = 自动
maxDurationSec: 7200 # 媒体时长上限(秒)
chapterWindowSec: 300 # 分章时长窗口(秒),默认 5 分钟
silenceGapSec: 8 # 静音间隔阈值(秒),超过则另起一章
ffmpegPath: '' # ffmpeg 路径;视频输入/云端裁剪必需
tempDir: '' # 临时音频目录;空 = 系统临时目录
openai: # 云端引擎(默认 provider)
baseURL: https://api.openai.com/v1
apiKeyEnv: OPENAI_API_KEY # 环境变量名,密钥只从环境变量读
model: whisper-1
timeoutMs: 600000
whisper: # 本地引擎(local-whisper)
binaryPath: whisper-cli # whisper.cpp 二进制路径
modelPath: '' # 模型文件路径(如 ggml-base.bin),必填
timeoutMs: 3600000换兼容端点:Groq / DeepInfra 等 OpenAI 兼容转录端点只需改 openai.baseURL(及 apiKeyEnv/model),例如 Groq:
openai:
baseURL: https://api.groq.com/openai/v1
apiKeyEnv: GROQ_API_KEY
model: whisper-large-v3安装 whisper.cpp(local-whisper 需要,插件不内置、不编译):
git clone https://github.com/ggml-org/whisper.cpp && cd whisper.cpp
cmake -B build && cmake --build build --config Release
bash models/download-ggml-model.sh base # 下载模型
# 然后把 build/bin/whisper-cli 填入 whisper.binaryPath,models/ggml-base.bin 填入 whisper.modelPath二进制缺失时插件会报出带上述指引的可读错误。安装 ffmpeg(视频输入或云端时间范围裁剪需要):Windows winget install ffmpeg,macOS brew install ffmpeg,Linux apt install ffmpeg,然后配置 ffmpegPath。
工具
transcribe_file:转录音/视频文件为结构化结果。参数:path(必填)、provider(覆盖配置)、language、startSec/endSec(只处理片段:local-whisper 经 whisper-cli-ot/-d原生支持;云端端点不支持,需配置ffmpegPath由插件先本地裁剪,未配置则拒绝并说明)。返回transcript(text + 带起止时间的 segments)、chapters(启发式分章,标题为该章首句截取)、actionItems(关键词命中句,启发式、未经模型核对)、warnings。transcript_format:把transcribe_file返回的transcript导出为可读文本。format三选一:plain([mm:ss]逐行)、srt(HH:MM:SS,mmm)、vtt(HH:MM:SS.mmm);写入outputDir指定目录(自动创建),文件名默认transcript-<时间戳>.<ext>,可用filename覆盖。
典型流程:transcribe_file → 用户浏览章节/待办 → transcript_format 导出 srt/vtt 字幕或 plain 纪要。
两个 Provider 的边界
- openai-compatible:把音频文件以 multipart 形式上送到
${baseURL}/audio/transcriptions,response_format=verbose_json拿回分段。密钥只从openai.apiKeyEnv环境变量读取。时间范围参数该端点不支持,插件用 ffmpeg 先裁剪出临时音频再上传。 - local-whisper:纯子进程编排——检查
whisper-cli与模型文件存在 → 执行-oj输出 JSON → 解析(JSON 缺失时回退解析 stdout 时间轴)→ 清理临时输出文件。完全离线。时间范围经-ot/-d传给 whisper-cli。
说话人分段(diarization):whisper.cpp 与 Whisper API 都不做说话人分离,首版所有分段的 speaker 恒为空,README 明示;v2 可接 pyannote 类服务实现 TranscriptionProvider 同一接口。
章节与待办:均为本地启发式,不做任何模型调用。分章按静音间隔(silenceGapSec)与时长窗口(chapterWindowSec,默认 5 分钟)切分,标题取该章首句(超 30 字截断);待办为关键词(TODO/待办/需要/下一步/action item,不区分大小写)命中句,输出中始终标注启发式属性,请人工核对后使用。
权限透明
本插件对宿主环境的影响面,逐条交代清楚:
- 读:用户通过
transcribe_file的path参数显式指定的音/视频文件(只读,绝不修改原文件);local-whisper 另读whisper.modelPath模型文件。 - 写:① 系统临时目录(或
tempDir)下的dsh-transcription-*工作目录——视频抽轨/裁剪的临时音频与 whisper-cli 的 JSON 输出,用完即删(finally 清理);②transcript_format的outputDir参数显式指定的导出目录。除此之外不写任何位置。 - 网络:仅当 provider 为 openai-compatible 时,访问
openai.baseURL配置的唯一端点。local-whisper 与导出功能完全离线。 - 凭证:云端 API Key 只从
openai.apiKeyEnv指定的环境变量读取,不写入配置、导出文件或日志。 - 子进程:local-whisper 执行
whisper.binaryPath;视频/裁剪路径执行ffmpegPath。取消(exec.signal)会 kill 子进程。 - 确认点:无 dsh ask 挂钩;
transcribe_file对原文件只读,导出目录由调用方显式指定。 - 日志内容:启动日志含 provider 名、ffmpeg/模型是否已配置;不含音频内容、密钥。
⚠️ 隐私提示:使用默认的 openai-compatible provider 时,音频文件的完整内容会发往你配置的转录端点(可能是第三方云服务)。录音通常含人声与谈话内容等高度敏感信息;介意请改用
provider: local-whisper(全离线),或把openai.baseURL指向你自建的兼容端点。
已知限制
- 无说话人分段:两个引擎都不做 diarization,
speaker恒为空;需要分角色的场景请等 v2(pyannote 类服务)或外部工具预处理。 - 章节与待办是启发式:分章标题是首句截取、待办是关键词命中,均无语义理解,可能不准;输出中已标注,请勿跳过人工核对。
- 大文件:超过
maxDurationSec(默认 2 小时)拒绝处理;云端端点自身还有文件大小限制(如 OpenAI 25 MB),超限请配置ffmpegPath后用startSec/endSec分段处理。 - 云端时间范围:端点不支持,依赖本地 ffmpeg 裁剪;未配置
ffmpegPath时带startSec/endSec的云端请求会被拒绝并提示。 - 视频支持依赖 ffmpeg:插件不内置 ffmpeg;未配置时视频输入报可读错误。
- 转录质量取决于所用引擎与模型(whisper-1 / 本地 ggml 模型尺寸),中英文混合、强噪声场景可能退化。
手动验证
本仓库的 CI 只覆盖类型检查与纯函数/替身单测。接入真实 dsh 后请手动验证:
- 在 dsh 配置中启用本插件,确认启动日志出现
transcription: loaded。 - 云端路径:设置
OPENAI_API_KEY(或自建端点),对transcribe_file传一段短音频(mp3/wav),确认返回transcript.segments带起止时间、chapters/actionItems非空且 warnings 标注启发式;再把apiKeyEnv指向不存在的环境变量,确认报错含变量名指引。 - 离线路径:安装 whisper.cpp 并配置
whisper.binaryPath/whisper.modelPath,以provider: local-whisper转录同一音频,确认成功且 warnings 含「不做说话人分段」;把binaryPath改成一个不存在的路径,确认报错含安装指引。 - 视频路径:配置
ffmpegPath后传一个 mp4,确认临时 wav 被抽取并转录、结束后系统临时目录无dsh-transcription-*残留;不传ffmpegPath时确认报「请先抽取音轨」类可读错误。 - 时间范围:local-whisper 传
startSec: 60, endSec: 120,确认只转录该片段(分段时间从 0 起算);云端在不配置ffmpegPath时传时间范围,确认被拒绝并说明。 - 导出:对结果调用
transcript_format分别导出 srt 与 vtt,用播放器加载字幕确认时间轴正确;plain 导出确认[mm:ss]逐行格式。 - 取消:转录长音频中途取消会话,确认报「操作已取消」且本地子进程被终止。
许可
MIT
