Skip to content
dsh.fish
Bundle

media-preview

DSH 插件:在聊天记录中自动将本地音视频/图片路径渲染为可播放的预览组件。When an assistant message or tool result contains a local media path, the path is replaced inline with a playable <audio>/<video>/<img> element backed by same-origin /api/media-preview/* route.

Source
xiaokaizhou
License
MIT
Updated
Updated 3 days ago

Readme

# dsh-media-preview

[![中文](https://img.shields.io/badge/语言-中文-blue)](./README.md) [![English](https://img.shields.io/badge/language-English-lightgrey)](./README.en.md) [![npm](https://img.shields.io/npm/v/@xiaokaizhou/dsh-media-preview)](https://www.npmjs.com/package/@xiaokaizhou/dsh-media-preview)

> **DSH 插件:在聊天记录中自动将本地/在线音视频/图片路径渲染为可播放的预览组件**

当助手消息或工具结果中出现本地音频/视频/图片路径,或在线 http(s) 媒体链接时,自动将其替换为内联的 `<audio>` / `<video controls playsInline>` / `<img>` 预览。

**默认模式为 `unrestricted`**:DSH 进程可读的任何文件路径均可访问;权限 / IO 错误会以明确的 HTTP 状态码和原因字符串返回,方便浏览器原生播放器呈现有意义的错误提示。

---

## 功能特性

- **Range 请求**(`bytes=start-end`)→ `206 Partial Content`,支持 `<video>` 进度拖拽
- **全文件 GET** → `200 OK`
- **缓存** → `Cache-Control: private, max-age=60`
- **客户端正则**仅匹配 `/Users|/tmp|/private/tmp|/var/folders|/var/tmp` 根路径 + 15 种扩展名,避免误匹配外部 URL
- **UTF-8 安全**路径编码,支持非 ASCII 文件夹名
- **`<style>` 自动清理**:插件卸载时客户端 Fiber 自动移除注入样式

### 支持格式(27 种)

本地路径与在线链接均支持以下扩展名:

**音频/视频(15 种)**:`mp3 wav m4a flac ogg opus aac mp4 mov mkv m4v webm avi 3gp ogv`

**图片(12 种)**:`png jpg jpeg gif bmp webp svg tiff ico avif heic heif`

在线链接示例:`https://example.com/clip.mp4`、`https://cdn.site.com/img/photo.webp`

### Preview

![Demo](https://raw.githubusercontent.com/xiaokaizhou/dsh-media-preview/main/.github/demo-preview.png)

---

## 安装

```bash
# 进入 DSH web profile
cd ~/.dsh/profiles/web

# 方式一(推荐):dsh 官方命令(自动写入 bundles 与 cordis.patch.yml)
dsh plugin --profile web add xiaokaizhou/dsh-media-preview

# 方式二:pnpm 直装(需手动补一步,见下方说明)
pnpm add xiaokaizhou/dsh-media-preview
```

`package.json` 位于 DSH profile 根目录:

- 默认路径:`~/.dsh/profiles/web/package.json`(macOS / Linux)
- Windows:`%USERPROFILE%\.dsh\profiles\web\package.json`
- 自定义路径:`$DSH_HOME/profiles/web/package.json`,可通过环境变量 `DSH_HOME` 覆盖
- 如有多个 profile,对应路径为 `~/.dsh/profiles/<profile-name>/package.json`

方式二手动补全:在上面的 `package.json` 中添加:

```json
"dsh": {
  "profile": {
    "bundles": [
      "media-preview"
    ]
  }
}
```

源码修改后需重启 `dsh web`。

---

## 限制

- 全文件缓冲读取(上限 500 MB)。大视频首帧可能较慢;Range 请求在同一内存缓冲区上切片。
- 无目录列表。无符号链接策略(依赖 `fs.stat`)。
- 500 MB 限制是单请求的,不是会话级的。未来版本可能会通过 `child_process` `dd` 流式传输。

---

## 错误状态码

| 条件 | 状态码 | 原因 |
|------|--------|------|
| 文件不存在 | `404` | `not found: <errno>` |
| 权限不足 | `500` | `permission denied: <errno>` |
| 是目录 | `415` | `is a directory, not a file` |
| 符号链接循环 | `400` | `symlink loop or too many links` |
| 路径过长 | `400` | `path too long` |
| 不支持的扩展名 | `415` | `unsupported media type: <ext>` |
| 文件 > 500 MB | `413` | `file too large: <bytes> > 524288000 cap` |
| Range 无效 | `416` | `Content-Range: bytes */<total>` |

---

## 开源协议

MIT

## 打赏支持

若这个插件帮到了你,欢迎用下面的二维码请我喝杯咖啡。

<table>
  <tr>
    <td align="center">
      <img src="https://raw.githubusercontent.com/xiaokaizhou/dsh-media-preview/main/.github/wechat-pay.jpg" width="180" alt="WeChat Pay"><br>
      <strong>微信支付</strong>
    </td>
    <td align="center">
      <img src="https://raw.githubusercontent.com/xiaokaizhou/dsh-media-preview/main/.github/alipay.jpg" width="180" alt="Alipay"><br>
      <strong>支付宝</strong>
    </td>
  </tr>
</table>

Install

dsh plugin --profile web add github:xiaokaizhou/dsh-media-preview

Profile: web

  • This source has no pinned commit, so a later push upstream changes what installs. Prefer pinning a commit.
Source