在 DSH 右侧边栏预览音频和视频

前言

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
羽毛球分组比赛记分
小程序二维码

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

小夜