用Python调用百度语音识别API实现视频转文字全流程 📅 发布时间:2026/9/20 9:54:00 👁 浏览次数: 简介针对课堂录像、会议录音等视频中语音内容难以检索与编辑的痛点这份基于Python与百度语音识别API的实用小项目可直接读取视频文件并将其中的语音自动转换为文字输出适合掌握基础Python语法、希望入门语音识别的小白也可作为毕业设计、课程设计或大作业的初期原型。压缩包共3个文件包含1个Python主程序、1个wav示例音频和1份Markdown说明文档整体仅421KBPython主程序完成视频读取、音频抽取与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 写代码的读者装完解释器后按CtrlShiftP选择 Python 解释器不然终端里虽然能运行VSCode 的调试和代码提示却会报错。除了 Python 本体还要装第三方库和 ffmpeg。videotoword.py这种项目一般依赖这几个库pip install baidu-aip moviepy pydubbaidu-aip百度 AI 官方 Python SDK核心是AipSpeech类。moviepy用来读取视频并抽取音频轨底层依赖 ffmpeg。pydub负责把长音频按时间切片以及格式转换。moviepy和pydub都是对 ffmpeg 的封装所以系统里必须装 ffmpeg。Windows 用户去 ffmpeg.org 下载 release build解压后把bin目录加到系统环境变量Path里macOS 用brew install ffmpegLinux 用发行版包管理装即可。装完之后在终端验证ffmpeg -version如果输出版本信息但 Python 里还是报错找不到 ffmpeg多半是环境变量没生效重开一个终端再试。我一般会把ffmpeg.exe直接复制到项目目录下省得跟全局环境变量较劲。2.2 创建百度 AI 应用拿到三个关键参数百度语音识别 API 不是拿过来就能用先去百度智能云控制台创建一个语音应用。路径是控制台 → 语音技术 → 短语音识别 → 创建应用。创建成功后在应用详情里能看到三个值参数名示例用途AppID11223344应用唯一标识API Key4E1g...用于换取 access tokenSecret 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。moviepy的AudioFileClip可以在导出时通过参数完成这些操作后面我会给出具体代码。如果抽出来的是 WAV 文件却还是识别失败用 ffprobe 检查一下内部编码ffprobe out.wav重点看Stream #0:0: Audio: pcm_s16le这一行pcm_s16le才符合要求。如果显示的是aac或mp3说明扩展名虽然叫 wav但编码不对需要重新转码。这个细节是排查问题的关键。3. 用 videotoword.py 提取视频音频并切片3.1 先抽取音频moviepy 还是 ffmpegvideotoword.py的第一步是把视频文件里的声音抽出来。网上类似项目多用moviepy因为它以对象方式操作音视频代码简洁但如果你只想要一个音频文件直接用 ffmpeg 命令更可控。下面两种方式都可行。用 moviepy 抽取音频from moviepy.editor import VideoFileClip video VideoFileClip(demo.mp4) audio video.audio audio.write_audiofile(out.wav, fps16000, nbytes2, codecpcm_s16le) audio.close() video.close()这段代码做了三件事读取视频文件取出音频轨导出为 WAV。关键是fps16000把采样率降到 16kHznbytes2表示 16 bitcodecpcm_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 秒以内的音频而且音频文件越大上传耗时越长超时概率越高。录屏、网课视频动辄十几分钟必须切块。切片有两种思路。第一种是固定时长切直接用pydubfrom pydub import AudioSegment audio AudioSegment.from_wav(out.wav) chunk_len 58 * 1000 # 58秒单位毫秒 chunks [audio[i:ichunk_len] for i in range(0, len(audio), chunk_len)] for idx, chunk in enumerate(chunks): chunk.export(fchunk_{idx}.wav, formatwav)留 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_ratesample_rate16000且channels1是正确的。如果出现sample_rate44100说明处理链里的降采样没生效。另外从数据恢复工具拿回来的视频文件经常出现 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, encodingutf-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, formatwav, rate16000, dev_pid1537, ) return result这段代码把整个 WAV 文件读成二进制传给asr()。参数说明formatwav或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成功直接取result3300输入参数不正确检查format、rate、dev_pid3301音频质量过差或格式不支持重新转码为 16kHz 单声道 PCM3302音频过长切片到 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), keylambda 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, encodingutf-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, retries3): 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_workers2) as pool: results list(pool.map(recognize_with_retry, wav_files))max_workers设置成 2 是因为很多百度账号的语音识别 QPS 限制是 1开 2 个线程再配合重试机制既不会立刻撞限流又能比串行快一倍。如果你确认自己的配额更高再调到 4 或 8否则只会收到一堆3310错误码。线程安全方面AipSpeech的asr()是幂等操作多个线程共用一个client实例没有问题。每个线程读取自己的音频文件互不干扰。5.2 识别率优化自定义词表比换模型参数更有效如果你的视频里全是专业术语比如“Transformer”“PyTorch”“卷积神经网络”百度默认模型可能识别成同音词。在百度语音控制台的“自定义词表”里添加这些词能明显提升识别率。需要注意的是词表配置有生效延迟修改后等几分钟再调用。另外切片策略直接影响识别率固定 58 秒切分虽然简单但可能在句子中间断开。更稳妥的做法是先按静音切分再把超过 60 秒的段落强制拆分。用pydub的split_on_silence时把min_silence_len设成 500mssilence_thresh设为音频的均方根值减去 16dB这样能保留完整句子的概率更高。5.3 视频文件本身有问题时先修再转重装系统后视频文件没有访问权限或者数据恢复软件拿回来的文件无法播放这类问题在实操中非常常见。先用ffprobe查看元数据ffprobe -v error -show_streams corrupted.mp4如果能正常输出流信息通常只是文件权限问题。Linux 下执行chmod 644 corrupted.mp4Windows 下右键文件属性去掉“只读”即可。如果 ffprobe 都报错那就不是格式问题而是文件损坏可以用ffmpeg -err_detect explode -i corrupted.mp4 -c copy fixed.mp4尝试跳过损坏帧再抽取音频。处理完视频修复再回到第 3 章的流程否则后面所有识别工作都是在错误数据上白费力气。本文还有配套的精品资源点击获取