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

78 阅读1分钟

介绍

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

实现

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

初始化方法,用于设置音频事件监听。

  1. load(audioType, options)

根据 audioType 加载对应的音频文件,并生成一个 AudioManager 实例。通过传入 options,我们可以设置自动播放、音量等参数。

  1. handleAudioEvent(event)

该方法是 AudioTools 的事件处理核心,根据不同的事件类型(如 load play stop)进行相应的操作。

  1. updateAudioVolume(volume)

用于更新所有音频实例的音量设置。

  1. listenAudioEvent()

设置监听音频事件,通过 uni.$on 来订阅 _audio_event 事件,实现音频控制与应用逻辑的解耦。

使用方式

main.js中引入

import AudioTools from '@/utils/AudioTools'
AudioTools.init();

然后就可以在任何地方~

uni.$emit("_audio_event", {
  eventType: "play",
  audioType: "main_audio",
  volume: 1,
  loop: true,
  startTime: 0
});
//或
uni.$emit("_audio_event", {
  eventType: "stop",
  audioType: "main_audio",
});