一个简单的uniapp音频管理工具

介绍

最近做一个项目需要播放各种音效,为了方便管理资源写了一个简单的小工具。

实现

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",
});