Skip to content

音乐播放类方法

微信小程序Audio Class封装 (该方法退出小程序后无法使用)

ts
/** 局部播放 **/

// 音乐播放器
class AudioPlay {
    constructor(option) {
        // 创建音频上下文对象
        this.audio = wx.createInnerAudioContext();
        // 判断是否重复执行
        this.currentTimeFlag = 0;
    }

    /**
     * 初始化
     * @param {*} url 音频路径
     * @param {*} callback 回调函数,(包含自动播放)
     */
    init(url, callback) {
        // 音频路径
        this.audio.src = url;

        // 回调函数
        callback && callback({
            // 是否立即播放方法
            play: () => this.play(),
        });
    }

    /**
     * 监听事件集合
     * @param {*} callback 为对象包含多个函数 (每个函数均为实时监听)
     * 
     * callback.onPlay:音频播放事件
     * 
     * callback.onPause: 音频暂停事件
     * 
     * callback.onEnded:音频自然播放至结束的事件
     * 
     * callback.onTimeUpdate:监听当前音乐播放的进度
     * 
     * callback.onSeeked:监听音频位置发生改变
     * 
     * callback.onError:音频播放错误事件
     */
    change(callback) {
        // 音频播放事件(参数为回调函数)
        this.audio.onPlay(() => {
            callback.onPlay && callback.onPlay();
        });

        // 音频暂停事件
        this.audio.onPause(() => {
            callback.onPause && callback.onPause();
        });

        // 音频自然播放至结束的事件(参数为回调函数)
        this.audio.onEnded(() => {
            callback.onEnded && callback.onEnded();
        });

        // 监听当前音乐播放的进度
        this.audio.onTimeUpdate(() => {
            // 总时间
            let duration = parseInt(this.audio.duration);
            // 当前播放进度的时间
            let currentTime = parseInt(this.audio.currentTime);
            // 判断是否重复触发
            if (this.currentTimeFlag == currentTime) return;
            // 记录当前播放的时间 (防止重复触发)
            this.currentTimeFlag = currentTime;

            // 回调函数,该播放器播放后返回总播放进度以及当前播放进度
            callback.onTimeUpdate && callback.onTimeUpdate({
                // 总时间
                allTime: duration,
                // 当前播放的时间
                currentTime: currentTime,
                // 百分之一为多少秒 (计算音频的百分比)
                $audio: duration / 100,
                // 进度条的进度比例
                $progress: (currentTime / duration) * 100,
            });
        });

        // 监听音频位置发生改变
        this.audio.onSeeked(() => {
            // 解决onTimeUpdate不生效问题
            this.audio.duration;
            // 执行onSeeked监听回调
            callback.onSeeked && callback.onSeeked();
        });

        // 音频播放错误事件(参数为回调函数)
        this.audio.onError(() => {
            callback.onError && callback.onError();
        });
    }

    // 播放
    play() {
        this.audio.duration
        // 解决onTimeUpdate不生效问题
        setTimeout(() => { this.audio.duration }, 800);
        // 音频播放
        this.audio.play();
    }

    // 设置当前音频播放的进度
    setSteep(num) {
        this.audio.seek(num);
    }

    // 暂停(暂停后的音频再播放会从暂停处开始播放)
    pause() {
        this.audio.pause();
    }

    // 停止(停止后的音频再播放会从头开始播放)
    stop() {
        this.audio.stop();
    }

};

微信小程序musicPlayback Class封装 (后台仍可继续播放)

ts
// 音频播放
class musicPlayback {
    // 属性
    constructor(options) {
        // 获取全局唯一背景音乐管理器
        this.$audio = wx.getBackgroundAudioManager();

        // 判断是否重复执行 [防止onTimeUpdate(监听音频进度)事件重复执行]
        this.currentTimeFlag = 0;

        // 当前播放音频的路径
        this.$src = "";

        // 当前音频播放时间 (用于暂停该实例被销毁,无法继续播放的问题) (解决小程序暂停后无法继续播放问题)
        this.$time = 0;

        // 背景音乐集合 (用于音频播放结束 后 [循环,逆时针,顺时针]播放条件)
        this.audioArr = [];
    }

