3.10-electron-voice-to-text测试,图片添加,内容优化

This commit is contained in:
SherryTECNU
2026-03-26 23:07:56 +08:00
committed by sanbuphy
parent 04e0dbf0a0
commit e064f933b6
11 changed files with 45 additions and 51 deletions
Binary file not shown.

After

Width:  |  Height:  |  Size: 177 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 200 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 153 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 148 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 193 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 170 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 187 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 176 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 129 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 143 KiB

@@ -20,6 +20,8 @@ Electron 是一个开源框架,它让你可以用 **HTML + CSS + JavaScript**
**一句话理解**Electron = 一个"隐形的 Chrome 浏览器" + Node.js 的系统能力。 **一句话理解**Electron = 一个"隐形的 Chrome 浏览器" + Node.js 的系统能力。
![placeholder: 一张示意图,展示 Electron 的架构:Chromium(负责 UI 渲染)+ Node.js(负责系统访问)= 桌面应用](images/image1.png)
<!-- ![placeholder: 一张示意图,展示 Electron 的架构:Chromium(负责 UI 渲染)+ Node.js(负责系统访问)= 桌面应用](images/image1.png) --> <!-- ![placeholder: 一张示意图,展示 Electron 的架构:Chromium(负责 UI 渲染)+ Node.js(负责系统访问)= 桌面应用](images/image1.png) -->
## 1.2 Electron 的核心架构 ## 1.2 Electron 的核心架构
@@ -47,6 +49,7 @@ Electron 应用由两种进程组成,理解它们是开发的关键:
它们之间通过 **IPC(进程间通信)** 来传递消息,就像打电话一样:渲染进程说"我要录音",主进程收到后去调用系统麦克风。 它们之间通过 **IPC(进程间通信)** 来传递消息,就像打电话一样:渲染进程说"我要录音",主进程收到后去调用系统麦克风。
![placeholder: 一张 Electron 进程架构图,展示 Main Process、Renderer Process、Preload Script 之间的关系和 IPC 通信](images/image2.png)
<!-- ![placeholder: 一张 Electron 进程架构图,展示 Main Process、Renderer Process、Preload Script 之间的关系和 IPC 通信](images/image2.png) --> <!-- ![placeholder: 一张 Electron 进程架构图,展示 Main Process、Renderer Process、Preload Script 之间的关系和 IPC 通信](images/image2.png) -->
## 1.3 我们要做什么? ## 1.3 我们要做什么?
@@ -69,6 +72,7 @@ Electron 应用由两种进程组成,理解它们是开发的关键:
| 模型体积 | 无需下载 | tiny 模型 75MBlarge 模型 3GB | | 模型体积 | 无需下载 | tiny 模型 75MBlarge 模型 3GB |
| 适合场景 | 快速上手、轻量使用 | 注重隐私、离线使用、长期高频使用 | | 适合场景 | 快速上手、轻量使用 | 注重隐私、离线使用、长期高频使用 |
![placeholder: 一张应用效果预览图,展示语音转文字应用的 UI:顶部有录音按钮和波形动画,下方是识别出的文字,右上角有模式切换开关](images/image3.png)
<!-- ![placeholder: 一张应用效果预览图,展示语音转文字应用的 UI:顶部有录音按钮和波形动画,下方是识别出的文字,右上角有模式切换开关](images/image3.png) --> <!-- ![placeholder: 一张应用效果预览图,展示语音转文字应用的 UI:顶部有录音按钮和波形动画,下方是识别出的文字,右上角有模式切换开关](images/image3.png) -->
## 1.4 重要提醒:Web Speech API 在 Electron 中不可用 ## 1.4 重要提醒:Web Speech API 在 Electron 中不可用
@@ -96,12 +100,10 @@ Google 已经关闭了对非 Chrome/Edge 浏览器壳的语音 API 支持。Elec
打开你的 AI 编程助手,在对话框中输入以下 Prompt: 打开你的 AI 编程助手,在对话框中输入以下 Prompt:
``` ```
帮我使用 Electron Forge 创建一个新的 Electron 项目,使用 Vite 模板 帮我用 Electron Forge 创建一个新的 Electron 项目,项目名称叫 voice-to-text,使用 Vite 模板。命令参考:npx create-electron-app voice-to-text --template=vite创建完后进入项目目录,安装依赖并帮我把基础环境搭好
项目名叫 voice-to-text。
请执行:npx create-electron-app voice-to-text --template=vite
创建完成后进入项目目录并安装依赖。
``` ```
Electron Forge 是 Electron 官方推荐的脚手架工具,它帮你处理了项目初始化、打包、分发等繁琐的事情。 Electron Forge 是 Electron 官方推荐的脚手架工具,它帮你处理了项目初始化、打包、分发等繁琐的事情。
创建完成后,项目结构大致如下: 创建完成后,项目结构大致如下:
@@ -125,11 +127,12 @@ voice-to-text/
让 AI 帮你启动开发服务器: 让 AI 帮你启动开发服务器:
``` ```
帮我启动 Electron 开发服务器,执行 npm start 帮我把 voice-to-text 项目的 Electron 开发服务器启动,用 npm start 启动
``` ```
几秒钟后,一个桌面窗口会弹出来——这就是你的 Electron 应用!虽然现在只有一个默认的欢迎页面,但它已经是一个真正的桌面程序了。 几秒钟后,一个桌面窗口会弹出来——这就是你的 Electron 应用!虽然现在只有一个默认的欢迎页面,但它已经是一个真正的桌面程序了。
![placeholder: Electron 应用首次启动的截图,展示默认的欢迎页面窗口](images/image4.png)
<!-- ![placeholder: Electron 应用首次启动的截图,展示默认的欢迎页面窗口](images/image4.png) --> <!-- ![placeholder: Electron 应用首次启动的截图,展示默认的欢迎页面窗口](images/image4.png) -->
## 2.3 理解进程间通信(IPC) ## 2.3 理解进程间通信(IPC)
@@ -141,12 +144,12 @@ voice-to-text/
``` ```
渲染进程(UI) 主进程(系统) 渲染进程(UI) 主进程(系统)
│ │ │ │
│── "我要开始录音" ──────────→ │ │── "我要开始录音" ──────────→
│ │── 调用麦克风 │ │── 调用麦克风
│ │── 处理音频 │ │── 处理音频
│ ←──── "这是识别结果" ────────│ ←──── "这是识别结果" ────────│
│ │ │ │
│── 显示文字到界面 │ │── 显示文字到界面
``` ```
在代码中,这个通信通过 `preload.js` 来桥接: 在代码中,这个通信通过 `preload.js` 来桥接:
@@ -174,6 +177,7 @@ ipcMain.handle('transcribe-audio', async (event, audioData) => {
}) })
``` ```
![placeholder: 一张 IPC 通信流程图,展示 Renderer → Preload → Main 的消息传递过程](images/image5.png)
<!-- ![placeholder: 一张 IPC 通信流程图,展示 Renderer → Preload → Main 的消息传递过程](images/image5.png) --> <!-- ![placeholder: 一张 IPC 通信流程图,展示 Renderer → Preload → Main 的消息传递过程](images/image5.png) -->
# 第 3 章:实现录音功能 # 第 3 章:实现录音功能
@@ -183,21 +187,19 @@ ipcMain.handle('transcribe-audio', async (event, audioData) => {
浏览器(也就是 Electron 的渲染进程)提供了 `navigator.mediaDevices.getUserMedia` API 来访问麦克风。让 AI 帮你实现录音功能: 浏览器(也就是 Electron 的渲染进程)提供了 `navigator.mediaDevices.getUserMedia` API 来访问麦克风。让 AI 帮你实现录音功能:
``` ```
帮我修改 src/index.html 和 src/renderer.js,实现以下功能 麻烦帮我修改一下项目里的 src/index.html 和 src/renderer.js 这两个文件,帮我实现完整的语音录制 + 语音识别功能,具体要求我整理好了
界面设计: 界面设计:
1. 一个大的圆形 "开始录音" 按钮,点击后变成红色的 "停止录音" 1. 一个大尺寸的圆形按钮,默认显示“开始录音”;点击后按钮变成红色,文字切换成“停止录音
2. 录音时显示一个简单的脉冲动画,表示正在录音 2. 录音过程中,按钮要带一个简单的脉冲动画,让用户能直观看到正在录音
3. 下方有一个文字示区,用于展示识别结果 3. 按钮下方放一块文字示区,用来显示语音识别出来的文本内容
4. 底部有 "复制文字""清空" 两个按钮 4. 页面底部配置 “复制文字清空 两个功能按钮,分别实现识别结果复制、结果区域清空的功能
5. 右上角有一个设置图标,点击可切换识别模式(云端/本地 5. 页面右上角增加设置图标,点击可切换识别模式(云端识别 / 本地识别
录音逻辑要求(需要在 renderer.js 中实现)
录音逻辑(在 renderer.js 中): 1. 点击录音按钮后,调用 navigator.mediaDevices.getUserMedia 获取麦克风权限
1. 点击按钮后,使用 navigator.mediaDevices.getUserMedia 获取麦克风权限 2. 用 MediaRecorder 实现音频录制,录制格式固定为 webm
2. 使用 MediaRecorder 录制音频,格式为 webm 3. 停止录音后,把录制好的音频 Blob 对象转成 ArrayBuffer 格式
3. 停止录音后,将音频 Blob 转为 ArrayBuffer 4. 调用 window.electronAPI.sendAudio 方法,把音频数据发送给主进程
4. 通过 window.electronAPI.sendAudio 发送给主进程 5. 还需要监听主进程返回的识别结果,并将结果展示在文字显示区域中
5. 等待主进程返回识别结果并显示
``` ```
核心录音代码: 核心录音代码:
@@ -236,7 +238,7 @@ async function startRecording() {
mediaRecorder.start() mediaRecorder.start()
} }
``` ```
![placeholder: 应用录音界面的截图,展示录音按钮(录音中状态,红色脉冲动画)和下方的文字显示区域](images/image6.png)
<!-- ![placeholder: 应用录音界面的截图,展示录音按钮(录音中状态,红色脉冲动画)和下方的文字显示区域](images/image6.png) --> <!-- ![placeholder: 应用录音界面的截图,展示录音按钮(录音中状态,红色脉冲动画)和下方的文字显示区域](images/image6.png) -->
## 3.2 处理麦克风权限 ## 3.2 处理麦克风权限
@@ -245,9 +247,9 @@ Electron 默认会拦截权限请求。我们需要在主进程中明确允许
``` ```
请帮我在 main.js 中添加麦克风权限处理: 请帮我在 main.js 中添加麦克风权限处理:
1. 使用 session.defaultSession.setPermissionRequestHandler 处理权限请求 1. 用 session.defaultSession.setPermissionRequestHandler 处理权限请求
2. 当请求类型为 'media' 时,自动允许 2. 当请求类型media 麦克风权限时,直接自动允许
3. 对于 macOS,确保在 package.json 或 entitlements 中声明了麦克风使用说明 3. 如果是 macOS 系统,记得在 package.json 或 entitlements 里加上麦克风使用说明,保证权限能正常生效
``` ```
```javascript ```javascript
@@ -285,12 +287,12 @@ session.defaultSession.setPermissionRequestHandler(
``` ```
请帮我在 main.js 中实现 OpenAI Whisper API 的调用: 请帮我在 main.js 中实现 OpenAI Whisper API 的调用:
1. 安装 node-fetch(如果需要)或使用 Node.js 内置的 fetch 1. 安装 node-fetch(如果项目需要),或者直接用 Node.js 自带的 fetch
2. 创建 transcribeWithWhisper 函数,接收音频 ArrayBuffer 2. 写一个 transcribeWithWhisper 函数,参数传入音频 ArrayBuffer
3. ArrayBuffer 转 Blob/File构建 FormData 3. 把传入的 ArrayBuffer 转换成 BlobFile然后组装成 FormData 格式
4. 调用 https://api.openai.com/v1/audio/transcriptions 4. 调用 https://api.openai.com/v1/audio/transcriptions
5. 模型使用 whisper-1,语言设为 zh(中文) 5. 模型指定用 whisper-1,语言设置为中文 zh
6. 返回识别出的文 6. 接口调用完成后,返回识别出的文本内容
7. API Key 从环境变量或配置文件读取 7. API Key 从环境变量或配置文件读取
``` ```
@@ -318,7 +320,7 @@ async function transcribeWithWhisper(audioBuffer, apiKey) {
return data.text return data.text
} }
``` ```
![placeholder: 应用运行截图,展示用户说了一段中文后,Whisper API 返回的识别结果](images/image7.png)
<!-- ![placeholder: 应用运行截图,展示用户说了一段中文后,Whisper API 返回的识别结果](images/image7.png) --> <!-- ![placeholder: 应用运行截图,展示用户说了一段中文后,Whisper API 返回的识别结果](images/image7.png) -->
## 4.3 添加设置界面 ## 4.3 添加设置界面
@@ -327,15 +329,12 @@ async function transcribeWithWhisper(audioBuffer, apiKey) {
``` ```
请帮我在 index.html 中添加一个设置面板: 请帮我在 index.html 中添加一个设置面板:
1. 右上角一个齿轮图标,点击展开设置面板 1. 页面右上角一个齿轮样式的设置图标,点击后弹出设置面板
2. 设置面板包含: 2. 面板里要包含这几项:识别模式切换(云端 API / 本地模型)、API Key 输入框(只有云端模式下才显示)、语言选择下拉菜单(中文、英文、自动检测可选)
- 识别模式切换(云端 API / 本地模型) 3. 所有设置内容自动保存到 localStorage
- API Key 输入框(仅云端模式显示) 4. 点击面板外面的区域就能关闭面板
- 语言选择下拉框(中文/英文/自动检测)
3. 设置保存到 localStorage
4. 面板可以点击外部区域关闭
``` ```
![placeholder: 设置面板展开的截图,展示模式切换开关和 API Key 输入框](images/image8.png)
<!-- ![placeholder: 设置面板展开的截图,展示模式切换开关和 API Key 输入框](images/image8.png) --> <!-- ![placeholder: 设置面板展开的截图,展示模式切换开关和 API Key 输入框](images/image8.png) -->
# 第 5 章:方案 B——本地识别(whisper.cpp # 第 5 章:方案 B——本地识别(whisper.cpp
@@ -351,7 +350,7 @@ async function transcribeWithWhisper(audioBuffer, apiKey) {
npm install nodejs-whisper npm install nodejs-whisper
安装完成后,请帮我下载 whisper 的 tiny 模型(用于测试,体积小速度快)。 安装完成后,请帮我下载 whisper 的 tiny 模型(用于测试,体积小速度快)。
nodejs-whisper 会自动处理模型下载。 nodejs-whisper 本身会自动完成模型下载,不用额外处理
``` ```
> **模型选择指南** > **模型选择指南**
@@ -366,13 +365,8 @@ nodejs-whisper 会自动处理模型下载。
让 AI 帮你实现本地识别功能: 让 AI 帮你实现本地识别功能:
``` ```
请帮我在 main.js添加 whisper.cpp 本地识别功能: 请帮我在main.js添加 whisper.cpp 本地语音识别功能:
1. 引入 nodejs-whisper 引入 nodejs-whisper 包,然后写一个 transcribeWithLocal 函数。函数接收音频 ArrayBuffer,先把它保存成临时的 WAV 文件(要求 16kHz、单声道),再调用 nodejs-whisper 做识别,识别完成后返回文字结果,最后把临时文件删掉就行
2. 创建 transcribeWithLocal 函数
3. 接收音频 ArrayBuffer,先保存为临时 WAV 文件(16kHz 单声道)
4. 调用 nodejs-whisper 进行识别
5. 返回识别文字
6. 识别完成后删除临时文件
``` ```
核心代码: 核心代码:
@@ -405,7 +399,7 @@ async function transcribeWithLocal(audioBuffer) {
} }
} }
``` ```
![placeholder: 本地模型识别的运行截图,展示离线状态下依然能正常识别中文语音](images/image9.png)
<!-- ![placeholder: 本地模型识别的运行截图,展示离线状态下依然能正常识别中文语音](images/image9.png) --> <!-- ![placeholder: 本地模型识别的运行截图,展示离线状态下依然能正常识别中文语音](images/image9.png) -->
## 5.3 Apple Silicon 用户的福音 ## 5.3 Apple Silicon 用户的福音
@@ -423,7 +417,7 @@ async function transcribeWithLocal(audioBuffer) {
Electron Forge 已经内置在我们的项目中,打包非常简单: Electron Forge 已经内置在我们的项目中,打包非常简单:
``` ```
请帮我执行 Electron Forge 的打包命令: 麻烦帮我运行一下 Electron Forge 的打包命令,执行以下指令就行
npx electron-forge make npx electron-forge make
``` ```
@@ -434,7 +428,7 @@ npx electron-forge make
* **Linux**:生成 `.deb`Debian/Ubuntu)和 `.rpm`Fedora)包 * **Linux**:生成 `.deb`Debian/Ubuntu)和 `.rpm`Fedora)包
打包产物在 `out/make/` 目录下。 打包产物在 `out/make/` 目录下。
![placeholder: out/make 目录的文件列表截图,展示生成的 .dmg 或 .exe 安装包](images/image10.png)
<!-- ![placeholder: out/make 目录的文件列表截图,展示生成的 .dmg 或 .exe 安装包](images/image10.png) --> <!-- ![placeholder: out/make 目录的文件列表截图,展示生成的 .dmg 或 .exe 安装包](images/image10.png) -->
## 6.2 应用体积优化 ## 6.2 应用体积优化