
Videocut Clip Oral
- 189 installs
- 263 repo stars
- Updated July 22, 2026
- zrt-ai-lab/opencode-skills
Helps with ai & agent building tasks during AI-assisted development.
About
videocut-clip-oral is a Claude Code skill for ai & agent building. It helps solo builders move faster with AI-assisted coding.
- videocut-clip-oral
- AI & Agent Building
- AI-coding skill
Videocut Clip Oral by the numbers
- 189 all-time installs (skills.sh)
- Ranked #2,916 of 16,556 AI & Agent Building skills by installs in the Skillselion catalog
- Data as of Aug 3, 2026 (Skillselion catalog sync)
npx skills add https://github.com/zrt-ai-lab/opencode-skills --skill videocut-clip-oralAdd your badge
Show developers this skill is listed on Skillselion. Paste this into your README.
| Installs | 189 |
|---|---|
| repo stars | ★ 263 |
| Last updated | July 22, 2026 |
| Repository | zrt-ai-lab/opencode-skills ↗ |
What it does
Helps with ai & agent building tasks during AI-assisted development.
Files
<!-- input: 视频文件 (*.mp4) output: 转录JSON、审查稿、删除任务TodoList pos: 转录+识别,到用户审核为止
架构守护者:一旦我被修改,请同步更新: 1. ../README.md 的 Skill 清单 2. /CLAUDE.md 路由表 -->
剪口播
转录 + 口误/静音识别 → 生成审查稿
快速使用
用户: 帮我剪这个口播视频
用户: 处理一下这个视频流程
1. FunASR 30s 分段转录(字符级时间戳)
↓
2. 识别口误(逐句检查)
↓
3. 识别微口误(VAD 检测短片段)
↓
4. 识别语气词(嗯/哎/诶 等)
↓
5. 识别静音(≥1s)
↓
6. 生成审查稿(时间戳驱动)
↓
7. 输出删除任务 TodoList
↓
【等待用户确认】→ 用户确认后,执行 /videocut:剪辑⚠️ 为什么用 30s 分段
FunASR 长视频有时间戳漂移,30s 分段可避免。
进度 TodoList
启动时创建:
- [ ] 读取「转录最佳实践」→ 转录视频
- [ ] 读取「口误识别方法论」→ 识别口误
- [ ] VAD 检测微口误(短片段 < 0.5s)
- [ ] 扫描语气词(嗯/哎/诶 等)
- [ ] 识别静音(≥1s)
- [ ] 生成审查稿
- [ ] 输出删除任务清单⚠️ 必须先读方法论再执行
| 阶段 | 先读 | 再执行 |
|---|---|---|
| 转录 | tips/转录最佳实践.md | 调用ASR |
| 识别口误 | tips/口误识别方法论.md | 逐句分析 |
---
核心:时间戳驱动
删除任务格式
每项必须标注精确时间戳 (start-end):
口误(N处):
- [ ] 1. `(start-end)` 删"错误文本" → 保留"正确文本"
语气词(N处):
- [ ] 1. `(前字end-后字start)` 删"嗯" 上下文: XX【嗯】YY
静音(N处):
- [ ] 1. `(start-end)` 静音Xs口误类型
| 类型 | 示例 | 删除策略 |
|---|---|---|
| 重复型 | 拉满新拉满 | 只删差异("新") |
| 替换型 | AI就是AI就会 | 删第一个完整版本("AI就是") |
| 卡顿型 | 听会会 | 删第一个重复字 |
⚠️ 关键规则
1. 时间戳驱动:审查稿直接标注时间戳,剪辑不再搜索文本 2. 逐token分析:对于"删前面保后面"的口误,必须逐token查时间戳 3. 检查时间跨度:如果口误时间跨度 > 2秒,必有静音,需拆分
---
输出文件
01-xxx-v1_transcript.json # 转录结果(含时间戳)
01-xxx-v1_审查稿.md # 口误审查稿展示要求
生成审查稿后,必须展示给用户: 1. 写入文件 01-xxx-v1_审查稿.md 2. 读取并展示内容 3. 等待用户确认要删除哪些项目
---
方法论
详见 tips/口误识别方法论.md:
- 口误识别方法(逐句检查)
- "删前面保后面"的精确处理
- FunASR 时间戳对齐规则
<!-- 架构守护者:一旦本文件夹有任何变化(新增/删除/重命名文件),请更新此文件 -->
videocut:剪口播
口播视频剪辑助手
文件清单
| 文件 | 功能 |
|---|---|
SKILL.md | 入口:流程、触发词、核心规则 |
tips/口误识别方法论.md | 核心:口误识别 + 时间戳对齐 |
tips/转录最佳实践.md | 辅助:FunASR 转录参数 |
输入输出
输入: 01-xxx-v1.mp4 (原始视频)
↓
输出: 01-xxx-v1_transcript.json 转录(含时间戳)
01-xxx-v1_审查稿.md 审查稿(时间戳驱动)核心原则
1. 时间戳驱动:删除任务直接标注 (start-end) 2. 逐token分析:口误需逐token查时间戳 3. 删前面保后面:重复时删前面版本
<!-- input: 转录文本 (带时间戳的 JSON) output: 审查稿 pos: 核心方法论,口误识别和删除决策
架构守护者:一旦我被修改,请同步更新: 1. ../README.md 文件清单 -->
口误识别方法论
一、识别方法
❌ 不要用正则匹配
✅ 逐段阅读,逐句检查
每句话问自己: 1. 句子完整吗? - 残句 = 口误 2. 有重复吗? - 词语/短语/句子重复 3. 通顺吗? - 不通顺 = 说错了
口误特征
| 特征 | 判断 |
|---|---|
| 残句(没说完) | 一定是口误 |
| 同一内容说两遍 | 删前面保后面 |
| 语义不通顺 | 说错了重说 |
| 多余的字词 | 卡顿/口吃 |
---
二、口误类型与删除策略
| 类型 | 示例 | 删除策略 |
|---|---|---|
| 重复型 | 拉满新拉满 | 只删差异部分("新") |
| 替换型 | AI就是AI就会 | 删第一个完整版本("AI就是") |
| 卡顿型 | 听会会 | 删第一个重复字 |
⚠️ 精确处理步骤
当遇到 🔴~~错误版本~~正确版本 时:
步骤1:识别口误类型(重复/替换/卡顿)
步骤2:逐token查时间戳
for i in range(start_idx, end_idx):
gap = timestamps[i][0] - timestamps[i-1][1] if i > 0 else 0
print(f"[{i}] {tokens[i]} @ {timestamps[i][0]/1000:.2f}s" +
(f" ⚠️ gap={gap/1000:.1f}s" if gap > 500 else ""))步骤3:确定精确删除边界
- 时间跨度 > 2秒 → 必有静音,需拆分
- 替换型:删第一个完整版本
- 重复型:只删差异token
案例库
| 口误 | 错误处理 | 正确处理 |
|---|---|---|
拉满新拉满 | 删40.84-47.69s | 删41.35-47.69s(静音+新) |
AI就是AI就会 | 只删"就是" | 删"AI就是"(85.78-86.50s) |
听会会 | 删整个"听会会" | 只删第一个"会" |
---
三、微口误检测(2026-01-15 新增)
什么是微口误
不成词的卡顿音,转录检测不到,但听起来不舒服。
| 类型 | 示例 | 特点 |
|---|---|---|
| 起音卡顿 | "呃...你以为" | 开头有杂音 |
| 吞字 | "钉钉A...钉钉AI" | 说到一半重来 |
| 气口声 | 吸气/呼气声 | 换气太重 |
VAD 检测方法
用 FunASR 的 VAD(语音活动检测)找出所有发声片段:
from funasr import AutoModel
import subprocess
# 提取音频
subprocess.run(['ffmpeg', '-y', '-i', 'video.mp4', '-ss', '0', '-t', '5',
'-vn', '-acodec', 'pcm_s16le', '-ar', '16000', '-ac', '1',
'/tmp/check.wav'], capture_output=True)
# VAD 检测
vad_model = AutoModel(model="fsmn-vad", disable_update=True)
result = vad_model.generate(input="/tmp/check.wav")
for item in result:
if 'value' in item:
for start_ms, end_ms in item['value']:
print(f"[{start_ms/1000:.3f}s - {end_ms/1000:.3f}s] 语音活动")输出示例
[0.000s - 0.430s] 语音活动 ← 微口误!(0.71s才是正式语音)
[0.710s - 4.980s] 语音活动 ← 正式语音判断规则
| 模式 | 判断 |
|---|---|
| 短语音 + 长静音 + 长语音 | 第一个短语音是微口误 |
| 语音时长 < 0.5s 且后面有静音 | 可能是微口误 |
---
三.5、语气词检测(2026-01-15 新增)
什么是语气词
转录能识别,但属于多余的过渡音,删除后更流畅。
| 类型 | 示例 | 特点 |
|---|---|---|
| 过渡词 | "嗯"、"啊" | 句子之间的填充 |
| 感叹词 | "哎"、"诶"、"唉" | 无意义感叹 |
| 犹豫音 | "呃"、"额" | 思考时发出 |
检测方法
# 语气词列表
filler_words = ['嗯', '啊', '哎', '诶', '呃', '额', '唉', '哦', '噢', '呀', '欸']
# 扫描转录结果
for i, item in enumerate(all_chars):
if item['char'] in filler_words:
# 获取上下文
prev_char = all_chars[i-1] if i > 0 else None
next_char = all_chars[i+1] if i < len(all_chars)-1 else None
print(f"[{item['start']:.2f}s] \"{item['char']}\"")
print(f" 上下文: {prev_char['char']}【{item['char']}】{next_char['char']}")⚠️ 删除边界要精确
错误:删语气词的时间戳 (语气词.start - 语气词.end)
→ 可能删掉前面字的尾音
正确:从前一个字的 end 到后一个字的 start
→ (前字.end - 后字.start) 包含静音+语气词案例模式
| 上下文 | 错误删除 | 正确删除 |
|---|---|---|
| "A [静音] 语气词 B" | 只删语气词时间戳 | 删 "A.end - B.start" |
| "A 语气词 B" | 删语气词时间戳 | 删 "A.end - B.start" |
---
四、静音段
阈值规则
| 静音长度 | 处理 |
|---|---|
| < 1秒 | 忽略 - 自然停顿 |
| ≥ 1秒 | 建议删除 |
| 开头 > 1秒 | 建议删除 |
识别方法
# 开头静音
if timestamps[0][0] > 1000:
print(f"开头静音 {timestamps[0][0]/1000:.1f}s")
# 句间静音
for i in range(len(timestamps) - 1):
gap = timestamps[i+1][0] - timestamps[i][1]
if gap >= 1000:
print(f"静音 {gap/1000:.1f}s @ {timestamps[i][1]/1000:.1f}s")---
五、审查稿格式(时间戳驱动)
# 口误审查稿
视频:01-xxx-v1.mp4
---
【正文】
⏸️[1.36s @ 0.00-1.36]
🔴~~你以为今天a~~(1.36-2.54)你以为钉钉AI录音卡...
---
【删除任务清单】
**口误(3处)**:
- [ ] 1. `(1.36-2.54)` 删"你以为今天a" → 保留"你以为钉钉"
- [ ] 2. `(47.55-47.69)` 删"新" → 保留"拉满"
- [ ] 3. `(85.78-86.50)` 删"AI就是" → 保留"AI就会"
**静音(2处)**:
- [ ] 1. `(41.35-47.55)` 静音6.2s
- [ ] 2. `(0.00-1.36)` 开头静音关键:
- 删除项用
(start-end)格式 - 剪辑脚本直接用时间戳,不搜索文本
---
六、FunASR 时间戳对齐
Token规则
| 元素 | 时间戳 |
|---|---|
| 中文字符 | 每字1个 |
| 英文单词 | 整词1个(agent 算1个) |
| 标点/空格 | 无时间戳 |
Token化函数
def tokenize(text):
tokens = []
i = 0
while i < len(text):
char = text[i]
if '\u4e00' <= char <= '\u9fff': # 中文
tokens.append(char)
i += 1
elif char.isascii() and char.isalpha(): # 英文
word = ''
while i < len(text) and text[i].isascii() and text[i].isalpha():
word += text[i]
i += 1
tokens.append(word)
else:
i += 1
return tokens---
七、验证清单
- [ ] 删的是前面版本?
- [ ] 保留的文本完整通顺?
- [ ] 删除后不会产生新的重复?
- [ ] 时间戳精确到小数点后两位?
<!-- input: 视频/音频文件 output: 带时间戳的转录 JSON pos: 辅助,转录参数和输出格式说明
架构守护者:一旦我被修改,请同步更新: 1. ../README.md 文件清单 -->
转录最佳实践
---
零、环境准备
0.1 安装依赖
pip install funasr
pip install modelscope # 模型下载0.2 模型下载
首次运行会自动下载模型到 ~/.cache/modelscope/(约 2GB):
| 模型 | 大小 | 用途 |
|---|---|---|
| paraformer-zh | 953MB | 语音识别(带时间戳) |
| punc_ct | 1.1GB | 标点预测 |
| fsmn-vad | 4MB | 语音活动检测 |
手动预下载(可选,避免首次运行等待):
from funasr import AutoModel
# 运行一次即可触发下载
model = AutoModel(
model="paraformer-zh",
vad_model="fsmn-vad",
punc_model="ct-punc",
)
print("模型下载完成")0.3 验证安装
from funasr import AutoModel
model = AutoModel(model="paraformer-zh", disable_update=True)
result = model.generate(input="test.wav")
print(result) # 应该输出转录结果---
一、技术选型
FunASR Paraformer
阿里开源,中文识别最优,支持字符级时间戳。
⚠️ 关键发现(2026-01-15)
| 方案 | 问题 |
|---|---|
| FunASR 全视频 | 长视频时间戳漂移(~10s/3分钟)→ 剪辑不准 |
| FunASR 30s分段 | ✅ 无漂移 + 精确时间戳 |
结论:口播剪辑用 FunASR 30s 分段转录
---
二、音频预处理
2.1 从视频提取音频
ffmpeg -i video.mp4 \
-vn \ # 不要视频
-acodec pcm_s16le \ # 16-bit PCM
-ar 16000 \ # 16kHz 采样率
-ac 1 \ # 单声道
output.wav2.2 参数说明
| 参数 | 值 | 原因 |
|---|---|---|
| 采样率 | 16000 Hz | FunASR 模型训练采样率 |
| 声道 | 单声道 | 语音识别不需要立体声 |
| 格式 | WAV | 无损,兼容性好 |
| 位深 | 16-bit | 足够,文件更小 |
---
三、FunASR 使用
3.1 ⭐ 推荐:30s 分段转录(口播剪辑用这个)
from funasr import AutoModel
import subprocess
import os
video = "video.mp4"
segment_len = 30 # 30秒一段
duration = 217.97 # 视频时长(用 ffprobe 获取)
model = AutoModel(model="paraformer-zh", disable_update=True)
all_chars = []
num_segments = int(duration // segment_len) + 1
for i in range(num_segments):
start = i * segment_len
dur = min(segment_len, duration - start)
wav = f'/tmp/seg_{i}.wav'
# 提取音频段
subprocess.run(['ffmpeg', '-y', '-i', video, '-ss', str(start), '-t', str(dur),
'-vn', '-acodec', 'pcm_s16le', '-ar', '16000', '-ac', '1', wav],
capture_output=True)
# FunASR 转录(字符级时间戳)
result = model.generate(input=wav, return_raw_text=True,
timestamp_granularity="character")
for item in result:
if 'timestamp' in item and 'text' in item:
text = item['text'].replace(' ', '')
for char, ts in zip(text, item['timestamp']):
all_chars.append({
'char': char,
'start': round(start + ts[0] / 1000, 2), # 加偏移!
'end': round(start + ts[1] / 1000, 2)
})
os.remove(wav)关键点:
- 30s 分段避免时间戳漂移
timestamp_granularity="character"获取字符级时间戳- 每段结果要 加上段起始偏移
3.2 基础用法(短视频可用)
from funasr import AutoModel
model = AutoModel(
model="paraformer-zh", # 中文模型
vad_model="fsmn-vad", # 语音活动检测
punc_model="ct-punc", # 标点预测
)
result = model.generate(
input="audio.wav",
batch_size_s=300, # 批处理时长(秒)
)3.2 输出格式
[{
"key": "audio",
"text": "大家好,我是陈峰。",
"timestamp": [
[880, 1120], // 第1个字的时间范围 (ms)
[1120, 1360], // 第2个字
...
]
}]3.3 模型说明
| 模型 | 用途 |
|---|---|
paraformer-zh | 中文语音识别主模型 |
fsmn-vad | 检测哪里有人说话 |
ct-punc | 自动添加标点符号 |
---
四、输出格式设计
4.1 详细 JSON 格式
{
"audio_file": "/path/to/audio.wav",
"full_text": "完整转录文本...",
"duration_ms": 935455,
"segments": [
{
"char": "大",
"start_ms": 880,
"end_ms": 1120
},
...
],
"raw_result": { /* FunASR 原始输出 */ }
}4.2 可读 TXT 格式
======================================
视频转录结果 - video.mp4
======================================
总时长: 15:35 (15分35秒)
字符数: 2006
======================================
完整文本
======================================
大家好,我是陈峰。一直有同学问我...
======================================
带时间戳的句子记录
======================================
[00:01 - 00:02]
大家好,我是陈峰。
[00:05 - 00:17]
一直有同学问我能不能做一期企业级PPT模板的教程?---
五、常见问题
Q0: 调用方式错误(2026-01-13)
错误:尝试用命令行 funasr --input video.mp4 调用 正确:只能用 Python API
# ❌ 错误 - 没有 funasr CLI
subprocess.run(['funasr', '--input', 'video.mp4'])
# ✅ 正确 - 用 Python API
from funasr import AutoModel
model = AutoModel(model="paraformer-zh", ...)
result = model.generate(input="video.mp4")Q0.5: 模型选错没有时间戳(2026-01-13)
错误:用 SenseVoiceSmall 模型,只输出文本没有时间戳 正确:必须用 paraformer-zh 才有字符级时间戳
# ❌ 错误 - 没有时间戳
model = AutoModel(model="iic/SenseVoiceSmall", ...)
# ✅ 正确 - 有时间戳
model = AutoModel(
model="paraformer-zh", # 这个才有时间戳!
vad_model="fsmn-vad",
punc_model="ct-punc",
)Q1: 模型下载慢
首次运行会下载 ~1GB 模型到 ~/.cache/modelscope/
解决:
- 使用国内镜像
- 或手动下载后放到缓存目录
Q2: 时间戳和文字对不上
原因:标点符号没有时间戳,需要特殊处理
解决:
# 去掉标点后再对齐
import re
text_no_punc = re.sub(r'[,。!?、;:]', '', text)Q2.5: 时间戳数量少于字符数(2026-01-13)
现象:纯字符数828,时间戳数763,末尾67个字符没有时间戳
原因:FunASR 对视频末尾部分可能丢失时间戳
解决:
# 访问时间戳要兜底
if idx < len(timestamps):
ts = timestamps[idx]
else:
ts = timestamps[-1] # 用最后一个时间戳兜底Q2.6: 正则表达式漏掉英文标点(2026-01-13)
现象:搜索文本时位置偏移,因为 clean_text 里还有英文标点
原因:正则只移除中文标点,没处理英文 , . 等
解决:
# ❌ 错误 - 只有中文标点
clean = re.sub(r'[,。!?、;:]', '', text)
# ✅ 正确 - 包含英文标点
clean = re.sub(r'[,。?!、:;""''()《》【】\s\.,!?;:\'"()]', '', text)Q3: 长视频处理慢
解决:
- 增大
batch_size_s参数 - 使用 GPU 加速(需要 PyTorch CUDA)
Q4: 识别准确率低
可能原因:
- 背景噪音太大
- 说话人口音重
- 音频采样率不对
解决:
- 预处理降噪
- 确保 16kHz 采样率
---
六、性能参考
| 指标 | 值 |
|---|---|
| RTF (Real-Time Factor) | ~0.16 |
| 含义 | 1秒音频只需0.16秒处理 |
| 15分钟视频 | 约2.5分钟处理完 |
测试环境:M1 Mac,CPU 推理