Skip to content

dsh-media-inspect

Verified

dsh-media-inspect · v0.3.1 · MIT

Identify any common audio or video format by reading its real container structure, codec headers, or playlist text — MP4/MOV, Matroska/WebM, WAV/AVI, Ogg, FLAC, ASF/WMV/WMA, MP3, AAC, AC-3, MPEG-TS, and M3U/M3U8. Read-only and offline: reports findings an

Install

dsh plugin add dsh-media-inspect

Confirm the layer applied with dsh --profile default --dump-config — see the install guide.

Source

Published to npm without a public repository. Inspect the package contents before installing.

Tags

Creators

Readme

dsh-media-inspect

一个 DSH(DeepSeek Harness)插件:识别所有常见音频与视频格式,只说话、不做事。

它直接解析文件的真实二进制结构(容器头、编解码器头、标签)或播放列表文本,因此扩展名说谎也能识破。 纯 Node 实现,不需要 ffmpeg、不需要任何原生依赖、不联网。

安装

把仓库克隆(或下载解压)到任意目录,然后在该目录的上一级执行:

dsh plugin --profile web add "file:/path/to/dsh-media-inspect"

Windows 下路径写法示例:

dsh plugin --profile web add "file:C:/path/to/dsh-media-inspect"

然后在 %APPDATA%\dsh-desktop\harness\profiles\web\package.json 的 dsh.profile.bundles 数组末尾追加 "dsh-media-inspect",重启 DSH 即可。

提供的工具

inspect_media

参数 类型 说明
path string(必填) 文件绝对路径
paths string[] 一次比较多达 16 个文件
headBytes integer 头部读取字节数,默认 8 MiB
includeTags boolean 是否输出标签,默认 true

支持的格式

判定一律基于真实字节(magic bytes),扩展名只作提示。 扩展名与内容不符时会给出提示。

容器 / 编解码器

格式 覆盖范围 报告内容
ISO-BMFF MP4 / MOV / M4A / M4B / 3GP / HEIC / AVIF 品牌、时长、视频编码、分辨率、帧率、音频编码、声道、采样率、码率、轨道清单、创建时间、iTunes ilst 与 QuickTime mdta 标签
Matroska / WebM MKV / MKA / MKS / MK3D / WebM DocType、TimestampScale、时长、EBML 元素树、各轨道类型与 CodecID、分辨率、帧率、声道、采样率、位深、Tags
RIFF WAV / AVI(以及其他 RIFF form) WAVE fmt (含 WAVE_FORMAT_EXTENSIBLE 子格式 GUID)、声道布局、采样率、位深、码率、data 字节数、时长、LIST/INFO 标签、AVI avih/strh/strf 流清单
Ogg Vorbis / Opus / Ogg-FLAC / Theora / Speex / Skeleton 页与逻辑流计数、编解码器识别头字段、声道、采样率、标称码率、Theora 尺寸与帧率、Vorbis comment / OpusTags 标签、末页 granule
FLAC 原生 .flac STREAMINFO 全部字段(块大小、采样率、声道、位深、总样本数)、精确时长、metadata block 链、VORBIS_COMMENT 标签、PICTURE 封面
ASF WMV / WMA / ASF 对象树、File Properties(时长已扣除 preroll)、WAVEFORMATEX 音频编码、视频尺寸与压缩 FOURCC、Content Description / Extended Content Description 标签、Windows FILETIME 创建时间
MPEG 音频 MP3 / MP2 / MP1 MPEG-1/2/2.5 各 Layer、时长(优先 Xing/Info/VBRI)、采样率、声道与立体声模式、码率与 CBR/VBR 判定、ID3v2.2/2.3/2.4、ID3v1/1.1
AAC (ADTS) .aac / .adts Profile(LC/HE-AAC…)、采样率、声道配置、帧长度、帧链校验、估算时长与平均码率
AC-3 / E-AC-3 .ac3 / .ec3 / .eac3 bsid、fscod、acmod 声道模式、LFE、A/52 帧长表、标称码率、估算时长
MPEG-TS TS / M2TS / MTS / TP 包长(188/192/204)自动判定、PAT/PMT 解析、节目与 PID 清单、流类型表、M2TS timecode 前缀识别
MPEG 基本流 .mpg / .m2v / .vob 等 序列头尺寸、帧率码、宽高比码、Program Stream 识别
M3U / M3U8 纯文本播放列表 见下节

