DeepSeek Harness Plugin Hub

Publish and manage complete Harness Profiles. Discover Plugins for your next setup.

Explore

PluginsPresetsDocsNews

Community

Publish a pluginContactReport an issue

Resources

Plugin Hub on GitHubDeepSeek HarnessSystem statusPrivacy notice
© 2026 DeepSeek Harness Plugin HubPowered byPaxTech

Independent and unofficial. Not affiliated with, authorized by, or endorsed by DeepSeek.

DeepSeek Harness Plugin Hub
ProfilesPluginsCategoriesNewsDocsSign inManage Profiles
ProfilesPluginsCategoriesNewsDocsSign in
← Plugins

dsh-media-converter

Media Converter

Local media toolbox for DeepSeek Harness: convert, trim, split tracks, export subtitles, compress images, edit metadata, and Base64 — all through local ffmpeg.

The plugin will be installed here. Keep web if you are unsure.

npx -y @deepseek-ai/dsh plugin --profile web add dsh-media-converter@1.2.0
READMECompatibilityVersions

Compatibility and provenance

Media Converter is published as dsh-media-converter and currently resolves to version 1.2.0. The Hub verifies its manifest and preserves the exact installation source for reproducible installs.

DSH compatibility
*
Runtime surfaces
web
Release source
npm
Registry updated
11/4/2026

Versions

1.2.0stable
11/4/2026
1.1.0stable
11/4/2026
1.0.1stable
11/4/2026

Related plugins

Loading related plugins…

Latest
1.2.0
DSH
*
HMR
Process restart
Tree shaking
Safe tree shaking not declared
Unpacked size
994.3 kB
Files
13
Surface
web
License
MIT
Source
npm
GitHub
★ 0
Weekly downloads
0
Last push
11/4/2026
View source ↗
README badge

Click the badge to copy Markdown for your README.

Do you maintain this Plugin?Claim benefit · Priority security scan

Verify the GitHub repository declared in package.json to manage this listing. After you claim it, Hub will prioritize a security scan of the current version and publish the result when it passes.

Claim this Plugin →
Report an issue

Related plugins

More verified plugins in vision-media.

Experimental Voice Input Bundle@deepseek-ai/dsh-experimental-voice-input-bundleExperimental voice input with local SenseVoice; downloads its runtime on first useModlens@liustack/modlensPlug-in vision for text-only LLMs, powered by the free Antigravity CLIImage Gendsh-image-genBring ChatGPT-like image generation to DeepSeek Harness — Gemini, OpenAI, Seedream, DashScope, local ComfyUI & more.Ab Ocrdsh-ab-ocr--- description: "The out-of-tree ocr tool: recognizes a scanned PDF or image page by page, merges the pages in order only after the last one, and saves one Markdown document with the heading levels the model decided." kind: "package-reference" ---

README

dsh-media-converter

DeepSeek Harness 的本地多媒体工具箱插件:转换、裁剪、提取音轨/画面、字幕导出、图片压缩、元数据查看与改写、Base64 编解码。全部在本机用 ffmpeg 完成,文件不出本机。

icon

功能

动作说明
转成 X视频 12 种(mp4/mov/mkv/webm/avi/flv/wmv/ts/ogv/gif/mp3/m4a)、音频 8 种(mp3/m4a/aac/wav/flac/ogg/opus/aiff)、图片 7 种(png/jpg/webp/gif/bmp/tiff/avif)
裁一段从播放器取起点/终点,或手填 分:秒;裁剪与转换一次完成
提取音频 / 提取画面直接拷贝轨道,不重编码
提取字幕内嵌字幕轨导出 .srt,文件名带语言码(如 clip.chi.srt)
图片压缩选 JPG / WEBP 时按质量滑杆重编码;右侧实时预览 + 并排/滑块对比
元数据查看容器、章节、逐轨参数与全部标签;改写标题/作者/专辑/备注/日期/流派(另存为新文件)
Base64当前文件 → data: URL;或粘贴 Base64 还原成文件 / 文本
取消转换中随时点「取消」结束 ffmpeg;上传中也能中断传输

界面是一个「动作面板」:选文件 → 搜索或点动作 → 参数就地展开 → 结果就地显示。支持 ⌘K 聚焦搜索、回车执行第一个动作、Esc 收起。

