介绍
最近做一个项目需要播放各种音效,为了方便管理资源写了一个简单的小工具。
实现
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104
| const AudioTools = { audioInstance: {}, audioSrcMap: { indexBgm: '/static/sound/bgm.mp3', },
init() { this.listenAudioEvent(); },
load(audioType, options = {}) { const audioSrc = this.audioSrcMap[audioType]; if (!audioSrc) { console.error(audioType + '音频资源不存在'); return; } let audioManager = new AudioManager(audioSrc, options); this.audioInstance[audioType] = audioManager; return audioManager; },
handleAudioEvent(event) { const audioKey = event.audioType; let audioManager = this.audioInstance[audioKey];
switch (event.eventType) { case "load": if (!audioManager) { this.load(audioKey); } break; case "play": if (!audioManager) { audioManager = this.load(audioKey); if (!audioManager) return; } audioManager.stop(); audioManager.setLoop(event.loop || false); audioManager.setVolume(event.volume || 1); if (event.startTime) { audioManager.seekTo(event.startTime); } audioManager.play(); if (event.stopTime) { setTimeout(() => { audioManager.stop(); }, event.stopTime); } break; case "stop": if (audioManager) { audioManager.stop(); } break; } },
updateAudioVolume(volume) { Object.keys(this.audioInstance).forEach(audioType => { const audioInstance = this.audioInstance[audioType]; audioInstance.setVolume(volume); }); },
listenAudioEvent() { uni.$on("_audio_event", event => { this.handleAudioEvent(event); }); }, }; class AudioManager { constructor(src, options = {}) { this.audioContext = uni.createInnerAudioContext(); this.audioContext.src = src; this.audioContext.autoplay = options.autoplay || true; this.audioContext.onError((res) => { console.log(res); }); }
setVolume(volume) { this.audioContext.volume = volume; }
setLoop(loop) { this.audioContext.loop = loop; }
seekTo(time) { this.audioContext.seek(time); }
play() { this.audioContext.play(); }
pause() { this.audioContext.pause(); }
stop() { this.audioContext.stop(); } }
|
核心方法详解
1. init
初始化方法,用于设置音频事件监听。
2. load(audioType, options)
根据 audioType 加载对应的音频文件,并生成一个 AudioManager
实例。通过传入 options
,我们可以设置自动播放、音量等参数。
3. handleAudioEvent(event)
该方法是 AudioTools 的事件处理核心,根据不同的事件类型(如 load
play
stop
)进行相应的操作。
4. updateAudioVolume(volume)
用于更新所有音频实例的音量设置。
5. listenAudioEvent()
设置监听音频事件,通过 uni.$on
来订阅 _audio_event
事件,实现音频控制与应用逻辑的解耦。
使用方式
在main.js
中引入
1 2
| import AudioTools from '@/utils/AudioTools' AudioTools.init();
|
然后就可以在任何地方~
1 2 3 4 5 6 7 8 9 10 11 12
| uni.$emit("_audio_event", { eventType: "play", audioType: "main_audio", volume: 1, loop: true, startTime: 0 });
uni.$emit("_audio_event", { eventType: "stop", audioType: "main_audio", });
|