目录
[1. 视频转音频核心模块](#1. 视频转音频核心模块)
[2. 讯飞语音识别核心模块](#2. 讯飞语音识别核心模块)
(3)轮询识别结果(get_recognition_result)
[3. 转写结果结构化解析](#3. 转写结果结构化解析)
[4. LLM 智能优化模块](#4. LLM 智能优化模块)
[(1)批量文本降噪 + 角色修正](#(1)批量文本降噪 + 角色修正)
[5. 多格式输出模块](#5. 多格式输出模块)
[1. 环境安装](#1. 环境安装)
[2. 配置修改](#2. 配置修改)
[3. 运行代码](#3. 运行代码)
[CSV 输出示例](#CSV 输出示例)
[CV-JSON 输出示例](#CV-JSON 输出示例)
前言
在课堂教学评价、教学数据分析场景中,课堂教学视频的语音转写、文本结构化是核心刚需。传统手动转写效率极低,且纯转写文本存在识别噪声、角色错乱、无教学活动标注等问题,无法直接适配后续 CV/NLP 教学分析系统。
本文基于 Python 实战开发一款课堂视频自动化处理工具,整合讯飞 LFASR 语音识别、通义千问大模型能力,实现从 MP4 视频输入到「音频提取→语音转写→文本降噪→角色修正→课堂活动识别→多格式结构化输出」的全流程自动化,最终输出 CV 专用 JSON、句子级 CSV、结构化 JSON,直接对接教学评价系统。
项目概述
核心功能
- 视频转音频:基于 MoviePy 提取 MP4 视频中的音频轨道,支持自定义截取时长
- 讯飞语音转写:调用讯飞 LFASR API 实现课堂语音高精度转写,支持双发言人识别
- 文本结构化解析:提取转写结果中的发言人、时间戳、逐句文本,自动分配师生角色
- LLM 智能优化:通义千问批量处理转写噪声、修正角色分配错误、识别课堂教学活动
- 多格式输出:生成 CV 专用 JSON、句子级 CSV、结构化 JSON,适配后续教学分析系统
应用场景
- 课堂教学视频自动化转写与数据结构化
- 教学评价系统的前端 CV 模块数据输入
- 教学 NLP 分析的原始语料输出
- 课堂教学活动自动标注与分析
技术栈
| 模块 | 技术 / 工具 | 作用 |
|---|---|---|
| 音频处理 | MoviePy | MP4 视频提取 WAV 音频、时长截取 |
| 语音识别 | 讯飞 LFASR API | 课堂语音转文字、发言人分离 |
| 大模型 | 通义千问(DeepSeek-V3) | 文本降噪、角色修正、课堂活动识别 |
| HTTP 请求 | requests/httpx | 讯飞 API 接口调用 |
| 数据处理 | json/csv/hmac/base64 | 签名生成、结果解析、格式转换 |
| 开发语言 | Python 3.x | 核心逻辑开发 |
核心流程梳理
MP4课堂视频 → 提取WAV音频 → 讯飞API上传音频 → 轮询获取转写结果 → 解析结构化转写数据
→ 分句+师生角色自动分配 → LLM文本降噪+角色修正 → 按时间/角色合并段落 → LLM识别课堂活动
→ 输出CV专用JSON + 句子级CSV + 结构化JSON
核心模块代码拆解
1. 视频转音频核心模块
通过MoviePy实现 MP4 视频音频提取,自动创建音频存储目录,支持自定义截取测试时长,处理无音频轨道、文件不存在等异常。
python
def movie_to_audio(self, mp4_file, wav_file, duration_seconds=None):
# 校验文件存在性
if not os.path.exists(mp4_file):
print(f"错误: 输入文件不存在: {mp4_file}")
return False
# 创建输出目录
output_dir = os.path.dirname(wav_file)
if output_dir and not os.path.exists(output_dir):
os.makedirs(output_dir)
# 加载视频并截取时长
video_clip = VideoFileClip(mp4_file)
if duration_seconds:
end_duration = min(duration_seconds, video_clip.duration)
video_clip = video_clip.subclipped(0, end_duration)
# 提取音频并保存为WAV
audio_clip = video_clip.audio
audio_clip.write_audiofile(wav_file, codec='pcm_s16le')
# 释放资源
audio_clip.close()
video_clip.close()
return True
2. 讯飞语音识别核心模块
讯飞 LFASR API 需签名鉴权,核心包含签名生成、音频上传、结果轮询三个方法:
(1)签名生成(get_signa)
基于 MD5+HMAC-SHA1 生成接口签名,满足讯飞 API 鉴权规则:
python
def get_signa(self, ts):
# MD5加密appid+时间戳
m2 = hashlib.md5()
m2.update((self.appid + ts).encode('utf-8'))
md5 = bytes(m2.hexdigest(), encoding='utf-8')
# HMAC-SHA1加密+Base64编码
signa = hmac.new(self.secret_key.encode('utf-8'), md5, hashlib.sha1).digest()
signa = base64.b64encode(signa)
return str(signa, 'utf-8')
(2)音频上传(upload_file)
拼接接口参数,通过 POST 请求上传音频文件,校验上传结果:
python
def upload_file(self, ts, signa):
file_len = os.path.getsize(self.upload_file_path)
param_dict = {
'appId': self.appid, 'signa': signa, 'ts': ts,
"fileSize": file_len, "fileName": os.path.basename(self.upload_file_path),
"duration": "200", "pd": "edu", "roleType": "1", "roleNum": "2"
}
# 上传音频
with open(self.upload_file_path, 'rb') as f:
data = f.read(file_len)
response = requests.post(url=lfasr_host+api_upload, params=param_dict, data=data)
result = json.loads(response.text)
return result if result['code'] == '000000' else None
(3)轮询识别结果(get_recognition_result)
讯飞转写为异步任务,通过循环轮询获取最终结果,直到任务完成 / 失败:
python
def get_recognition_result(self, ts, signa, order_id):
param_dict = {'appId': self.appid, 'signa': signa, 'ts': ts, 'orderId': order_id, 'resultType': "transfer,predict"}
status = 3
while status == 3:
response = requests.post(url=lfasr_host+api_get_result, params=param_dict)
result = json.loads(response.text)
status = result['content']['orderInfo']['status']
time.sleep(5)
return result
3. 转写结果结构化解析
解析讯飞返回的lattice2字段,提取发言人、时间戳、逐字文本,保存为结构化 JSON:
python
def save_processed_result(self,api_response):
order_data = json.loads(api_response['content']['orderResult'])
segments = order_data.get('lattice2', [])
all_detailed_paragraphs = []
for segment in segments:
speaker_id = segment.get('spk', 'unknown')
# 提取段落文本与逐字时间戳
ws_list = segment['json_1best']['st']['rt'][0]['ws']
para_text = "".join([word['cw'][0]['w'] for word in ws_list])
word_details = [{"text": word['cw'][0]['w'], "start_ms": word['wb'], "end_ms": word['we'], "spk": speaker_id} for word in ws_list]
all_detailed_paragraphs.append({
"paragraph_text": para_text, "words": word_details,
"spk": speaker_id, "start_ms": segment['begin'], "end_ms": segment['end']
})
# 保存结构化JSON
with open(output_path, 'w', encoding='utf-8') as f:
json.dump(all_detailed_paragraphs, f, ensure_ascii=False, indent=4)
4. LLM 智能优化模块
基于通义千问兼容 OpenAI SDK,实现文本降噪、角色修正、课堂活动识别:
(1)批量文本降噪 + 角色修正
过滤转写噪声(无意义语气词、识别错误),修正师生角色分配错误:
python
def batch_llm_filter(self, sentences, batch_size=50):
# 分批处理避免token超限
for i in range(0, len(sentences), batch_size):
batch = sentences[i:i+batch_size]
batch_text = "\n".join([f"{s['spk']},{s['start_ms']},{s['end_ms']},\"{s['text']}\"" for s in batch])
# 调用通义千问降噪+角色修正
filtered_text = self.llm_filter(batch_text)
# 解析结果并重构句子
filtered_lines = filtered_text.strip().split('\n')
# 解析CSV格式结果
...
(2)课堂活动自动识别
通过 LLM 推理课堂对话间隙的教学活动(独立思考、小组讨论、练习等),插入活动标注:
python
def _llm_identify_activity(self, sentences):
# 提示词定义教学活动规则,调用大模型识别
response = client.chat.completions.create(
model="deepseek-v3",
messages=[{"role": "system", "content": "你是AI教学分析师,识别课堂对话间隙的教学活动"}],
temperature=0.5
)
return response.choices[0].message.content
5. 多格式输出模块
适配教学系统输出两种核心格式:
- CV 专用 JSON:时间戳转秒、角色编号(老师 = 1 / 学生 = 2),直接对接视觉分析模块
- 句子级 CSV:时间(MM:SS)+ 角色 + 文本,适配 NLP 语料分析
python
# CV专用JSON输出
def json_to_sentences_cv_json(self):
video_text = []
for s in self.sentences_activity:
begin_sec = int(s.get('start_ms',0))//1000
role_num = "2" if s.get('spk') == "学生" else "1"
video_text.append({
"beginTime": begin_sec, "endTime": int(s.get('end_ms',0))//1000,
"paragraphNum": 0, "role": role_num, "roleName": s.get('spk'),
"sentenceContent": s.get('text')
})
return {"videoText": video_text}
项目运行步骤
1. 环境安装
python
pip install moviepy requests openai httpx
2. 配置修改
替换代码中__main__模块的密钥与视频路径:
python
# 讯飞API配置
APPID = "你的讯飞APPID"
SECRET_KEY = "你的讯飞SECRET_KEY"
# 通义千问API配置
LLM_API_KEY = "你的通义千问API_KEY"
# 课堂视频路径
VIDEO_FILE_PATH = r"你的MP4视频路径"
3. 运行代码
直接执行脚本,自动完成全流程处理:
python
if __name__ == '__main__':
# 初始化处理类
audio_processor = audio_to_data(APPID, SECRET_KEY, VIDEO_FILE_PATH, LLM_API_KEY)
# 执行核心处理流程
processed_result = audio_processor.process_audio_file()
# 打印输出文件路径
print("cv专用JSON路径:",processed_result[2])
print("句子级CSV路径:",processed_result[1])
输出结果展示
生成文件结构
├── audio/ # 提取的WAV音频文件
├── result/ # 处理结果目录
│ ├── test_processed.json # 结构化转写JSON
│ ├── test_processed_cv.json # CV专用JSON
│ └── test_processed_sentences.csv # 句子级CSV
CSV 输出示例
| 时间 | 角色 | 内容 |
|---|---|---|
| 00:03 | 老师 | 同学们开始独立思考这道题 |
| 00:10 | 学生 | 老师我有思路了 |
| 00:15 | 老师 | (独立思考) |
CV-JSON 输出示例
{
"videoText": [
{
"beginTime": 3,
"endTime": 7,
"paragraphNum": 0,
"role": "1",
"roleName": "老师",
"sentenceContent": "同学们开始独立思考这道题"
}
]
}
项目亮点与拓展方向
核心亮点
- 全流程自动化:从视频到结构化数据零人工干预
- 双模型协同:讯飞语音识别 + 通义千问 LLM 优化,准确率大幅提升
- 多格式适配:直接输出 CV/NLP 系统所需格式,降低对接成本
- 异常处理完善:文件校验、音频轨道检测、API 失败重试
拓展方向
- 支持批量视频处理,新增 GUI 可视化界面
- 切换大模型(GPT / 讯飞星火),优化课堂活动识别精度
- 新增教学评价指标自动分析模块
- 支持更多视频格式(MOV/AVI)与音频格式(MP3/FLAC)
总结
本文实战开发的课堂视频结构化工具,解决了教学视频转写的效率与质量问题,通过语音识别 + 大模型的组合,实现了从原始视频到可直接用于教学分析的结构化数据的全流程自动化,可快速落地于课堂教学评价、教学数据分析等场景,也可作为 AI 教学系统的核心数据预处理模块。