用Python调用百度语音识别API实现视频转文字全流程
2026/9/20 9:53:59 网站建设 项目流程

简介:针对课堂录像、会议录音等视频中语音内容难以检索与编辑的痛点,这份基于Python与百度语音识别API的实用小项目,可直接读取视频文件并将其中的语音自动转换为文字输出,适合掌握基础Python语法、希望入门语音识别的小白,也可作为毕业设计、课程设计或大作业的初期原型。压缩包共3个文件,包含1个Python主程序、1个wav示例音频和1份Markdown说明文档,整体仅421KB;Python主程序完成视频读取、音频抽取与API调用,wav文件用于快速验证识别效果,Markdown文档对运行环境、密钥配置和调用流程做了说明,结构精简、开箱易读。借助这套资源,读者可以跑通从视频提取音频、调用百度语音识别API到输出文字结果的完整链路,理解音频抽取、API参数与返回解析等关键细节;说明文档对环境配置、密钥申请和调用步骤做了梳理,能帮助初学者快速上手,并在此基础上改造成自己所需的语音转写工具。目前已有860人学习浏览,适合边看边练,逐步掌握语音识别项目的基本实现思路,并在此框架上继续扩展不同视频格式或接入其他识别能力,进一步锻炼工程实践能力。

1. 用 Python 把视频语音转成文字,为什么我选了百度语音识别 API

做视频字幕、会议记录、课程复盘时,最耗时的就是对着视频一句句听写。自己用 Python 从零训练语音识别模型不现实,直接调云端 API 是最快路径。对比了多家服务后,我选了百度语音识别 API:中文识别率稳定、有免费额度、SDK 封装简单,一个asr()方法就能拿到结果,非常适合当课程设计、毕设或者内部工具的基础能力。这套流程拆开就是三件事:用 ffmpeg 从视频里抽音频、把音频切成符合 API 限制的片段、逐段调用语音识别最后合并文本。下面以videotoword.py为例,把每一步的参数设置和踩坑点都说清楚。新手跟着搭能跑通,熟手也能顺便看看并发和格式边界怎么处理。

2. 百度语音识别 API 接入前的环境与账号参数

2.1 先装 Python 和 ffmpeg,这两个缺一个都跑不起来

项目要跑起来,Python 环境是第一道坎。如果你刚接触 Python,去官网下载安装包时记得勾选Add Python to PATH,否则后面在命令行执行python会提示找不到命令。用 VSCode 写代码的读者,装完解释器后按Ctrl+Shift+P选择 Python 解释器,不然终端里虽然能运行,VSCode 的调试和代码提示却会报错。

除了 Python 本体,还要装第三方库和 ffmpeg。videotoword.py这种项目一般依赖这几个库:

pip install baidu-aip moviepy pydub
  • baidu-aip:百度 AI 官方 Python SDK,核心是AipSpeech类。
  • moviepy:用来读取视频并抽取音频轨,底层依赖 ffmpeg。
  • pydub:负责把长音频按时间切片,以及格式转换。

moviepypydub都是对 ffmpeg 的封装,所以系统里必须装 ffmpeg。Windows 用户去 ffmpeg.org 下载 release build,解压后把bin目录加到系统环境变量Path里;macOS 用brew install ffmpeg,Linux 用发行版包管理装即可。装完之后在终端验证:

ffmpeg -version

如果输出版本信息但 Python 里还是报错找不到 ffmpeg,多半是环境变量没生效,重开一个终端再试。我一般会把ffmpeg.exe直接复制到项目目录下,省得跟全局环境变量较劲。

2.2 创建百度 AI 应用,拿到三个关键参数

百度语音识别 API 不是拿过来就能用,先去百度智能云控制台创建一个语音应用。路径是:控制台 → 语音技术 → 短语音识别 → 创建应用。创建成功后,在应用详情里能看到三个值:

参数名示例用途
AppID11223344应用唯一标识
API Key4E1g...用于换取 access token
Secret Key9B7d...与 API Key 配对

这三个参数建议写进独立的配置文件或环境变量,不要硬编码在videotoword.py里。我习惯在项目根目录建一个config.json

{ "app_id": "11223344", "api_key": "你的API Key", "secret_key": "你的Secret Key" }

然后代码里用json.load读取,这样无论是提交到 Git 还是发给别人看,都不会不小心泄露密钥。百度短语音识别有免费额度,注册后可用,新用户会有一定量免费调用次数,足够测试和做课程设计;如果要做长时间批量语音转写,注意配额消耗速度,QPS 限制通常为每秒一次,并发前先确认自己的账号配额。

2.3 音频格式的硬性要求:16kHz、单声道、PCM/WAV

很多人第一次调用百度语音识别 API 失败,不是代码写错,而是音频格式不对。短语音识别接口要求音频必须是:

属性要求
采样率16000 Hz 或 8000 Hz
声道单声道
位深16 bit
编码原始 PCM 或 PCM 编码的 WAV
时长单段小于 60 秒
数据大小不超过几 MB,视格式而定

