音乐播放类方法
微信小程序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("播放结束");
}
});