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

开机动画音效 2034126171/dsh-boot-animation-sound

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

启动时播放带声音的开机动画,开声不必进全屏

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

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

自动兼容检查有告警:未发布到 npm registry,仅可从源码安装。
安装命令 · 需先装 dsh CLI 引擎
dsh plugin --profile web add 2034126171/dsh-boot-animation-sound
该包不可直接 npm 安装,改从 GitHub 源安装(明细见下方安装检查)

状态速览

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

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

验证判据与等级说明 →
社区实装还没有人打卡 · 装过的第一个就是你
安装兼容性检查⚠ 装前注意

未发布到 npm registry,仅可从源码安装

展开查看检查明细 ↓

以下结论由程序自动检查 npm 包、engines 声明与入口文件得出,未做人工实机验证——能装不等于用着没问题。

✗npm 包dsh-boot-animation-sound(未发布到 npm,仅可源码安装)
✓Node 引擎要求 >=20 · 基线 Node 22.19 满足
✓dsh CLI 依赖未声明 dsh 版本约束
✓入口文件main/exports/bin 已声明

验证方式:npm registry 存在性 + package.json 静态校验 · 最后检查 2026/10/14 03:22:17

安全扫描自动 · 静态分析源码
v2.7.0
🔵 扫描:含敏感能力尚无人工评估
展开查看扫描说明与证据 ↓

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

可执行外部命令读写/删除本地文件
查看扫描证据(共 36 处,展示前 31 条)
  • 读取本地文件
    index.js:379
    if (!existsSync(path)) return { configured: true, source, problem: 'missing-file', extension, path }
  • 读取本地文件
    index.js:383
    stats = statSync(path)
  • 读取本地文件
    index.js:432
    const parsed = JSON.parse(readFileSync(stateFile(dshHome), 'utf8'))
  • 写入本地文件
    index.js:445
    mkdirSync(stateDir(dshHome), { recursive: true })
  • 写入本地文件
    index.js:448
    writeFileSync(temporary, `${JSON.stringify(value, null, 2)}\n`, 'utf8')
  • 写入本地文件
    index.js:451
    renameSync(temporary, file)
  • 写入本地文件
    index.js:461
    mkdirSync(stateDir(dshHome), { recursive: true })
  • 写入本地文件
    index.js:462
    writeFileSync(join(stateDir(dshHome), 'last-boot.json'), `${JSON.stringify(report, null, 2)}\n`, 'utf8')
  • 读取本地文件
    index.js:472
    return JSON.parse(readFileSync(join(stateDir(dshHome), 'last-boot.json'), 'utf8'))
  • 读取本地文件
    index.js:495
    raw = JSON.parse(readFileSync(join(stateDir(dshHome), 'play-state.json'), 'utf8'))
  • 写入本地文件
    index.js:514
    mkdirSync(stateDir(dshHome), { recursive: true })
  • 读取本地文件
    index.js:585
    const stream = createReadStream(media.path, { start, end })
  • 执行外部命令固定命令
    index.js:717
    child = spawn('powershell.exe', ['-NoProfile', '-STA', '-ExecutionPolicy', 'Bypass', '-Command', script], { windowsHide: true })
  • 删除本地文件
    index.js:742
    unlinkSync(carrier)
  • 读取本地文件
    verify/check-media.mjs:51
    const text = readFileSync(path).toString('latin1')
  • 读取本地文件
    verify/check-media.mjs:53
    bytes: statSync(path).size,
  • 读取本地文件
    verify/check-media.mjs:63
    files = readdirSync(MEDIA_DIR).filter((name) => /\.(mp4|m4v|webm|mov|mkv|ogv)$/i.test(name)).sort()
  • 读取本地文件
    verify/client-smoke.mjs:27
    const CLIENT = readFileSync(join(PACKAGE_DIR, 'client.js'), 'utf8')
  • 读取本地文件
    verify/host-verify.mjs:36
    const CLIENT = readFileSync(join(PACKAGE_DIR, 'client.js'), 'utf8')
  • 读取本地文件
    verify/host-verify.mjs:37
    const MANIFEST = JSON.parse(readFileSync(join(PACKAGE_DIR, 'package.json'), 'utf8'))
  • 读取本地文件
    verify/host-verify.mjs:219
    check('the bundled clip exists in the package', existsSync(BUNDLED_MEDIA), BUNDLED_MEDIA)
  • 写入本地文件
    verify/host-verify.mjs:226
    writeFileSync(junk, 'not a video')
  • 读取本地文件
    verify/host-verify.mjs:273
    check('the settings file was written', existsSync(join(home, 'dsh-boot-animation-sound', 'settings.json')))
  • 读取本地文件
    verify/host-verify.mjs:307
    check('the report file was written', existsSync(reportFile), reportFile)
  • 读取本地文件
    verify/host-verify.mjs:308
    const storedReport = JSON.parse(readFileSync(reportFile, 'utf8'))
  • 写入本地文件
    verify/host-verify.mjs:357
    writeFileSync(dailyState, JSON.stringify(backdated))
  • 删除本地文件递归
    verify/host-verify.mjs:377
    for (const leftover of [freshHome, dailyHome, onceHome, conversationHome]) rmSync(leftover, { recursive: true, force: true })
  • 删除本地文件递归
    verify/host-verify.mjs:402
    rmSync(offHome, { recursive: true, force: true })
  • 删除本地文件递归
    verify/host-verify.mjs:416
    rmSync(spentHome, { recursive: true, force: true })
  • 删除本地文件递归
    verify/host-verify.mjs:427
    rmSync(occasionHome, { recursive: true, force: true })
  • 删除本地文件递归
    verify/host-verify.mjs:511
    rmSync(home, { recursive: true, force: true })
