Skip to content
Back to skills

transcribe

BSecurity

音视频转写 skill — 将在线视频 URL、本地音视频文件,通过通义听悟 API 转写为中文文字稿(Markdown 格式), 同时归档到阿里云 OSS。当用户提到"转写"、"字幕"、"听悟"、"在线视频"、"把视频变成文字"、"音频转文字"、 "视频转文字"、"yt-dlp"等相关需求时,立即使用本 skill,不要等用户明确说"用 transcribe skill"。

  • 5 stars
  • 0 votes
  • 0 copies
  • 2 views
  • Added May 26, 2026
developmentpythonbashgitapi

Works with

  • claude code
  • api

Security analysis

B88/100
  • criticalSends environment variables or credentials to an external URL

Pro scans all 14 files and shows the line behind each finding

Scanned May 27, 2026

npx -y skills add kkzeros/transcribe-openclaw --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of transcribe?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for transcribe
[![Security: B — Skills Directory](https://www.skillsdirectory.com/api/skills/kkzeros-transcribe/badge)](https://www.skillsdirectory.com/skills/kkzeros-transcribe)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: transcribe
version: 1.0.0
description: >
  音视频转写 skill — 将在线视频 URL、本地音视频文件,通过通义听悟 API 转写为中文文字稿(Markdown 格式),
  同时归档到阿里云 OSS。当用户提到"转写"、"字幕"、"听悟"、"在线视频"、"把视频变成文字"、"音频转文字"、
  "视频转文字"、"yt-dlp"等相关需求时,立即使用本 skill,不要等用户明确说"用 transcribe skill"。
metadata:
  openclaw:
    requires:
      env:
        - ALIBABA_CLOUD_ACCESS_KEY_ID
        - ALIBABA_CLOUD_ACCESS_KEY_SECRET
        - TINGWU_APP_KEY
        - OSS_BUCKET
        - OSS_ENDPOINT
        - TINGWU_REGION
      bins:
        - python3
        - ffmpeg
        - yt-dlp
    primaryEnv: ALIBABA_CLOUD_ACCESS_KEY_ID
    emoji: "🎙"
    os:
      - macos
      - linux
    install:
      - kind: uv
        package: yt-dlp
        bins: [yt-dlp]
---

# Transcribe — 音视频转写 Skill

将音视频内容转写为带时间戳、说话人标注的 Markdown 文字稿。

## 支持的输入方式

| 方式 | 示例 |
|------|------|
| 在线视频 URL | 支持 yt-dlp 可解析的视频平台链接 |
| 本地音视频文件路径 | `/path/to/video.mp3` |
| 已公开的 HTTP 文件 URL | `https://example.com/audio.mp4` |

**输出**:保存到 Step 0.5 确认的 `OUTPUT_DIR` 目录下:

| 文件 | 内容 |
|------|------|
| `{ts}-{name}-{taskId}.md` | 转写全文(带时间戳、说话人标注)+ 摘要总结 |
| `{ts}-{name}-{taskId}_meta.json` | task_id、原文件名、本地路径、OSS 路径、听悟临时 URL(兜底用) |

---

## Step 0:依赖自检(每次调用前执行)

**第一步:确定 skill 根目录的绝对路径**

skill 根目录是 SKILL.md 所在的目录。用以下命令获取并记录,后续所有步骤都以此为基准:

```bash
SKILL_ROOT=$(python3 -c "from pathlib import Path; print(Path('scripts/pipeline.py').resolve().parent.parent)")
```

若上述命令因 CWD 不同而不准确,改用脚本的绝对路径推算:

```bash
SKILL_ROOT=$(python3 -c "from pathlib import Path; import sys; print(Path(sys.argv[1]).resolve().parent.parent)" "$SKILL_ROOT/scripts/pipeline.py")
```

或直接用已知的安装路径(openclaw 环境下通常为):

```
~/.openclaw/skills/transcribe-openclaw
```

**第二步:运行依赖自检**

```bash
bash $SKILL_ROOT/scripts/setup.sh
```

幂等脚本,已安装则秒过。

**第三步:检查 `.env` 文件**

检查 `$SKILL_ROOT/.env` 是否存在:
- **存在** → 继续
- **不存在** → 停止,提示用户:
  ```
  未找到 .env 文件,请在 skill 根目录下创建:
    cp $SKILL_ROOT/.env.example $SKILL_ROOT/.env
  然后编辑 .env 填入真实凭证(参考 .env.example 中的字段说明)
  ```

**第四步:解析 cookie 路径**

读取 `$SKILL_ROOT/.env` 中的 `COOKIES_FILE` 值,拼出绝对路径并检查文件是否存在:

```bash
COOKIES_FILE=$(grep '^COOKIES_FILE=' $SKILL_ROOT/.env | cut -d'=' -f2 | tr -d ' ')
if [ -n "$COOKIES_FILE" ] && [ -f "$SKILL_ROOT/$COOKIES_FILE" ]; then
  COOKIES_OPT="--cookies $SKILL_ROOT/$COOKIES_FILE"
  echo "Cookie 文件已就绪:$SKILL_ROOT/$COOKIES_FILE"
else
  COOKIES_OPT=""
  echo "未配置 cookie,yt-dlp 以匿名模式运行"
fi
```

后续所有 yt-dlp 命令统一使用 `$COOKIES_OPT` 变量(已包含 `--cookies <绝对路径>`),无需手动拼路径。

---

## Step 0.5:输出路径确认(每次调用前执行)

读取 `scripts/pipeline.py` 顶部的 `OUTPUT_DIR` 变量:

- **为空或路径不合法** → 不要直接运行脚本,先向用户确认:
  - 若运行环境是 **openclaw**:
    ```
    .openclaw/workspace/data/transcribe_results
    ```
  - 若运行环境是 **Claude Code 或其他终端**:检测当前项目根目录(优先用 `git rev-parse --show-toplevel`,若不在 git 仓库则用 `pwd` 输出的当前目录),建议路径为:
    ```
    <项目根目录>/results
    ```
    将检测到的完整路径返回给用户确认
  - 若用户有自定义偏好,按用户指定路径
  - 确认后将路径写入 `scripts/pipeline.py` 的 `OUTPUT_DIR`,同步更新 `scripts/get_result.py` 的 `OUTPUT_DIR`

- **已填写且路径合法** → 直接进入 Step 1,不再询问

> 依赖检查(Step 0)和路径确认(Step 0.5)是两个独立步骤,互不影响。

---

## Step 1:执行转写

> 以下命令中 `$SKILL_ROOT` 为 skill 根目录绝对路径(Step 0 已确定)。
> cookie 文件固定在 `$SKILL_ROOT/cookies.txt`,**每条 yt-dlp 命令都必须加上 `--cookies $SKILL_ROOT/cookies.txt`**,不要省略。

### 方式 A:在线视频 URL(yt-dlp 可解析的平台)

```bash
TITLE=$(yt-dlp --cookies $SKILL_ROOT/cookies.txt --get-title "<视频URL>")
yt-dlp --cookies $SKILL_ROOT/cookies.txt -x --audio-format mp3 -o - "<视频URL>" | python3 $SKILL_ROOT/scripts/pipeline.py --stdin "${TITLE}.mp3"
```

### 方式 B:本地文件

```bash
python3 $SKILL_ROOT/scripts/pipeline.py "/path/to/file.mp3"
```

### 方式 C:已有公开 HTTP URL(文件可被听悟服务器直接访问)

```bash
python3 $SKILL_ROOT/scripts/pipeline.py "https://example.com/audio.mp3"
```

### 方式 D:yt-dlp 取直链 → 先上传 OSS 再转写

适用场景:视频平台 CDN 直链有时效或需要 Headers,听悟无法直接拉取,需经 OSS 中转。

```bash
TITLE=$(yt-dlp --cookies $SKILL_ROOT/cookies.txt --get-title "<视频URL>")
DIRECT_URL=$(yt-dlp --cookies $SKILL_ROOT/cookies.txt -g "<视频URL>" | head -1)
OSS_URL=$(python3 $SKILL_ROOT/scripts/upload_oss.py --url "$DIRECT_URL" "${TITLE}.mp4")
python3 $SKILL_ROOT/scripts/pipeline.py "$OSS_URL"
```

> **注意**:`yt-dlp -g` 返回原始视频格式(mp4/flv),不会转码为 mp3。
> 若需要 mp3,优先用方式 A(流式转码)。方式 D 适合服务器本地带宽有限、希望让 OSS 直接拉流的场景。

> **yt-dlp 下载失败时**(如需要登录、地区限制等),可先在本地手动下载音频文件,再用**方式 B** 传入本地路径处理。

### 可选参数

| 参数 | 说明 | 默认值 |
|------|------|--------|
| `--timeout N` | 最长等待转写完成时间(秒) | 600(10 分钟) |
| `--output-dir PATH` | 结果保存目录(覆盖 OUTPUT_DIR) | 同 OUTPUT_DIR |

### 超时时间估算

调用前建议先用 ffprobe 获取文件时长,再按下表设置 `--timeout`:

```bash
ffprobe -v error -show_entries format=duration -of csv=p=0 "audio.mp3"
```

| 文件时长 | 建议 --timeout |
|----------|---------------|
| < 10 分钟 | 600s(默认) |
| 10 ~ 30 分钟 | 1800s |
| 30 ~ 60 分钟 | 3600s |
| > 1 小时 | 文件时长(秒)× 3 |

---

## 断点续传

脚本不做自动断点检测,TaskId 打印在终端,agent 持有上下文后可按下表手动续接:

| 中断位置 | 已有信息 | 恢复方式 |
|----------|----------|---------|
| OSS 上传中 | 无 TaskId | 重新运行全流程 |
| OSS 上传完、建任务前 | 有 OSS URL,无 TaskId | 重新运行全流程(重传代价小) |
| 建任务后,轮询中断 | 有 TaskId | `query_task.py` 轮询,再调 `get_result.py` |
| 轮询完成,取结果中断 | TaskId + 状态 COMPLETED | 直接调 `get_result.py` |

```bash
# 查询任务状态
python3 scripts/query_task.py <taskId>

# 状态为 COMPLETED 时直接取结果
# OUTPUT_DIR 已写入脚本时无需传 --output-dir;否则手动指定
python3 scripts/get_result.py <taskId> --input-name "原文件名.mp3" --output-dir <输出路径>
```

---

## .env 配置说明

`.env` 放在 skill 根目录(与 SKILL.md 同级),完整模板见 `.env.example`。

必填项:

```
ALIBABA_CLOUD_ACCESS_KEY_ID=
ALIBABA_CLOUD_ACCESS_KEY_SECRET=
TINGWU_APP_KEY=
OSS_BUCKET=
OSS_ENDPOINT=
```

可选项(有默认值):

```
TINGWU_REGION=cn-beijing   # 服务地域,按实际开通地域填写
```

---

## 错误排查

脚本遇到错误码会自动输出中文说明和排查建议。常见错误速查见 `references/errors.md`。

### 账号级严重错误(遇到立即停止并提醒用户)

以下错误表示账号或服务本身存在问题,继续重试无意义,**必须中断任务并向用户发出明确警告**:

| 错误码 | 含义 | 建议提示用户 |
|--------|------|-------------|
| `BRK.InvalidService` | 账号未开通通义听悟服务 | 请前往 https://tingwu.console.aliyun.com 开通服务后重试 |
| `BRK.OverdueService` | 账号服务已超配额 | 当前用量已达上限,请检查套餐或联系阿里云升配 |
| `BRK.OverdueTenant` | 账号已欠费 | 请前往阿里云控制台充值后重试 |
| `BRK.InvalidTenant` | 账号服务未开通或已欠费 | 请确认通义听悟服务已开通且账号余额充足 |

这类错误由 `errors.py` 的 `explain_error()` 自动识别并输出中文说明。若脚本抛出包含上述错误码的异常,**不要静默忽略,直接将错误信息展示给用户**。

---

## 获取结果失败时的兜底方案

主流程:听悟 API 完成 → 直接从听悟临时 URL 下载(不经 OSS,节省流量)

若主流程失败,按以下顺序兜底:

1. **重试听悟 API**:重新执行 `get_result.py <taskId>`,临时 URL 未过期则可重新拉取
2. **从 OSS 下载**:先读取 `_meta.json` 中的 `oss_transcript` 字段,格式为 `oss://<bucket>/transcribe/transcript/<文件名>.md`,取最后的路径部分替换到命令中:
   ```bash
   # 将 <oss_key> 替换为 oss_transcript 字段中 bucket 后面的路径部分
   # 将 <本地保存路径> 替换为实际输出路径
   python3 -c "
   import oss2, os; from dotenv import load_dotenv; load_dotenv()
   auth = oss2.Auth(os.environ['ALIBABA_CLOUD_ACCESS_KEY_ID'], os.environ['ALIBABA_CLOUD_ACCESS_KEY_SECRET'])
   bucket = oss2.Bucket(auth, 'https://' + os.environ['OSS_ENDPOINT'], os.environ['OSS_BUCKET'])
   bucket.get_object_to_file('<oss_key>', '<本地保存路径>')
   "
   ```
3. **使用 tingwu_result_urls**:`_meta.json` 中保存了听悟原始临时 URL,在有效期内可直接 curl 下载

---

## 历史转写文本检索

### 本地检索

```bash
# 以下命令中的 <OUTPUT_DIR> 替换为实际输出路径(即 Step 0.5 确认的目录)

# 按日期前缀(替换 {YYYYMMDD} 为实际日期,如 20260321)
ls <OUTPUT_DIR> | grep "^{YYYYMMDD}"

# 按文件名关键词
ls <OUTPUT_DIR> | grep "关键词"

# 按 TaskId 精确查找
ls <OUTPUT_DIR> | grep "<taskId>"

# 查看某条任务的元数据
cat <OUTPUT_DIR>/<文件名>_meta.json
```

### OSS 检索

- 文件名以时间戳开头,控制台默认按字典序展示即为时间顺序
- 前缀筛选 `transcribe/transcript/{YYYYMMDD}` 可快速定位某天的文件

Files in this skill

  • .clawhubignore75 B
  • .env.example1 KB
  • SKILL.md10.6 KB
  • references/api_overview.md3 KB
  • references/errors.md1.9 KB
  • references/requirements.txt58 B
  • references/setup-guide.md5.3 KB
  • scripts/create_task.py3.4 KB
  • scripts/errors.py3.3 KB
  • scripts/get_result.py7 KB
  • scripts/pipeline.py5.1 KB
  • scripts/query_task.py2.4 KB
  • scripts/setup.sh1.1 KB
  • scripts/upload_oss.py5.7 KB

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…

Newsletter

Get the weekly list of safe new skills, and the ones we pulled.