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

频谱律动 sqslm/dsh-pinpu

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

让对话轮次刻度条随系统播放的声音跳动

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

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

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

状态速览

判定依据:实装验证 · 静态安装检查 · 自动扫描 · 仓库维护状态
信任档位:待复验
是什么
dsh 原生插件 · vision
装得上吗
曾在 dsh 0.2.0-rc.2 下真实安装成功,但当前 dsh 已更新至 0.2.1-rc.5,本站尚未在新版下复验
L4 · 真实安装等级说明 →
安全吗
本站尚未对该插件做风险分级
暂未覆盖,不等同于无风险
还在维护吗
活跃:最近一次提交在 20 天前
档位由哪些信号合成

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

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

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

可执行外部命令读写/删除本地文件发起外部网络请求
查看扫描证据(共 8 处,展示前 8 条)
  • 发起网络请求
    lib/client.js:878
    var request = typeof fetch === 'function' ? fetch(url, { credentials: 'same-origin', headers: { accept: 'application/json' } }) : Promise.reject(new E
  • 发起网络请求
    lib/client.js:1235
    fetch(url, { credentials: 'same-origin', headers: { accept: 'application/json' } })
  • 发起网络请求
    lib/client.js:1384
    fetch(CLIENT_URL + '?event=' + encodeURIComponent(event) + suffix, { credentials: 'same-origin' }).catch(function () {});
  • 读取本地文件
    lib/loopback.js:68
    const found = candidates.filter((candidate) => existsSync(candidate))
  • 读取本地文件
    lib/loopback.js:73
    if (existsSync(candidate) && !found.includes(candidate)) found.push(candidate)
  • 删除本地文件递归
    lib/loopback.js:126
    rmSync(target, { recursive: true, force: true })
  • 执行外部命令来自配置/变量
    lib/loopback.js:160
    const child = spawn(python, [helperPath(), '--list'], {
  • 执行外部命令来自配置/变量
    lib/loopback.js:382
    child = spawn(python, ['-u', helperPath(), '--device', wantedDevice], {
扫描于 2026/11/4(0 天前) · 范围 入口闭包 + 发布文件清单 · 来源 GitHub 仓库

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

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

给 DeepSeek Harness 的音频响应式回合轨:转录文本自带的回合标记跟着系统正在播放的声音(WASAPI 回环)跳动,高亮只在悬停时出现,还可选左右轨布局。

README

由 DeepSeek 最新模型翻译生成
dsh-pinpu · 频谱律动 接管 DSH 对话右侧那条轮次刻度条本身,让它跟着系统正在播放的声音律动;同时按 Codex 的做法改掉高亮行为——默认不再高亮最新一条,鼠标移上去的那条才高亮,点击跳转照旧。 律动中 上图不是示意图:它是 tools/verify/rail-preview.mjs 在真实 Chromium 里、用从 DSH 自己的 dsh-client-ui-chat 安装包里抽出来的刻度条样式表 + 真实类名搭出刻度条,再加载真实的 lib/client.js 跑出来的(只有 /api/dsh-pinpu/spectrum 的数据是桩)。刻度长度的差异就是频谱:低频对应靠下的刻度(靠近最新一轮),高频在上。 鼠标悬停(同一次运行的第三张截图)只让指针下那一条变亮变满,其余保持暗色: 悬停高亮 安装 - 从本仓库装:在 DSH 的插件页用它安装 GitHub 仓库 sqslm/dsh-pinpu(和装其它 GitHub 插件一样),或 - 本地打包装:node tools/install-profile.mjs(pnpm pack → 写进 profile 的 dsh.profile.bundles,可 --uninstall 撤销、--dry-run 只看计划)。
展开完整文档(README 剩余 1 节)
dsh-pinpu · 频谱律动

接管 DSH 对话右侧那条轮次刻度条本身,让它跟着系统正在播放的声音律动;同时按 Codex 的做法改掉高亮行为——默认不再高亮最新一条,鼠标移上去的那条才高亮,点击跳转照旧。

律动中

上图不是示意图:它是 tools/verify/rail-preview.mjs 在真实 Chromium 里、用从 DSH 自己的 dsh-client-ui-chat 安装包里抽出来的刻度条样式表 + 真实类名搭出刻度条,再加载真实的 lib/client.js 跑出来的(只有 /api/dsh-pinpu/spectrum 的数据是桩)。刻度长度的差异就是频谱:低频对应靠下的刻度(靠近最新一轮),高频在上。

鼠标悬停(同一次运行的第三张截图)只让指针下那一条变亮变满,其余保持暗色:

悬停高亮

安装

- 从本仓库装:在 DSH 的插件页用它安装 GitHub 仓库 sqslm/dsh-pinpu(和装其它 GitHub 插件一样),或
- 本地打包装:node tools/install-profile.mjs(pnpm pack → 写进 profile 的 dsh.profile.bundles,可 --uninstall 撤销、--dry-run 只看计划)。
- 首次装载后需要重启一次 DSH:宿主半边(抓音频、注册路由)在进程启动时装载,浏览器半边随页面加载。
- 运行时无需安装任何依赖:原生采集模块随包分发(见 THIRD-PARTY.md),但需要一个 CPython 3.12 解释器——DSH 自带的那个就是,插件会自己去找。
- 平台:目前只支持 Windows(WASAPI 回环)。Linux 下 getUserMedia 的 monitor 源或 PulseAudio 的 .monitor 需要另做,尚未实现。

它改了什么

DSH 的刻度条有自己的状态类(mark / markActive / markPreview / markBusy / markUnloaded,名字是构建期哈希过的 xpvNua_)。插件不读类名,而是:

1. 按几何识别:在 [data-conversation-scroll] 里找出「同一父节点下、尺寸一致、右边缘对齐、垂直等距(≈10px)的一列按钮」——那就是刻度条;
2. 给它们加插件自己的属性(data-pinpu-rail / data-pinpu-tick="i",i 从最下面一条开始数 0);
3. 用一张 !important 的样式表覆盖状态:
- 所有刻度统一为暗色 + 统一长度 → 内置的“最新一条高亮”被关掉(不需要知道哪个类表示高亮);
- :hover 的那条变亮、拉满 → 只有鼠标在刻度条上才高亮;
- 播放时每条长度 = 它那一段频段的电平(transform: scaleX(var(--pinpu-scale))),频段按 log 从 45Hz 铺到 16kHz;
- 正在生成的那条(markBusy,靠 ::before 上是否有 animation 判断)不接管,保留它自己的脉冲动画。

点击跳转不动:插件的样式表只改 ::before 伪元素,命中区域仍是刻度条原来的按钮,app 自己的点击监听照旧收到事件(预览工具里实测 clicks delivered to the app handler: ["7"])。

实测(同一次预览运行):

| 状态 | 最后一条刻度(原本是内置高亮) | 悬停的那条 | 未被悬停的 |
| 接管前 | rgb(249,250,251)、scaleX(1)(亮、满) | — | 暗 |
| 接管后(播放中) | rgba(255,255,255,.2)、scaleX(0.87) | rgb(249,250,251)、scaleX(1) | 暗、scaleX(0.49) |

音源:直接读系统输出(网易云之类)

网易云 / 浏览器 / 任何程序 → 默认输出设备 → WASAPI 回环 → 频谱 → 刻度条

- 采集默认输出设备的回环,也就是「你现在听到的声音」,不需要任何虚拟声卡,也不挑播放器。
- 想固定到某个输出设备(例如插了耳机但想抓主板声卡),在设置卡片的设备下拉里选;留空 = 跟随系统默认输出。
- 采集在宿主半边(Node)里做:它用随 DSH 分发的 Python 跑 vendor/loopback.py,后者用随插件一起分发的 PyAudioWPatch(≈290KB,PortAudio 的回环构建)打开 [Loopback] 输入,把单声道 float32 PCM 从 stdout 流出来。宿主做 FFT 与频段映射,浏览器半边只负责画。
- 因此不需要麦克风权限、不需要用户手势,浏览器端一行采集代码都没有。

为什么不走 getUserMedia:它只能开「采集端点」。本机实测——注册表里 立体声混音 (Realtek USB Audio) 存在但处于禁用态(DeviceState=0x10000001,而 Chromium 会列出的端点都是 0x1),navigator.mediaDevices 里根本看不到它;更要紧的是立体声混音只镜像某一个输出设备,而本机的默认输出是耳机,所以就算启用了它,也听不到你在听的声音。回环抓默认输出才是正解。

设置项(设置 → 频谱律动)

宿主管信号,浏览器管呈现,所以下面分成两类。全部 .volatile(),改完立即生效(首次装载插件仍需重启一次)。

| 字段 | 默认 | 属于 | 说明 |
| enabled | true | 宿主 | 总开关;关掉后连采集进程都不再启动 |
| device | '' | 宿主 | 空 = 跟随默认输出;也可选具体 [Loopback] 设备 |
| fftSize | 1024 | 宿主 | FFT 窗口,≈21ms @48kHz |
| smoothing | 0.78 | 宿主 | 帧间平滑,越大越稳 |
| gain | 1 | 宿主 | 曲线后的整体增益 |
| autoGain | true | 宿主 | 按最响频段归一(见下) |
| gate | 0.04 | 宿主 | 低于它算静音 |
| minHz / maxHz | 45 / 16000 | 宿主 | 频谱范围 |
| punch | 0.55 | 宿主 | 打击感:某个频段瞬间高过它自己最近的峰值时按超出比例放大,鼓点是跳一下而不是"稍快一点" |
| flutter | 0.08 | 宿主 | 灵动:每个频段一条慢速随机游走,乘在该频段电平上(相邻刻度不再整体一起动,安静时自动消失) |
| disableActiveHighlight | true | 浏览器 | 关掉内置的“最新一条高亮” |
| hoverHighlight | true | 浏览器 | 鼠标移到刻度上才高亮 |
| restoreOnSilence | true | 浏览器 | 静音一段时间后停止律动(刻度停在基准长度) |
| minScale / maxScale | 0.4 / 1 | 浏览器 | 最短 / 最长刻度(20px 的比例;0.4 就是内置“未加载”刻度的长度) |
| invert | false | 浏览器 | 低频改到最上面 |
| side | right | 浏览器 | 刻度条所在的那一侧:right = 应用自己的位置,left = 镜像到左侧(刻度朝向和悬停预览卡片一起镜像) |
| colorMode | theme | 浏览器 | theme 用刻度条自己的颜色;spectrum 按频段给色;custom 用自定色 |
| customColor | #4d93f8 | 浏览器 | custom 的颜色 |
| glow | true | 浏览器 | 亮度层次:每段的亮度跟着自己的电平走(短=暗、命中=长且亮),悬停时仍是满亮 |
| hotScale | 0.85 | 浏览器 | 长度阈值高亮:某段长度达到满长的这个比例就点亮它(0 = 关闭) |
| spark | 1.5 | 浏览器 | 随机高亮:每秒期望点亮几次(每次随机挑一段亮 160–420ms;0 = 关闭,静音时不亮) |
| demo | false | 浏览器 | 无采集时用合成波形演示(默认关闭——会动的假波形容易骗人) |

两种高亮

都是在已有刻度条上点亮,不新增任何元素:被点亮的段用悬停时那支亮色 + 满亮度,长度仍是频谱自己的值。

- 阈值高亮(hotScale):判据是看得见的长度,不是电平——拿写进 --pinpu-scale 的那个值直接比较,所以一个参数只被解释一次。默认 0.85:高频段满长时亮,1.05 就等于关掉(频谱到不了),0 也等于关。
- 随机高亮(spark):每秒期望次数(1.5 = 大约每 0.7 秒一次)。每一次随机挑一个 没有* 正在跳动、也没被阈值点亮的段,亮 160–420ms 后自行熄灭。静音时不闪,所以正常听歌是"偶尔点缀"而不是一直闪。
- 正在生成的那条(markBusy)两种高亮都不碰,保留它自己的脉冲动画;鼠标悬停仍然优先于高亮。

真浏览器实测(tools/verify/rail-preview.mjs,一次运行采样 28 帧):

samples with a highlighted mark: 23 of 28 (threshold 20, random 3)
a highlighted mark, computed: {"reason":"spark","background":"rgb(249, 250, 251)","opacity":"1","transform":"matrix(0.693…)","scale":"0.723"}

即:被随机点亮的段确实是亮色 + 满亮度,而长度仍是它自己的 0.723。

律动是怎么算出来的(v0.3.0 重写)

旧实现的机械感来自四个具体原因,逐条对应:64 个频段共用同一个一阶平滑系数(所有段时间常数相同,只能整体一起动);同一个系数同时管上升和下降(鼓点被抹成缓慢起伏);没有瞬态强调与惯性保持;只有长度会变、亮度恒定。现在每个频段各自走一套:

1. 快起慢落,且每段速率不同:上升瞬时到位,回落用该频段自己的系数(低频拖尾 ~150ms、高频干脆 ~85ms 半衰期),所以同一次鼓点在不同段上是不同性格,不再形成一条"扫过去"的波。
2. Peak Hold + 惯性:命中后保持 4 帧,然后按该频段自己的速率衰减(这里踩过一次坑:用统一衰减速率会把刚做的分频段差异完全盖掉)。
3. 瞬态强调 punch:判据是"比这个频段最近的峰值高出多少",而不是"比缓慢均值高多少"——后者对持续音也成立,会把整块主体一起抬起来(实测对比度反而从 1.63× 掉到 1.17×)。改判据后同一段音频:2.13×(开)对 1.74×(关)。
4. flutter 微动:每个频段一条低通随机游走,乘在电平上。它没有周期(正弦式的固定周期正是"循环扫描感"的来源),而且安静时会自动归零,不会让安静的房间里刻度还在抖。
5. 静音自然衰减:静音判定只看原始频谱能量(抖动与强调都不能把安静弄活),但包络继续按各自的速率下落,浏览器侧在落的过程中照常绘制——停顿/切歌时是渐落,落完(约 700ms)才交还刻度条。
6. 亮度层次 glow:每段同时写长度和亮度,亮度用同一个电平的凹曲线(0.18 + 0.82·level^0.6),所以是"层次"而不是第二套动画。

实测(tools/verify/dynamics-profile.mjs,合成"底鼓+旋律+噪声+静音"喂真实分析器):

| 指标 | 结果 | 意义 |
| 最响频段同向连续移动的最长帧数 | 2 帧(43ms),方向反转 23 次 | 没有固定方向扫描(机械扫频会是几十帧同向) |
| 低频 / 高频衰减半衰期 | 171ms / 43ms | 有快有慢 |
| 相邻频段变化的相关性 | 0.48 | 不是整体同步(1.0 = 完全同步) |
| 鼓点对比度(关 / 开 punch) | 1.74× → 2.13× | 鼓点确实跳(同一段音频的 A/B) |
| 音乐停止后 | 峰值 0.008,下行过程 0 次上跳 | 安静时自然减弱,不闪烁 |

为什么需要自动增益

预览工装实测:不开归一化时,24 个频段只有 0.51~0.76 的跨度,37 条里只有 6 种长度,画出来像一堵墙;打开后同一信号得到 0.18~1.0、11 种长度。另一个实测结论是 Chromium 默认的 -100..-30 dB 分析窗口会把正常响度的内容整排顶格,所以窗口上沿抬到 -25 dB。

左右两侧

刻度条位置 选 左侧 时,插件不是另画一条,而是把应用自己的那条刻度条的定位容器(那层 position:absolute 的 frame)从 right:12px 改成 left:12px,同时把刻度的生长方向镜像过来(原本挂在右边缘、向左生长,改成挂在左边缘、向右生长),连悬停预览卡片也一起镜像,不然它会跑到屏幕外。真浏览器里实测:frame left 从 ~1160 变成 203(即对话左边缘),预览卡片由「开在左侧」变成「开在右侧」。

验证状态

| 手段 | 覆盖 | 结果 |
| node --test test/.mjs(75 项) | 清单/补丁契约、三处默认值一致、真实 schemastery 校验(每个字段都解析成 volatile 引用)、路由的鉴权与响应、采集的启停、PCM 环形缓冲的窗口随时间前进(用可辨认的样本值验证,含绕回之后)、FFT 对拍(与朴素 DFT 逐频段比对)、频段/重采样/电平契约、律动契约(快起慢落、低频比高频拖尾长、瞬态强调、微动存在但不闪烁且不能把安静弄活)、按几何识别刻度条的判别、左右镜像、亮度层次与不扫描的 CSS 规则、以及引擎的完整接管行为(发现→打标→轮询→写长度→写亮度→静音渐落→归位→错误停靠→禁用清理) | 全绿 |
| node tools/verify/dynamics-profile.mjs | 律动"性格"的量化:合成底鼓+旋律+噪声+静音喂真实分析器,测同向连续帧数、分频段半衰期、相邻频段相关性、鼓点对比度 A/B、停止后的下行过程 | 6/6 通过(数字见上表) |
| node tools/verify/host-smoke.mjs | 真实宿主链路:apply() → 采集进程 → 回环 PCM → FFT → 路由载荷 | 实测 status: live、设备 Speakers (Realtek Audio) [Loopback]、6 秒内峰值 0.34~0.88、23 种不同频段签名、12 种条长;非本机 Host 被 403 拒绝 |
| node tools/verify/rail-preview.mjs | 真浏览器 + 真刻度条样式/类名 + 真 lib/client.js:内置高亮被关、悬停高亮、点击仍触发 app 的处理器、长度随频谱变化 | VERDICT: the shipped rail was taken over and dances |
| node tools/verify/payload-contract.mjs --installed | 跨半边契约:把正在运行的宿主真实返回的载荷喂给窗口里正在跑的那份客户端代码,看它会画出什么(无需重启) | 修复前 distinct scales: 1(每个刻度同长),修复后 4 种长度 |
| 插件页与设置卡在运行中的应用里注册 | 未验证 | 需要重启一次 DSH(本会话就跑在那个进程里,重启会杀掉它) |

重启后的验收清单:

1. 「插件」页出现 dsh-pinpu / 频谱律动且为启用;
2. 设置 → 频谱律动能读到配置,状态行显示 采集中 与设备名(说明宿主采集起来了);
3. 放音乐(网易云即可)——对话右侧刻度条开始变长变短,最新一条不再常亮;把鼠标移到刻度条上,指针下那条变亮变满;点击仍能跳到对应轮次。若状态是 未找到 Python 运行时 或 错误,卡片里会给出原因。
4. 判"律动是否自然"看三点:鼓点处跳一下再回落(不是缓慢起伏)、相邻刻度不同步(不会整齐划一地动)、停歌后渐落而不是硬切。嫌太跳就把 打击感 调低,嫌太死就把 灵动 调高(两者都在设置卡的"响应"区,改完立即生效,无需重启)。

排查:是哪个半边没起来

插件有两个半边,由两套不同机制装载:宿主半边(Node:抓音频、提供路由、有日志)和浏览器半边(接管刻度条、渲染设置卡片)。「没反应」可能只是其中一半,而浏览器半边平时不留痕迹——所以宿主会记录它的上报:

curl.exe "http://127.0.0.1:19387/api/dsh-pinpu/spectrum?diag=1&ticks=4"
{"ok":true,"status":"live",...,"client":{"event":"heartbeat","detail":"live","ageMs":1200,"count":18,"errors":[]},
"python":"…\\python.exe","bands":64}

client.event 为 none = 浏览器半边从未运行(宿主半边是好的);error 会带上出错的那一步和原因。另外 node tools/diag-client-scan.mjs 能离线回答「这个包会不会被客户端模块系统认成浏览器半边」(把包名换成 dsh-plugin-proxy 可作对照)。

安装 / 更新 / 卸载

cd path\to\dsh-pinpu
node --test test/.mjs # 先跑测试
node tools/verify/host-smoke.mjs # 想确认能抓到系统声音
node tools/install-profile.mjs # 打包 + 备份 + 改 profile + pnpm install --offline
然后重启 DSH(组合包一层需要一次重启才会装载)

- 为什么装 tarball 而不是 link::link: 依赖会被解析到 profile 之外的源码目录,宿主半边 import z from '@deepseek-ai/schemastery' 会从源码目录往外找,而核心包在 profile 的 node_modules 里——找不到。dsh-purge 的注释记过同一个坑。装成 tarball(含 vendor/)后解析路径与 harness 自身一致。
- 改了源码要重新打包并重装,并且改一下版本号(同一版本号重打包,pnpm 可能认为“已是最新”而保留旧副本)。
- 卸载:node tools/install-profile.mjs --uninstall 后重启;或直接用 .bak-pinpu-* 备份覆盖 package.json / pnpm-lock.yaml。

已知限制

- 接管依赖刻度条的几何形状(一列等距、右对齐的按钮)。如果 DSH 以后改了刻度条的布局,插件可能认不出来——那时它不会乱改页面,只是不生效;设置卡片里的状态会显示刻度数为 0。
- 采集的是你选的那个输出设备的回环;系统默认输出换设备后,留空会自动跟随,但钉住某个设备时不会。
- 频段数由刻度条数量决定(一轮一条),不是自定义条数;minScale/maxScale 只能调长度范围。
- 内置的“忙碌脉冲”那条刻度不参与律动(保留它自己的动画)。
- 回环采集需要 Windows 上的 PortAudio 回环构建(pyaudiowpatch 的 Windows 轮子已随包分发);其它平台要另装或改用虚拟声卡。

许可

MIT。
预览分享卡片长什么样 ↓sqslm/dsh-pinpu
分享 · DeepSeek Harness Hub
sqslm/dsh-pinpu

让对话轮次刻度条随系统播放的声音跳动

这是你的仓库?认领条目

回到顶部