원클릭으로
podcastcut-edit-fine
精剪播客。根据统一审查稿执行字符级FFmpeg剪辑,默认快速模式。触发词:精剪、执行精剪、fine cut
Codex 또는 Claude로 설치 이 Prompt를 복사해 Codex, Claude 또는 다른 어시스턴트에 붙여 넣으면 Skill 페이지를 검토하고 설치를 진행할 수 있습니다.
메뉴
精剪播客。根据统一审查稿执行字符级FFmpeg剪辑,默认快速模式。触发词:精剪、执行精剪、fine cut
Codex 또는 Claude로 설치 이 Prompt를 복사해 Codex, Claude 또는 다른 어시스턴트에 붙여 넣으면 Skill 페이지를 검토하고 설치를 진행할 수 있습니다.
SOC 직업 분류 기준
使用 browser-use CLI 对 PodcastCut webapp 做浏览器验收。始终使用 headed 模式,覆盖打开页面、登录、上传指定音频、触发生成审查稿、刷新审查稿、手动标记删除、确认剪辑、核对 workspace 产物。触发词:browser validation、浏览器验证、用 browser-use 跑流程、上传音频验收
生成播客审查画布数据。根据当前工作区中的音频、转录、QA 报告和剪辑结果, 产出固定格式的 review_data.json,供右侧审查画布直接读取。 触发词:审查画布、review data、审查稿、生成播客审查
语音克隆 + 播客生成完整流程。 上传音频 → 转录 → 修正文稿 → 提取声音样本 → 克隆声音模型 → TTS 合成 → 合并成品音频。 全自动执行,无需用户逐步操作。 触发词:语音克隆、声音克隆、生成播客、克隆声音
音频剪辑。根据 delete_segments.json 删除指定片段,自适应淡入淡出,可选说话人音量对齐。触发词:剪辑、cut、编辑音频
将当前 webapp 发布到 Fly.io,并在发布前后做最小健康检查。 适用于前端或后端改动后的一键上线。触发词:deploy、发布、上线、推到 fly、fly.io
使用 browser-use CLI 对 webapp 做端到端验证。覆盖登录、上传音频、生成 review_data.json、刷新审查稿、手动标记删除、确认剪辑、验证 podcast_cut.mp3。触发词:browser e2e、端到端验证、验证网页剪辑、用浏览器跑流程
| name | podcastcut-edit-fine |
| description | 精剪播客。根据统一审查稿执行字符级FFmpeg剪辑,默认快速模式。触发词:精剪、执行精剪、fine cut |
读取统一审查稿 → 过滤/合并 → 快速执行 FFmpeg
用户: 精剪
用户: 执行精剪
用户: 按审查稿精剪
需要先执行 /podcastcut-transcribe 生成统一审查稿。
1. 读取统一审查稿(来自 transcribe)
↓
2. 过滤微小删除(< 0.3s)
↓
3. 合并相邻删除(gap < 1.0s)
↓
4. 计算保留片段
↓
5. 生成 FFmpeg filter → 执行剪辑
↓
6. 输出 v3 音频
目标:减少 FFmpeg 分段数,加速处理。
# 快速模式参数
MIN_DELETE_DURATION = 0.3 # 忽略 < 0.3s 的删除(听不出来)
MIN_SILENCE_DURATION = 2.0 # 静音阈值(原 1.5s)
MERGE_GAP_THRESHOLD = 1.0 # 合并阈值(原 0.3s)
| 模式 | 分段数 | 处理时间 | FFmpeg 速度 |
|---|---|---|---|
| 原版 | 570 | 38 分钟 | 2.5x |
| 快速 | 154 | 3.5 分钟 | 32x |
加速 ~11 倍,代价是保留了一些微小的静音/语气词(总计约 2-3 分钟),听感影响很小。
只读取 /podcastcut-transcribe 输出的统一审查稿:
<工作目录>/
├── 审查稿.md # 统一审查稿(包含所有删除标记)
├── deletions.json # 删除清单
└── transcript_chars.json # 字符级时间戳
不需要扫描多个审查稿:transcribe 已经合并了所有来源。
def filter_deletions(deletions):
"""过滤微小删除"""
return [
d for d in deletions
if d['end'] - d['start'] >= MIN_DELETE_DURATION
]
def merge_deletions(deletions, gap_threshold=MERGE_GAP_THRESHOLD):
"""合并相邻的删除"""
if not deletions:
return []
sorted_dels = sorted(deletions, key=lambda x: x['start'])
merged = []
current = {'start': sorted_dels[0]['start'], 'end': sorted_dels[0]['end']}
for d in sorted_dels[1:]:
if d['start'] <= current['end'] + gap_threshold:
current['end'] = max(current['end'], d['end'])
else:
merged.append(current)
current = {'start': d['start'], 'end': d['end']}
merged.append(current)
return merged
ffmpeg -y -i input.mp3 \
-filter_complex_script filter.txt \
-map "[outa]" \
-c:a libmp3lame -q:a 2 \
output_v3.mp3
[0:a]atrim=start=0.000:end=35.310,asetpts=PTS-STARTPTS[a0];
[0:a]atrim=start=37.769:end=46.129,asetpts=PTS-STARTPTS[a1];
[0:a]atrim=start=49.029:end=120.500,asetpts=PTS-STARTPTS[a2];
...
[a0][a1][a2]...concat=n=N:v=0:a=1[outa]
删除时保留微小过渡,避免卡顿:
| 删除类型 | 过渡规则 |
|---|---|
| 语气词 | 前后各 0.05s |
| 静音 | 保留 0.15s |
| 口误 | 无需过渡 |
相邻片段边界要小心避免重叠:
# "对" 结束于 49.030,"这" 开始于 49.030
# 删除结束设为 49.029,避免重叠
deletion_end = 49.029 # 不是 49.030
<工作目录>/
├── 原始音频_v3.mp3 # 精剪后音频
├── 删除清单_v3.json # 合并后的删除清单
├── keep_segments_v3.json # 保留片段列表
├── filter_v3.txt # FFmpeg filter 脚本
└── ffmpeg_cmd_v3.sh # FFmpeg 完整命令
脚本位置:scripts/ 目录
一键快速模式:过滤 + 合并 + 生成 FFmpeg 命令。
python scripts/merge_deletions_fast.py <工作目录> [输入文件] [输出文件]
输入: deletions_unified.json 或 deletions.json
输出:
deletions_fast.json - 合并后的删除清单keep_segments_fast.json - 保留片段filter_fast.txt - FFmpeg filter 脚本ffmpeg_cmd_fast.sh - 执行命令使用时机: 精剪时必须使用此脚本,否则分段过多导致 FFmpeg 极慢。
WORK_DIR="/path/to/project"
INPUT="/path/to/v2.mp3"
OUTPUT="/path/to/v3.mp3"
# 1. 快速模式合并 + 生成 FFmpeg 命令
python scripts/merge_deletions_fast.py "$WORK_DIR" "$INPUT" "$OUTPUT"
# 2. 执行剪辑
bash "$WORK_DIR/ffmpeg_cmd_fast.sh"
| 方式 | 分段数 | FFmpeg 时间 |
|---|---|---|
| 不合并 | 570+ | 38 分钟 |
| 用脚本 | 150 | 3.5 分钟 |
加速 11 倍,代价是保留微小静音(听感影响很小)。
用户: 精剪
AI: 好的,读取统一审查稿...
- 删除项: 168 处
- 过滤微小删除后: 82 处
- 合并后: 45 个删除块
- 保留: 46 段
执行 FFmpeg...
- 处理时间: 3 分 26 秒
- 速度: 32x
结果:
- 原始时长: 1:28:00
- 精剪后: 1:26:30
- 删除: 1:30
输出: 原始音频_v3.mp3
快速模式作为默认
简化输入:只读取统一审查稿
边界精度问题
merge_deletions_fast.py 中删除结束时间减 0.001sd['end'] = round(d['end'] - 0.001, 3)