mirror of
https://github.com/volcengine/mediakit-cli.git
synced 2026-09-14 20:06:30 +08:00
feat: 优化
This commit is contained in:
@@ -47,6 +47,10 @@ archives:
|
||||
checksum:
|
||||
name_template: checksums.txt
|
||||
|
||||
release:
|
||||
prerelease: auto
|
||||
make_latest: "{{ if .Prerelease }}false{{ else }}true{{ end }}"
|
||||
|
||||
snapshot:
|
||||
version_template: "{{ incpatch .Version }}-snapshot"
|
||||
|
||||
|
||||
+189
@@ -0,0 +1,189 @@
|
||||
# AI MediaKit CLI
|
||||
|
||||
[](https://opensource.org/licenses/MIT)
|
||||
[](https://go.dev/)
|
||||
[](https://www.npmjs.com/package/@volcengine/mediakit-cli)
|
||||
|
||||
[中文版](./README.md) | [English](./README.en.md)
|
||||
|
||||
The official Mediakit CLI — an FFmpeg-compatible command surface. The same command can run FFmpeg locally for editing operations such as trimming, concatenation, subtitling, mixing, and audio extraction, or switch to the cloud with a single flag to invoke AI capabilities that FFmpeg cannot deliver — quality enhancement, subtitle erasure, ASR, OCR, storyline analysis, and more. It already covers atomic capabilities across video, image, and audio modalities plus 5 AI Agent [Skills](./skills/), with 100+ audio/video atomic capabilities planned.
|
||||
|
||||
[Installation](#installation--quick-start) · [AI Agent Skills](#agent-skills) · [Authentication](#authentication) · [Command Structure](#command-structure) · [Advanced Usage](#advanced-usage) · [License](#license)
|
||||
|
||||
## Why choose mediakit-cli?
|
||||
|
||||
- **Comprehensive capability matrix**: spans video, image, and audio modalities, from low-level processing such as trimming / concatenation / subtitling to high-level understanding such as quality enhancement, subtitle erasure, ASR, OCR, and storyline analysis — a single command covers the full pipeline from preprocessing to final output.
|
||||
- **FFmpeg-compatible, seamless migration**: local mode is built on `ffmpeg` / `ffprobe`, covering common capabilities such as trimming, concatenation, image overlay, subtitle overlay, speed adjustment, volume adjustment, flipping, fade in/out, mixing, audio/video composition, audio extraction, green-screen keying, and metadata probing — aligned with FFmpeg command intuition. Complex / AI capabilities such as filters, image-to-video, and concatenation transitions are handled in the cloud.
|
||||
- **Cloud is faster and more powerful**: append `--cloud` to the same command to unlock capabilities FFmpeg cannot deliver — quality enhancement / generative quality restoration, subtitle erasure (standard / fine-grained), ASR, video OCR, highlight clipping (short drama / mini-game), storyline analysis, scene segmentation, green-screen / portrait keying, and other AI atomic capabilities. Cloud elastic compute provides second-level concurrency.
|
||||
- **One command, two modes**: `--local` / `--cloud` can be switched per command; local mode is zero-cost and cloud provides elastic compute, complementing each other. They share the same parameters and `--schema`, so Agents / scripts can switch with zero modification.
|
||||
- **Cost-effective processing**: leverages cloud elastic resource scheduling and off-peak batch processing strategies to provide highly competitive pricing for large batches of media tasks, significantly reducing overall token consumption and operational cost for AI applications.
|
||||
|
||||
## Features
|
||||
|
||||
| Domain | Capabilities | Runtime |
|
||||
| -------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------ |
|
||||
| 🎬 **Editing** (17) | Video trim · Audio trim · Video concat · Audio concat · Video image overlay · Video subtitle overlay · Video speed · Audio speed · Video volume adjust · Video filter · Video flip · Video audio fade in/out · Audio fade in/out · Audio mix · Video + audio · Extract audio · Image to video | Cloud **or** Local |
|
||||
| 🎚️ **Audio** (2) | Voice / background separation · Audio metadata | Cloud |
|
||||
| 🖼️ **Image AI** (5) | Image quality enhancement · Image erase & inpaint · Image quality assessment · Image OCR · Image background removal | Cloud |
|
||||
| 🎥 **Video AI** (14) | Quality enhancement · Generative quality enhancement · Subtitle erasure (standard) · Fine-grained subtitle erasure · Speech-to-subtitles (ASR) · Video subtitle OCR · Highlight clipping - short drama · Highlight clipping - mini-game · Highlight extraction · Storyline analysis · Scene segmentation · Video green-screen keying · Video portrait keying · Video metadata | Cloud |
|
||||
| 🔧 **Common** (2) | Async task query · Remote file fetch | Local / Cloud |
|
||||
| 🚧 **Coming soon** | Video translation · Narration generation · Manga-to-animation (rolling out) | Cloud |
|
||||
|
||||
## Installation & Quick Start
|
||||
|
||||
### Requirements
|
||||
|
||||
Before you begin, make sure you have:
|
||||
|
||||
- Node.js `>=18` (`npm` / `npx`)
|
||||
|
||||
- Local mode: `ffmpeg` `5.1.x` and `ffprobe`
|
||||
|
||||
### Quick Start (Human Users)
|
||||
|
||||
#### Installation
|
||||
|
||||
Choose **one** of the following methods:
|
||||
|
||||
**Option 1 — one-click install:**
|
||||
|
||||
```bash
|
||||
npx @volcengine/mediakit-cli install -y
|
||||
```
|
||||
|
||||
**Option 2 — build from source:**
|
||||
|
||||
Requires Go `v1.22`+.
|
||||
|
||||
```bash
|
||||
git clone https://github.com/volcengine/mediakit-cli.git
|
||||
cd mediakit-cli
|
||||
make build # Artifact: .mediakit/build/dev/mediakit-cli
|
||||
|
||||
# Install AI Agent Skills from local skills directory (required)
|
||||
npx -y skills add ./skills -g -y
|
||||
```
|
||||
|
||||
#### Configuration & Usage
|
||||
|
||||
```bash
|
||||
# 1. Initialize configuration (interactive wizard)
|
||||
mediakit-cli init
|
||||
|
||||
# 2. Environment self-check (cloud connectivity, local dependencies, install suggestions)
|
||||
mediakit-cli doctor
|
||||
|
||||
# 3. Local editing (synchronous, no API Key needed): run FFmpeg locally to trim
|
||||
mediakit-cli --local editing trim-video --video-url ./in.mp4 --start-time 3 --end-time 8
|
||||
|
||||
# 4. Cloud AI (async): enhance a video to 1080p, then poll for the final result
|
||||
mediakit-cli --cloud video enhance-video --video-url <url> --resolution 1080p
|
||||
mediakit-cli shared query-task --task-id <task_id> --poll-complete
|
||||
```
|
||||
|
||||
### Quick Start (AI Agent)
|
||||
|
||||
> The following steps are designed for AI Agents and support fully unattended workflows.
|
||||
|
||||
**Step 1 — Install**
|
||||
|
||||
```bash
|
||||
npx @volcengine/mediakit-cli install -y
|
||||
```
|
||||
|
||||
**Step 2 — Non-interactive initialization (`--yes` mode)**
|
||||
|
||||
```bash
|
||||
# Get an API Key at: https://console.volcengine.com/imp/ai-mediakit/settings
|
||||
mediakit-cli init \
|
||||
--mode cloud-first \
|
||||
--api-key <your-api-key> \
|
||||
--yes
|
||||
```
|
||||
|
||||
**Step 3 — Verify**
|
||||
|
||||
```bash
|
||||
mediakit-cli doctor
|
||||
mediakit-cli version
|
||||
```
|
||||
|
||||
## Agent Skills
|
||||
|
||||
| Skill | Description |
|
||||
| ------------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| `byted-mediakit-shared` | Common capabilities: task query — required by all other skills |
|
||||
| `byted-mediakit-editing` | Editing: video trim, audio trim, video concat, audio concat, video image overlay, video subtitle overlay, video speed, audio speed, video volume adjust, video filter, video flip, video audio fade in/out, audio fade in/out, audio mix, video + audio, extract audio, image to video |
|
||||
| `byted-mediakit-audio` | Audio: voice / background separation, audio metadata |
|
||||
| `byted-mediakit-image` | Image AI: image quality enhancement, image erase & inpaint, image quality assessment, image OCR, image background removal |
|
||||
| `byted-mediakit-video` | Video AI: quality enhancement, generative quality enhancement, subtitle erasure (standard), fine-grained subtitle erasure, speech-to-subtitles (ASR), video subtitle OCR, highlight clipping - short drama, highlight clipping - mini-game, highlight extraction, storyline analysis, scene segmentation, video green-screen keying, video portrait keying, video metadata |
|
||||
|
||||
## Authentication
|
||||
|
||||
`mediakit-cli` uses minimal authentication: just an API Key — no OAuth / STS / IAM role configuration required.
|
||||
|
||||
```bash
|
||||
# Option A: choose a storage method during init (config / shell / export)
|
||||
mediakit-cli init --api-key <your-api-key> --credential-store config --yes
|
||||
|
||||
# Option B: inject temporarily via environment variables
|
||||
export MEDIAKIT_API_KEY=<your-api-key>
|
||||
export MEDIAKIT_OUTPUT_PATH=<optional-custom-endpoint>
|
||||
```
|
||||
|
||||
| Environment variable | Description |
|
||||
| ---------------------- | -------------------------------------------------------------------------------------------------- |
|
||||
| `MEDIAKIT_API_KEY` | Cloud API Key ([get it from the console](https://console.volcengine.com/imp/ai-mediakit/settings)) |
|
||||
| `MEDIAKIT_OUTPUT_PATH` | Local mode output directory, defaults to `~/.mediakit/temp` |
|
||||
|
||||
## Command Structure
|
||||
|
||||
```
|
||||
mediakit-cli [--cloud|--local] <domain> <tool> [flags]
|
||||
```
|
||||
|
||||
- **Two modes, one command surface**: `--cloud` uses cloud elastic compute (asynchronously returns a `task_id`); `--local` uses local FFmpeg (synchronous, zero cost). Default is `cloud-first`, and it can be overridden per command with `--cloud` / `--local`.
|
||||
- **Output**: cloud results are returned as URLs; local results land in `~/.mediakit/temp` (override with `--output-path` or `MEDIAKIT_OUTPUT_PATH`).
|
||||
|
||||
System commands:
|
||||
|
||||
| Command | Description |
|
||||
| -------------------------------------------- | ------------------------------------------------------------------------------------------- |
|
||||
| `mediakit-cli init [--yes]` | Initialize configuration, interactive or non-interactive (Agent-friendly) |
|
||||
| `mediakit-cli doctor` | Check cloud connectivity, local dependencies, and install suggestions |
|
||||
| `mediakit-cli config` | View / modify configuration |
|
||||
| `mediakit-cli version [--check]` | Show version; `--check` compares against the latest npm release |
|
||||
| `mediakit-cli update [--check]` | Update the CLI and Skills via `npm install -g`; `--check` only checks without installing |
|
||||
| `mediakit-cli --domains` | List all domains |
|
||||
| `mediakit-cli --help-full` | List the full capability index |
|
||||
| `mediakit-cli <domain> <tool> --schema` | Output the JSON Schema for the capability (Mode / Async / polling command metadata) |
|
||||
| `mediakit-cli shared query-task --task-id X` | Query an async task; add `--poll-complete` to poll until terminal state |
|
||||
|
||||
## Advanced Usage
|
||||
|
||||
### Schema Introspection
|
||||
|
||||
Every capability command supports `--schema`, which outputs the input / output schema plus Mode and Async information for Agents to discover tool capabilities dynamically:
|
||||
|
||||
```bash
|
||||
mediakit-cli video enhance-video --schema
|
||||
mediakit-cli --local editing trim-video --schema
|
||||
```
|
||||
|
||||
### Local Mode Output Naming
|
||||
|
||||
Local mode output files are named by the following priority:
|
||||
|
||||
1. Explicit `--output-path` with a complete file path (including extension) → used directly
|
||||
2. Input filename available → `{original_filename}_{tool_name}.{ext}`; if a file with the same name already exists, a 6-digit random number is appended
|
||||
3. No input filename → `{tool_name}-{timestamp}.{ext}`
|
||||
|
||||
## License
|
||||
|
||||
This project is open-sourced under the **MIT License**.
|
||||
|
||||
At runtime this software calls MediaKit cloud APIs. Using those APIs is subject to the following agreements:
|
||||
|
||||
- [Video Cloud Services Specific Terms](https://www.volcengine.com/docs/6448/79646?lang=zh)
|
||||
- [Intelligent Processing Service Billing Rules](https://www.volcengine.com/docs/6448/104992?lang=zh)
|
||||
- [Intelligent Processing Service SLA](https://www.volcengine.com/docs/6448/79648?lang=zh)
|
||||
@@ -1,143 +1,189 @@
|
||||
# AI MediaKit CLI
|
||||
|
||||
[简体中文](./README.zh.md)
|
||||
[](https://opensource.org/licenses/MIT)
|
||||
[](https://go.dev/)
|
||||
[](https://www.npmjs.com/package/@volcengine/mediakit-cli)
|
||||
|
||||
<p align="center">
|
||||
<img src="./assets/cover.en.png" alt="AI MediaKit CLI — interface rebuilt for LLMs · agent-native · cloud + local" width="880" />
|
||||
</p>
|
||||
[中文版](./README.md) | [English](./README.en.md)
|
||||
|
||||
> The agent-native command-line toolkit for audio & video. Run Volcengine's cloud AI and local editing through **one unified command** — built to be driven by AI agents (Claude Code, Trae, Cursor …) or by you in the terminal.
|
||||
Mediakit 官方 CLI —— 兼容 FFmpeg 的命令面,同一条命令既能在本地跑 FFmpeg 完成裁剪 / 拼接 / 加字幕 / 混音 / 提取音频等剪辑操作,也能一键切到云端调用画质增强、字幕擦除、ASR、OCR、剧情线分析等 FFmpeg 做不到的 AI 能力。目前已覆盖视频、图像、音频等多模态原子能力和 5 个 AI Agent [Skills](./skills/),未来预计提供 100+ 音视频原子能力。
|
||||
|
||||
`mediakit-cli` packs video enhancement, subtitle removal, and a full editing toolbox into a single tool. Heavy AI runs in the cloud; lightweight editing runs locally — switch with one flag, same command surface.
|
||||
[安装](#安装与快速开始) · [AI Agent Skills](#agent-skills) · [鉴权](#鉴权) · [命令结构](#命令结构) · [进阶用法](#进阶用法) · [许可证](#许可证)
|
||||
|
||||
---
|
||||
## 为什么选 mediakit-cli?
|
||||
|
||||
## ✨ What it can do
|
||||
- **完备的能力矩阵**:横跨视频、图像、音频三大模态,从裁剪 / 拼接 / 加字幕等底层处理,到画质增强、字幕擦除、ASR、OCR、剧情线分析等上层理解,一条命令覆盖预处理到成片输出的全链路。
|
||||
- **兼容 FFmpeg,无缝迁移**:本地模式基于 `ffmpeg` / `ffprobe`,覆盖裁剪、拼接、加图片、加字幕、调速、调音量、翻转、淡入淡出、混音、音视频合成、提取音频、绿幕抠图、元信息探测等常用能力,与 FFmpeg 命令直觉对齐;滤镜、图片转视频、拼接转场等复杂 / AI 能力交由云端处理。
|
||||
- **云端更快更强**:同一条命令加 `--cloud` 就能升维到 FFmpeg 做不到的能力 —— 画质增强 / 生成式画质修复、字幕擦除(标准版 / 精细化)、ASR、视频 OCR、高光智剪(短剧 / 小游戏)、剧情故事线分析、场景切分、绿幕 / 人像抠图等 AI 原子能力,云端弹性算力提供秒级并发。
|
||||
- **一命令双模态**:`--local` / `--cloud` 可逐命令切换,本地零成本 + 云端弹性算力互补;共用同一份参数与 `--schema`,Agent / 脚本零改造切换。
|
||||
- **高性价比处理**:依托云端弹性资源调度与闲时批量处理策略,为大批量媒体任务提供极具竞争力的价格,显著降低 AI 应用的整体 Token 消耗与运行成本。
|
||||
|
||||
**40+ capabilities across 5 domains** — run `mediakit-cli --help-full` to list them all.
|
||||
## 功能
|
||||
|
||||
| Domain | Capabilities | Runs on | Status |
|
||||
| -------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------ | ------------ |
|
||||
| 🎬 **Editing** (17) | trim · concat · watermark · subtitle · speed · volume · filter · flip · fade · mix · mux · extract audio · image-to-video | cloud **or** local | ✅ Available |
|
||||
| 🎚️ **Audio** (2) | voice / background separation · audio metadata probe | cloud | ✅ Available |
|
||||
| 🖼️ **Image AI** (5) | enhance · object / text erase · quality scoring · OCR · background removal | cloud | ✅ Available |
|
||||
| 🎥 **Video AI** (14) | enhancement (+ generative restore) · subtitle removal · ASR subtitles · OCR · highlight clipping (short-drama / mini-game) · storyline analysis · scene split · portrait & green-screen matting · metadata probe | cloud | ✅ Available |
|
||||
| 🔧 **Shared** (2) | async task query · remote-file fetch | local / cloud | ✅ Available |
|
||||
| 🚧 **Coming** | video translation · commentary generation · anime restyling | cloud | Rolling out |
|
||||
| 领域 | 能力 | 运行 |
|
||||
| ------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------- |
|
||||
| 🎬 **剪辑** (17) | 视频裁剪 · 音频裁剪 · 视频拼接 · 音频拼接 · 视频加图片 · 视频加字幕 · 视频调速 · 音频调速 · 调整视频音量 · 视频添加滤镜 · 视频画面翻转 · 视频声音淡入淡出 · 音频声音淡入淡出 · 音频混合 · 视频加音频 · 提取音频 · 图片转视频 | 云端 **或** 本地 |
|
||||
| 🎚️ **音频** (2) | 人声背景音分离 · 音频元信息获取 | 云端 |
|
||||
| 🖼️ **图像 AI** (5) | 图像画质增强 · 图像擦除修复 · 图像画质评估 · 图像文字识别 OCR · 图像背景移除 | 云端 |
|
||||
| 🎥 **视频 AI** (14) | 画质增强 · 生成式画质增强 · 字幕擦除(标准版)· 精细化字幕擦除 · 语音转字幕(ASR)· 视频识别字幕(OCR)· 高光智剪-短剧 · 高光智剪-小游戏 · 高光片段提取 · 剧情故事线分析 · 场景切分 · 视频绿幕抠图 · 视频人像抠图 · 视频元信息获取 | 云端 |
|
||||
| 🔧 **通用** (2) | 异步任务查询 · 远程文件拉取 | 本地 / 云端 |
|
||||
| 🚧 **即将上线** | 视频翻译 · 解说生成 · 漫剧转绘(陆续上线) | 云端 |
|
||||
|
||||
> AI capabilities run in the cloud (elastic compute, async). Editing runs **either** in the cloud **or** locally (sync, zero cost) — pick per command with `--cloud` / `--local`.
|
||||
## 安装与快速开始
|
||||
|
||||
---
|
||||
### 环境要求
|
||||
|
||||
## 🚀 Quick Start
|
||||
开始之前,请确保具备以下条件:
|
||||
|
||||
- Node.js `>=18`(`npm` / `npx`)
|
||||
|
||||
- 本地模式:`ffmpeg` `5.1.x` 与 `ffprobe`
|
||||
|
||||
### 快速开始(人类用户)
|
||||
|
||||
#### 安装
|
||||
|
||||
以下两种方式**任选其一**:
|
||||
|
||||
**方式一 — 一键安装:**
|
||||
|
||||
```bash
|
||||
npm install -g @volcengine/mediakit-cli
|
||||
npx skills add volcengine/mediakit-cli -g -y # optional — install agent Skills (Claude Code / Trae / Cursor …)
|
||||
export MEDIAKIT_API_KEY=<your-api-key> # from the AI MediaKit console
|
||||
npx @volcengine/mediakit-cli install -y
|
||||
```
|
||||
|
||||
# Cloud AI (async): enhance to 1080p, then poll for the result
|
||||
**方式二 — 从源码构建:**
|
||||
|
||||
需要 Go `v1.22`+。
|
||||
|
||||
```bash
|
||||
git clone https://github.com/volcengine/mediakit-cli.git
|
||||
cd mediakit-cli
|
||||
make build # 产物:.mediakit/build/dev/mediakit-cli
|
||||
|
||||
# 从本地 skills 目录安装 AI Agent Skills(必需)
|
||||
npx -y skills add ./skills -g -y
|
||||
```
|
||||
|
||||
#### 配置与使用
|
||||
|
||||
```bash
|
||||
# 1. 初始化配置(交互式引导)
|
||||
mediakit-cli init
|
||||
|
||||
# 2. 环境自检(检查云端连通性、本地依赖、安装建议)
|
||||
mediakit-cli doctor
|
||||
|
||||
# 3. 本地剪辑(同步、无需 API Key):本机运行 FFmpeg 完成裁剪
|
||||
mediakit-cli --local editing trim-video --video-url ./in.mp4 --start-time 3 --end-time 8
|
||||
|
||||
# 4. 云端 AI(异步):将视频画质增强至 1080p,然后轮询获取最终结果
|
||||
mediakit-cli --cloud video enhance-video --video-url <url> --resolution 1080p
|
||||
mediakit-cli shared query-task --task-id <task_id> --poll-complete
|
||||
|
||||
# Local editing (sync, no key needed): runs on your machine
|
||||
mediakit-cli --local editing trim-video --video-url ./in.mp4 --start-time 3 --end-time 8
|
||||
```
|
||||
|
||||
---
|
||||
### 快速开始(AI Agent)
|
||||
|
||||
## 📦 Install
|
||||
> 以下步骤面向 AI Agent,全流程支持无人值守。
|
||||
|
||||
**第 1 步 — 安装**
|
||||
|
||||
```bash
|
||||
# One-click install (CLI + AI agent Skills)
|
||||
npx @volcengine/mediakit-cli install -y
|
||||
|
||||
# npm only (CLI, recommended, cross-platform — pulls the right build for your OS / arch)
|
||||
npm install -g @volcengine/mediakit-cli
|
||||
|
||||
# npx (no install)
|
||||
npx @volcengine/mediakit-cli version
|
||||
|
||||
# curl (macOS / Linux)
|
||||
curl -fsSL https://raw.githubusercontent.com/volcengine/mediakit-cli/main/scripts/install.sh | bash
|
||||
```
|
||||
|
||||
Pin a version or path: `VERSION=<version> INSTALL_DIR="$HOME/.local/bin" curl -fsSL …/install.sh | bash`
|
||||
|
||||
Verify: `mediakit-cli doctor` (checks cloud readiness + local tool deps + install hints).
|
||||
|
||||
### Update
|
||||
|
||||
The CLI checks the npm registry for new releases once a day (TTL 24h). When an update is available you'll see a hint in `stderr` and a `_notice.update` field in the stdout JSON.
|
||||
**第 2 步 — 非交互式初始化(`--yes` 模式)**
|
||||
|
||||
```bash
|
||||
mediakit-cli version --check # report current vs latest as JSON
|
||||
mediakit-cli update --check # check only, no install
|
||||
mediakit-cli update # install the latest via `npm install -g`
|
||||
# API Key 获取地址:https://console.volcengine.com/imp/ai-mediakit/settings
|
||||
mediakit-cli init \
|
||||
--mode cloud-first \
|
||||
--api-key <your-api-key> \
|
||||
--yes
|
||||
```
|
||||
|
||||
Suppress the check with `MEDIAKIT_DISABLE_UPDATE_CHECK=1` or in CI (`CI` env set).
|
||||
|
||||
---
|
||||
|
||||
## 🤖 Use with AI Agents
|
||||
|
||||
`mediakit-cli` ships **AI agent Skills** that teach an agent how to call it — so a user can just say _"enhance this video to 1080p and trim the best 5 seconds"_ and the agent orchestrates the commands.
|
||||
**第 3 步 — 验证**
|
||||
|
||||
```bash
|
||||
# One command installs the Skills into every supported agent on your machine
|
||||
npx skills add volcengine/mediakit-cli -g -y
|
||||
mediakit-cli doctor
|
||||
mediakit-cli version
|
||||
```
|
||||
|
||||
This auto-detects and installs to **10+ runtimes** — Claude Code, Trae (CN & Global), Cursor, Codex, Gemini CLI, GitHub Copilot, OpenCode, OpenClaw, Antigravity, and more.
|
||||
## Agent Skills
|
||||
|
||||
Every capability is also **MCP-compatible** — `mediakit-cli <domain> <tool> --schema` emits a JSON Schema for MCP / Anthropic Tool Use / function-calling, no hand-written adapter needed.
|
||||
| Skill | 说明 |
|
||||
| ------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| `byted-mediakit-shared` | 通用能力:查询任务,其它 skill 依赖此项 |
|
||||
| `byted-mediakit-editing` | 剪辑:视频裁剪、音频裁剪、视频拼接、音频拼接、视频加图片、视频加字幕、视频调速、音频调速、调整视频音量、视频添加滤镜、视频画面翻转、视频声音淡入淡出、音频声音淡入淡出、音频混合、视频加音频、提取音频、图片转视频 |
|
||||
| `byted-mediakit-audio` | 音频:人声背景音分离、音频元信息获取 |
|
||||
| `byted-mediakit-image` | 图像 AI:图像画质增强、图像擦除修复、图像画质评估、图像文字识别 OCR、图像背景移除 |
|
||||
| `byted-mediakit-video` | 视频 AI:画质增强、生成式画质增强、字幕擦除(标准版)、精细化字幕擦除、语音转字幕(ASR)、视频识别字幕(OCR)、高光智剪-短剧、高光智剪-小游戏、高光片段提取、剧情故事线分析、场景切分、视频绿幕抠图、视频人像抠图、视频元信息获取 |
|
||||
|
||||
---
|
||||
## 鉴权
|
||||
|
||||
## 🧩 How it works
|
||||
|
||||
- **Two modes, one command surface.** `--cloud` runs heavy AI in Volcengine's cloud (elastic compute, async `task_id`); `--local` runs deterministic editing locally (sync, zero cloud cost). Default mode is `cloud-first`; per-command flags override it.
|
||||
- **Command structure:** `mediakit-cli [--cloud|--local] <domain> <tool> [flags]` — domains are `editing` · `audio` · `image` · `video` · `shared`.
|
||||
- **Outputs:** cloud results are returned as URLs; local results write to `~/.mediakit/temp` (override with `--output-path` or `MEDIAKIT_OUTPUT_PATH`).
|
||||
|
||||
---
|
||||
|
||||
## 📖 Documentation
|
||||
|
||||
- Volcengine AI MediaKit product docs & pricing: https://www.volcengine.com/docs/6448
|
||||
- Full command reference & FAQ: see the docs site.
|
||||
- [Error codes & exit code contract](./docs/error-codes.md) — stdout JSON protocol and exit-code rules.
|
||||
|
||||
---
|
||||
|
||||
## 🛠 Development
|
||||
`mediakit-cli` 采用极简鉴权:只需一个 API Key,无需 OAuth / STS / IAM 角色配置。
|
||||
|
||||
```bash
|
||||
make build # local build → .mediakit/build/dev/mediakit-cli
|
||||
make build-all # all platforms
|
||||
make snapshot # snapshot release
|
||||
# 方式 A:init 时选择存储方式(config / shell / export)
|
||||
mediakit-cli init --api-key <your-api-key> --credential-store config --yes
|
||||
|
||||
# 方式 B:临时通过环境变量注入
|
||||
export MEDIAKIT_API_KEY=<your-api-key>
|
||||
export MEDIAKIT_OUTPUT_PATH=<optional-custom-endpoint>
|
||||
```
|
||||
|
||||
Releases are produced via `.goreleaser.yml`; npm distribution via `package.json` + `scripts/install.js`; curl install via `scripts/install.sh`.
|
||||
| 环境变量 | 说明 |
|
||||
| ---------------------- | ------------------------------------------------------------------------------------- |
|
||||
| `MEDIAKIT_API_KEY` | 云端 API Key([控制台获取](https://console.volcengine.com/imp/ai-mediakit/settings)) |
|
||||
| `MEDIAKIT_OUTPUT_PATH` | 本地模式输出目录,默认 `~/.mediakit/temp` |
|
||||
|
||||
<details>
|
||||
<summary><b>Local Tool Admission</b> (FFmpeg policy)</summary>
|
||||
## 命令结构
|
||||
|
||||
- `ffmpeg` / `ffprobe`: required, `5.1.x`, `LGPL v2.1 or later`, commercial use allowed
|
||||
- Optional FFmpeg features: `openh264`, `libmp3lame`, `libass`, `libfreetype`, `libfontconfig`, `libfribidi`, `libharfbuzz`, `zlib`, `libpng`, `libjpeg-turbo`
|
||||
- Boundary: external process execution only (no static/dynamic linking of local tools into the Go binary); FFmpeg stays in LGPL mode by default; no `non-free` components; no local intermediate artifacts retained (only final outputs + `fetch-file` downloads).
|
||||
```
|
||||
mediakit-cli [--cloud|--local] <domain> <tool> [flags]
|
||||
```
|
||||
|
||||
</details>
|
||||
- **两种模式,同一命令面**:`--cloud` 走云端弹性算力(异步返回 `task_id`);`--local` 走本地 FFmpeg(同步、零成本)。默认为 `cloud-first`,可用 `--cloud` / `--local` 逐命令覆盖。
|
||||
- **输出**:云端结果以 URL 返回;本地结果落到 `~/.mediakit/temp`(可用 `--output-path` 或 `MEDIAKIT_OUTPUT_PATH` 覆盖)。
|
||||
|
||||
---
|
||||
系统命令:
|
||||
|
||||
## License
|
||||
| 命令 | 说明 |
|
||||
| -------------------------------------------- | ----------------------------------------------------------- |
|
||||
| `mediakit-cli init [--yes]` | 初始化配置,支持交互式或非交互式(Agent 友好) |
|
||||
| `mediakit-cli doctor` | 检查云端连通性、本地依赖与安装建议 |
|
||||
| `mediakit-cli config` | 查看 / 修改配置项 |
|
||||
| `mediakit-cli version [--check]` | 显示版本;`--check` 对比 npm 最新版 |
|
||||
| `mediakit-cli update [--check]` | 通过 `npm install -g` 更新 CLI 和 Skills;`--check` 只检查不安装 |
|
||||
| `mediakit-cli --domains` | 列出所有域 |
|
||||
| `mediakit-cli --help-full` | 列出全部能力索引 |
|
||||
| `mediakit-cli <domain> <tool> --schema` | 输出该能力的 JSON Schema(Mode / Async / 轮询命令等元信息) |
|
||||
| `mediakit-cli shared query-task --task-id X` | 查询异步任务;加 `--poll-complete` 轮询至终态 |
|
||||
|
||||
This project is open-sourced under the [MIT License](./LICENSE).
|
||||
## 进阶用法
|
||||
|
||||
This software calls MediaKit APIs at runtime. Use of these APIs is subject to the following terms and privacy policies:
|
||||
### Schema 自省
|
||||
|
||||
- [Video Cloud Service Special Terms](https://www.volcengine.com/docs/6448/79646?lang=zh)
|
||||
- [Intelligent Processing Service Billing Rules](https://www.volcengine.com/docs/6448/104992?lang=zh)
|
||||
- [Intelligent Processing Service Level Agreement](https://www.volcengine.com/docs/6448/79648?lang=zh)
|
||||
每个能力命令都支持 `--schema`,输出输入 / 输出 schema、Mode 与 Async 信息,供 Agent 动态发现工具能力:
|
||||
|
||||
```bash
|
||||
mediakit-cli video enhance-video --schema
|
||||
mediakit-cli --local editing trim-video --schema
|
||||
```
|
||||
|
||||
### 本地模式输出命名
|
||||
|
||||
本地模式输出文件按以下优先级命名:
|
||||
|
||||
1. 显式 `--output-path` 指定完整文件路径(含扩展名)→ 直接使用
|
||||
2. 有输入文件名 → `{原文件名}_{工具名}.{ext}`;同名文件已存在时追加 6 位随机数字
|
||||
3. 无输入文件名 → `{工具名}-{时间戳}.{ext}`
|
||||
|
||||
## 许可证
|
||||
|
||||
本项目基于 **MIT 许可证** 开源。
|
||||
|
||||
该软件运行时会调用 MediaKit 云端 API,使用这些 API 需要遵守如下协议:
|
||||
|
||||
- [视频云服务专有条款](https://www.volcengine.com/docs/6448/79646?lang=zh)
|
||||
- [智能处理服务计费规则](https://www.volcengine.com/docs/6448/104992?lang=zh)
|
||||
- [智能处理服务 SLA](https://www.volcengine.com/docs/6448/79648?lang=zh)
|
||||
|
||||
-143
@@ -1,143 +0,0 @@
|
||||
# AI MediaKit CLI
|
||||
|
||||
[English](./README.md)
|
||||
|
||||
<p align="center">
|
||||
<img src="./assets/cover.png" alt="AI MediaKit CLI — 接口为模型重构 · Agent 原生 · 端云一体" width="880" />
|
||||
</p>
|
||||
|
||||
> 面向 Agent 的音视频命令行工具集。用**一个统一的命令**调用火山引擎的云端 AI 能力、跑本地剪辑——既能让 AI Agent(Claude Code、Trae、Cursor……)自然语言调度,也能你自己在终端直接用。
|
||||
|
||||
`mediakit-cli` 把画质增强、字幕擦除和一整套剪辑能力收进一个工具:重算力 AI 跑云端,轻量剪辑在本地跑——一个 flag 切换,命令写法不变。
|
||||
|
||||
---
|
||||
|
||||
## ✨ 能做什么
|
||||
|
||||
**5 大领域、40+ 能力** —— 运行 `mediakit-cli --help-full` 可列全。
|
||||
|
||||
| 领域 | 能力 | 运行 | 状态 |
|
||||
| --- | --- | --- | --- |
|
||||
| 🎬 **剪辑** (17) | 裁剪 · 拼接 · 加水印 · 加字幕 · 调速 · 调音量 · 滤镜 · 翻转 · 淡入淡出 · 混音 · 合成 · 提取音频 · 图片转视频 | 云端 **或** 本地 | ✅ 已上线 |
|
||||
| 🎚️ **音频** (2) | 人声 / 背景音分离 · 音频元信息探测 | 云端 | ✅ 已上线 |
|
||||
| 🖼️ **图像 AI** (5) | 画质增强 · 擦除修复 · 画质评分 · OCR · 背景移除 | 云端 | ✅ 已上线 |
|
||||
| 🎥 **视频 AI** (14) | 画质增强(含生成式修复)· 字幕擦除 · ASR 字幕 · OCR · 高光智剪(短剧 / 小游戏)· 剧情线分析 · 场景切分 · 人像 & 绿幕抠图 · 元信息探测 | 云端 | ✅ 已上线 |
|
||||
| 🔧 **通用** (2) | 异步任务查询 · 远程文件拉取 | 本地 / 云端 | ✅ 已上线 |
|
||||
| 🚧 **即将上线** | 视频翻译 · 解说生成 · 漫剧转绘 | 云端 | 陆续上线 |
|
||||
|
||||
> AI 能力跑在云端(弹性算力、异步);剪辑能力**云端或本地**皆可(本地跑,同步、零成本)—— 每条命令用 `--cloud` / `--local` 选。
|
||||
|
||||
---
|
||||
|
||||
## 🚀 快速开始
|
||||
|
||||
```bash
|
||||
npm install -g @volcengine/mediakit-cli
|
||||
npx skills add volcengine/mediakit-cli -g -y # 可选 —— 装 Agent Skill(Claude Code / Trae / Cursor …)
|
||||
export MEDIAKIT_API_KEY=<你的 API Key> # 在 AI MediaKit 控制台获取
|
||||
|
||||
# 云端 AI(异步):增强到 1080p,再轮询拿结果
|
||||
mediakit-cli --cloud video enhance-video --video-url <url> --resolution 1080p
|
||||
mediakit-cli shared query-task --task-id <task_id> --poll-complete
|
||||
|
||||
# 本地剪辑(同步、无需 Key):在本机跑
|
||||
mediakit-cli --local editing trim-video --video-url ./in.mp4 --start-time 3 --end-time 8
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 📦 安装
|
||||
|
||||
```bash
|
||||
# 一键安装(CLI + AI Agent Skill)
|
||||
npx @volcengine/mediakit-cli install -y
|
||||
|
||||
# 仅装 CLI(推荐,跨平台——自动拉取对应平台 / 架构的构建产物)
|
||||
npm install -g @volcengine/mediakit-cli
|
||||
|
||||
# npx(免安装)
|
||||
npx @volcengine/mediakit-cli version
|
||||
|
||||
# curl(macOS / Linux)
|
||||
curl -fsSL https://raw.githubusercontent.com/volcengine/mediakit-cli/main/scripts/install.sh | bash
|
||||
```
|
||||
|
||||
指定版本 / 路径:`VERSION=<version> INSTALL_DIR="$HOME/.local/bin" curl -fsSL …/install.sh | bash`
|
||||
|
||||
验证环境:`mediakit-cli doctor`(检查云端就绪 + 本地工具依赖 + 安装指引)。
|
||||
|
||||
### 更新
|
||||
|
||||
CLI 每天会向 npm registry 检查一次新版本(TTL 24h)。有更新时,`stderr` 会出现提示,stdout JSON 会带上 `_notice.update` 字段。
|
||||
|
||||
```bash
|
||||
mediakit-cli version --check # 以 JSON 输出当前版本 vs 最新版本
|
||||
mediakit-cli update --check # 只检查,不安装
|
||||
mediakit-cli update # 通过 `npm install -g` 安装最新版
|
||||
```
|
||||
|
||||
如需关闭自动检查,设置 `MEDIAKIT_DISABLE_UPDATE_CHECK=1`,或在 CI 中运行(`CI` 环境变量被设置时也会自动抑制)。
|
||||
|
||||
---
|
||||
|
||||
## 🤖 配合 AI Agent 使用
|
||||
|
||||
`mediakit-cli` 自带 **AI Agent Skill**——教 Agent 怎么调它。于是用户只需说一句*"把这个视频增强到 1080p,再剪出最精彩的 5 秒"*,Agent 就能自动编排命令。
|
||||
|
||||
```bash
|
||||
# 一个命令把 Skill 装进本机所有支持的 Agent
|
||||
npx skills add volcengine/mediakit-cli -g -y
|
||||
```
|
||||
|
||||
它会自动检测并安装到 **10+ 种 runtime**——Claude Code、Trae(国内 & 海外)、Cursor、Codex、Gemini CLI、GitHub Copilot、OpenCode、OpenClaw、Antigravity 等。
|
||||
|
||||
每个能力还**MCP 兼容**——`mediakit-cli <domain> <tool> --schema` 吐出 JSON Schema,直接喂 MCP / Anthropic Tool Use / function calling,无需手写适配器。
|
||||
|
||||
---
|
||||
|
||||
## 🧩 工作原理
|
||||
|
||||
- **两种模式,同一套命令。** `--cloud` 把重算力 AI 跑在火山引擎云端(弹性算力、异步 `task_id`);`--local` 在本机跑确定性剪辑(同步、零云端成本)。默认 `cloud-first`,单命令 flag 可覆盖。
|
||||
- **命令结构:** `mediakit-cli [--cloud|--local] <domain> <tool> [flags]`——domain 为 `editing` · `audio` · `image` · `video` · `shared`。
|
||||
- **输出:** 云端结果以 URL 返回;本地结果写到 `~/.mediakit/temp`(可用 `--output-path` 或 `MEDIAKIT_OUTPUT_PATH` 覆盖)。
|
||||
|
||||
---
|
||||
|
||||
## 📖 文档
|
||||
|
||||
- Volcengine AI MediaKit 产品文档 & 定价:https://www.volcengine.com/docs/6448
|
||||
- 完整命令参考 & FAQ:见文档站。
|
||||
- [错误码与退出码契约](./docs/error-codes.md) —— stdout JSON 协议与退出码规则。
|
||||
|
||||
---
|
||||
|
||||
## 🛠 开发
|
||||
|
||||
```bash
|
||||
make build # 本地构建 → .mediakit/build/dev/mediakit-cli
|
||||
make build-all # 全平台
|
||||
make snapshot # snapshot release
|
||||
```
|
||||
|
||||
发布走 `.goreleaser.yml`;npm 分发走 `package.json` + `scripts/install.js`;curl 安装走 `scripts/install.sh`。
|
||||
|
||||
<details>
|
||||
<summary><b>本地工具 Admission</b>(FFmpeg 策略)</summary>
|
||||
|
||||
- `ffmpeg` / `ffprobe`:必需,`5.1.x`,`LGPL v2.1 或更高`,允许商用
|
||||
- 可选 FFmpeg 能力:`openh264`、`libmp3lame`、`libass`、`libfreetype`、`libfontconfig`、`libfribidi`、`libharfbuzz`、`zlib`、`libpng`、`libjpeg-turbo`
|
||||
- 边界:仅通过外部进程调用(不把本地工具静态 / 动态链接进 Go 二进制);FFmpeg 默认保持 LGPL 模式;默认不引入 `non-free` 组件;不保留本地中间产物(仅保留最终产物 + `fetch-file` 下载)。
|
||||
|
||||
</details>
|
||||
|
||||
---
|
||||
|
||||
## License
|
||||
|
||||
本项目基于 [MIT 许可证](./LICENSE) 开源。
|
||||
|
||||
该软件运行时会调用 MediaKit 的 API,使用这些 API 需要遵守如下协议和隐私政策:
|
||||
|
||||
- [视频云服务专用条款](https://www.volcengine.com/docs/6448/79646?lang=zh)
|
||||
- [智能处理服务计费结算规则](https://www.volcengine.com/docs/6448/104992?lang=zh)
|
||||
- [智能处理服务等级协议](https://www.volcengine.com/docs/6448/79648?lang=zh)
|
||||
+2
-2
@@ -85,8 +85,8 @@
|
||||
```json
|
||||
{
|
||||
"error": {
|
||||
"type": "invalid_parameter | security_violation | environment_error | execution_error",
|
||||
"code": "missing_required_param | invalid_param_type | param_out_of_range | param_insufficient | unsupported_value | forbidden_operation | not_whitelisted | unsafe_characters | handler_not_implemented | local_unsupported | dependency_missing | execution_failed | download_failed | unknown",
|
||||
"type": "InvalidParameter | SecurityViolation | EnvironmentError | ExecutionError",
|
||||
"code": "MissingRequiredParam | InvalidParamType | ParamOutOfRange | ParamInsufficient | UnsupportedValue | ForbiddenOperation | NotWhitelisted | UnsafeCharacters | HandlerNotImplemented | LocalUnsupported | DependencyMissing | ExecutionFailed | DownloadFailed | Unknown",
|
||||
"message": "<原始错误信息(不截断、不摘要)>"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,6 +9,7 @@ import (
|
||||
"os"
|
||||
"strings"
|
||||
|
||||
"mediakit-cli/internal/build"
|
||||
cliconfig "mediakit-cli/internal/config"
|
||||
)
|
||||
|
||||
@@ -86,8 +87,9 @@ func (c *Client) newRequest(method string, path string, query map[string]any, bo
|
||||
req.Header.Set("Accept", "application/json")
|
||||
req.Header.Set("Content-Type", "application/json")
|
||||
req.Header.Set("x-surface", resolveSurface(c.Surface))
|
||||
req.Header.Set("x-runtime", resolveRuntime(c.Runtime))
|
||||
req.Header.Set("X-Amk-Task-Runtime", resolveRuntime(c.Runtime))
|
||||
req.Header.Set("X-Amk-Task-Source", "cli")
|
||||
req.Header.Set("X-Amk-Cli-Version", build.Version)
|
||||
if c.APIKey != "" {
|
||||
req.Header.Set("Authorization", "Bearer "+c.APIKey)
|
||||
}
|
||||
|
||||
@@ -3171,7 +3171,7 @@ func classifyErrorType(err error) string {
|
||||
case strings.Contains(msg, "禁止") ||
|
||||
strings.Contains(msg, "不在白名单") ||
|
||||
strings.Contains(msg, "不安全字符"):
|
||||
return "security_violation"
|
||||
return "SecurityViolation"
|
||||
case strings.Contains(msg, "必填参数") ||
|
||||
strings.Contains(msg, "必须是") ||
|
||||
strings.Contains(msg, "取值范围") ||
|
||||
@@ -3179,13 +3179,13 @@ func classifyErrorType(err error) string {
|
||||
strings.Contains(msg, "仅支持") ||
|
||||
strings.Contains(msg, "必须大于") ||
|
||||
strings.Contains(msg, "必须大于等于"):
|
||||
return "invalid_parameter"
|
||||
return "InvalidParameter"
|
||||
case strings.Contains(msg, "本地处理器未实现") ||
|
||||
strings.Contains(msg, "不支持本地执行") ||
|
||||
strings.Contains(msg, "本地依赖"):
|
||||
return "environment_error"
|
||||
return "EnvironmentError"
|
||||
default:
|
||||
return "execution_error"
|
||||
return "ExecutionError"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3193,37 +3193,37 @@ func classifyErrorCode(err error) string {
|
||||
msg := err.Error()
|
||||
switch {
|
||||
case strings.Contains(msg, "禁止"):
|
||||
return "forbidden_operation"
|
||||
return "ForbiddenOperation"
|
||||
case strings.Contains(msg, "不在白名单"):
|
||||
return "not_whitelisted"
|
||||
return "NotWhitelisted"
|
||||
case strings.Contains(msg, "不安全字符"):
|
||||
return "unsafe_characters"
|
||||
return "UnsafeCharacters"
|
||||
case strings.Contains(msg, "必填参数"):
|
||||
return "missing_required_param"
|
||||
return "MissingRequiredParam"
|
||||
case strings.Contains(msg, "必须大于等于"):
|
||||
return "param_out_of_range"
|
||||
return "ParamOutOfRange"
|
||||
case strings.Contains(msg, "必须大于"):
|
||||
return "param_out_of_range"
|
||||
return "ParamOutOfRange"
|
||||
case strings.Contains(msg, "取值范围"):
|
||||
return "param_out_of_range"
|
||||
return "ParamOutOfRange"
|
||||
case strings.Contains(msg, "必须是"):
|
||||
return "invalid_param_type"
|
||||
return "InvalidParamType"
|
||||
case strings.Contains(msg, "至少需要"):
|
||||
return "param_insufficient"
|
||||
return "ParamInsufficient"
|
||||
case strings.Contains(msg, "仅支持"):
|
||||
return "unsupported_value"
|
||||
return "UnsupportedValue"
|
||||
case strings.Contains(msg, "本地处理器未实现"):
|
||||
return "handler_not_implemented"
|
||||
return "HandlerNotImplemented"
|
||||
case strings.Contains(msg, "不支持本地执行"):
|
||||
return "local_unsupported"
|
||||
return "LocalUnsupported"
|
||||
case strings.Contains(msg, "本地依赖"):
|
||||
return "dependency_missing"
|
||||
return "DependencyMissing"
|
||||
case strings.Contains(msg, "download failed"):
|
||||
return "download_failed"
|
||||
return "DownloadFailed"
|
||||
case strings.Contains(msg, "执行失败"):
|
||||
return "execution_failed"
|
||||
return "ExecutionFailed"
|
||||
default:
|
||||
return "unknown"
|
||||
return "Unknown"
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -20,15 +20,15 @@ func Execute() error {
|
||||
|
||||
func newRootCmd() *cobra.Command {
|
||||
cmd := &cobra.Command{
|
||||
Use: "mediakit-cli",
|
||||
Short: "MediaKit command line interface",
|
||||
Use: "mediakit-cli",
|
||||
Short: "MediaKit command line interface",
|
||||
Long: `MediaKit CLI provides system commands, domain navigation, and generated capability commands.
|
||||
|
||||
One-click install (CLI + AI agent Skills):
|
||||
npx @volcengine/mediakit-cli install -y
|
||||
|
||||
Update:
|
||||
mediakit-cli update # install latest via npm install -g
|
||||
mediakit-cli update # update CLI and AI Agent Skills via npm
|
||||
mediakit-cli update --check # only report status
|
||||
mediakit-cli version --check # show current vs latest
|
||||
|
||||
@@ -36,15 +36,8 @@ AI Agent Skills:
|
||||
mediakit-cli pairs with AI agent skills (Claude Code, etc.) that
|
||||
teach the agent MediaKit CLI patterns, best practices, and workflows.
|
||||
|
||||
Install all skills:
|
||||
npx skills add volcengine/mediakit-cli -g -y
|
||||
|
||||
Or pick specific domains:
|
||||
npx skills add volcengine/mediakit-cli -s byted-mediakit-editing -y
|
||||
npx skills add volcengine/mediakit-cli -s byted-mediakit-audio -y
|
||||
npx skills add volcengine/mediakit-cli -s byted-mediakit-image -y
|
||||
npx skills add volcengine/mediakit-cli -s byted-mediakit-video -y
|
||||
npx skills add volcengine/mediakit-cli -s byted-mediakit-shared -y`,
|
||||
Reinstall all skills:
|
||||
npx @volcengine/mediakit-cli install --skills-only -y`,
|
||||
SilenceUsage: true,
|
||||
SilenceErrors: true,
|
||||
DisableAutoGenTag: true,
|
||||
|
||||
+99
-21
@@ -5,6 +5,7 @@ import (
|
||||
"fmt"
|
||||
"os"
|
||||
"os/exec"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
buildinfo "mediakit-cli/internal/build"
|
||||
@@ -13,16 +14,26 @@ import (
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
var (
|
||||
checkNow = func() *updatecheck.Result {
|
||||
return updatecheck.CheckNow(3 * time.Second)
|
||||
}
|
||||
runNpmInstall = runNpmInstallLatest
|
||||
runSkillsInstall = runSkillsInstallFromPackage
|
||||
)
|
||||
|
||||
func newUpdateCmd() *cobra.Command {
|
||||
var checkOnly bool
|
||||
var force bool
|
||||
var asJSON bool
|
||||
cmd := &cobra.Command{
|
||||
Use: "update",
|
||||
Short: "Check and apply mediakit-cli updates from the npm registry",
|
||||
Long: "Check the npm registry for the latest @volcengine/mediakit-cli release and optionally install it via npm install -g.",
|
||||
Short: "Update mediakit-cli",
|
||||
Long: "Update @volcengine/mediakit-cli from npm.",
|
||||
Args: cobra.NoArgs,
|
||||
DisableAutoGenTag: true,
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
r := updatecheck.CheckNow(3 * time.Second)
|
||||
r := checkNow()
|
||||
if r == nil {
|
||||
return writeUpdatePayload(cmd, map[string]any{
|
||||
"current": buildinfo.Version,
|
||||
@@ -40,27 +51,57 @@ func newUpdateCmd() *cobra.Command {
|
||||
payload["action"] = "skipped"
|
||||
return writeUpdatePayload(cmd, payload)
|
||||
}
|
||||
if !r.HasUpdate {
|
||||
payload["action"] = "noop"
|
||||
return writeUpdatePayload(cmd, payload)
|
||||
}
|
||||
payload["upgrade_command"] = fmt.Sprintf("npm install -g %s@latest", updatecheck.PackageName)
|
||||
payload["upgrade_command"] = "mediakit-cli update"
|
||||
if checkOnly {
|
||||
payload["action"] = "check"
|
||||
if !asJSON {
|
||||
return writeUpdateCheckText(cmd, r)
|
||||
}
|
||||
return writeUpdatePayload(cmd, payload)
|
||||
}
|
||||
payload["action"] = "install"
|
||||
if err := runNpmInstallLatest(cmd); err != nil {
|
||||
payload["install_status"] = "failed"
|
||||
payload["error"] = err.Error()
|
||||
_ = writeUpdatePayload(cmd, payload)
|
||||
return err
|
||||
|
||||
if r.HasUpdate {
|
||||
payload["action"] = "install"
|
||||
if !asJSON {
|
||||
fmt.Fprintf(cmd.OutOrStdout(), "Updating mediakit-cli %s → %s via npm ...\n", r.Current, r.Latest)
|
||||
}
|
||||
if err := runNpmInstall(cmd); err != nil {
|
||||
payload["install_status"] = "failed"
|
||||
payload["error"] = err.Error()
|
||||
if asJSON {
|
||||
_ = writeUpdatePayload(cmd, payload)
|
||||
}
|
||||
return err
|
||||
}
|
||||
payload["install_status"] = "ok"
|
||||
} else {
|
||||
payload["action"] = "noop"
|
||||
}
|
||||
|
||||
shouldInstallSkills := !r.HasUpdate && force
|
||||
if shouldInstallSkills {
|
||||
if !asJSON {
|
||||
fmt.Fprintln(cmd.OutOrStdout(), "\nInstalling skills from the current npm package ...")
|
||||
}
|
||||
if err := runSkillsInstall(cmd); err != nil {
|
||||
payload["skills_action"] = "failed"
|
||||
payload["skills_error"] = err.Error()
|
||||
if asJSON {
|
||||
_ = writeUpdatePayload(cmd, payload)
|
||||
}
|
||||
return err
|
||||
}
|
||||
payload["skills_action"] = "installed"
|
||||
}
|
||||
if !asJSON {
|
||||
return writeUpdateText(cmd, r, shouldInstallSkills)
|
||||
}
|
||||
payload["install_status"] = "ok"
|
||||
return writeUpdatePayload(cmd, payload)
|
||||
},
|
||||
}
|
||||
cmd.Flags().BoolVar(&checkOnly, "check", false, "Only check for updates; do not install")
|
||||
cmd.Flags().BoolVar(&force, "force", false, "Force reinstall skills from the current npm package even when CLI is already up to date")
|
||||
cmd.Flags().BoolVar(&asJSON, "json", false, "Output structured JSON")
|
||||
return cmd
|
||||
}
|
||||
|
||||
@@ -71,6 +112,30 @@ func writeUpdatePayload(cmd *cobra.Command, payload map[string]any) error {
|
||||
return encoder.Encode(payload)
|
||||
}
|
||||
|
||||
func writeUpdateCheckText(cmd *cobra.Command, r *updatecheck.Result) error {
|
||||
if r.HasUpdate {
|
||||
_, err := fmt.Fprintf(cmd.OutOrStdout(),
|
||||
"Update available: %s → %s\n Release: https://www.npmjs.com/package/%s/v/%s\n\nRun `mediakit-cli update` to install.\n",
|
||||
r.Current, r.Latest, updatecheck.PackageName, r.Latest)
|
||||
return err
|
||||
}
|
||||
_, err := fmt.Fprintf(cmd.OutOrStdout(), "mediakit-cli %s is already up to date\n", r.Current)
|
||||
return err
|
||||
}
|
||||
|
||||
func writeUpdateText(cmd *cobra.Command, r *updatecheck.Result, skillsInstalled bool) error {
|
||||
if r.HasUpdate {
|
||||
fmt.Fprintf(cmd.OutOrStdout(), "\n✓ Successfully updated mediakit-cli and skills from %s to %s\n", r.Current, r.Latest)
|
||||
} else {
|
||||
fmt.Fprintf(cmd.OutOrStdout(), "mediakit-cli %s is already up to date\n", r.Current)
|
||||
}
|
||||
if skillsInstalled {
|
||||
_, err := fmt.Fprintln(cmd.OutOrStdout(), "✓ Skills installed from the current npm package")
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func runNpmInstallLatest(cmd *cobra.Command) error {
|
||||
target := fmt.Sprintf("%s@latest", updatecheck.PackageName)
|
||||
c := exec.Command("npm", "install", "-g", target)
|
||||
@@ -79,18 +144,31 @@ func runNpmInstallLatest(cmd *cobra.Command) error {
|
||||
return c.Run()
|
||||
}
|
||||
|
||||
func runSkillsInstallFromPackage(cmd *cobra.Command) error {
|
||||
c := exec.Command("npx", "-y", updatecheck.PackageName, "install", "--skills-only", "-y")
|
||||
c.Stdout = os.Stderr
|
||||
c.Stderr = os.Stderr
|
||||
return c.Run()
|
||||
}
|
||||
|
||||
func normalizeVersion(version string) string {
|
||||
version = strings.TrimSpace(version)
|
||||
version = strings.TrimPrefix(version, "v")
|
||||
return strings.TrimPrefix(version, "V")
|
||||
}
|
||||
|
||||
// newUpdateRefreshCmd is the hidden entry the detached refresh subprocess runs.
|
||||
// It fetches the latest version and writes the cache, with no output. The empty
|
||||
// persistent hooks override the root's update-notice hooks so the child never
|
||||
// re-spawns itself or prints a nag.
|
||||
func newUpdateRefreshCmd() *cobra.Command {
|
||||
return &cobra.Command{
|
||||
Use: "__update-refresh",
|
||||
Hidden: true,
|
||||
Args: cobra.NoArgs,
|
||||
DisableAutoGenTag: true,
|
||||
PersistentPreRun: func(cmd *cobra.Command, args []string) {},
|
||||
PersistentPostRun: func(cmd *cobra.Command, args []string) {},
|
||||
Use: "__update-refresh",
|
||||
Hidden: true,
|
||||
Args: cobra.NoArgs,
|
||||
DisableAutoGenTag: true,
|
||||
PersistentPreRun: func(cmd *cobra.Command, args []string) {},
|
||||
PersistentPostRun: func(cmd *cobra.Command, args []string) {},
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
updatecheck.RunRefresh()
|
||||
return nil
|
||||
|
||||
@@ -32,7 +32,7 @@ func newVersionCmd() *cobra.Command {
|
||||
payload["error"] = r.Err.Error()
|
||||
}
|
||||
if r.HasUpdate {
|
||||
payload["upgrade_command"] = fmt.Sprintf("npm install -g %s@latest", updatecheck.PackageName)
|
||||
payload["upgrade_command"] = "mediakit-cli update"
|
||||
}
|
||||
}
|
||||
encoder := json.NewEncoder(cmd.OutOrStdout())
|
||||
|
||||
@@ -231,8 +231,8 @@ func (e *DependencyError) Error() string {
|
||||
func (e *DependencyError) StructuredError() map[string]any {
|
||||
return map[string]any{
|
||||
"error": map[string]any{
|
||||
"type": "environment_error",
|
||||
"code": "dependency_missing",
|
||||
"type": "EnvironmentError",
|
||||
"code": "DependencyMissing",
|
||||
"message": fmt.Sprintf("命令 %s 所需本地依赖缺失: %s", e.Command, strings.Join(e.Missing, ", ")),
|
||||
"install_guide": cliconfig.InstallGuide(e.Missing),
|
||||
},
|
||||
|
||||
@@ -16,7 +16,7 @@ func NoticePayload() map[string]any {
|
||||
return map[string]any{
|
||||
"current": r.Current,
|
||||
"latest": r.Latest,
|
||||
"command": fmt.Sprintf("npm install -g %s@latest", PackageName),
|
||||
"command": "mediakit-cli update",
|
||||
"message": fmt.Sprintf("New %s release available: %s -> %s", PackageName, r.Current, r.Latest),
|
||||
}
|
||||
}
|
||||
@@ -53,8 +53,8 @@ func PrintStderrNag(w io.Writer) {
|
||||
if !isCharDevice(f) {
|
||||
return
|
||||
}
|
||||
fmt.Fprintf(w, "\n[mediakit-cli] new version available: %s -> %s\n run: npm install -g %s@latest\n",
|
||||
r.Current, r.Latest, PackageName)
|
||||
fmt.Fprintf(w, "\n[mediakit-cli] new version available: %s -> %s\n run: mediakit-cli update\n",
|
||||
r.Current, r.Latest)
|
||||
}
|
||||
|
||||
func isCharDevice(f *os.File) bool {
|
||||
|
||||
+25
-21
@@ -1,12 +1,13 @@
|
||||
#!/usr/bin/env node
|
||||
|
||||
const { spawnSync } = require('node:child_process')
|
||||
const fs = require('node:fs')
|
||||
const path = require('node:path')
|
||||
|
||||
const pkg = require('../package.json')
|
||||
|
||||
const PACKAGE_NAME = pkg.name || '@volcengine/mediakit-cli'
|
||||
const SKILL_REPO = 'volcengine/mediakit-cli'
|
||||
const SKILLS_DIR = path.join(__dirname, '..', 'skills')
|
||||
|
||||
function parseArgs(argv) {
|
||||
const opts = {
|
||||
@@ -14,7 +15,6 @@ function parseArgs(argv) {
|
||||
skillsOnly: false,
|
||||
skills: [],
|
||||
yes: false,
|
||||
versionTag: pkg.version || 'latest',
|
||||
}
|
||||
for (let i = 0; i < argv.length; i++) {
|
||||
const a = argv[i]
|
||||
@@ -38,17 +38,11 @@ function parseArgs(argv) {
|
||||
}
|
||||
break
|
||||
}
|
||||
case '--version': {
|
||||
const next = argv[i + 1]
|
||||
if (next && !next.startsWith('-')) {
|
||||
opts.versionTag = next
|
||||
i++
|
||||
}
|
||||
break
|
||||
}
|
||||
case '--version':
|
||||
throw new Error('--version is not supported; install the npm package version you want directly')
|
||||
default:
|
||||
if (a.startsWith('--version=')) {
|
||||
opts.versionTag = a.slice('--version='.length)
|
||||
throw new Error('--version is not supported; install the npm package version you want directly')
|
||||
} else if (a.startsWith('--skills=')) {
|
||||
opts.skills.push(
|
||||
...a
|
||||
@@ -69,10 +63,21 @@ function log(msg) {
|
||||
}
|
||||
|
||||
function whichSync(cmd) {
|
||||
const probe = process.platform === 'win32' ? 'where' : 'command'
|
||||
const probeArgs = process.platform === 'win32' ? [cmd] : ['-v', cmd]
|
||||
const result = spawnSync(probe, probeArgs, { stdio: 'ignore', shell: true })
|
||||
return result.status === 0
|
||||
const pathValue = process.env.PATH || ''
|
||||
const extensions =
|
||||
process.platform === 'win32'
|
||||
? (process.env.PATHEXT || '.EXE;.CMD;.BAT;.COM').split(';')
|
||||
: ['']
|
||||
for (const dir of pathValue.split(path.delimiter)) {
|
||||
if (!dir) continue
|
||||
for (const ext of extensions) {
|
||||
const candidate = path.join(dir, `${cmd}${ext}`)
|
||||
if (fs.existsSync(candidate)) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
function runNpmInstall(target) {
|
||||
@@ -91,14 +96,13 @@ function runNpmInstall(target) {
|
||||
}
|
||||
|
||||
function runSkillsAdd(opts) {
|
||||
const args = ['-y', 'skills', 'add', SKILL_REPO]
|
||||
if (opts.skills.length === 0) {
|
||||
args.push('-g')
|
||||
} else {
|
||||
const args = ['-y', 'skills', 'add', SKILLS_DIR]
|
||||
if (opts.skills.length > 0) {
|
||||
for (const skill of opts.skills) {
|
||||
args.push('-s', skill)
|
||||
}
|
||||
}
|
||||
args.push('-g')
|
||||
if (opts.yes) {
|
||||
args.push('-y')
|
||||
}
|
||||
@@ -120,10 +124,10 @@ async function runInstallWizard(rawArgs) {
|
||||
}
|
||||
|
||||
if (!opts.skillsOnly) {
|
||||
runNpmInstall(`${PACKAGE_NAME}@${opts.versionTag}`)
|
||||
runNpmInstall(PACKAGE_NAME)
|
||||
}
|
||||
|
||||
if (!opts.cliOnly) {
|
||||
if (opts.skillsOnly && !opts.cliOnly) {
|
||||
if (!whichSync('npx')) {
|
||||
throw new Error('npx is required to install skills but not found in PATH')
|
||||
}
|
||||
|
||||
@@ -36,6 +36,7 @@ const RELEASE_BASE_URL =
|
||||
const TMP_PREFIX = "mediakit-cli-install-";
|
||||
const packageRoot = path.resolve(__dirname, "..");
|
||||
const binDir = path.join(packageRoot, "bin");
|
||||
const skillsDir = path.join(packageRoot, "skills");
|
||||
|
||||
const platformMap = {
|
||||
darwin: "darwin",
|
||||
@@ -198,9 +199,24 @@ function findBinary(rootDir, targetName) {
|
||||
return null;
|
||||
}
|
||||
|
||||
function installSkills() {
|
||||
const result = spawnSync(
|
||||
"npx",
|
||||
["-y", "skills", "add", skillsDir, "-g", "-y"],
|
||||
{ stdio: "inherit" }
|
||||
);
|
||||
if (result.error) {
|
||||
throw result.error;
|
||||
}
|
||||
if (result.status !== 0) {
|
||||
throw new Error(`npx skills add failed with exit code ${result.status}`);
|
||||
}
|
||||
}
|
||||
|
||||
async function install(options = {}) {
|
||||
if (readEnv("MEDIAKIT_CLI_SKIP_DOWNLOAD", "MEDIKIT_CLI_SKIP_DOWNLOAD") === "1") {
|
||||
console.log("[mediakit-cli] skip download because MEDIAKIT_CLI_SKIP_DOWNLOAD=1");
|
||||
installSkills();
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -211,6 +227,7 @@ async function install(options = {}) {
|
||||
const targetBinary = path.join(binDir, binaryName());
|
||||
|
||||
if (!options.force && fs.existsSync(targetBinary)) {
|
||||
installSkills();
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -246,6 +263,7 @@ async function install(options = {}) {
|
||||
}
|
||||
|
||||
console.log(`[mediakit-cli] installed ${targetBinary}`);
|
||||
installSkills();
|
||||
}
|
||||
|
||||
if (require.main === module) {
|
||||
|
||||
Reference in New Issue
Block a user