Electron.js环境下Arduino控制的本地音频录制方案技术问询
我之前做过类似的硬件+JS录音项目,完全适配你的需求——不用用户碰隐藏的Windows笔记本,靠Arduino按钮控制录音启停,本地存储单独文件,全程用JS生态实现。下面是完整的落地方案:
核心思路
用Electron打包JS代码成Windows桌面应用,它既能调用Node.js的硬件/文件API,又能使用浏览器的MediaRecorder录音API。Arduino通过串口给Electron发送按钮指令,Electron监听指令触发录音,每次录音生成带时间戳的独立文件,全程后台运行,用户完全感知不到笔记本的存在。
1. Arduino按钮控制代码
先搞定Arduino端,让按钮按下时发送录音切换指令(加防抖避免误触):
const int buttonPin = 2; int lastButtonState = HIGH; int currentButtonState; unsigned long lastDebounceTime = 0; unsigned long debounceDelay = 50; void setup() { pinMode(buttonPin, INPUT_PULLUP); Serial.begin(9600); } void loop() { currentButtonState = digitalRead(buttonPin); if (currentButtonState != lastButtonState) { lastDebounceTime = millis(); } if ((millis() - lastDebounceTime) > debounceDelay) { if (currentButtonState == LOW && lastButtonState == HIGH) { // 按钮按下,发送切换指令(第一次按启动,第二次按停止) Serial.println("TOGGLE_REC"); } lastButtonState = currentButtonState; } }
2. Electron应用核心实现(JS)
初始化项目
先创建Electron项目,安装依赖:
npm init -y npm install electron serialport @serialport/parser-readline
主进程代码(main.js)
负责串口监听、窗口隐藏、开机自启:
const { app, BrowserWindow, ipcMain } = require('electron'); const SerialPort = require('serialport'); const Readline = require('@serialport/parser-readline'); const path = require('path'); let mainWindow; let isRecording = false; function createWindow() { mainWindow = new BrowserWindow({ width: 800, height: 600, show: false, // 隐藏窗口,用户完全看不到 webPreferences: { nodeIntegration: true, contextIsolation: false } }); mainWindow.loadFile('index.html'); // 自动检测Arduino串口(也可以手动指定端口,比如COM3) SerialPort.list().then(ports => { // 匹配Arduino的vendorId,不同型号可能略有差异,可自行调整 const arduinoPort = ports.find(port => port.vendorId === '2341' || port.vendorId === '2A03'); if (arduinoPort) { const port = new SerialPort(arduinoPort.path, { baudRate: 9600 }); const parser = port.pipe(new Readline({ delimiter: '\r\n' })); parser.on('data', (data) => { if (data.trim() === 'TOGGLE_REC') { isRecording = !isRecording; // 给渲染进程发消息,切换录音状态 mainWindow.webContents.send('toggle-recording', isRecording); } }); } else { console.error('未找到Arduino设备,请检查USB连接'); } }); // 设置开机自启,且后台隐藏运行 app.setLoginItemSettings({ openAtLogin: true, openAsHidden: true }); } app.whenReady().then(createWindow); app.on('window-all-closed', () => { if (process.platform !== 'darwin') app.quit(); });
渲染进程代码(index.html + 内嵌JS)
负责录音和本地文件存储:
<!DOCTYPE html> <html> <body> <script> const { ipcRenderer } = require('electron'); const fs = require('fs'); const path = require('path'); const os = require('os'); let mediaRecorder; let audioChunks = []; // 录音存储目录:用户文档下的RecordingFiles文件夹 const saveDir = path.join(os.homedir(), 'Documents', 'ExperienceRecordings'); // 提前创建存储目录,避免保存失败 if (!fs.existsSync(saveDir)) { fs.mkdirSync(saveDir, { recursive: true }); } // 获取麦克风权限并初始化录音流 async function initAudioStream() { try { const stream = await navigator.mediaDevices.getUserMedia({ audio: { sampleRate: 44100, channelCount: 1 } // 配置单声道、标准采样率 }); mediaRecorder = new MediaRecorder(stream); mediaRecorder.ondataavailable = (event) => { if (event.data.size > 0) { audioChunks.push(event.data); } }; mediaRecorder.onstop = async () => { const audioBlob = new Blob(audioChunks, { type: 'audio/wav' }); // 用时间戳命名,确保每个录音文件唯一 const timestamp = new Date().toISOString().replace(/[:.]/g, '-'); const fileName = `recording-${timestamp}.wav`; const filePath = path.join(saveDir, fileName); // 把Blob转成Buffer保存到本地 fs.writeFile(filePath, Buffer.from(await audioBlob.arrayBuffer()), (err) => { if (err) console.error('保存录音失败:', err); else console.log(`录音已保存: ${filePath}`); }); audioChunks = []; // 重置缓存,准备下一次录音 }; } catch (err) { console.error('麦克风权限获取失败:', err); } } // 初始化音频流 initAudioStream(); // 监听主进程的录音切换指令 ipcRenderer.on('toggle-recording', (event, start) => { if (start && mediaRecorder) { mediaRecorder.start(); console.log('录音开始'); } else if (mediaRecorder && mediaRecorder.state === 'recording') { mediaRecorder.stop(); console.log('录音停止'); } }); </script> </body> </html>
3. 部署与测试
- 打包应用:安装
electron-builder,在package.json中添加build配置,打包成Windows exe安装包,安装到目标笔记本上。 - 串口测试:确保Arduino通过USB连接笔记本,串口驱动正常,应用能识别到设备。
- 功能验证:按下Arduino按钮,检查
文档/ExperienceRecordings目录下是否生成带时间戳的wav文件。 - 后台运行:重启笔记本后,应用会自动后台启动,用户完全无需操作笔记本。
关键注意事项
- 串口权限:Windows下可能需要管理员权限访问串口,打包时可配置应用请求管理员权限。
- 麦克风权限:第一次运行应用会弹出权限请求,允许后后续启动不会再提示。
- 文件兼容性:用wav格式保存,确保录音文件能在任意设备上播放。
内容的提问来源于stack exchange,提问作者user9685408
相关产品推荐
相关产品推荐