扫描于 2026/11/4(0 天前) · 范围 入口闭包 + 发布文件清单 · 来源 GitHub 仓库

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

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

功能亮点

  • 启动播放开机动画
  • 播放音效无需全屏
  • 自定义触发时机

DSH 开机动画:声音不需要全屏。触发时机(启动应用/页面刷新/新对话/任意会话)与播放频率(每次/每天一次/只播一次/限播 N 次)可自选。

README

由 DeepSeek 最新模型翻译生成
dsh-boot-animation-sound 给 DeepSeek Harness(DSH)加一段开机动画:启动时铺满窗口播放一段视频。 和别的开机动画比,这一版只改一件事:声音不需要全屏。 纯 JavaScript,没有构建步骤。 作者:LSY(个人创作) · MIT · 版权归 LSY 所有,见 LICENSE。 为什么需要它 参考社区里几个开机动画,它们的做法是: 浏览器禁止带声音自动播放 → 动画一律静音起播 → 想听声音就点一下画面 → 但那一按同时还会 requestFullscreen(),于是「开声音」和「进全屏」被绑成了同一个动作。 (dsh-boot-animation-pro 的 README 自己就是这么写的:点一下画面即可开启声音并进入全屏。
展开完整文档(README 剩余 1 节)
dsh-boot-animation-sound

给 DeepSeek Harness(DSH)加一段开机动画:启动时铺满窗口播放一段视频。

和别的开机动画比,这一版只改一件事:声音不需要全屏。

纯 JavaScript,没有构建步骤。

作者:LSY(个人创作) · MIT · 版权归 LSY 所有,见 LICENSE。

为什么需要它

参考社区里几个开机动画,它们的做法是:

浏览器禁止带声音自动播放 → 动画一律静音起播 → 想听声音就点一下画面 → 但那一按同时还会 requestFullscreen(),于是「开声音」和「进全屏」被绑成了同一个动作。

(dsh-boot-animation-pro 的 README 自己就是这么写的:点一下画面即可开启声音并进入全屏。)

本插件把这两件事拆开:

| 动作 | 常见的绑定式做法 | 本插件 |
| 起播 | 一律静音 | sound: true 时先试带声音起播 |
| 被系统拦下 | 静音播放,等点击 | 静音播放,等点击(一样) |
| 点一下画面 | 开声 + 进全屏 | 只开声,窗口大小一动不动 |
| 第一次点击/按键 | 必须点在画面上 | 窗口内任意位置的第一次点击/按键就开声 |
| 进全屏 | 开声的副作用 | 只有那个默认关闭的「全屏」按钮才会进 |

代码层面:client.js 里 requestFullscreen() 只出现一次,就在全屏按钮的事件处理函数里;开声那条路径(unlock)只做两件事:video.muted = false 和 video.play()。
这条约束由验证脚本静态断言,改坏了跑测试就会红。

声音到底能不能自动响

先说规则。这个结论是在真实环境里实测出来的,不是照抄文档:

- 在一个没有任何用户手势的页面里,非静音的 play() 会被 Chromium 拒绝(NotAllowedError)。
Electron 的默认自动播放策略本应是 no-user-gesture-required,但实测就是拒绝了,所以本插件按「会被拒绝」来设计,而不是赌它不拒绝。
- 一旦这个页面有过用户手势(哪怕只是之前随便点过一下),非静音播放就会被放行。

于是分三种情况,插件三种都实现了:

1. 平台放行 → 直接就有声音,一次都不用点。
2. 平台拦下 → 画面照常播,右下角出现一个「🔊 点这里开声(不用全屏)」的小按钮; 同时你在窗口里随便点一下或按一下键盘也会开声。同一个窗口,不进全屏。
3. 设置里关掉声音 → 连试都不试,静音播放,也不出现任何开声提示。

想彻底免点击,只能改平台策略本身(例如给 Electron 传 --autoplay-policy=no-user-gesture-required),那不是插件能做的事。
本插件能做的是:不让你用全屏去换声音,并把「要点的那一下」缩到最小——点哪都行。

实测记录

真实窗口里跑过一次之后,插件自己写下的 last-boot.json(原文摘录):

{
"audio": "on", // 有声播放 "muted": false, // 元素没被静音 "audioDecodedBytes": 115835, // 真的解码出 115 KB 音频,声音确实出来了 "fullscreen": false, // 没有全屏 "fullscreenEverRequested": false, // 全程没请求过全屏 "duration": 7.05, "videoWidth": 1280, "videoHeight": 720, "ua": "… @deepseek-ai/dsh-desktop/0.2.0-rc.2 Chrome/152.0.7977.54 Electron/44.0.0 …"
}

audioDecodedBytes 是关键:它说明音频真的被解码并送进了输出管线,而不是「元素说自己没静音」而已。

触发时机与播放频率

触发时机(什么时刻播)

| 选项 | 含义 |
| 启动应用 | 一次 DSH 运行里只算第一次页面加载 |
| 页面刷新 | 每次页面加载都算(默认;也就是这个插件最早的行为) |
| 新对话 | 点「新建对话」时 |
| 任意会话 | 打开任意对话时,新建的也算 |

「启动应用」与「页面刷新」的区别由宿主判定,不是浏览器猜的:宿主半在每次 DSH 运行时只挂载一次,它数自己服务过多少次首页渲染——第 1 次就是「启动应用」,之后都是「页面刷新」。
这样「触发时机」和「要不要盖住首帧」用的是同一个计数器,不可能互相矛盾。

后两个是会话触发:它们不在页面加载时播,而是在你新建/打开对话时把动画盖在界面上(Esc 随时可退)。

会话触发没有现成的事件可用——DSH 客户端的事件表里只有 connection/reset、locale/change、 slots/changed、theme/change,没有会话事件。所以插件包了一层界面用来导航的那个服务(uiWorkspace 的 startSession / openSession / connectWorkspace)。
这层包装写得很保守:先调用原方法并原样返回它的结果,通知失败绝不影响导航;赋值不成功就干脆不包;插件卸载时逐个还原。宁可这个触发不生效,也不让导航出问题。

播放频率(一共能播几次)

| 选项 | 含义 |
| 每次 | 不限(默认) |
| 每天一次 | 每个自然日最多一次(按本机本地日期,不是 24 小时窗口) |
| 只播一次 | 一辈子最多一次 |
| 限播 N 次 | 最多 N 次,N 可填 1–1000 |

计数存在宿主这边(<DSH_HOME>/dsh-boot-animation-sound/play-state.json),不是浏览器里:只存浏览器的话,刷新一下就忘了、开第二个窗口就各算各的。所以:
- 播放权由宿主唯一判定,判定通过时当场扣一次(POST /claim);被拒绝的请求不扣。
- 只有真的开始播才计数;被拒绝的那些页面加载不算。
- 次数用完后,那些页面加载连首帧遮罩都不会注入——不会先黑屏再放出来。
- 设置页有「重置计数」,否则「只播一次」就是一扇只能改文件才能打开的门。

只在「一次页面加载」时播放

页面加载类的触发还有一道额外的判定:开机动画属于一次页面加载,不属于「插件被加载的那一刻」。
DSH 的 client 模块图是活的——把插件当场启用、或 HMR 把模块塞进一个开着很久的页面,都会加载这个文件。
所以浏览器半会先判断这是不是属于本次加载:

- 宿主在服务端 HTML 里注入的首帧遮罩在 里——它在,就是本次加载(精确信号);
- 遮罩关掉时(coverApplication: false)退回用页面年龄判断:模块在页面开了几分钟后才到,那一定是热加载,不播。

这样正常启动照常播,而不会突然盖住你正在干活的窗口。

安装

profile 目录是 <DSH_HOME>/profiles/<profile 名>(<DSH_HOME> 未设置时默认 ~/.dsh)。

方式一:让 agent 用 plugin_manager 装(桌面版首选)

plugin_manager: action=install_bundle, target=github:2034126171/dsh-boot-animation-sound

方式二:命令行

npm install -g @deepseek-ai/dsh
dsh plugin --profile web add github:2034126171/dsh-boot-animation-sound

方式三:手动

1. 在 profile 目录的 package.json 里,dependencies 加 "dsh-boot-animation-sound": "github:2034126171/dsh-boot-animation-sound";
2. 把 "dsh-boot-animation-sound" 加进同一个文件的 dsh.profile.bundles 数组;
3. 在该目录里用 pnpm 执行 install(桌面版自带 pnpm,在 <DSH_HOME>/.desktop-bin/pnpm.cmd);
4. 重启 DSH。

通过 GitHub 安装需要本机装有 git。

开发机上的现状(与使用者无关,仅供本仓库作者参考):源码放在工作区,profile 用两个 junction 指过来(profiles/node_modules/… 与 profiles/desktop/node_modules/…;前者给依赖 spec 用,因为它没有空格),并在 dsh.profile.bundles 里列了包名;改 profile package.json 之前已备份为 package.json.before-dsh-boot-animation-sound.bak。

使用

设置页在 设置 → 插件 → 开机动画:

| 项 | 说明 |
| 触发时机 | 启动应用 / 页面刷新 / 新对话 / 任意会话 |
| 播放频率 | 每次 / 每天一次 / 只播一次 / 限播 N 次(N 可填 1–1000) |
| 播放影片声音 | 这个插件的主角。默认开。关掉=整段动画静音,也不再出现开声提示 |
| 音量 | 0–100% |
| 首次点击/按键自动开声 | 默认开。关掉后只能点右下角那个开声按钮 |
| 启动时显示动画 | 临时关掉动画,但保留已选路径 |
| 显示全屏按钮 | 默认关。和声音毫无关系:开声永远不会触发它 |
| 退出方式 | 右下角按钮 / 点任意位置 / 自动退出 / 不能退出 |
| 视频文件 | 路径输入框 + 「选择文件…」原生对话框 + 保存 / 清除 |
| 播放账本 | 已播次数 + 上次日期,旁边有「重置计数」 |

「清除」=不再播放,DSH 启动起来和没装这个插件时一模一样。

保命键

Esc 永远能退出动画,任何退出方式下都生效。全屏层吞得掉鼠标点击,吞不掉键盘。
一个铺满屏幕、又关不掉的面板离「软件没法用」只差一个 bug,所以这个键是无条件保留的。

出问题怎么看

每次真实启动的结果都会写进:

<DSH_HOME>/dsh-boot-animation-sound/last-boot.json

设置页底部也会显示一行摘要。关键字段:

| 字段 | 含义 |
| audio | on 有声播放 / off 按设置静音 / blocked 被系统拦下(点一下就能开)/ error 播放失败 |
| muted | 那一刻元素是否静音 |
| audioDecodedBytes | 音频真的被解码出来的字节数。> 0 说明视频有音轨、音频管线真的跑了;0 说明这段视频根本没声音 |
| fullscreen | 那一刻是否处于全屏 |
| fullscreenEverRequested | 本次启动是否请求过全屏(正常情况下永远是 false) |
| userActivation | 当时的用户激活状态 |

排查顺序:先看 audioDecodedBytes 是不是 0(是 0 → 换一个带音轨的视频),再看 audio 是不是 blocked(是 → 点一下窗口任意位置,或确认「首次点击/按键自动开声」是开的),最后看 muted 和音量。

配置(可选)

也可以直接改 profile 的 cordis.patch.yml:

- id: dsh-boot-animation-sound
config:
src: D:/videos/boot.mp4 # 留空字符串 = 不播;不写 = 用自带视频 trigger: pageRefresh # appStart / pageRefresh / newConversation / anySession frequency: every # every / daily / once / times maxPlays: 3 # 仅 frequency: times 时有效,1–1000 sound: true volume: 0.9 fit: cover # cover 铺满裁切 / contain 完整留边 / fill 拉伸 skip: button # button / click / auto / never fadeOutMs: 360 showFullscreenButton: false

设置页里改过的项会盖在 patch 上面(存在 <DSH_HOME>/dsh-boot-animation-sound/settings.json;播放计数另存 play-state.json)。字段写错只会退回默认值,不会导致启动失败。完整字段见 index.js 里的 DEFAULTS。

验证

npm run verify

252 项检查,全部不依赖 DSH、不依赖浏览器,也不需要安装任何依赖:

- verify/check-media.mjs(6 项):media/ 里的片段是否真的是视频容器、是否带音轨。
自带视频没声音的话这个插件就没意义了,所以这一条是硬检查。
- verify/host-verify.mjs(168 项):跑宿主半的真实代码——配置归一化、媒体解析、七个 HTTP 路由(媒体流含 Range 取字节、设置保存、开机报告落盘、播放权 claim 与计数 reset)、
首帧遮罩注入,以及静态断言:「requestFullscreen() 只有一个调用点且在按钮里」、「结束时什么都不画」。
触发与频率单独一节逐条验:四种触发×四种频率的判定矩阵、每天一次按本地日期而不是 24 小时、被拒绝的请求不扣次数、次数用尽的页面加载不注入遮罩、以及 /claim 真的把账记到 play-state.json 上。
- verify/client-smoke.mjs(78 项):用一个迷你 React + 假 DOM + 假 + 可切换的自动播放策略(复现真实环境那个 NotAllowedError)把浏览器半真跑一遍:带声起播 → 被拒 → 静音兜底 → 出现开声提示 → 第一次点击开声 → 全程零次 requestFullscreen(); 断言页面加载时 claim 的是宿主给的那个 occasion、会话触发在页面加载时一次都不 claim、被拒绝的 claim 什么都不画;会话包装原样返回导航结果并且能被还原;热加载进老页面时不播;以及收场回归测试(跳过 / 播完 / Esc 都要让出屏幕)。
这个迷你 React 会真的调用上一次的 effect 清理函数——清理函数要是被丢掉,组件漏掉监听器也能「通过」,那这些测试就没有意义了。

变异验证(一次性做过):把 if (!running) return null 换回
if (!active) return null,client-smoke.mjs 立刻 2 项失败,失败详情里正是那个
position: fixed; inset: 0; z-index: 2147483000 的盒子和「正在加载视频…」。
测试对着它命名的缺陷会红,才叫回归测试。

已修过的严重缺陷

动画结束后整个界面点不动。 覆盖层是铺满视口的固定定位盒子,而槽位注册表会让组件在整个页面生命周期里保持挂载;原来的渲染判断只看了「该不该播」,没看「还在不在播」,于是播完之后那层 透明但仍在最上面的盒子继续吃掉每一次点击。修法是把「该不该播」和「现在还在不在播」分开,并让所有 effect 跟着它走,另加三道独立保险(pointerEvents 随淡出放行、10 分钟硬上限、 Esc 无条件可退出)。完整来龙去脉见 CHANGELOG.md。

素材与权利

media/视频测试.mp4 是示例片头,不在下面的 MIT 授权范围内,其权利归属请自行确认;要公开分发请先换成你拥有权利的素材(替换该文件即可,不需要改代码)。

verify/check-media.mjs 会检查它带不带音轨——视频必须自带音轨,否则声音那一栏没有任何东西可放。

许可

MIT,覆盖插件代码(见 LICENSE)。示例素材不在该授权范围内,详见 NOTICE。

作者:LSY(个人创作) —— 版权归 LSY 所有。MIT 授权下你可以自由使用、修改、再分发,但请保留 LICENSE 里的版权声明。
预览分享卡片长什么样 ↓2034126171/dsh-boot-animation-sound
分享 · DeepSeek Harness Hub
2034126171/dsh-boot-animation-sound

启动时播放带声音的开机动画,开声不必进全屏

这是你的仓库?认领条目

回到顶部