🧩 一、研究背景与目标
在 AI 工具不断桌面化的趋势下,如何让深度学习模型落地为非技术用户可操作的 GUI 工具,成为开发者的新方向。
🎯 项目目标:
- 将 Whisper 语音识别模型封装成本地应用;
- 允许用户上传视频并自动提取音频;
- 支持语音转文字与定时截图;
- 输出可视化结果并可打包为
.exe桌面端程序。
🧠 二、系统架构设计
系统采用 Electron + Python 混合架构,
通过 IPC 通信机制实现前端与模型端解耦。
┌───────────────────────────────┐
│ Electron 前端层 │
│ ├── index.html(界面层) │
│ ├── preload.js(桥接层) │
│ └── main.js(主进程控制) │
└───────────────┬──────────────┘
│ IPC 调用
┌───────────────▼──────────────┐
│ Python 后端处理层 │
│ ├── video-Text.py(语音识别) │
│ └── autoScreenshot.py(截图) │
└───────────────────────────────┘
🔹 Electron 提供前端交互与窗口管理
🔹 Python 模块负责模型推理与媒体处理
🔹 Node.js child_process.spawn() 用于跨语言调用
⚙️ 三、技术栈与依赖
| 模块 | 技术 | 功能描述 |
|---|---|---|
| 🎬 视频提取 | moviepy + ffmpeg | 提取音频流 |
| 🧠 语音识别 | openai-whisper | Whisper 模型推理 |
| 🖼 图像处理 | opencv-python | 每秒截图 |
| 💻 GUI 框架 | Electron | 桌面端封装与渲染 |
| 🔄 通信机制 | Node.js spawn() | 前后端进程交互 |
| 🧰 环境管理 | Conda + npm | 环境隔离与依赖管理 |
🧱 四、项目结构
video-assistant/
├── main.js # Electron 主进程
├── preload.js # 渲染与主进程桥接
├── index.html # GUI 界面
├── package.json # Electron 配置文件
├── python/
│ ├── video-Text.py # Whisper 语音识别
│ └── autoScreenshot.py # 视频截图
└── node_modules/
└── electron/
🧩 五、开发过程与问题解决
🧠 1. Whisper 模型加载失败(Numpy 版本冲突)
错误信息:
RuntimeError: Numpy is not available
原因分析:
Whisper 不兼容 numpy>=2.0 版本。
解决方案:
pip install "numpy<2.0" --force-reinstall -i https://mirrors.aliyun.com/pypi/simple/
🎬 2. FFmpeg 环境变量未配置
报错:
FileNotFoundError: [WinError 2] 系统找不到指定的文件。
原因:
moviepy 内部使用 FFmpeg 调用命令行提取音频。
解决方法:
setx PATH "%PATH%;F:\ffmpeg\bin"
验证:
ffmpeg -version
🌐 3. Electron 下载超时
问题:
npm error RequestError: connect ETIMEDOUT 20.205.243.166:443
解决方案:
npm config set registry https://registry.npmmirror.com
npm config set ELECTRON_MIRROR https://registry.npmmirror.com/-/binary/electron/
npm install electron --save-dev
💬 4. 控制台中文乱码
报错:
UnicodeEncodeError: 'gbk' codec can't encode character
修复:
import sys, io
sys.stdout = io.TextIOWrapper(sys.stdout.buffer, encoding='utf-8')
🧩 5. Electron 与 Python 进程通信
通过 child_process.spawn() 调用 Python 并传递参数:
ipcMain.handle('run-python', async (event, script, videoPath) => {
return new Promise((resolve) => {
const py = spawn('python', [path.join(__dirname, 'python', script), videoPath]);
py.stdout.on('data', (data) => console.log(data.toString()));
py.on('close', (code) => resolve(code));
});
});
Python 端接收路径参数:
VIDEO_PATH = sys.argv[1] if len(sys.argv) > 1 else None
🧩 六、语音识别核心脚本实现
import whisper, sys, io, json
from moviepy.editor import VideoFileClip
sys.stdout = io.TextIOWrapper(sys.stdout.buffer, encoding='utf-8')
VIDEO_PATH = sys.argv[1]
AUDIO_PATH = "temp_audio.wav"
OUTPUT_PATH = "output_text.txt"
clip = VideoFileClip(VIDEO_PATH)
clip.audio.write_audiofile(AUDIO_PATH)
clip.close()
model = whisper.load_model("base")
result = model.transcribe(AUDIO_PATH, language='zh')
with open(OUTPUT_PATH, "w", encoding="utf-8") as f:
for seg in result["segments"]:
f.write(f"[{seg['start']:.2f}s - {seg['end']:.2f}s] {seg['text']}\n")
print(json.dumps({"text": result["text"]}, ensure_ascii=False))
💻 七、前端交互设计
🎞 文件选择模块
ipcMain.handle('select-video', async () => {
const result = await dialog.showOpenDialog({
title: '选择视频文件',
filters: [{ name: 'Video Files', extensions: ['mp4', 'mov', 'avi'] }],
properties: ['openFile'],
});
if (result.canceled) return null;
return result.filePaths[0];
});
🪄 Whisper 调用与输出展示
<button id="upload">选择视频文件</button>
<button id="transcribe">开始识别</button>
<textarea id="output" rows="15" cols="80" readonly></textarea>
前端调用:
const result = await window.electronAPI.runPython('video-Text.py', videoPath);
document.getElementById('output').value = result.text;
🧮 八、系统运行流程
1️⃣ 用户选择视频文件
↓
2️⃣ Electron 调用 Python
↓
3️⃣ 提取音频(MoviePy)
↓
4️⃣ Whisper 模型转录语音
↓
5️⃣ 输出文字文件 + 可视化展示
输出结果示例:
[0.00s - 3.20s] 大家好,今天我们介绍视频语音识别。
[3.21s - 5.70s] Whisper 是一个通用语音转录模型。
💎 九、扩展与优化方向
| 功能方向 | 说明 |
|---|---|
| 🧠 模型选择 | 支持 tiny、base、small、medium、large 模型 |
| 💬 实时显示 | 前端动态显示识别文本 |
| 📊 进度条 | 通过 Electron 进度条显示识别进度 |
| 🗂 自定义保存 | 用户可选择输出路径 |
| 🎬 字幕导出 | 生成 .srt 或 .vtt 文件 |
| 🔍 多语言识别 | 支持 language='auto' 自动识别语言 |
| 🤖 智能摘要 | Whisper 输出结果可传递至 GPT 自动生成摘要 |