来源:
notes/projects/audio_transcription_workflow/01_长音频转写与博客同步流程.md长音频转写与博客同步流程
背景
2026-06-10 收到音频附件:
/home/admin/code/cc-connect-work-space/.cc-connect/attachments/地平线机器人202606.10.mp3
目标是先分析音频,再生成带时间戳逐字稿,写入个人助理,并同步到 GitHub Pages 博客。
音频基本信息
检查命令:
file .cc-connect/attachments/地平线机器人202606.10.mp3
ffprobe -v error \
-show_entries format=duration,bit_rate,size \
-show_entries stream=codec_name,channels,sample_rate \
-of default=noprint_wrappers=1 \
.cc-connect/attachments/地平线机器人202606.10.mp3
结果:
- 格式:MP3
- 采样率:44.1 kHz
- 声道:Stereo
- 码率:128 kbps
- 时长:约 3247.78 秒,约 54 分 08 秒
- 文件大小:约 51.97 MB
环境检查
系统已有:
ffmpeg
系统没有现成语音识别库:
whisper
faster_whisper
whisperx
torch
torchaudio
transformers
speech_recognition
vosk
funasr
全局 Python 受 PEP 668 保护,不能直接 pip install --user。因此创建项目内临时虚拟环境:
python3 -m venv .venv-transcribe
.venv-transcribe/bin/pip install -U pip
Whisper 路线尝试
先安装 faster-whisper:
.venv-transcribe/bin/pip install faster-whisper
安装成功,但模型下载走 Hugging Face,访问 huggingface.co 超时:
curl -I --max-time 10 https://huggingface.co/Systran/faster-whisper-small/resolve/main/config.json
结果是连接超时。因此放弃 Whisper 模型下载路线。
FunASR 路线
ModelScope 可访问:
curl -I --max-time 10 https://modelscope.cn/models/iic/SenseVoiceSmall/summary
安装 FunASR 和 ModelScope:
.venv-transcribe/bin/pip install funasr modelscope
FunASR 需要 PyTorch 和 torchaudio,安装 CPU 版:
.venv-transcribe/bin/pip install torch --index-url https://download.pytorch.org/whl/cpu
.venv-transcribe/bin/pip install torchaudio --index-url https://download.pytorch.org/whl/cpu
最终关键依赖:
funasrmodelscopetorchtorchaudioffmpeg
模型选择
使用模型:
iic/SenseVoiceSmall
原因:
- 适合中文、英文混合音频。
- 可从 ModelScope 下载,避开 Hugging Face 超时问题。
- CPU 推理可接受,约 2 分钟音频片段推理 13-14 秒。
模型权重约 893 MB,首次运行会下载到:
/home/admin/.cache/modelscope/hub/models/iic/SenseVoiceSmall
样本验证
先截取前 60 秒验证模型可用:
mkdir -p .cc-connect/tmp
ffmpeg -y -v error \
-i .cc-connect/attachments/地平线机器人202606.10.mp3 \
-t 60 -ar 16000 -ac 1 \
.cc-connect/tmp/horizon_sample60.wav
测试脚本:
from funasr import AutoModel
model = AutoModel(model="iic/SenseVoiceSmall", hub="ms", device="cpu")
res = model.generate(
input=".cc-connect/tmp/horizon_sample60.wav",
language="zh",
use_itn=True,
batch_size_s=60,
)
print(res)
样本识别成功,确认音频开头是地平线机器人 2026 年股东周年大会的英文开场。
完整转写策略
长音频直接转写不利于定位问题,因此先用 ffmpeg 切成 120 秒小片段:
ffmpeg -y -v error \
-i .cc-connect/attachments/地平线机器人202606.10.mp3 \
-ar 16000 -ac 1 \
-f segment -segment_time 120 -reset_timestamps 1 \
.cc-connect/tmp/horizon_chunks/chunk_%03d.wav
完整转写脚本逻辑:
- 加载
SenseVoiceSmall。 - 逐个识别 120 秒音频片段。
- 去掉 FunASR 输出里的
<|...|>标签。 - 给每个片段加粗略时间戳。
- 输出 TXT 和 JSONL。
关键输出:
.cc-connect/attachments/地平线机器人202606.10.funasr.transcript.txt
.cc-connect/attachments/地平线机器人202606.10.funasr.segments.jsonl
逐字稿写入个人助理
正式笔记位置:
codex_personal_assistant/notes/projects/地平线机器人20260610股东大会/01_逐字稿.md
源材料位置:
codex_personal_assistant/notes/projects/地平线机器人20260610股东大会/source_materials/
写入内容包括:
- 音频来源
- 音频时长
- 转写方式
- 校对状态
- 内容概览
- 分段摘要
- 带时间戳逐字稿
- 下一步动作
后续为了避免博客文章变成一大坨,又做了一次格式化:
- 按时间段增加章节标题。
- 每个章节增加“本段摘要”。
- 每条 2 分钟转写段之间增加空行。
- 校验所有时间戳逐字稿行与原 ASR 源文本完全一致,没有改动逐字稿原文。
校验脚本:
from pathlib import Path
note = Path("codex_personal_assistant/notes/projects/地平线机器人20260610股东大会/01_逐字稿.md")
src = Path("codex_personal_assistant/notes/projects/地平线机器人20260610股东大会/source_materials/地平线机器人202606.10.funasr.transcript.txt")
note_lines = [line for line in note.read_text(encoding="utf-8").splitlines() if line.startswith("[")]
src_lines = [line for line in src.read_text(encoding="utf-8").splitlines() if line.startswith("[")]
print(note_lines == src_lines)
飞书同步
创建飞书 Docs 文档:
lark-cli docs +create \
--api-version v2 \
--as user \
--content @codex_personal_assistant/notes/projects/地平线机器人20260610股东大会/01_逐字稿.md \
--doc-format markdown \
--parent-position my_library \
--format json
最终格式化版飞书文档:
https://my.feishu.cn/docx/JX27d4h99ojvvYxB3h5cmXmFnLe
回填到:
codex_personal_assistant/config/feishu_base.json
然后同步多维表格:
cd codex_personal_assistant
python3 scripts/sync_to_feishu_base.py
同步范围包括:
- 待办事项
- 每日记录
- 文档资产
- 知识索引
- 阅读书籍
博客同步
博客仓库:
/home/admin/code/cc-connect-work-space/andywu1998.github.io
同步命令:
cd /home/admin/code/cc-connect-work-space/andywu1998.github.io
scripts/sync_personal_assistant_notes.sh
该脚本会:
- 从
../codex_personal_assistant/notes导入 Markdown。 - 生成 Jekyll
_posts。 - 提交
_posts。 - 推送到 GitHub Pages 仓库。
本次逐字稿博客文件:
andywu1998.github.io/_posts/2026-06-10-地平线机器人-2026-06-10-股东周年大会逐字稿.md
最终博客提交:
0b731c0 2026-06-10 sync
踩坑记录
1. 全局 pip 受保护
全局 Python 环境受 PEP 668 管理,直接安装失败。解决方式是创建 .venv-transcribe。
2. Hugging Face 超时
faster-whisper 本身安装成功,但模型无法从 Hugging Face 下载。解决方式是改用 ModelScope 上的 FunASR/SenseVoiceSmall。
3. FunASR 没有自动安装 torch
安装 FunASR 后导入失败:
ModuleNotFoundError: No module named 'torch'
解决方式是安装 CPU 版 torch 和 torchaudio。
4. 飞书 Docs 更新命令参数不稳定
lark-cli docs +update 的帮助与实际校验不一致,要求内部 --command 参数但帮助没有列出。最终处理方式是重新创建格式化版飞书文档,并把配置链接替换成新文档。
5. Markdown 只有单换行会在博客里显示成大段
原始逐字稿每条记录只有单换行,Jekyll 渲染后阅读体验差。解决方式是在每条时间戳片段之间增加空行,并按主题加入二级分段。
可复用 SOP
- 检查音频格式和时长。
- 如果本机没有 ASR 环境,创建
.venv-transcribe。 - 优先尝试可访问的模型源;当前环境推荐 ModelScope + FunASR。
- 先截取 60 秒样本验证。
- 对长音频按 120 秒切片。
- 逐片识别并生成带时间戳 TXT/JSONL。
- 把正式逐字稿写入
codex_personal_assistant/notes/projects/<主题>/01_逐字稿.md。 - 将原始 ASR 文件放入
source_materials/。 - 增加分段标题、段落摘要和空行,但不要改逐字稿原文。
- 创建飞书 Docs 文档,回填
config/feishu_base.json。 - 运行
python3 scripts/sync_to_feishu_base.py。 - 运行博客同步脚本
scripts/sync_personal_assistant_notes.sh。
下一步动作
- 把完整转写脚本整理成个人助理或 cc-connect 的可复用脚本,减少下次手工命令。
- 增加“逐字稿格式化器”:自动按时间段插入标题、摘要和空行,并校验原文未变。
- 评估是否需要更高质量的二次校对流程,例如对关键问答片段单独复听修正。