    /**
     * 初始化
     * @param {*} initParameter 初始化配置 <Object>
     *          --- current:当前播放音乐的路径
     *          --- [urls]:音乐集合 (播放结束后从中抽取 根据自然播放结束事件执行的回调进行选择) [可选 (如果只有一首音频的情况下可不传)]
     * 
     * @param {*} callback 回调函数,(包含自动播放) <Function>
     */
    init(initParameter, callback) {
        // 抛出错误提示
        if (!initParameter.current) return console.log(new Error("未指向当前播放的路径,应初始化时指向初始化路径"));

        // 保存当前视频的路径
        this.$src = initParameter.current;

        // 保存当前音乐集合
        this.audioArr = initParameter.urls ? initParameter.urls : [initParameter.current];

        // 恢复默播放时间
        this.$time = 0;
        // 回调函数
        callback && callback({
            // 暴露播放方法
            play: () => this.play(),
        });
    };

    /**
     * 监听事件集合
     * @param {*} callback 为对象包含多个函数  <Object>(每个函数均为实时监听)
     * 
     * callback.onPlay:音频播放事件 <Function>
     * 
     * callback.onPause: 音频暂停事件 <Function>
     * 
     * callback.onEnded:音频自然播放至结束的事件 <Function>
     *                  函数回调函数返回 4 个方法  示例:(res) => { res.loop() }
     *                      1. loop()  循环播放
     *                      2. last()  上一首(逆时针) 播放
     *                      3. next()  下一首(顺时针) 播放
     *                      4. random()  随机播放
     * 
     * callback.onTimeUpdate:监听当前音乐播放的进度 <Function>
     *                  函数回调函数返回 当前播放进度 
     *                      { 
     *                          allTime:<Number>         音频总时间
     *                          currentTime:<Number>     当前播放音频时间
     *                          $step:<Number>           音频步长 (即进度条的1% 为该音频的多少秒)
     *                          $progress:<Number>       进度条进度
     *                      }
     * 
     * callback.onSeeked:监听音频位置发生改变 <Function>
     * 
     * callback.onError:音频播放错误事件 <Function>
     */
    change(callback) {
        // 音频播放事件(参数为回调函数)
        this.$audio.onPlay(() => {
            callback.onPlay && callback.onPlay();
        });

        // 音频暂停事件
        this.$audio.onPause(() => {
            callback.onPause && callback.onPause();
        });

        // 音频自然播放至结束的事件(参数为回调函数)
        this.$audio.onEnded(() => {
            // 播放结束当前播放时间为0
            this.$time = 0;
            // 执行回调函数
            callback.onEnded && callback.onEnded({
                // 循环播放
                loop: () => {
                    this.play();
                },
                //(逆时针播放)
                last: () => this.last(),
                //( 顺时针播放)
                next: () => this.next(),
                // 随机播放
                random: () => {
                    // 判断该音频集合是不是为一个链接
                    if (this.audioArr.length <= 1) return this.play();
                    // 赛选出除当前播放音频的链接路径集合 (在其中随机选取一个进行播放)
                    let audioItems = this.audioArr.filter(item => item != this.$src);
                    // 生成随机数
                    const rand = this.randomNumber(0, audioItems.length - 1);

                    // 保存当前音频播放的路径
                    this.$src = audioItems[rand];
                    // 背景播放器必须拥有title属性,否则无法播放
                    this.$audio.title = '无';
                    // 选取随机播放音频路径
                    this.$audio.src = audioItems[rand];
                }
            });
        });

        // 监听当前音乐播放的进度
        this.$audio.onTimeUpdate(() => {
            // 保存当前事件
            if (this.$audio.currentTime) this.$time = this.$audio.currentTime;

            // 总时间
            let duration = parseInt(this.$audio.duration);
            // 当前播放进度的时间
            let currentTime = parseInt(this.$audio.currentTime);
            // 判断是否重复触发
            if (this.currentTimeFlag == currentTime) return;
            // 记录当前播放的时间 (防止重复触发)
            this.currentTimeFlag = currentTime;

            // 回调函数,该播放器播放后返回总播放进度以及当前播放进度
            callback.onTimeUpdate && callback.onTimeUpdate({
                // 总时间
                allTime: duration,
                // 当前播放的时间
                currentTime: currentTime,
                // 百分之一为多少秒 (计算音频的百分比)
                $step: duration / 100,
                // 进度条的进度比例
                $progress: (currentTime / duration) * 100 ? (currentTime / duration) * 100 : 0,
            });
        });

        // 监听音频位置发生改变
        this.$audio.onSeeked(() => {
            // 解决onTimeUpdate不生效问题
            this.$audio.duration;
            // 执行onSeeked监听回调
            callback.onSeeked && callback.onSeeked();
        });

        // 音频播放错误事件(参数为回调函数)
        this.$audio.onError(() => {
            callback.onError && callback.onError();
        });
    }