视频里的音轨大多是 44.1kHz 或 48kHz 的立体声 AAC,直接丢给百度接口会被拒绝,错误码通常是3301(音频格式问题)。所以抽出来的音频必须先降采样到 16kHz、转成单声道、存成 WAV 或 PCM。moviepyAudioFileClip可以在导出时通过参数完成这些操作,后面我会给出具体代码。

如果抽出来的是 WAV 文件却还是识别失败,用 ffprobe 检查一下内部编码:

ffprobe out.wav

重点看Stream #0:0: Audio: pcm_s16le这一行,pcm_s16le才符合要求。如果显示的是aacmp3,说明扩展名虽然叫 wav,但编码不对,需要重新转码。这个细节是排查问题的关键。

3. 用 videotoword.py 提取视频音频并切片

3.1 先抽取音频:moviepy 还是 ffmpeg?

videotoword.py的第一步是把视频文件里的声音抽出来。网上类似项目多用moviepy,因为它以对象方式操作音视频,代码简洁;但如果你只想要一个音频文件,直接用 ffmpeg 命令更可控。下面两种方式都可行。

用 moviepy 抽取音频:

from moviepy.editor import VideoFileClip video = VideoFileClip("demo.mp4") audio = video.audio audio.write_audiofile("out.wav", fps=16000, nbytes=2, codec="pcm_s16le") audio.close() video.close()

这段代码做了三件事:读取视频文件;取出音频轨;导出为 WAV。关键是fps=16000把采样率降到 16kHz,nbytes=2表示 16 bit,codec="pcm_s16le"强制使用 PCM 编码。这三个参数只要有一个漏掉,最后得到的 WAV 就可能不符合百度接口要求。

如果视频文件比较大,或者不想在 Python 里耗内存,用 ffmpeg 命令更干脆:

ffmpeg -i demo.mp4 -vn -acodec pcm_s16le -ar 16000 -ac 1 out.wav

参数含义:-vn表示不处理视频流;-acodec pcm_s16le指定音频编码;-ar 16000设置采样率为 16000Hz;-ac 1强制单声道。我通常先在命令行跑通这条命令,把out.wav拿到手,再写 Python 代码把它交给百度 API,这样能更快定位问题。

3.2 为什么要切成长度小于 60 秒的音频块

百度短语音识别单次请求只接受 60 秒以内的音频,而且音频文件越大,上传耗时越长,超时概率越高。录屏、网课视频动辄十几分钟,必须切块。

切片有两种思路。第一种是固定时长切,直接用pydub

from pydub import AudioSegment audio = AudioSegment.from_wav("out.wav") chunk_len = 58 * 1000 # 58秒,单位毫秒 chunks = [audio[i:i+chunk_len] for i in range(0, len(audio), chunk_len)] for idx, chunk in enumerate(chunks): chunk.export(f"chunk_{idx}.wav", format="wav")

留 2 秒余量是为了避免网络波动导致语音刚好在边界被截断。固定切分的缺点是可能把一个词切成两半,影响识别率。第二种是先用split_on_silence按静音切分,再把过长的片段二次切分,这种适合访谈类视频,但实现复杂一些。作为起步,固定 58 秒切分最稳妥。

videotoword.py这类项目里通常还会生成一个out.wav,它就是视频抽取出来的中间音频文件。如果你的项目里有这个文件,可以先检查它是否已是 16kHz 单声道,避免后续重复处理。

3.3 切片前先验证 out.wav 的编码参数

切片导出的文件看起来都叫.wav,但内里编码可能完全不同。如果某个chunk_3.wav识别报错3301,用 ffprobe 看一眼就知道问题:

ffprobe -show_streams chunk_3.wav | grep sample_rate

sample_rate=16000channels=1是正确的。如果出现sample_rate=44100,说明处理链里的降采样没生效。另外,从数据恢复工具拿回来的视频文件,经常出现 ffprobe 能读到流信息但 ffmpeg 无法解码的情况,这时先尝试用ffmpeg -xerror看具体错误;如果文件本来就损坏,抽出来的音频自然也是坏的,识别结果必然是一堆错误码,这不是 API 的问题。

4. 调用百度语音识别 API 与返回结果解析

4.1 使用 baidu-aip 的 AipSpeech 模块

baidu-aip是百度官方 SDK,安装后导入AipSpeech,把上一章拿到的三个参数传进去即可初始化客户端:

import json from aip import AipSpeech with open("config.json", "r", encoding="utf-8") as f: cfg = json.load(f) client = AipSpeech(cfg["app_id"], cfg["api_key"], cfg["secret_key"]) def recognize_file(path): with open(path, "rb") as f: audio_data = f.read() result = client.asr( audio_data, format="wav", rate=16000, dev_pid=1537, ) return result

这段代码把整个 WAV 文件读成二进制,传给asr()。参数说明:

  • format"wav""pcm",与文件实际编码保持一致。
  • rate:采样率,这里填 16000,和转码时的参数对应。
  • dev_pid:语言模型编号,1537 是普通话(输入法模型),1737 是英语,1936 是普通话(远场模型)。做视频字幕选 1537 就够了。

