音频转录工具
目的
本技能实现了从音频到文本转录的自动化,可输出专业的 Markdown 格式,提取丰富的技术元数据(发言人、时间戳、语言、文件大小、时长),并生成结构化的会议纪要和执行摘要。它支持 Faster-Whisper 或 Whisper 且无需配置,可在不同项目中通用,无需硬编码路径或 API 密钥。
受 Plaud 等工具的启发,本技能将原始音频录音转化为可操作的文档,非常适合用于会议、访谈、讲座和内容分析。
使用场景
在以下情况下调用此技能:- 用户需要将音频/视频文件转录为文本
- 用户希望从录音中自动生成会议纪要
- 用户在对话中需要发言人识别(分角色转录)
- 用户需要字幕文件(SRT, VTT 格式)
- 用户需要长音频内容的执行摘要
- 用户提出类似“转录这段音频”、“将音频转换为文本”、“根据录音生成会议笔记”的需求
- 用户拥有常见格式的音频文件(MP3, WAV, M4A, OGG, FLAC, WEBM)
工作流
步骤 0:探测(自动检测转录工具)
目标: 在无需用户配置的情况下识别可用的转录引擎。
操作:
运行检测命令以查找已安装的工具:
# 检查 Faster-Whisper (首选 - 速度快 4-5 倍)
if python3 -c "import faster_whisper" 2>/dev/null; then
TRANSCRIBER="faster-whisper"
echo "✅ 检测到 Faster-Whisper (已优化)"
回退至原始 Whisper
elif python3 -c "import whisper" 2>/dev/null; then
TRANSCRIBER="whisper"
echo "✅ 检测到 OpenAI Whisper"
else
TRANSCRIBER="none"
echo "⚠️ 未找到转录工具"
fi
检查 ffmpeg (用于音频格式转换)
if command -v ffmpeg &>/dev/null; then
echo "✅ ffmpeg 可用 (已启用格式转换)"
else
echo "ℹ️ 未找到 ffmpeg (格式支持有限)"
fi如果未找到转录工具:
提供使用预设脚本的自动安装选项:
echo "⚠️ 未找到转录工具"
echo ""
echo "🔧 是否自动安装依赖?(推荐)"
read -p "运行安装脚本? [Y/n]: " AUTO_INSTALL
if [[ ! "$AUTO_INSTALL" =~ ^[Nn] ]]; then
# 获取技能目录 (适用于仓库安装和符号链接安装)
SKILL_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
# 运行安装脚本
if [[ -f "$SKILL_DIR/scripts/install-requirements.sh" ]]; then
bash "$SKILL_DIR/scripts/install-requirements.sh"
else
echo "❌ 未找到安装脚本"
echo ""
echo "📦 手动安装:"
echo " pip install faster-whisper # 推荐"
echo " pip install openai-whisper # 备选"
echo " brew install ffmpeg # 可选 (macOS)"
exit 1
fi
# 验证安装是否成功
if python3 -c "import faster_whisper" 2>/dev/null || python3 -c "import whisper" 2>/dev/null; then
echo "✅ 安装成功!正在继续转录..."
else
echo "❌ 安装失败。请手动安装。"
exit 1
fi
else
echo ""
echo "📦"
需要手动安装:"
echo ""
echo "推荐(最快):"
echo " pip install faster-whisper"
echo ""
echo "备选(原版):"
echo " pip install openai-whisper"
echo ""
echo "可选(格式转换):"
echo " brew install ffmpeg # macOS"
echo " apt install ffmpeg # Linux"
echo ""
exit 1
fi
这确保了用户可以通过一次确认安装依赖,或者根据偏好选择手动安装。
如果找到转录器:
进入步骤 0b(CLI 检测)。
步骤 1:验证音频文件
目标: 验证文件是否存在,检查格式并提取元数据。
操作:
1. 接收用户提供的文件路径或 URL:
- 本地文件:meeting.mp3
- URL:https://example.com/audio.mp3(下载至临时目录)
2. 验证文件是否存在:
if [[ ! -f "$AUDIO_FILE" ]]; then
echo "❌ 未找到文件: $AUDIO_FILE"
exit 1
fi
3. 使用 ffprobe 或 file 工具提取元数据:获取文件大小
FILE_SIZE=$(du -h "$AUDIO_FILE" | cut -f1)
使用 ffprobe 获取时长和格式
DURATION=$(ffprobe -v error -show_entries format=duration \ -of default=noprint_wrappers=1:nokey=1 "$AUDIO_FILE" 2>/dev/null) FORMAT=$(ffprobe -v error -select_streams a:0 -show_entries \ stream=codec_name -of default=noprint_wrappers=1:nokey=1 "$AUDIO_FILE" 2>/dev/null)将时长转换为 HH:MM:SS
DURATION_HMS=$(date -u -r "$DURATION" +%H:%M:%S 2>/dev/null || echo "Unknown")4. 检查文件大小(若针对云端 API 且文件过大则发出警告):5. 验证格式(支持:MP3, WAV, M4A, OGG, FLAC, WEBM):if [[ ! " ${SUPPORTED_FORMATS[@]} " =~ " ${EXTENSION,,} " ]]; then
echo "⚠️ 不支持的格式: $EXTENSION"
if command -v ffmpeg &>/dev/null; then
echo "🔄 正在转换为 WAV..."
ffmpeg -i "$AUDIO_FILE" -ar 16000 "${AUDIO_FILE%.*}.wav" -y
AUDIO_FILE="${AUDIO_FILE%.*}.wav"
else
echo "❌ 请安装 ffmpeg 以转换格式: brew install ffmpeg"
exit 1
fi
fi
### 步骤 3:生成 Markdown 输出
目标: 创建包含元数据、转录内容、会议纪要和摘要的结构化 Markdown 文档。
输出模板:
音频转录报告
📊 元数据
| 字段 | 数值 |
|-------|-------|
| 文件名 | {filename} |
| 文件大小 | {file_size} |
| 时长 | {duration_hms} |
| 语言 | {language} ({language_code}) |
| 处理日期 | {process_date} |
| 识别发言人人数 | {num_speakers} |
| 转录引擎 | {engine} (模型: {model}) |
📋 会议纪要
参会人员
- {speaker_1}
- {speaker_2}
- ...
讨论议题
1. {topic_1} ({timestamp}) - {key_point_1} - {key_point_2}2. {topic_2} ({timestamp})
- {key_point_1}
达成决策
- ✅ {decision_1}
- ✅ {decision_2}
待办事项
- [ ] {action_1} - 负责人: {speaker} - 截止日期: {date_if_mentioned}
- [ ] {action_2} - 负责人: {speaker}
*由 audio-transcriber skill v1.0.0 生成*
*转录引擎: {engine} | 处理耗时: {elapsed_time}s*
实现方式:
使用 Python 或 bash 结合 AI 模型(Claude/GPT)进行智能总结:
def generate_meeting_minutes(segments):
"""从转录文本中提取主题、决策和待办事项。"""
# 按主题对片段进行分组(通过时间戳进行简单聚类)
topics = cluster_by_topic(segments)
# 识别待办事项(关键词:"should", "will", "need to", "action")
action_items = extract_action_items(segments)
# 识别决策(关键词:"decided", "agreed", "approved")
decisions = extract_decisions(segments)
return {
"topics": topics,
"decisions": decisions,
"action_items": action_items
}
def generate_summary(segments, max_paragraphs=5):
"""使用 AI(通过 API 调用 Claude/GPT 或使用本地模型)创建执行摘要。"""
full_text = " ".join([s["text"] for s in segments])
# 使用密度链(Chain of Density)方法(源自 prompt-engineer 框架)
summary_prompt = f"""
请将以下转录文本总结为 {max_paragraphs} 个简洁的段落。
重点关注关键主题、决策和待办事项。
转录文本:
{full_text}
"""
# 调用 AI 模型(占位符 - 用户可以集成 Claude API 或使用本地模型)
summary = call_ai_model(summary_prompt)
return summary
输出文件命名:
# v1.1.0: 使用时间戳以避免覆盖
TIMESTAMP=$(date +%Y%m%d-%H%M%S)
TRANSCRIPT_FILE="transcript-${TIMESTAMP}.md"
ATA_FILE="ata-${TIMESTAMP}.md"
echo "$TRANSCRIPT_CONTENT" > "$TRANSCRIPT_FILE"
echo "✅ 转录文件已保存: $TRANSCRIPT_FILE"
if [[ -n "$ATA_CONTENT" ]]; then
echo "$ATA_CONTENT" > "$ATA_FILE"
echo "✅ 会议纪要已保存: $ATA_FILE"
fi
#### 场景 A:用户提供了自定义 Prompt
工作流:
1. 显示用户 Prompt:
📝 用户提供的 Prompt:
┌──────────────────────────────────┐
│ [用户 Prompt 预览] │
└──────────────────────────────────┘2. 使用 prompt-engineer 自动优化(如果可用):
🔧 正在使用 prompt-engineer 优化 Prompt...
[调用: gh copilot -p "优化这个 prompt: {user_prompt}"]3. 显示两个版本:
✨ 优化版本:
┌──────────────────────────────────┐
│ 角色:你是一名文档专家... │
│ 指令:将...转换为... │
│ 步骤:1) ... 2) ... │
│ 最终目标:... │
└──────────────────────────────────┘
📝 原始版本:
┌──────────────────────────────────┐
│ [用户原始 Prompt] │
└──────────────────────────────────┘
4. 询问使用哪个版本:
💡 使用优化版本?[y/n] (默认: y):5. 使用选定的 Prompt 进行处理:
- 如果为 "y":使用优化版本
- 如果为 "n":使用原始版本
#### LLM 处理(两种场景通用)
Prompt 确定后:
from rich.progress import Progress, SpinnerColumn, TextColumn
def process_with_llm(transcript, prompt, cli_tool='claude'):
full_prompt = f"{prompt}\n\n---\n\n转录文本:\n\n{transcript}"
with Progress(
SpinnerColumn(),
TextColumn("[progress.description]{task.description}"),
transient=True
) as progress:
progress.add_task(
description=f"🤖 正在使用 {cli_tool} 处理...",
total=None
)
if cli_tool == 'claude':
result = subprocess.run(
['claude', '-'],
input=full_prompt,
capture_output=True,
text=True,
timeout=300 # 5 分钟
)
elif cli_tool == 'gh-copilot':
result = subprocess.run(
['gh', 'copilot', 'suggest', '-t', 'shell', full_prompt],
capture_output=True,
text=True,
timeout=300
)
if result.returncode == 0:
return result.stdout.strip()
else:
return None进度输出:
🤖 正在使用 claude 处理... ⠋
[完成后:]
✅ 会议纪要生成成功!#### 最终输出
成功(两个文件):
💾 正在保存文件...
✅ 文件已创建:
- transcript-20260203-023045.md (纯转录文本)
- ata-20260203-023045.md (经 LLM 处理)
🧹 已删除临时文件:metadata.json, transcription.json
✅ 完成!总耗时:3m 45s
仅转录文本(用户拒绝 LLM):
💾 正在保存文件...
✅ 文件已创建:
- transcript-20260203-023045.md
ℹ️ 未生成会议纪要(用户拒绝了 LLM 处理)
🧹 已删除临时文件:metadata.json, transcription.json
✅ 完成!
第 5 步:显示结果摘要
目标: 显示完成状态和后续步骤。
输出:
echo ""
echo "✅ 转录完成!"
echo ""
echo "📊 结果:"
echo " 文件: $OUTPUT_FILE"
echo " 语言: $LANGUAGE"
echo " 时长: $DURATION_HMS"
echo " 发言人数: $NUM_SPEAKERS"
echo " 字数: $WORD_COUNT"
echo " 处理时间: ${ELAPSED_TIME}s"
echo ""
echo "📝 已生成:"
echo " - $OUTPUT_FILE (Markdown 报告)"
[如果存在其他格式:]
echo " - ${OUTPUT_FILE%.*}.srt (字幕)"
echo " - ${OUTPUT_FILE%.*}.json (结构化数据)"
echo ""
echo "🎯 后续步骤:"
echo " 1. 审查会议纪要和待办事项"
echo " 2. 与参会者分享报告"
echo " 3. 跟踪待办事项的执行情况"使用示例
示例 1:基础转录
用户输入:
copilot> transcribe audio to markdown: meeting-2026-02-02.mp3技能输出:
✅ 检测到 Faster-Whisper (已优化)
✅ ffmpeg 可用 (已启用格式转换)
📂 文件: meeting-2026-02-02.mp3
📊 大小: 12.3 MB
⏱️ 时长: 00:45:32
🎙️ 正在处理...
[████████████████████] 100%
✅ 检测到语言: 葡萄牙语 (pt-BR)
👥 识别到发言人数: 4
📝 正在生成 Markdown 输出...
✅ 转录完成!
📊 结果:
文件: meeting-2026-02-02.md
语言: pt-BR
时长: 00:45:32
发言人数: 4
字数: 6,842
处理时间: 127s
📝 已生成:
- meeting-2026-02-02.md (Markdown 报告)
🎯 后续步骤:
1. 审查会议纪要和待办事项
2. 与参会者分享报告
3. 跟踪待办事项的执行情况
示例 3:批量处理
用户输入:
copilot> transcreva estes áudios: recordings/*.mp3技能输出:
📦 批量模式:找到 5 个文件
1. team-standup.mp3
2. client-call.mp3
3. brainstorm-session.mp3
4. product-demo.mp3
5. retrospective.mp3
🎙️ 正在批量处理...
[1/5] team-standup.mp3 ✅ (2m 34s)
[2/5] client-call.mp3 ✅ (15m 12s)
[3/5] brainstorm-session.mp3 ✅ (8m 47s)
[4/5] product-demo.mp3 ✅ (22m 03s)
[5/5] retrospective.mp3 ✅ (11m 28s)
✅ 批量处理完成!
📝 已生成 5 份 Markdown 报告
⏱️ 总处理时间: 6m 15s
示例 5:大文件警告
用户输入:
copilot> transcribe audio to markdown: conference-keynote.mp3技能输出:
✅ 检测到 Faster-Whisper (已优化)
📂 文件: conferenc
e-keynote.mp3
📊 大小:87.2 MB
⏱️ 时长:02:15:47
⚠️ 大文件 (87.2 MB) - 处理可能需要几分钟
继续?[Y/n]:
用户: Y🎙️ 正在处理... (可能需要 10-15 分钟)
[████░░░░░░░░░░░░░░░░] 20% - 预计剩余时间:12m
```
该技能具有平台无关性,可在任何支持 GitHub Copilot CLI 的终端环境中运行。它遵循零配置哲学,不依赖于特定的项目配置或外部 API。
局限性
- 仅在任务明确符合上述范围时使用此技能。
- 不要将输出结果视为环境特定验证、测试或专家评审的替代方案。
- 如果缺少必要的输入、权限、安全边界或成功标准,请停止并请求澄清。