不说别的,先上效果图。表示微信小程序createAudioContext的坑真的是成堆成堆的。
坑一:ios动态更换音频播放地址后 onCanplay 不执行
这个bug至今无解,当然这里也就不累赘onCanplay不加timeout获取不到音频总时长了,事实是就算加了ios也获取不到第二条音频的总时长,但是安卓没问题。直接说解决方案吧。
楼主比较幸运,展示的音频有限,本来也是指望onCanplay动态获取音频总长的,后来没办法直接提前获取到写死代码里了。至于切换音频之后更改右下角显示的总时长,这部分代码写到了onplay里
坑二:onxxx 事件需要取消监听
不取消的后果是什么呢?就是下次点击的时候前几次监听的事件一起触发。
下面是代码:
wxss:
/* inner/pages/sleep/sleep.wxss */
@import "../../../templates/loading/loading.wxss";
page{background: #efeff4;}
.container{width: 750rpx;}
/* fullBg */
.fullBg{padding: 50rpx 30rpx 150rpx;}
.fullBg .eachFull{width: 330rpx;position: relative;margin: 15rpx 0;}
.fullBg .eachFull:nth-child(2n-1){float: left;}
.fullBg .eachFull:nth-child(2n){float: right;}
.sleepBg{display:block;width: 100%;height: 350rpx;border-top-left-radius: 20rpx;border-top-right-radius: 20rpx;position: relative;}
.sleepBg image{width: 100%;height: 100%;display: block;border-top-left-radius: 20rpx;border-top-right-radius: 20rpx;}
.sleepBg .sleepCover{width: 100%;height: 100%;position: absolute;background: rgba(255, 255, 255, .15);border-top-left-radius: 20rpx;border-top-right-radius: 20rpx;top: 0;left: 0;}
.sleepCont{width: 100%;padding: 30rpx 20rpx;border-bottom-left-radius: 20rpx;border-bottom-right-radius: 20rpx;box-sizing: border-box;background: #fff;}
.sleepCont text{display: block;float: left;line-height: 50rpx;width: 220rpx;}
.sleepCont image{display: block;float: right;width: 50rpx;height: 50rpx;}
/* player */
.player{width: 750rpx;position: fixed;bottom: 0;left: 0;height: 120rpx;border-top: 1rpx solid #ccc;text-align: center;box-sizing: border-box;background: #fff;}
.musicBg{width: 750rpx;height: 120rpx;display: block;}
.musicBg image{width: 750rpx;height: 120rpx;display: block;}
.playerBtns{width: 750rpx;height: 120rpx;position: absolute;top: 0;left: 0;padding-top: 10rpx;}
.leftAdjust{margin-left: 20rpx;}
.leftAdjust.lastAdjust{margin-right: 10rpx;margin-left: 10rpx;}
.playerAdjust{width: 80rpx;height: 80rpx;float: left;margin-top: 10rpx;}
.playerHandler{float: left;}
.playerHandler image{width: 100rpx;height: 100rpx;display: block;}
.progressBar{float: right;width: 250rpx;height: 10rpx;border-radius: 10rpx;background: #ccc;margin-top: 40rpx;margin-right: 20rpx;position: relative;}
.progressBarInner{position: absolute;height: 10rpx;background: #d74518;top: 0;left: 0;border-radius: 10rpx;}
.progressTime{float: right;line-height: 80rpx;margin-top: 5rpx;font-size: 24rpx;width: 180rpx;text-align: left;}
wxml:
{{ item.name }}
{{ currentTime }} / {{ totalTime }}
js:
// inner/pages/sleep/sleep.js
const mta = require('../../../utils/mta_analysis.js')
const dataset = require('../../../utils/data.js');
const { backend_url, wx_token } = require('../../../constants.js')
const app = getApp()
Page({
/**
* 页面的初始数据
*/
data: {
songDetail : [
{ name: '晨渐', total: 400.039184},
{ name: '穿过森林', total: 372.68898},
{ name: '水彩的素描', total: 367.725714},
{ name: '春风微风', total: 229.093878 },
{ name: '回想', total: 369.632653 },
{ name: '水纹', total: 358.739592 },
{ name: '薰衣草香时', total: 458.475102 },
{ name: '森之树', total: 413.23102 },
{ name: '小春气息', total: 365.087347 },
{ name: '水蓝的梦', total: 377.443265}
],
audioArr:[],
currentIndex:null,
playing:false,
font:{},
stay_start_time: null,
audioTotal:0,
audioDuration:0,
currentTime:'00:00',
totalTime:'00:00',
playInterval:null,
playRate:0,
loading: {
isLoading: true, //加载
},
},
update(){
const that = this
clearInterval(that.data.playInterval)
that.data.playInterval = setInterval(function(){
let audioDuration = that.data.audioDuration - 1
if (audioDuration > 0){
var min = parseInt(audioDuration / 60);
var sec = parseInt(audioDuration % 60);
if (min.toString().length == 1) {
min = `0${min}`;
}
if (sec.toString().length == 1) {
sec = `0${sec}`;
}
let rate = (that.data.audioTotal - audioDuration) / that.data.audioTotal * 100
that.setData({
audioDuration: audioDuration,
currentTime: `${min}:${sec}`,
playRate: rate
})
}
}.bind(that),1000)
},
onEnd(){
let that = this
clearInterval(that.data.playInterval)
that.setData({
audioDuration: 0,
totalTime: '00:00',
currentTime: '00:00',
playRate: 0,
playing:false
});
},
play(index, start){
const that = this
console.log(start)
if (that.data.currentIndex != null){
that.innerAudio.offPlay()
that.innerAudio.offWaiting()
that.innerAudio.offCanplay()
that.innerAudio.offEnded()
}
that.setData({
audioArr: that.data.audioArr,
currentIndex: index,
playing: true
})
that.innerAudio.play()
that.innerAudio.onPlay(() => {
if (start){
let total = that.data.audioArr[index].total
console.log(total)
var min = parseInt(total / 60);
var sec = parseInt(total % 60);
if (min.toString().length == 1) {
min = `0${min}`;
}
if (sec.toString().length == 1) {
sec = `0${sec}`;
}
console.log(min, sec)
that.setData({
audioTotal: total,
audioDuration: total,
totalTime: `${min}:${sec}`,
currentTime: `${min}:${sec}`
});
}
that.update()
})
that.innerAudio.onWaiting(() => {
console.log('wait')
})
that.innerAudio.onCanplay(() => {
console.log('canplay')
})
that.innerAudio.onEnded(() => {
that.onEnd()
that.play(index, true)
})
},
// 列表播放音乐 -- 方式三
playSong(e){
let that = this
const index = e.currentTarget.dataset.index
that.innerAudio.src = that.data.audioArr[index].url;
if (index != that.data.currentIndex){
that.setData({
audioDuration: 0,
totalTime: '00:00',
currentTime: '00:00',
playRate: 0
});
that.play(index, true)
}
},
// 开关播放音乐 -- 方式三
playNow(){
const that = this
const index = that.data.currentIndex
if (index == null){
that.innerAudio.src = that.data.audioArr[0].url;
that.play(0, true)
}else{
that.play(index, false)
}
},
// 暂停播放音乐 -- 方式三
pauseNow(){
const that = this
// non - active
for (var i = 0; i < that.data.audioArr.length; i++) {
that.data.audioArr[i].play = false;
}
that.setData({
playing: false,
audioArr: that.data.audioArr
})
that.innerAudio.pause()
clearInterval(that.data.playInterval)
},
// 播放上一个 -- 方式三
playFront(){
const that = this
if (that.data.currentIndex == 0){
wx.showToast({
title: '当前为第一首',
icon:"none"
})
}else{
const index = that.data.currentIndex - 1;
that.innerAudio.src = that.data.audioArr[index].url;
that.setData({
audioDuration: 0,
totalTime: '00:00',
currentTime: '00:00',
playRate: 0
});
that.play(index, true)
}
},
// 播放下一个 -- 方式三
playNext(e){
let that = this
if (that.data.currentIndex == that.data.audioArr.length - 1){
wx.showToast({
title: '当前为最后一首',
icon: "none"
})
}else{
const index = that.data.currentIndex + 1;
that.innerAudio.src = that.data.audioArr[index].url;
that.setData({
audioDuration: 0,
totalTime: '00:00',
currentTime: '00:00',
playRate: 0
});
that.play(index, true)
}
},
getData(){
let that = this
wx.request({
url: backend_url + '/music_urls',
method: 'GET',
header:{
'Authorization': wx_token
},
success: (res) => {
console.log(res)
let rawArr = []
let songDetail = that.data.songDetail
that.data.loading.isLoading = false
that.setData({
loading: that.data.loading
})
if(res.data.length > 0){
let len = res.data.length - 1
console.log(len)
for (var i = len; i >= 0; i--){
// console.log(i)
let _i = i
rawArr.push({
url: backend_url + res.data[i],
poster: "../images/sleep" + _i + ".jpg",
name: songDetail[_i].name,
total: songDetail[_i].total
})
if (_i == 0){
that.setData({
audioArr: rawArr
})
}
}
}
}
})
},
/**
* 生命周期函数--监听页面加载
*/
onLoad: function (options) {
let that = this
that.setData({
font: app.globalData.font
})
wx.setInnerAudioOption({
obeyMuteSwitch: false
})
that.innerAudio = wx.createInnerAudioContext()
let now = new Date().getTime()
mta.Event.stat('scan_route', { 'params': app.globalData.userId + '_' + now + '_sleep' })
that.getData()
},
/**
* 生命周期函数--监听页面初次渲染完成
*/
onReady: function () {
},
/**
* 生命周期函数--监听页面显示
*/
onShow: function () {
let that = this
let time = new Date()
that.setData({
stay_start_time: time
})
// mta.Event.stat('sroute', { 'route': '睡眠' })
},
/**
* 生命周期函数--监听页面隐藏
*/
onHide: function () {
let that = this
// 停止播放
// innerAudio.stop()
clearInterval(that.data.playInterval)
that.setData({
playing:false
})
},
/**
* 生命周期函数--监听页面卸载
*/
onUnload: function () {
let that = this
// 停止播放
that.innerAudio.stop()
clearInterval(that.data.playInterval)
let gap_final = dataset.dealSeconds(that.data.stay_start_time)
mta.Event.stat('duration_recovery_sleep', { 'params': app.globalData.userId + '_' + gap_final })
},
/**
* 页面相关事件处理函数--监听用户下拉动作
*/
onPullDownRefresh: function () {
},
/**
* 页面上拉触底事件的处理函数
*/
onReachBottom: function () {
},
/**
* 用户点击右上角分享
*/
onShareAppMessage: function () {
},
})