asr()返回一个字典,识别成功时结构类似:

{ "err_no": 0, "err_msg": "success.", "result": ["北京今天天气不错"] }

result是列表,通常只有一条字符串,就是识别出的文本。

4.2 错误码不是玄学,按表排查就行

调用接口经常遇到各种err_no,我整理了一份高频错误码对照表:

err_no含义处理方式
0成功直接取result
3300输入参数不正确检查formatratedev_pid
3301音频质量过差或格式不支持重新转码为 16kHz 单声道 PCM
3302音频过长切片到 60 秒以内
3303音频解码失败用 ffprobe 确认编码
3304音频数据为空确认文件是否已读取完整
3305音频文件大小超限压缩或降低位深
3310应用 QPS 超限降低并发,加 sleep

看到3301第一反应别怀疑网络,先用 ffprobe 检查文件。遇到3310就检查自己的循环里是不是连续快速调用,百度短语音接口的 QPS 默认通常为 1,并发太高会直接触发限流。项目里如果持续出现3310,最简单的做法是在循环里加:

import time time.sleep(1.2)

4.3 多段转写结果按顺序合并成完整文本

单段音频识别成功后,需要把所有片段的结果按原顺序拼接。如果切片用的是chunk_0.wav这种带序号的命名,直接按文件名排序再拼接即可。

import os import glob wav_files = sorted(glob.glob("chunk_*.wav"), key=lambda x: int(x.split("_")[1].split(".")[0])) lines = [] for wav_file in wav_files: resp = recognize_file(wav_file) if resp["err_no"] == 0: lines.append(resp["result"][0]) else: lines.append(f"[识别失败:{resp['err_no']}]") with open("transcript.txt", "w", encoding="utf-8") as f: f.write("\n".join(lines))

排序时用key把文件名里的数字提取出来,否则chunk_10.wav会排到chunk_2.wav前面。合并文本时我习惯每句换一行,方便后面做字幕时间轴对齐;如果你只需要纯文本,用"".join(lines)即可。

注意百度返回的文本默认不带标点,如果需要带标点,可以在控制台开通标点功能或使用后处理方式补全。这点在生成字幕时经常被忽略,对话类视频的阅读体验会差很多。

5. 从毕设到工具:并发提速与音频质量修复的几个技巧

5.1 用 ThreadPoolExecutor 提高批量识别速度

短语音识别每次只能处理一个 WAV,长视频切片后可能有几十个文件,逐个识别速度很慢。如果账号的 QPS 允许,可以用线程池并发提交:

from concurrent.futures import ThreadPoolExecutor def recognize_with_retry(path, retries=3): for i in range(retries): resp = recognize_file(path) if resp["err_no"] == 0: return resp["result"][0] if resp["err_no"] != 3310: time.sleep(0.5) return f"[失败:{path}]" with ThreadPoolExecutor(max_workers=2) as pool: results = list(pool.map(recognize_with_retry, wav_files))

max_workers设置成 2 是因为很多百度账号的语音识别 QPS 限制是 1,开 2 个线程再配合重试机制,既不会立刻撞限流,又能比串行快一倍。如果你确认自己的配额更高,再调到 4 或 8,否则只会收到一堆3310错误码。

线程安全方面,AipSpeechasr()是幂等操作,多个线程共用一个client实例没有问题。每个线程读取自己的音频文件,互不干扰。

5.2 识别率优化:自定义词表比换模型参数更有效

如果你的视频里全是专业术语,比如“Transformer”“PyTorch”“卷积神经网络”,百度默认模型可能识别成同音词。在百度语音控制台的“自定义词表”里添加这些词,能明显提升识别率。需要注意的是,词表配置有生效延迟,修改后等几分钟再调用。

另外,切片策略直接影响识别率:固定 58 秒切分虽然简单,但可能在句子中间断开。更稳妥的做法是先按静音切分,再把超过 60 秒的段落强制拆分。用pydubsplit_on_silence时,把min_silence_len设成 500ms,silence_thresh设为音频的均方根值减去 16dB,这样能保留完整句子的概率更高。

5.3 视频文件本身有问题时先修再转

重装系统后视频文件没有访问权限,或者数据恢复软件拿回来的文件无法播放,这类问题在实操中非常常见。先用ffprobe查看元数据:

ffprobe -v error -show_streams corrupted.mp4

如果能正常输出流信息,通常只是文件权限问题。Linux 下执行chmod 644 corrupted.mp4,Windows 下右键文件属性去掉“只读”即可。如果 ffprobe 都报错,那就不是格式问题而是文件损坏,可以用ffmpeg -err_detect explode -i corrupted.mp4 -c copy fixed.mp4尝试跳过损坏帧,再抽取音频。处理完视频修复,再回到第 3 章的流程,否则后面所有识别工作都是在错误数据上白费力气。

本文还有配套的精品资源,点击获取

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询