给 Agent 用的工具

同一个引擎也注册成工具 media_toolbox,助手可以直接调用:

action作用
probe读时长、分辨率、编码、音轨、字幕轨、标签
convert转格式(可带 trim 裁剪、quality 图片质量)
extract-audio / extract-video抽音轨 / 抽画面,不重编码
subtitle导出内嵌字幕为 .srt
rewrite-tags改写标题/作者/专辑/备注/日期/流派

工具吃的是本机绝对路径,不走上传:产物写在同一个输出目录,返回新文件路径。调用被取消或超时(30 分钟)时,ffmpeg 会被终止,半成品会被清掉。

输入框工具排(「+」按钮那一排)有一个「媒体工具箱」按钮:点一下把示例指令 把 xx.mov 裁 0:10 到 1:00 转成 mp4 插进输入框,改成你的文件和区间后发送即可。

大文件

  • 不整文件进内存:上传边收边落盘;Base64 结果边编码边发回;预览走 HTTP Range,拖进度条不会整段下载。
  • 不阻塞宿主:文件读写全部用异步 API,转码期间 DSH 界面照常响应。
  • 随时可取消:每个任务带一个 AbortSignal,取消即向 ffmpeg 发终止信号并清掉半成品;ffmpeg 要到下一帧才真正退出,这期间界面显示「正在取消…」,退出后才是「已取消」。上传用 AbortController 中断传输,服务端不留残余副本。
  • 临时文件会自我清理:上传的副本放在 $TMPDIR/dsh-media-toolbox,超过 2 小时自动删除,插件卸载时也清空。

安装

已发布到 npm(dsh-media-converter)。在 Harness 里用 plugin_manager 的 install_bundle 装,或在 profile 目录里:

dsh plugin add dsh-media-converter --profile <profile>

从源码装(开发用):plugin_manager 的 install_bundle,target 指向本仓库目录——它会在 profile 的 package.json 里登记包名,并在 node_modules/ 下建一条软链指向本目录。

从 GitHub 装(未发布 npm 时的退路):

dsh plugin add github:a1121611810/dsh-media-converter --profile <profile>

装好后左侧栏出现「媒体工具箱」。

换包名后需要重启应用:运行中的 Host 会缓存旧包名的客户端条目,热装清不掉。

依赖

  • ffmpeg:插件按顺序查找 config.ffmpegPath → FFMPEG_PATH → PATH → 常见安装目录 → imageio-ffmpeg 自带的静态包。找不到时页面顶部会提示安装方式。
    • macOS/Linux:/opt/homebrew/bin、/usr/local/bin;imageio 静态包在 ~/Library/Python/*/lib/python/site-packages/imageio_ffmpeg/binaries 或 ~/.local/lib/python*/site-packages/...。
    • Windows:PATH 里找 ffmpeg.exe(装在 C:\ffmpeg\bin 也认),imageio 静态包在 %LOCALAPPDATA%\imageio_ffmpeg\binaries 或 %APPDATA%\Python\Python*\site-packages\...。
    • 手动指定路径时,Windows 下写不写 .exe 都行。
  • 没有 ffprobe 也能用:元数据从 ffmpeg -i 的输出解析。

配置

设置弹窗侧边栏的「媒体工具箱」页可直接编辑配置:保存经宿主的 settings 服务校验并写入 profile(cordis.patch.yml 里会出现对应的 config 块),同时立即应用到运行中的插件——宿主加载器不会热重载,是插件在保存后自行应用合并,所以无需重启;直接手改 cordis.patch.yml 才需要重启。留空的字段保持默认(输出目录默认 ~/Downloads/media-toolbox,ffmpeg 自动查找,上传上限 2048 MB)。

同一个配置也驱动「内置插件」页里本插件行的官方配置表单(来自插件导出的 Schemastery schema,字段标记 volatile() 才可编辑):

