dsh-video-preview: Add video preview to DSH Web UI sidebar

Preface

The built-in document preview of DSH Web UI supports text, PDF, Excel, and images, but not video. Clicking a .mp4, .webm, or .mov in the file tree often results in a message saying “preview is not available for this file type yet,” or being blocked by the platform’s size limit and forced to read the entire segment before playing.

The lvxianchao/dsh-video-preview introduced below fills in this renderer: clicking a video file plays it locally, using a byte-range route with authentication, supporting seek and large files, with no build steps and zero runtime dependencies.

What is this

@lvxianchao/dsh-video-preview, maintained by lvxianchao, MIT license, current version 1.1.1, requires Node.js >= 22.19. Category is client-side plugin.

One-sentence positioning: Adds a video preview renderer to the DeepSeek Harness (DSH) Web UI sidebar, covering video file types that were previously missing. It has a separate page on the community plugin directory SkillHub. The directory site is an independent site with no official affiliation to DeepSeek / Huafan.

Core Features

  • Suffix matching rendering: mp4 / m4v / webm / ogv / ogg / mov, playable when clicked from the file tree, @ reference, or workspace change list.
  • True streaming playback: <video> requests the byte-range route directly (returning 206 Partial Content), seeking is instant; no limit on reading the entire file, watching a 5 GB video only consumes the bytes actually played.
  • Muted auto-play: Browsers do not allow auto-play with sound, so the preview starts muted by default; unmute by clicking once with native controls.
  • Metadata display: Filename, container format, size (from stat route).
  • Readable failure: Explicitly prompts when codec or container is not supported, instead of leaving a white screen player.
  • Zero runtime dependencies: React comes from the host, the rest uses standard Node/Browser APIs; the browser side is a hand-written __ModuleLoader__ module, no build steps required.
  • No coupling with host: Browser side registers via public documentPreviews / slots / locale services; host side uses connection.fetch routes, within the same browser authentication fence as other /api routes.

Installation and Enablement

Official installation command, choose any of the three sources:

# npm
dsh plugin --profile web add @lvxianchao/dsh-video-preview

# from GitHub
dsh plugin --profile web add "github:lvxianchao/dsh-video-preview"

# from a local checkout
dsh plugin --profile web add /path/to/dsh-video-preview

The main branch only carries published code; the first two remote installation forms install the latest stable version. After installation, restart dsh, and the Web UI will reload frontend modules on startup:

sudo systemctl restart dsh-web   # Adjust according to your deployment method

The package declares dsh.bundle, so the installation process appends the package to the profile’s bundle list and automatically mounts this line; no need to manually edit cordis.patch.yml.

If you want to test without modifying the existing profile, you can use an overlay:

dsh --profile web --patch ./dev.yml --host 127.0.0.1 --port 3099 --no-open
# dev.yml
- insert:
    - id: video-preview
      name: '/absolute/path/to/dsh-video-preview/lib/index.js'

Typical Usage

  1. Type @ in the input box and select a video file (can also be opened from the workspace change list).
  2. Click the file reference, the right sidebar opens the player and starts muted playback.
  3. Use native controls to drag the progress, unmute, and go fullscreen. When dragging, it only requests bytes near the new position.

Configuration

There is only one configuration item rangeBytes:

Key Default Meaning
rangeBytes 2097152 (2 MiB) The byte window returned by each stream request. The browser makes multiple range requests continuously during playback, so this is a latency/throughput knob, not a size limit.
# ~/.dsh/profiles/web/cordis.patch.yml
- id: video-preview
  config:
    rangeBytes: 4194304   # 4 MiB windows

How it works

The plugin is split into a host side and a browser side:

Half File Role
Host lib/index.js Registers GET/HEAD /api/video-preview.stream (provided via workspaceFiles.readBytes(range) for byte range, returning 206 + Content-Range), and GET /api/video-preview.stat (size/version/type), mounted on connection.fetch
Browser lib/client.js Registers renderer metadata (loading: "renderer") and document bodies with keys; renders <video src=…> pointing to the stream route, and reports the loaded version

The renderer uses loading: "renderer", so the preview framework never reads the video file as a whole byte stream—this is exactly why the platform’s 32 MB whole-file limit is removed from the video path.

The browser side does not require build steps; it is already a module format directly recognized by the host loader:

window.__ModuleLoader__.load({ id: "@lvxianchao/dsh-video-preview", factory: (require) => { /* … */ } });

Limitations and Use Cases

Suitable for: Users already using DSH Web UI who want to view videos directly in the sidebar, or those who need to handle large video files. Before installation, check the source code and license (MIT), and note that the plugin runs with the current dsh process permissions.

Known limitations, already listed in the README:

Limit Cause Workaround
Does not support mkv Chrome cannot decode Matroska Re-encode to mp4/webm
Depends on codecs Browsers can only play content the platform can decode; HEVC/AV1 performance varies mp4 with H.264/AAC is the most stable
Session must be parseable The stream route parses the file based on the session in the file address Previews from an active session are always parsable; a missing session results in a 404
Only authenticated browsers are available The route is within the same authentication fence as other /api routes This is by design; no unauthenticated file distribution

If you want to expose the Web UI on the public internet, the README suggests placing dsh-web-guard by the same author in front of it. This plugin only changes how files are previewed, not who can open them: if the UI’s reachable scope exceeds loopback, you need to place dsh-web-guard in front.

Conclusion

The value of this plugin lies in filling the video rendering gap in the DSH sidebar and changing the 32 MB whole-file limit issue in the original Blob solution to byte-range streaming. Zero runtime dependencies, no build steps, low barrier to entry; limitations are also clearly written in the README.

Directory page: https://www.skillhub.cn/plugins/lvxianchao/dsh-video-preview
GitHub: https://github.com/lvxianchao/dsh-video-preview

羽毛球分组比赛记分
小程序二维码

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

Xiaoye