音乐播放类方法
数组对象格式-如:[{},{},···]
封装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();
});