- id: media-converter
  name: 'dsh-media-converter'
  config:
    outputDir: ~/Movies/converted
    ffmpegPath: /opt/homebrew/bin/ffmpeg
    maxUploadMb: 2048
  • outputDir:~ 会展开成主目录,路径会被解析成绝对路径。
  • ffmpegPath:找不到 ffmpeg 时手动指定。
  • maxUploadMb:单次上传上限(默认 2048 MB),超了直接拒绝,不写盘。
  • composerButton:是否在输入框工具排显示「媒体工具箱」按钮(默认开)。
  • groups:动作面板的模块顺序与显隐(convert,edit,view,写进字符串的才显示)。
  • 设置页右上角还有版本号显示与「刷新界面」(等同 Ctrl+R)。

插件导出 Config schema 供宿主的 settings 服务投影表单(这是唯一的运行时依赖 @deepseek-ai/schemastery,由 npm 正常安装)。

开发

npm test              # 类型检查 + 构建(宿主 dist/ 与浏览器 client.js)+ 六套自检
npm run build         # 构建:宿主 tsrs → dist/,浏览器 vite → client.js
npm run build:host    # 只构建宿主半边(tsrs → dist/)
npm run build:client  # 只构建浏览器半边(vite → client.js + sourcemap)
npm run typecheck     # 只做类型检查(tsrs,连 .vue 一起查)
npm run check:build   # 改了源码却没重新构建时失败(CI 用)

