Whisper-large-v3 Gradio定制添加历史记录、导出SRT/VTT字幕功能扩展1. 引言语音转文字的需求无处不在从会议记录、视频字幕制作到播客内容整理我们经常需要将音频内容转化为可编辑、可搜索的文本。虽然市面上有不少在线工具但它们往往存在隐私顾虑、功能单一或收费昂贵的问题。今天要介绍的是一个基于 OpenAI Whisper Large v3 模型构建的本地化语音识别 Web 服务。这个项目最大的亮点在于它不仅提供了强大的多语言识别能力还通过二次开发增加了两个非常实用的功能历史记录管理和字幕文件导出。想象一下你处理完一段音频后不仅能立即看到文字还能一键导出为 SRT 或 VTT 格式的字幕文件方便直接导入视频剪辑软件。同时所有处理记录都会被保存下来方便你随时回顾和复用。本文将带你深入了解这个定制化项目的实现过程从基础部署到功能扩展一步步教你如何搭建属于自己的、功能更完善的语音识别工作站。2. 项目基础与环境搭建2.1 核心组件介绍这个项目建立在几个关键技术组件之上理解它们有助于后续的定制开发OpenAI Whisper Large v3 模型这是项目的核心引擎。它是一个拥有15亿参数的大规模语音识别模型支持99种语言的自动检测和转录。与 smaller 版本相比Large v3 在识别准确率尤其是对复杂口音、专业术语和背景噪声的处理上表现更为出色。模型文件大约2.9GB首次运行时会自动下载。Gradio 框架用于快速构建 Web 交互界面。它让我们能用简单的 Python 代码创建出包含文件上传、按钮、文本框等元素的网页应用无需编写复杂的前端代码。本项目基于 Gradio 4.x 版本。PyTorch CUDA提供模型推理的底层计算支持。利用 NVIDIA GPU如 RTX 4090进行加速可以大幅缩短长音频文件的处理时间。2.2 快速部署指南让我们从零开始把这个服务跑起来。整个过程非常直接几乎是一键式的。首先确保你的环境满足以下要求操作系统推荐 Ubuntu 24.04 LTS其他 Linux 发行版或 WindowsWSL2也可行。GPU至少需要 4GB 显存推荐 8GB 以上以流畅运行 Large v3 模型。RTX 409023GB能提供最佳体验。内存与存储16GB 系统内存10GB 以上的空闲磁盘空间。第一步获取项目代码通常项目代码会打包在一个压缩文件中。你可以在终端中通过git clone命令或直接下载 ZIP 包的方式获取。第二步安装系统依赖主要是 FFmpeg它是一个强大的音视频处理工具Whisper 用它来读取各种格式的音频文件。# 对于 Ubuntu/Debian 系统 sudo apt-get update sudo apt-get install -y ffmpeg第三步安装 Python 依赖项目根目录下会有一个requirements.txt文件列出了所有需要的 Python 包。# 进入项目目录 cd /path/to/Whisper-large-v3 # 创建并激活虚拟环境推荐避免包冲突 python3 -m venv venv source venv/bin/activate # Linux/macOS # venv\Scripts\activate # Windows # 安装依赖包 pip install -r requirements.txt这个过程会自动安装 Gradio、PyTorch带CUDA支持、Whisper 等库。第四步启动服务依赖安装完成后直接运行主程序即可。python3 app.py当你在终端看到类似下面的输出时说明服务已经成功启动Running on local URL: http://0.0.0.0:7860现在打开你的浏览器访问http://localhost:7860就能看到语音识别的 Web 界面了。3. 核心功能与二次开发动机启动服务后你会看到一个简洁但功能强大的界面。其核心功能包括多格式音频支持可以直接上传 WAV, MP3, M4A, FLAC, OGG 等常见音频文件。实时录音识别点击录音按钮即可现场录音并实时转写。语言自动检测上传音频后模型会自动识别其中使用的语言支持99种。转录与翻译除了转录成本地语言文本还可以选择将结果翻译成英语。GPU加速如果系统有 NVIDIA GPU处理速度会非常快。然而在原始版本的实际使用中我发现了两个可以大幅提升使用体验的改进点缺乏历史记录每次处理完音频刷新页面后之前的转录内容和设置就消失了。如果想回顾或复制之前的文本非常不方便。字幕导出不便转录结果是一整段文本或带时间戳的文本。如果想为视频添加字幕需要手动将其整理成 SRT 或 VTT 格式这是一个繁琐且容易出错的过程。因此本次二次开发的目标就是解决这两个痛点为这个强大的语音识别工具加上“历史记忆”和“格式转换”的能力。4. 功能扩展一实现历史记录管理历史记录功能的核心思想是将每次语音识别的任务详情如音频文件名、识别时间、语言、转录文本等保存下来并在界面上提供一个清晰的列表供用户查询和重用。4.1 设计思路与数据存储我们选择使用轻量级的SQLite数据库来存储历史记录。SQLite 是一个文件型数据库无需安装单独的数据库服务非常适合这种单机版应用。我们计划创建一张名为transcription_history的表用来存储以下信息id: 主键唯一标识每条记录。timestamp: 任务完成的时间。filename: 上传的音频文件名。language: 检测到或指定的语言。task: 任务类型如transcribe或translate。text: 完整的转录文本。segments_json: 包含详细时间戳的识别分段信息JSON格式这是后续导出字幕的关键。4.2 代码实现详解首先我们需要在app.py中增加数据库初始化模块。import sqlite3 import json from datetime import datetime # 初始化数据库 def init_database(): conn sqlite3.connect(transcription_history.db) c conn.cursor() # 创建历史记录表 c.execute( CREATE TABLE IF NOT EXISTS transcription_history ( id INTEGER PRIMARY KEY AUTOINCREMENT, timestamp TEXT NOT NULL, filename TEXT, language TEXT, task TEXT, text TEXT, segments_json TEXT ) ) conn.commit() conn.close() # 在应用启动时初始化数据库 init_database()接下来修改核心的语音识别函数使其在完成识别后将结果保存到数据库。def save_to_history(filename, result, language, task): 将识别结果保存到历史数据库 conn sqlite3.connect(transcription_history.db) c conn.cursor() # 将 segments 列表转为 JSON 字符串存储 segments_json json.dumps(result.get(segments, [])) c.execute( INSERT INTO transcription_history (timestamp, filename, language, task, text, segments_json) VALUES (?, ?, ?, ?, ?, ?) , (datetime.now().isoformat(), filename, language, task, result[text], segments_json)) conn.commit() conn.close() # 在原有的 transcribe_audio 函数中识别完成后调用保存函数 def transcribe_audio(audio_file, tasktranscribe): if audio_file is None: return 请先上传音频文件。, None # 原有的加载模型和识别代码... # model whisper.load_model(large-v3) # result model.transcribe(audio_file, tasktask, ...) # 新增保存结果到历史记录 save_to_history(audio_file.name, result, result.get(language), task) # 返回结果假设原有函数返回文本和 segments formatted_text result[text] segments result.get(segments, []) return formatted_text, segments4.3 创建历史记录查询界面最后我们需要在 Gradio 界面中添加一个新的选项卡Tab来展示历史记录。import gradio as gr # 函数从数据库加载历史记录 def load_history(): conn sqlite3.connect(transcription_history.db) c conn.cursor() c.execute(SELECT id, timestamp, filename, language, task, text FROM transcription_history ORDER BY timestamp DESC) records c.fetchall() conn.close() # 将记录格式化为HTML表格便于展示 html_table table border1 stylewidth:100%; border-collapse: collapse;trth时间/thth文件名/thth语言/thth任务/thth文本预览/thth操作/th/tr for rec in records: rec_id, timestamp, filename, lang, task, text rec preview text[:50] ... if len(text) 50 else text html_table f tr td{timestamp[:19]}/td td{filename or 实时录音}/td td{lang}/td td{task}/td td title{text}{preview}/td tdbutton onclickloadRecord({rec_id})加载/button/td /tr html_table /table return html_table # 函数根据ID加载某条历史记录的详细信息 def load_record_by_id(record_id): conn sqlite3.connect(transcription_history.db) c conn.cursor() c.execute(SELECT text, segments_json FROM transcription_history WHERE id?, (record_id,)) record c.fetchone() conn.close() if record: text, segments_json record segments json.loads(segments_json) if segments_json else [] return text, segments return 记录未找到。, [] # 构建 Gradio 界面 with gr.Blocks(titleWhisper 语音识别 - 增强版) as demo: # ... 原有的文件上传、录音、输出区域代码 ... # 新增一个“历史记录”选项卡 with gr.Tab(历史记录): history_html gr.HTML(valueload_history(), label识别历史) reload_btn gr.Button(刷新历史记录) # 定义刷新按钮的功能 def reload_history(): return load_history() reload_btn.click(reload_history, outputshistory_html) # 这里可以添加一个隐藏的组件来处理“加载”按钮的点击通过JavaScript交互 # 为了简化我们可以用另一个输出框来展示加载的详细文本 loaded_text gr.Textbox(label加载的历史文本, interactiveTrue, lines10) # 实际项目中加载操作可能需要更复杂的JS回调与Gradio结合。 # 启动 demo.launch(server_port7860)现在你的应用就拥有了一个带表格的历史记录页面可以查看、搜索和重新加载过去的识别任务。5. 功能扩展二导出SRT/VTT字幕文件字幕文件是视频制作中的刚需。SRT 和 VTT 是两种最通用的字幕格式它们都包含了文本及其出现的时间点。5.1 字幕格式解析SRT (SubRip Text)格式简单每一条字幕包含序号、时间轴和文本。1 00:00:01,000 -- 00:00:04,000 欢迎观看本视频。 2 00:00:05,000 -- 00:00:08,000 今天我们将介绍语音识别技术。VTT (WebVTT)与 SRT 类似但格式更现代支持更多样式常用于网页视频。WEBVTT 1 00:00:01.000 -- 00:00:04.000 欢迎观看本视频。 2 00:00:05.000 -- 00:00:08.000 今天我们将介绍语音识别技术。Whisper 模型识别返回的segments列表正好包含了每一段文本的起始时间start、结束时间end和文本内容text这为我们生成字幕文件提供了完美的基础数据。5.2 导出功能实现我们在app.py中添加两个函数分别用于生成 SRT 和 VTT 格式的字符串。def segments_to_srt(segments): 将 Whisper 的 segments 转换为 SRT 格式字符串 srt_content for i, segment in enumerate(segments, start1): start_time format_timestamp(segment[start]) end_time format_timestamp(segment[end]) text segment[text].strip() srt_content f{i}\n{start_time} -- {end_time}\n{text}\n\n return srt_content def segments_to_vtt(segments): 将 Whisper 的 segments 转换为 VTT 格式字符串 vtt_content WEBVTT\n\n for i, segment in enumerate(segments, start1): start_time format_timestamp(segment[start], ms_separator.) end_time format_timestamp(segment[end], ms_separator.) text segment[text].strip() vtt_content f{i}\n{start_time} -- {end_time}\n{text}\n\n return vtt_content def format_timestamp(seconds, ms_separator,): 将秒数格式化为 时:分:秒,毫秒 或 时:分:秒.毫秒 hours int(seconds // 3600) minutes int((seconds % 3600) // 60) secs int(seconds % 60) millisecs int((seconds - int(seconds)) * 1000) return f{hours:02d}:{minutes:02d}:{secs:02d}{ms_separator}{millisecs:03d}5.3 集成到Gradio界面现在我们需要在界面上添加导出按钮并让它们触发文件下载。import tempfile # 在 Gradio 界面构建代码中找到输出区域附近 # 假设你的转录文本输出组件叫 text_output segments 数据保存在一个 State 组件中 # 添加两个按钮 export_srt_btn gr.Button(导出为 SRT 字幕) export_vtt_btn gr.Button(导出为 VTT 字幕) # 定义按钮点击事件 def export_srt_file(segments): if not segments: return None srt_text segments_to_srt(segments) # 创建一个临时文件供用户下载 with tempfile.NamedTemporaryFile(modew, suffix.srt, deleteFalse) as f: f.write(srt_text) temp_path f.name return temp_path def export_vtt_file(segments): if not segments: return None vtt_text segments_to_vtt(segments) with tempfile.NamedTemporaryFile(modew, suffix.vtt, deleteFalse) as f: f.write(vtt_text) temp_path f.name return temp_path # 将按钮与函数连接并指定输出为文件 export_srt_btn.click(export_srt_file, inputs[gr.State(value[])], outputsgr.File(label下载 SRT 文件)) export_vtt_btn.click(export_vtt_file, inputs[gr.State(value[])], outputsgr.File(label下载 VTT 文件))这样当用户完成一次语音识别后点击“导出为 SRT 字幕”按钮浏览器就会自动下载一个.srt文件用文本编辑器或视频软件打开就是标准格式的字幕了。6. 总结与展望通过以上步骤我们成功地将一个基础的 Whisper 语音识别服务扩展成了一个具备历史记录管理和专业字幕导出功能的增强版工具。现在这个工具不仅能准确识别语音还能记住你的每一次操作并一键产出视频剪辑所需的字幕文件实用性大大增强。回顾整个扩展过程关键在于两点数据持久化利用简单的 SQLite 数据库我们赋予了应用“记忆”能力。数据格式转换深入理解模型输出segments和目标格式SRT/VTT的规范编写转换函数将数据价值最大化。这个项目展示了 Gradio 快速原型开发能力的优势也体现了对开源模型进行“微创新”的价值。你可以基于这个框架继续添加更多实用功能例如批量处理功能同时上传多个音频文件进行转写。识别结果编辑在 Web 界面上直接修改识别文本和时间戳。自定义词汇表添加专业词汇提升特定领域的识别准确率。任务队列与后台处理对于超长音频提供异步处理能力。希望本文的分享能帮助你更好地利用 Whisper 这一强大的开源模型构建出更贴合自己工作流的智能工具。获取更多AI镜像想探索更多AI镜像和应用场景访问 CSDN星图镜像广场提供丰富的预置镜像覆盖大模型推理、图像生成、视频生成、模型微调等多个领域支持一键部署。