M3U / M3U8 播放列表

先澄清一个常见误解:M3U8 不是媒体容器,而是 HLS 的纯文本播放列表,内容是一份「分片在哪」的清单。 它本身不含音频或视频数据。本插件只解析这份清单文本,报告它的结构:

  • 三种类型判定:普通 M3U 文件列表、HLS 媒体播放列表(分片清单)、HLS 主播放列表(多码率变体)。
  • 媒体播放列表:分片数量、#EXTINF 时长累加总时长、#EXT-X-TARGETDURATION、媒体序号、 VOD 与直播判定(有无 #EXT-X-ENDLIST)、#EXT-X-BYTERANGE 字节范围、 #EXT-X-DISCONTINUITY 断点、#EXT-X-MAP 初始化分片。
  • 主播放列表:各变体流的码率 / 分辨率 / 编码 / 帧率 / 音频组,以及 #EXT-X-MEDIA 备用音轨与字幕轨道。
  • 加密声明:#EXT-X-KEY 的方法(AES-128 / SAMPLE-AES)、密钥 URI、IV —— 仅报告声明,绝不取用。
  • 类型判定依据 RFC 8216:#EXT-X- 命名空间出现即视为 HLS;仅含 #EXTINF 的本地列表判为普通 M3U。

设计约束:只说话,不做事

