前言¶
DeepSeek Harness 的文档预览目前支持文本、Markdown、代码、图片、PDF、HTML 以及 Office 文档和表格,但不支持音频和视频。打开 mp4、mp3、wav 等文件时,预览区会提示 “Preview is not available for this file type yet”,只能通过顶部的 Open 按钮在宿主机上用原生应用打开。在宿主机上没问题,但在远程浏览器(例如手机、另一台电脑或 Tailscale 对等节点)上打开,就会在用户看不到的屏幕上弹出窗口。
dsh-media-web-preview 为 DSH 右侧边栏添加了原生播放器,支持音频和视频的即时预览与跳转。
插件介绍¶
dsh-media-web-preview 是一个 DSH 插件,由维护者 wilsonchengassistant 开发,分类属于「联网工具」。它注册了 video 和 audio 两种文档渲染器,在右侧边栏的文档预览区嵌入浏览器原生播放器。插件通过一个带认证的 HTTP Range 路由 /api/media 流式传输文件,使得远程浏览器可以播放和跳转大文件,而无需在宿主机上打开本地应用。
核心功能¶
- 原生播放器控制:支持播放/暂停、跳转、音量、全屏(视频),以及浏览器的画中画功能。
- 按需流式读取:利用 HTTP
Range请求(206 Partial Content和Content-Range),播放器按需请求字节片段,大视频无需将整个文件读入内存或对话上下文。 - 远程浏览器可用:URL 为文档相对路径,支持
http://127.0.0.1:3080、局域网地址、Tailscale MagicDNS 名称或tailscale serve端口 80,无需额外配置。 - 下载与新标签打开:播放器下方提供下载和在新标签页打开的操作。
- 本地化界面:提供英文和简体中文字典。
- 零运行时依赖:仅包含一个宿主机模块和一个浏览器打包文件。
支持的格式:
| 类型 | 后缀 |
|---|---|
| 视频 | mp4, m4v, webm, ogv, mov, mkv, avi, mpg, mpeg, 3gp, 3g2, ts, m2ts |
| 音频 | mp3, m4a, m4b, aac, wav, flac, ogg, oga, opus, weba, aiff, aif, wma, mid, midi |
安装与启用¶
从 npm 安装:
dsh plugin --profile web add dsh-media-web-preview
从本地目录安装:
dsh plugin --profile web add file:/absolute/path/to/dsh-media-web-preview
dsh plugin add 会记录依赖并将包追加到 dsh.profile.bundles。插件自带 dsh.bundle.patch,无需在 cordis.patch.yml 中手动添加 insert: 行。
宿主机端会热挂载插件到正在运行的 dsh web,刷新页面一次让浏览器包进入模块图;如果构建只在启动时组合插件,则重启 dsh web。
在右侧边栏的 Files 标签页打开任意支持格式的文件,播放器即可出现。顶部的原生 Open 菜单仍然可用。
为什么需要一个独立的媒体路由¶
DSH 已有 GET /api/file 路由,用于图片和 Markdown 预览。该路由总是返回完整 200 响应,忽略 Range 请求,且默认限制响应体大小约 20 MB。这对图片和文本预览是合适的,但对视频毫无用处:无法跳转,大文件会直接返回 413 Payload Too Large。为了避免改动共享路由,本插件新增了一个支持 Range 的兄弟路由 /api/media:
| 特性 | /api/file |
/api/media |
|---|---|---|
| 完整响应 | 200 |
200 |
Range 请求 |
忽略,返回完整 200 |
206 + Content-Range |
| 跳转 | 必须下载整个文件 | 即时 |
| 响应体大小限制 | ~20 MB | 受文件系统限制 |
| 读取方式 | 整个文件缓冲 | 通过 ctx.fs.readByteRange 每次读取 1 MiB 块 |
两个路由都位于 /api 下,因此共享同样的 Host/Origin 检查和浏览器 Cookie 认证。
技术实现¶
宿主机端:
- 通过
ctx.connection.fetch.register({ path: '/api/media', methods: ['GET', 'HEAD'] })注册路由。 - 请求通过
ctx.fs解析,解析Range头部为闭区间。 416错误携带bytes */<size>,HEAD请求仅返回头部,download=1参数添加Content-Disposition: attachment。- 响应携带
Cache-Control: private, no-store和X-Content-Type-Options: nosniff。
浏览器端:
- 通过
ctx.documentPreviews注册渲染器,设置loading: 'renderer',将文件后缀声明为二进制,避免回退到文本预览。 - 播放器从资源地址读取绝对路径,构建文档相对路径的
api/media?path=…URL,调用content.loaded(version)结束加载状态。
安全说明¶
- 路由位于
/api下,继承 DSH API 的认证和 Host/Origin 检查,未认证请求返回401,不受信 Host 返回403。 - 仅接受绝对路径,不提供目录列表,不会绕过文件系统提供者的解析和访问策略。
- 响应头包含
Cache-Control: private, no-store和X-Content-Type-Options: nosniff。 - 无遥测、无出站网络请求、无运行时依赖。
兼容性与使用范围¶
- DSH
0.2.0-rc.2及之后版本,需提供ctx.documentPreviews、sidebar.right.tab.document、ctx.connection.fetch和ctx.fs.readByteRange。 - Node.js 22+。
- 也可在 DSH 桌面应用中使用,此时媒体路由为文档相对路径。
本插件聚焦于默认右侧边栏和远程浏览器播放,不提供播放列表、字幕轨道、播放速度控制和对话中的内联媒体卡片,这些由其他社区插件覆盖。
结尾¶
dsh-media-web-preview 解决了 DSH 在远程场景下无法预览和跳转音视频的问题,通过 HTTP Range 路由实现流式读取,适合需要在远程浏览器中处理媒体文件的智能体开发者。
- 插件目录页:https://www.skillhub.cn/plugins/wilsonchengassistant/dsh-media-web-preview
- GitHub:https://github.com/wilsonchengassistant/dsh-media-web-preview