Skip to content

音乐播放类方法

数组对象格式-如:[{},{},···]

封装Class

ts
// 音频播放
class musicPlayback {
    // 属性
    constructor(options) {
        // 获取全局唯一背景音乐管理器
        this.$audio = uni.getBackgroundAudioManager();
        // 获取当前音频的当前时间
        this.dio = uni.createInnerAudioContext();

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

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

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

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

        // 用于控制音乐自然重复执行多次的问题
        this.$isFinish = false;
    }

    /**
     * 初始化
     * @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;


        // 当前播放音频的索引值
        let index = initParameter.urls.findIndex((item) => item.url == initParameter.current);

        // 测试
        this.dio.src = initParameter.current;

        this.dio.onCanplay(() => {
            // 回调函数
            callback && callback({
                // 暴露播放方法
                play: () => this.play(),
                // 音频总时间
                allTime: this.dio.duration,
                // 当前播放音频的数据
                par: initParameter.urls[index]
            });
        });
    };

    /**
     * 监听事件集合
     * @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>
     * 
     * callback.onStop:音频停止触发 <Function>
     */
    change(callback) {
        // 音频播放事件(参数为回调函数)
        this.$audio.onPlay(() => {
            // 开启 (用于控制音乐自然重复执行多次的问题)节流阀
            this.$isFinish = false;

            // 当前播放音频的索引值
            let index = this.audioArr.findIndex((item) => item.url == this.$src);
            // 暴露当前播放音乐的索引值以及item项信息
            callback.onPlay && callback.onPlay({ index, par: this.audioArr[index] });
        });

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

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

            // 控制自然播放结束的重复执行的问题
            if (this.$isFinish) return;
            // 关闭阀门
            this.$isFinish = true;

            // 判断是否重复执行 [防止onTimeUpdate(监听音频进度)事件重复执行]
            this.currentTimeFlag = 0;
            // 播放结束当前播放时间为0
            this.$time = 0;
            // 清除当前音乐实例参数配置
            this.stop();

            // 播放进度清除为0
            this.$audio.seek(0);
            this.$audio.startTime = 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.url != this.$src);
                    // 生成随机数
                    const rand = this.randomNumber(0, audioItems.length - 1);

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

        // 监听当前音乐播放的进度
        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.onError((err) => {
            callback.onError && callback.onError(err);
        });

        // 音频停止触发(参数为回调函数)
        this.$audio.onStop(() => {
            callback.onStop && callback.onStop();
        })

        // 	背景音频暂停事件(参数为回调函数)
        this.$audio.onPause(() => {
            callback.onPause && callback.onPause();
        })
    }

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

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

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

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

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

    /** 上一首 */
    last() {
        // 播放进度清除为0
        this.$audio.seek(0);
        this.$audio.startTime = 0;

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

    /** 下一首 */
    next() {
        // 播放进度清除为0
        this.$audio.seek(0);
        this.$audio.startTime = 0;

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

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


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

使用方法

ts
// 初始化
audio.init({
    // 当前默认播放音频 <string>
    current: item.url, 
    // 当前音乐集合
    urls: this.musicList //<Array>
    //例如: 歌曲链接集合
    urls: [
        {
            url: "http://xiaolu.3vzhuji.cc/appAudio/大家一起喜羊羊.mp3"
        ...
        },
        {
            url: "http://xiaolu.3vzhuji.cc/appAudio/大家一起喜羊羊.mp3"
        ...
        },
    ]
}, (res) => {
    // 是否立即播放
    res.play();

    // 保存当前视频总时间 (初始化音频总时间)
    this.schedule.allTime = appInst.formatTime(res.allTime);

    // 当前播放item项的数据
    // 保存当前音频数据
    this.$audio$ = res.par;
});

数组格式-如:["","",···]

封装Class

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

        this.dio = uni.createInnerAudioContext();

        // 判断是否重复执行 [防止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.dio.src = initParameter.current;

        this.dio.onCanplay(() => {
            // 回调函数
            callback && callback({
                // 暴露播放方法
                play: () => this.play(),
                allTime: this.dio.duration
            });
        });


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

        // 恢复默播放时间
        this.$time = 0;
    };

    /**
     * 监听事件集合
     * @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>
     *
     * callback.onStop:音频停止触发 <Function>
     */
    change(callback) {
        // 音频播放事件(参数为回调函数)
        this.$audio.onPlay(() => {
            let index = this.audioArr.indexOf(this.$src);
            callback.onPlay && callback.onPlay(index);
        });

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

        // 音频自然播放至结束的事件(参数为回调函数)
        this.$audio.onEnded(() => {
            // 播放结束当前播放时间为0
            this.$time = 0;
            this.stop();
            // 执行回调函数
            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.onError((err) => {
            callback.onError && callback.onError(err);
        });

        // 音频停止触发(参数为回调函数)
        this.$audio.onStop(() => {
            callback.onStop && callback.onStop();
        })
    }

    /** 播放 */
    play() {
        // 背景播放器必须拥有title属性,否则无法播放
        this.$audio.title = '无';
        // 继续播放
        this.$audio.src = this.$src;
        // 继续播放位置继续播放
        this.$audio.startTime = 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.src = "";
        // 停止播放
        this.$audio.stop();
    }

    /**
     * 设置当前音频播放的进度
     * @param {*} num <Number> 单位秒
     */
    step(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;
    }
};

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

使用方法

ts
// 初始化
audio.init({
    // 当前默认播放音频 <string>
    current: item.url, 
    // 当前音乐集合
    urls: this.musicList // <Array>
}, (res) => {
    // 是否立即播放
    res.play();
});

Copyright © 2026 Luke