这是刻意的设计,不是能力缺失:

  • 工具只读。不写入、不复制、不移动、不重命名、不删除、不转码、不抽取、不转换、不播放。
  • 不调用 ffmpeg 或任何外部程序,进程里没有任何 spawn/exec。
  • 完全不联网。 进程里没有 fetch、没有 node:http/node:https、没有 node:net。 M3U8 里的分片 URL(即使是 https://)只作为引用列出,绝不下载、不解密、不拼接、不合成媒体文件。
  • 工具描述里写死了行为约束:报告完结论就停,让用户决定下一步; 除非用户另行明确要求,否则不得自行发起转码、剪辑、抽轨、打标签、下载、上传等后续动作。

已知限制(诚实说明)

  1. 不做语音转文字。 本插件读取的是容器、编解码器头与标签,不会识别音频/视频里说了什么内容。 本机没有 ffmpeg 和 whisper,因此转写功能不具备可行性,也未包含。
  2. 部分格式的时长是估算值,报告中会明确标注。 ADTS、AC-3、MPEG-TS 这类无索引的 「裸流」格式不含总时长字段,时长只能由「固定帧长 ÷ 文件大小」推算,因此:
    • ADTS / AC-3 的报告会写出 durationBasis(估算依据);
    • MPEG-TS 不给时长,因为那需要遍历整个文件的 PCR/PTS 时间线,仅读头部做不到。 有索引的容器(MP4/MKV/FLAC/ASF 等)给出的是精确时长。
  3. 大文件只读头尾。 默认读前 8 MiB + 末 512 KiB。若 moov 位于文件中部且超出该范围, 会提示需要调大 headBytes;mdat 巨大的文件不会整体读入。
  4. MPEG-TS 只扫描头部有限个包。 节目表(PAT/PMT)通常出现在文件开头,但若被截断或加密, 会明确报告「未找到 Program Map Table」而不是猜测。
  5. 码率为估算值。 由样本大小表或音频流字节数 ÷ 时长推算,与容器开销和真实播放统计略有出入。
  6. Ogg 不推导时长。 Ogg 存的是编解码器相关的 granule position 而非时间;精确时长需要读取文件 最后一个页,仅读头部做不到。因此报告给出末页 granule 值并说明这一点。
  7. M3U8 只读清单本身。 不下载任何分片,因此无法得知分片真实是否存在、是否可访问, 也无法验证分片内的实际编码参数与时长。报告中的时长来自 #EXTINF 声明值,是声明值而非实测值。
  8. 不解码编解码器私有配置。 例如 Matroska 中 AAC 的 CodecPrivate (AudioSpecificConfig)只报告其存在,不解析内部字段。
  9. 不解析自定义标签。 未识别的 #EXT-* 标签会被归类列出,不做语义解读。

自测

# 1) 生成 14 个结构正确的合成样本(覆盖全部新增容器)
node test/make-fixtures.mjs <fixture-dir>

# 2) 解析器单元测试(141 项断言)
node test/run-formats.mjs <fixture-dir>

# 3) EBML 变长整数专项测试(18 项断言,最高风险逻辑)
node test/probe-ebml.mjs

# 4) M3U8 解析器单元测试(75 项断言,无需外部文件)
node test/run-m3u8.mjs

# 5) 端到端:走真实的 defineTool 注册与 execute()/render() 全链路(14 格式)
node test/e2e-formats.mjs <fixture-dir>

# 6) 回归:用真实 MP3/MP4 文件验证旧路径未被破坏
node test/run.mjs <media-file>
node test/regression.mjs <media-file> [...]

注意(依赖解析边界):@deepseek-ai/dsh-tools 是 peer dependency,它从 DSH 应用自己的 node_modules 解析,不在本插件目录内。因此:

  • 解析器单元测试(1–4)不需要该依赖,可在源码目录直接运行;
  • 端到端测试(5)需要该依赖,必须在能解析到 DSH 应用 node_modules 的位置运行, 例如安装到 profile 后在 profile 目录内执行,或为插件目录建立 @deepseek-ai/dsh-tools 链接。

这与插件本身无关,是 ESM 按脚本位置解析依赖的固有行为。

目录结构

dsh-media-inspect/
├── cordis.patch.yml     # bundle 补丁层:把插件插入 profile
├── package.json         # 声明 dsh.bundle.patch
├── lib/
│   ├── index.js         # 工具注册、文件读取、格式嗅探、报告渲染
│   ├── mp4.js           # ISO-BMFF(MP4/MOV/M4A)解析
│   ├── mp3.js           # MPEG 音频帧 + ID3v2/ID3v1 解析
│   ├── m3u8.js          # M3U / HLS 播放列表文本解析(纯本地,无网络)
│   ├── riff.js          # RIFF:WAV / AVI(含奇数块对齐、嵌套 LIST 递归)
│   ├── flac.js          # 原生 FLAC:位打包 STREAMINFO + metadata block 链
│   ├── ogg.js           # Ogg:页/段装帧、Vorbis/Opus/FLAC/Theora/Speex 识别头
│   ├── matroska.js      # Matroska/WebM:EBML 变长整数元素树
│   ├── asf.js           # ASF:GUID 对象树(WMV/WMA)
│   └── elementary.js    # 裸流:ADTS AAC、AC-3、MPEG-TS、MPEG 基本流
└── test/
    ├── make-fixtures.mjs  # 合成样本生成器
    ├── run-formats.mjs    # 新增容器解析器单元测试
    ├── probe-ebml.mjs     # EBML 变长整数专项测试
    ├── run.mjs            # MP4/MP3 解析器自测
    ├── run-m3u8.mjs       # M3U8 解析单元测试
    ├── e2e-formats.mjs    # 全格式端到端工具调用测试
    ├── e2e.mjs            # M3U8 端到端测试
    ├── regression.mjs     # MP4/MP3 回归测试
    └── load-installed.mjs