    /** 播放 */
    play() {
        // 背景播放器必须拥有title属性,否则无法播放
        this.$audio.title = '无';
        // 继续播放 
        this.$audio.src = this.$src;
        // 继续播放位置继续播放
        this.setSteep(this.$time);
    }

    /**
     * 切换
     * @param {*} url 切换的音频地址 <String>
     * @param {*} [urls] 音频集合 <Array>
     */
    switch(url, urls) {
        // 背景播放器必须拥有title属性,否则无法播放
        this.$audio.title = '无';
        // 保存当前播放音乐的路径
        this.$src = url;
        // 继续播放 
        this.$audio.src = url;

        // 切换音频可替换需要播放的音频集合 (有可进行替换)
        if (urls) this.audioArr = urls;
    }

    /** 停止播放 */
    stop() {
        // 停止播放
        this.$audio.stop();
    }

    /**
     * 设置当前音频播放的进度
     * @param {*} num <Number> 单位秒
     */
    setSteep(num) {
        this.$audio.seek(num);
    }

    /** 上一首 */
    last() {
        // 复原当前播放时间
        this.$time = 0;
        // 判断该音频集合是不是为一个链接
        if (this.audioArr.length <= 1) return this.play();
        // 查找当前播放音频的索引
        let index = this.audioArr.indexOf(this.$src);
        // 索引递减(为上一音频)
        index--;
        // 判断当前索引是否超过最小索引值
        if (index < 0) index = this.audioArr.length - 1;
        // 保存当前音频播放的路径
        this.$src = this.audioArr[index];
        // 背景播放器必须拥有title属性,否则无法播放
        this.$audio.title = '无';
        // 修改音频路径进行播放
        this.$audio.src = this.audioArr[index];
    }

    /** 下一首 */
    next() {
        // 复原当前播放时间
        this.$time = 0;
        // 判断该音频集合是不是为一个链接
        if (this.audioArr.length <= 1) return this.play();
        // 查找当前播放音频的索引
        let index = this.audioArr.indexOf(this.$src);
        // 索引递增 (为下一音频)
        index++;
        // 判断当前索引是否超过最大索引值
        if (this.audioArr.length - 1 < index) index = 0;
        // 保存当前音频播放的路径
        this.$src = this.audioArr[index];
        // 背景播放器必须拥有title属性,否则无法播放
        this.$audio.title = '无';
        // 修改音频路径进行播放
        this.$audio.src = this.audioArr[index];
    }

    /**
    * @randomNumber 动态生成随机数
    * @param {*} min 最小值 (包含) <Number>
    * @param {*} max 最大值(包含) <Number>
    * @returns retuen <数字 Number>
    */
    randomNumber(min, max) {
        return Math.floor(Math.random() * (max - min + 1)) + min;
    }
};

使用方法

ts
// 实例化
const audio = new musicPlayback();

audio.init({
    // 当前默认播放音频
    current: "https://wechat800.oss-cn-shanghai.aliyuncs.com/huilaijiuhao/material/made-in-xiaolu.mp3",
    // 后续播放音频集合
    urls: []
}, (res) => {
    /** 回调函数 */
    // 是否默认播放
    res.play();
});

// 监听事件
audio.change({
    onPlay() {
        console.log('开始播放');

    },
    onTimeUpdate(res) {
        // console.log(res);
    },
    onEnded(res) {
        res.next();
        console.log("播放结束");
    }
});

Copyright © 2026 Luke