【开源】基于 Electron+Vue3 的白噪音混音器,支持多轨道同时播放!
白噪音桌面应用 - 开源项目开发教程与使用指南
一个基于 Vue 3 + Electron 的专注放松桌面音频混音应用
版本:v1.0.3 | 开源协议:MIT | 作者:古月开发
---
目录
1. [项目概述](一项目概述)
2. [技术栈介绍](二技术栈介绍)
3. [项目结构解析](三项目结构解析)
4. [开发环境搭建](四开发环境搭建)
5. [核心功能实现详解](五核心功能实现详解)
6. [二次开发指南](六二次开发指南)
7. [使用教程](七使用教程)
8. [打包与发布](八打包与发布)
9. [常见问题](九常见问题)
---
一、项目概述
1.1 项目简介
白噪音是一款专注于帮助用户放松、专注和睡眠的桌面音频混音应用。它提供了丰富的环境音效(自然声音、轻音乐、白噪音、ASMR等),支持多轨道混音、场景预设、定时关闭等功能。
1.2 主要功能
| 功能模块 | 描述 |
|---------|------|
| 多轨道混音 | 同时播放多个音效,独立调节每个音轨音量 |
| 场景预设 | 一键切换预设环境组合(深度睡眠、雨天专注、森林冥想等) |
| 收藏管理 | 收藏喜爱的声音,快速访问 |
| 定时关闭 | 支持自定义时间自动停止播放 |
| 主题切换 | 浅色/深色模式切换 |
| 数据持久化 | 设置、自定义场景、收藏数据本地保存 |
---
二、技术栈介绍
2.1 核心技术
| 技术 | 版本 | 用途 |
|------|------|------|
| Vue 3 | ^3.5.33 | 前端框架,Composition API |
| Electron | ^29.1.0 | 桌面应用框架 |
| Vite | ^5.4.21 | 构建工具 |
| Pinia | ^2.3.1 | 状态管理 |
| Tailwind CSS | ^3.4.19 | 原子化CSS框架 |
2.2 开发工具
| 工具 | 用途 |
|------|------|
| electron-builder | 应用打包 |
| concurrently | 并行运行开发服务器 |
| wait-on | 等待开发服务器就绪 |
2.3 技术选型理由
1. Vue 3 + Composition API
- 更好的TypeScript支持
- 逻辑复用更灵活
- 性能优化
2. Electron
- 跨平台(Windows/macOS/Linux)
- 访问本地文件系统
- 成熟的桌面应用生态
3. Pinia
- Vue官方推荐
- 更简洁的API
- 完整的TypeScript支持
4. Tailwind CSS
- 开发效率高
- 文件体积小
- 易于定制主题
---
三、项目结构解析
3.1 目录结构
```
白噪音v1.0.3源码/
├── electron/ Electron 主进程
│ ├── main.js 主进程入口
│ └── preload.js 预加载脚本(安全通信)
├── public/ 静态资源
│ ├── audio/ 音频文件(15个音效)
│ │ ├── nature_.mp3 自然声音
│ │ ├── music_.mp3 轻音乐
│ │ ├── white_.mp3 白噪音
│ │ └── asmr_.mp3 ASMR音效
│ ├── bg-dark.svg 深色背景
│ ├── bg-light.svg 浅色背景
│ ├── icon.ico 应用图标
│ └── icon.png
├── src/
│ ├── components/ Vue 组件
│ │ ├── Home.vue 首页(声音播放)
│ │ ├── Scenes.vue 场景页面
│ │ ├── Favorites.vue 收藏页面
│ │ └── Settings.vue 设置页面
│ ├── stores/ Pinia 状态管理
│ │ └── app.js 全局状态
│ ├── assets/ 资源文件
│ ├── App.vue 根组件
│ ├── main.js 渲染进程入口
│ └── style.css 全局样式
├── index.html HTML模板
├── package.json 项目配置
├── vite.config.js Vite配置
├── tailwind.config.js Tailwind配置
└── postcss.config.js PostCSS配置
```
3.2 核心文件说明
package.json 关键配置
```json
{
"name": "white-noise",
"version": "1.0.3",
"main": "electron/main.js",
"scripts": {
"dev": "vite", // 开发模式
"build": "vite build", // 构建生产版本
"electron:dev": "concurrently \"vite\" \"wait-on http://localhost:5173 && electron .\"", // 开发模式运行Electron
"electron:build": "vite build && electron-builder", // 打包应用
"electron:build:win": "vite build && electron-builder --win" // 仅打包Windows
},
"build": {
"appId": "com.whitenoise.app",
"productName": "白噪音",
"asarUnpack": ["dist/audio//"], // 不解压音频文件
"win": {
"target": [{ "target": "nsis", "arch": ["x64"] }]
}
}
}
```
Electron 主进程 (electron/main.js)
```javascript
// 窗口配置
const mainWindow = new BrowserWindow({
width: 520,
height: 760,
minWidth: 420,
minHeight: 600,
webPreferences: {
nodeIntegration: false, // 安全:禁用Node集成
contextIsolation: true, // 安全:启用上下文隔离
preload: path.join(__dirname, 'preload.js') // 预加载脚本
}
})
// IPC通信:处理数据持久化
ipcMain.handle('get-settings', async () ={ ... })
ipcMain.handle('save-settings', async (event, settings) ={ ... })
ipcMain.handle('get-audio-path', async (event, fileName) ={ ... })
```
预加载脚本 (electron/preload.js)
```javascript
// 安全地暴露API给渲染进程
contextBridge.exposeInMainWorld('electronAPI', {
getSettings: () =ipcRenderer.invoke('get-settings'),
saveSettings: (settings) =ipcRenderer.invoke('save-settings', settings),
getAudioPath: (fileName) =ipcRenderer.invoke('get-audio-path', fileName)
})
```
---
四、开发环境搭建
4.1 环境要求
- Node.js: >= 18.0.0
- npm: >= 9.0.0
- 操作系统: Windows 10/11 / macOS / Linux
4.2 安装步骤
步骤1:克隆项目
```bash
git clone https://github.com/yourusername/white-noise.git
cd white-noise
```
步骤2:安装依赖
```bash
npm install
```
步骤3:开发模式运行
```bash
方式1:仅运行Web版本
npm run dev
方式2:运行Electron桌面应用(推荐)
npm run electron:dev
```
步骤4:构建生产版本
```bash
构建Web版本
npm run build
打包桌面应用(全平台)
npm run electron:build
仅打包Windows版本
npm run electron:build:win
```
4.3 开发工具推荐
| 工具 | 用途 |
|------|------|
| VS Code | 代码编辑器 |
| Vue DevTools | Vue调试 |
| Electron DevTools | Electron调试(已内置) |
---
五、核心功能实现详解
5.1 多轨道音频播放系统
实现原理
使用 `Map` 数据结构管理多个 `Audio` 对象,实现多轨道同时播放:
```javascript
// src/components/Home.vue
const audioTracks = ref(new Map()) // file -{ audio, volume, playing }
// 播放/暂停切换
async function toggleSound(sound) {
const existing = audioTracks.value.get(sound.file)
if (existing && existing.playing) {
// 暂停
existing.audio.pause()
existing.playing = false
} else if (existing && !existing.playing) {
// 恢复播放
await existing.audio.play()
existing.playing = true
} else {
// 新建轨道
const audioSrc = await getAudioSrc(sound.file)
const audio = new Audio(audioSrc)
audio.loop = true // 循环播放
audio.volume = (masterVolume.value / 100) 0.5
await audio.play()
audioTracks.value.set(sound.file, {
audio,
volume: 0.5,
playing: true,
name: sound.name,
emoji: sound.emoji
})
}
}
```
音量控制逻辑
```javascript
// 总音量控制 - 影响所有轨道
function setMasterVolume() {
for (const track of audioTracks.value.values()) {
track.audio.volume = track.volume (masterVolume.value / 100)
}
}
// 单轨道音量控制
function setTrackVolume(file, value) {
const track = audioTracks.value.get(file)
if (track) {
const vol = value / 100
track.volume = vol
track.audio.volume = vol (masterVolume.value / 100)
}
}
```
5.2 场景预设系统
场景数据结构
```javascript
// src/stores/app.js
const scenes = ref([
{
id: 'deep-sleep',
name: '深度睡眠',
emoji: '🌙',
description: '风扇声 + 雨声,助您安然入睡',
tracks: [
{ file: 'white_fan.mp3', volume: 40 },
{ file: 'nature_rain_forest.mp3', volume: 50 }
]
},
// ... 更多场景
])
```
场景播放实现
```javascript
// 播放场景 - 自动加载多个音轨
async function playScene(scene) {
// 停止当前所有
stopAll()
// 播放场景中的轨道
for (const trackInfo of scene.tracks) {
const sound = soundDefinitions.find(s =s.file === trackInfo.file)
if (!sound) continue
const audioSrc = await getAudioSrc(trackInfo.file)
const audio = new Audio(audioSrc)
audio.loop = true
const vol = trackInfo.volume / 100
audio.volume = vol (masterVolume.value / 100)
await audio.play()
audioTracks.value.set(trackInfo.file, {
audio,
volume: vol,
playing: true,
name: sound.name,
emoji: sound.emoji
})
}
}
```
5.3 定时关闭功能
```javascript
const autoStopMinutes = ref(0)
const remainingTime = ref(0)
let autoStopTimer = null
let countdownInterval = null
function setAutoStop(minutes) {
autoStopMinutes.value = minutes
clearAutoStop()
if (minutes 0) {
remainingTime.value = minutes 60
// 每秒更新倒计时显示
countdownInterval = setInterval(() ={
remainingTime.value--
if (remainingTime.value <= 0) {
stopAll()
showToast('定时关闭,已停止播放')
clearAutoStop()
}
}, 1000)
// 设置定时器
autoStopTimer = setTimeout(() ={
// 由 countdownInterval 处理停止逻辑
}, minutes 60 1000)
}
}
```
5.4 数据持久化(Electron IPC)
主进程处理
```javascript
// electron/main.js
const userDataPath = app.getPath('userData') // 获取用户数据目录
const settingsFile = path.join(userDataPath, 'settings.json')
// 读取设置
ipcMain.handle('get-settings', async () ={
return readFile(settingsFile) || {
theme: 'light',
masterVolume: 80,
autoStopMinutes: 0
}
})
// 保存设置
ipcMain.handle('save-settings', async (event, settings) ={
return writeFile(settingsFile, settings)
})
```
渲染进程调用
```javascript
// src/stores/app.js
async function loadSettings() {
if (window.electronAPI) {
const savedSettings = await window.electronAPI.getSettings()
settings.value = { ...settings.value, ...savedSettings }
theme.value = savedSettings.theme || 'light'
}
}
```
5.5 主题切换系统
Tailwind 配置
```javascript
// tailwind.config.js
darkMode: 'class', // 使用class模式
theme: {
extend: {
colors: {
light: { bg: 'f5f7fa', card: 'ffffff', text: '2d3748' },
dark: { bg: '1a1a2e', card: '16213e', text: 'e2e8f0' }
}
}
}
```
主题切换实现
```javascript
// App.vue
<div :class="[`theme-${store.theme}`]">
// 设置主题
function setTheme(theme) {
store.setTheme(theme)
const themes = ['light', 'dark']
themes.forEach(t ={
document.documentElement.classList.remove(`theme-${t}`)
})
document.documentElement.classList.add(`theme-${theme}`)
}
```
---
六、二次开发指南
6.1 添加新音效
步骤1:准备音频文件
将MP3文件放入 `public/audio/` 目录,命名规范:
- 自然声音:`nature_xxx.mp3`
- 轻音乐:`music_xxx.mp3`
- 白噪音:`white_xxx.mp3`
- ASMR:`asmr_xxx.mp3`
步骤2:注册音效
编辑 `src/components/Home.vue`:
```javascript
const soundDefinitions = [
// ... 原有音效
{
name: '新音效名称',
emoji: '🎵',
category: 'nature', // nature/music/white/asmr
description: '音效描述',
file: 'nature_new_sound.mp3'
},
]
```
步骤3:在场景中使用
```javascript
// src/stores/app.js
{
id: 'my-scene',
name: '我的场景',
emoji: '',
description: '自定义场景描述',
tracks: [
{ file: 'nature_new_sound.mp3', volume: 50 }
]
}
```
6.2 添加新主题
步骤1:配置颜色
编辑 `tailwind.config.js`:
```javascript
colors: {
mytheme: {
bg: 'your-bg-color',
card: 'your-card-color',
text: 'your-text-color'
}
}
```
步骤2:添加样式
编辑 `src/style.css`:
```css
.theme-mytheme {
@apply bg-theme-mytheme-bg text-theme-mytheme-text;
}
```
步骤3:添加到设置
编辑 `src/components/Settings.vue`,添加主题切换按钮。
6.3 自定义场景功能扩展
当前已支持用户创建自定义场景,数据存储在用户目录。如需扩展功能:
```javascript
// src/stores/app.js
async function saveCustomScene(scene) {
if (window.electronAPI) {
await window.electronAPI.saveCustomScene(scene)
await loadCustomScenes()
}
}
```
6.4 添加新页面
步骤1:创建组件
创建 `src/components/NewPage.vue`
步骤2:注册路由
编辑 `src/App.vue`:
```javascript
import NewPage from './components/NewPage.vue'
// 在导航中添加按钮
<button @click="goNewPage">新页面</button>
// 在页面内容中添加
<NewPage v-else-if="store.currentView === 'newpage'" />
```
步骤3:添加状态
编辑 `src/stores/app.js`:
```javascript
function setView(view) {
currentView.value = view // 支持 'newpage'
}
```
---
七、使用教程
7.1 安装应用
Windows
1. 下载 `白噪音_Setup.exe`
2. 双击运行安装程序
3. 按向导完成安装
4. 桌面会创建快捷方式
开发模式运行
```bash
npm install
npm run electron:dev
```
7.2 功能使用
播放声音
1. 打开应用,进入首页
2. 点击分类标签筛选声音类型
3. 点击声音卡片上的 ▶️ 按钮播放
4. 播放后会出现音量滑块,可调节音量
使用场景预设
1. 点击顶部导航的 🎭 场景按钮
2. 选择推荐场景(深度睡眠、雨天专注等)
3. 点击播放按钮,自动加载多个音效
4. 或点击 + 新建场景,创建自己的组合
收藏声音
1. 在首页播放喜欢的声音
2. (功能扩展:可在播放时添加到收藏)
3. 点击顶部 ⭐ 收藏按钮查看收藏列表
设置定时关闭
1. 点击首页的 ⏱️ 按钮
2. 选择预设时间(15/30/45/60/90/120分钟)
3. 或输入自定义分钟数
4. 倒计时结束后自动停止播放
切换主题
1. 点击顶部 ⚙️ 设置按钮
2. 选择浅色或深色主题
3. 设置默认音量和定时时间
7.3 快捷键
| 快捷键 | 功能 |
|--------|------|
| `Space` | 播放/暂停 |
| `Esc` | 关闭弹窗 |
---
八、打包与发布
8.1 打包配置
`package.json` 中的 `build` 配置:
```json
{
"build": {
"appId": "com.whitenoise.app",
"productName": "白噪音",
"directories": { "output": "build" },
"files": ["dist//", "electron//", "public//"],
"asar": true,
"asarUnpack": ["dist/audio//"], // 音频文件不解压
"icon": "public/icon.ico",
"win": {
"target": [{ "target": "nsis", "arch": ["x64"] }]
},
"nsis": {
"oneClick": false, // 非一键安装
"allowToChangeInstallationDirectory": true, // 允许选择安装目录
"createDesktopShortcut": true, // 创建桌面快捷方式
"language": "2052" // 中文语言包
}
}
}
```
8.2 打包命令
```bash
全平台打包
npm run electron:build
仅Windows
npm run electron:build:win
仅macOS
npx electron-builder --mac
仅Linux
npx electron-builder --linux
```
8.3 输出文件
打包完成后,`build` 目录下会生成:
```
build/
├── 白噪音_Setup.exe Windows安装程序
├── 白噪音-1.0.3.exe 便携版
└── win-unpacked/ 未打包文件
```
---
九、常见问题
Q1: 音频无法播放?
可能原因:
- 音频文件路径错误
- 打包后音频文件未正确解压
解决方案:
```javascript
// 检查音频路径
const audioPath = await window.electronAPI.getAudioPath(fileName)
console.log('音频路径:', audioPath)
```
Q2: 开发模式正常,打包后白屏?
可能原因:
- 路由模式问题
- 资源路径错误
解决方案:
- 确保 `vite.config.js` 中 `base: './'`
- 检查 `electron/main.js` 中加载路径
Q3: 如何修改应用图标?
替换 `public/icon.ico` 和 `public/icon.png` 文件,建议使用 256x256 像素的PNG和ICO格式。
Q4: 数据存储在哪里?
```
Windows: %APPDATA%/白噪音/
macOS: ~/Library/Application Support/白噪音/
Linux: ~/.config/白噪音/
```
存储文件:
- `settings.json` - 应用设置
- `customScenes.json` - 自定义场景
- `favoriteSounds.json` - 收藏的声音
Q5: 如何添加更多音效?
参考 [6.1 添加新音效](61-添加新音效) 章节。
---
十、开源协议
本项目采用 MIT 协议 开源,您可以:
- 自由使用和修改
- 用于商业用途
- 分发和发布
- 需保留版权声明
---
十一、贡献指南
欢迎提交 Issue 和 Pull Request!
1. Fork 本仓库
2. 创建特性分支 (`git checkout -b feature/AmazingFeature`)
3. 提交更改 (`git commit -m 'Add some AmazingFeature'`)
4. 推送到分支 (`git push origin feature/AmazingFeature`)
5. 创建 Pull Request
---
十二、联系方式
- 作者:古月开发
- 项目地址:https://github.com/guyue581/white-noise
---
让声音治愈你的每一刻
如果这个项目对你有帮助,请给个 Star ⭐ 支持一下!
更多推荐
所有评论(0)