源码是 TypeScript(strict):宿主是 index.ts + lib/*.ts,浏览器是 src/client/*.ts + .vue(<script setup lang="ts">)。类型只进编译期,运行时零新增依赖——npm 包里只有编译好的 JS。测试保持 test/*.test.mjs 不转,但改成跑编译产物,测的正是发布形态的代码。

编译器用 tsrs(TypeScript 7 的 Rust 移植版,drop-in 替换 tsc):.vue 走 TypeScript 7 的 content-mapper 协议检查(@vue/content-mapper 把 SFC 变成虚拟 TS),所以没有 vue-tsc。副作用:检查时编译产物与 tsc 5.9 逐字节相同,宿主检查快约 3 倍。

两半都是构建产物:

  • 浏览器半边:src/client/ 是源码,client.js 提交进仓库(DSH 直接从包目录读它,链接安装不会触发构建)。改了 src/client/ 之后必须 npm run build:client,否则 check:build 会红。
  • 宿主半边:源码是 index.ts + lib/*.ts,tsrs 编到 dist/,npm 包的入口是 dist/index.js。改完必须 npm run build:host,再重启 DSH。

两半之间的 JSON 契约没有单独一份文件:类型就住在产出数据的那段代码旁边(lib/plan.ts、index.ts),能推导的就推导(ReturnType<typeof parseMeta>),只有被多状态改写的形状(Job 状态机)才手写一次。面板用 import type 引入——编译期完全擦除,浏览器包不会因此拖进 node:fs。

node test/client-bundle.test.mjs  # 产物契约:loader 握手、React 注入、两个槽位
node test/client-lib.test.mjs     # 面板纯函数:格式化、时间码、裁剪窗口
node test/plan.test.mjs           # 格式表、参数、元数据解析、裁剪
node test/base64.test.mjs         # 魔数嗅探、Base64 往返、文本回退
node test/platform.test.mjs       # ffmpeg 查找顺序、文件管理器命令、文件名规则、目录归属判定(含 Windows 分支)
node test/host.test.mjs           # 真 ffmpeg 端到端:27 种格式矩阵 + 字幕 + 标签改写 + 取消 + 失败路径 + Agent 工具 + 上传上限

test/host.test.mjs 需要本机有 ffmpeg;没有会失败(不是跳过——静默跳过等于假绿)。

代码风格

  • oxlint:配置在 .oxlintrc.json。只开 correctness 一类——suspicious/perf/style/restriction 全开是 11/13/1750/137 条意见,基本是风格口味,其中 no-await-in-loop(上传和转码是故意串行的)、no-underscore-dangle(__dshReact 是 loader 的契约名)和这个仓库的写法正面冲突。插件开 typescript/oxc/unicorn/import/node/vue;.vue 的 <script> 块会被查(vue 插件)。两处 no-control-regex 是故意的(文件名里的控制字符就是要剔掉),在代码里就地豁免;reportUnusedDisableDirectives 会把失效的豁免报成错——它已经抓到过一条 2024 年留下的死豁免。
  • oxfmt:配置在 .oxfmtrc.json(单引号、行宽 120、sortPackageJson: false——不动已发布的 keywords 顺序)。client.js(压缩产物)和 README.md 不进格式化范围:前者是产物,后者一格式化就会按字符数给中文表格补列宽(CJK 是双宽字符,补出来的分隔线长短不齐)。.editorconfig 让编辑器跟格式化器用同一套缩进和行宽。
  • 类型相关的 lint 规则没开:oxlint --type-aware(需要额外的 oxlint-tsgolint)在这个仓库只报出 4 条,全是误报——const h = React.createElement、export const apply = plugin.apply 这种解引用方法(本来就不依赖 this)、测试里故意用的 new Function、以及断言里的 .sort()。类型层面的问题由 tsrs 负责,重复跑一套类型引擎不值。
npm run lint          # oxlint
npm run lint:fix      # oxlint --fix
npm run format        # oxfmt,就地改写
npm run format:check  # oxfmt --check,只报不改

npm test 里已经带上 lint 与 format:check,所以 CI 和发版都会拦住风格漂移。

发版

npm run release -- 1.2.0

一条命令做完全部步骤:校验在 main、工作区干净、跑 npm test、确认产物不是旧的、bump 版本、打 tag、push。tag 推上去之后由 CI 发布——本地 npm publish 会被 prepublishOnly 拒绝,所以不存在"手动发一半"的状态。CI 发布前会重跑全部测试并比对 tag 与 package.json 的版本。

结构

src/client/index.ts       加载器握手 + React 8 行壳 + 侧边栏图标 + i18n 字典 + CSS
src/client/App.vue        <media-panel>:状态机、动作面板、预览/对比、Base64、元数据
src/client/vue/           CompareSlider、ResultBlock(普通 Vue 组件)
src/client/lib.ts         纯函数(格式化/时间码/裁剪窗口)+ fetch 封装,不碰 DOM
vite.config.ts            构建:IIFE + __ModuleLoader__ 握手 + React 走宿主模块表
client.js                 构建产物(提交进仓库,勿手改)
index.ts                  宿主:/api/media-convert/* 路由、ffmpeg 任务、预览与 Base64、Agent 工具 media_toolbox
lib/plan.ts               格式表、参数生成、元数据解析、裁剪(也定义面板要用的媒体类型)
lib/base64.ts             Base64 嗅探与还原
lib/platform.ts           ffmpeg 查找、文件管理器、文件名规则(纯函数,跨平台分支可测)
test/                     六套自检(.mjs,跑编译产物)
dist/                     构建产物:宿主入口 dist/index.js(npm 包入口)+ dist/lib/、dist/src/

React 只剩一个壳:把 <media-panel> 挂进槽位并传 t。面板本身是 Vue,shadowRoot: false(light DOM),样式由壳注入的 <style> 提供——Vue 的 defineCustomElement 在 light DOM 下不会注入 SFC 样式。

限制

  • Base64 单文件上限 24 MB。
  • 上传单文件上限 2048 MB(maxUploadMb 可调)。
  • 裁剪区间必须落在文件时长内;区间无效时按钮不可用。
  • 视频转 GIF 会缩到宽 640、12 fps。
  • 上传的临时副本保留 2 小时后自动删除。
  • Windows 上「在资源管理器中显示」用 explorer /select,,macOS 用 open -R,Linux 用 xdg-open(打开所在目录)。

排查

页面打开时会向宿主取一次 /status(ffmpeg 路径、输出目录、可用格式)。宿主刚启动时这次请求可能失败,插件会自动重试(约 25 秒内最多 10 次),成功后就撤掉提示;选文件时若还没拿到,会再补一次。

上传失败时,原因会直接显示在选择框上方(而不是悄悄退回选择框),宿主同时往日志写一行:

[dsh-media-converter] upload truncated: big.mp4 got 4194304 of 8388608 bytes   # 传了一半
[dsh-media-converter] unrecognised media: clip.xyz (16 bytes)                  # ffmpeg 读不了
[dsh-media-converter] upload failed: aborted                                  # 连接中断

宿主的这些行在 DSH 的日志里;改了 index.ts 之后必须 npm run build:host 并重启 DSH才会生效(运行中的宿主用的是启动时那份代码)。