话不多说,做出来的效果图是这样的
从上个页面直接返回了40条语音课程的列表(本地缓存),跳转页面时拿下标利用下标去拿音频对象。这是wxml的代码
<view class="container">
<view class="audio">
<!-- 课程的banner图片 -->
<image class="poster" src="{{ imgUrl + poster }}"></image>
<text class="name">{{media.name}}</text>
<!-- 播放进度条 -->
<view class="progress">
<view class="controls">
<text class="current">{{currentSecond}}</text>
<view class="section section_gap">
<view class="body-view">
<slider disabled="true" min="0" max="{{duration}}" value="{{curSecond}}" activeColor="#F91C55" block-size="18"/>
</view>
</view>
<text class="total">{{media.timeLong}}</text>
</view>
</view>
<!-- 播放控件 -->
<view class="btns">
<image class="previous" src="/images/emotion/previous.png" bindtap="previousFun"></image>
<label class="play">
<image src="{{ playing == true ? '/images/emotion/playing.png' : '/images/emotion/stop.png'}}" bindtap="playClick"></image>
</label>
<image class="next" src="/images/emotion/next.png" bindtap="nextFun"></image>
</view>
</view>
</view>
踩坑:
1.slider里面的 value / min / max 都必须是整数!!!(在innerAudioContext.onTimeUpdate()里面拿到innerAudioContext.currentTime和innerAudioContext.duration都是小数,需Math.ceil()向上取整再赋值)
2.如果把 innerAudioContext.onPlay、onStop、onPause、onTimeUpdate、onEnded、onError监听音频的事件写在onLoad里面只执行一次,在我点击上一首、下一首时再点击播放时,因为监听不到导致curSecond不变,slider的value不变进度条不动(解决方法:封装innerAudioContext部分监听,每次点击调用)
js部分
const app = getApp();
// 创建内部 audio 上下文 InnerAudioContext 对象
var innerAudioContext = wx.createInnerAudioContext()
// 时间格式化
function format(t) {
let time = Math.floor(t / 60) >= 10 ? Math.floor(t / 60) : '0' + Math.floor(t / 60)
t = time + ':' + ((t % 60) / 100).toFixed(2).slice(-2)
return t
}
// 音频对象
function audio(media) {
innerAudioContext = wx.createInnerAudioContext()
innerAudioContext.src = app.globalData.globalUrl + media.url;
innerAudioContext.obeyMuteSwitch = false;
innerAudioContext.autoplay = false;
}
Page({
/**
* 页面的初始数据
*/
data: {
rId: null, //课程的id--添加记录时需要
curIndex: null, //音频当前下标
media: null, //音频信息对象
poster: '', //音频海报
imgUrl: app.globalData.globalUrl, //多媒体公共路径
currentSecond: '00:00', //页面所需当前播放的时间
curSecond: 0, // 当前播放的秒数
duration: null, //音频总时长
playing: false //是否正在播放
},
/**
* 生命周期函数--监听页面加载
*/
onLoad: function (options) {
// 从本地存储拿到文件信息、slider滑块的当前/总时长的换算
this.data.poster = options.url;
this.data.rId = options.rId;
this.data.curIndex = Number(options.index);
this.data.media = wx.getStorageSync('catalogList')[this.data.curIndex];
this.setData({
rId: this.data.rId,
media: this.data.media,
poster: this.data.poster,
curIndex: this.data.curIndex
})
this.watchAudio(); //初始化调用一次
},
// 点击控件中间按键---播放/暂停
playClick: function () {
if (this.data.playing) {
this.data.playing = false;
this.setData({
playing: this.data.playing
})
innerAudioContext.pause();
return;
} else {
this.data.playing = true;
this.setData({
playing: this.data.playing
})
innerAudioContext.play();
return;
}
},
// 上一首
previousFun: function () {
if (this.data.curIndex == 0) {
wx.showToast({
title: '这就是第一课哟~',
icon: "none"
})
return;
} else {
this.data.curIndex -= 1;
this.data.playing = false;
this.data.media = wx.getStorageSync('catalogList')[this.data.curIndex];
this.data.curSecond = 0;
this.data.currentSecond = format(0);
this.setData({
media: this.data.media,
playing: this.data.playing,
curIndex: this.data.curIndex,
curSecond: this.data.curSecond,
currentSecond: this.data.currentSecond
})
//重新调用音频
innerAudioContext.stop();
this.watchAudio();
}
},
// 下一首
nextFun: function () {
if (this.data.curIndex == wx.getStorageSync('catalogList').length - 1) {
wx.showToast({
title: '这就是最后一课哟~',
icon: "none"
})
return;
} else {
this.data.curIndex += 1;
this.data.playing = false;
this.data.media = wx.getStorageSync('catalogList')[this.data.curIndex];
this.data.curSecond = 0;
this.data.currentSecond = format(0);
this.setData({
media: this.data.media,
playing: this.data.playing,
curIndex: this.data.curIndex,
curSecond: this.data.curSecond,
currentSecond: this.data.currentSecond
})
//重新调用音频
innerAudioContext.stop();
this.watchAudio();
}
},
// 监听audio
watchAudio: function () {
let that = this;
audio(that.data.media); //重新赋值音频对象
//开始
innerAudioContext.onPlay(() => {
that.setData({
playing: true
})
})
//停止
innerAudioContext.onStop(() => {
that.setData({
playing: false
})
})
//暂停
innerAudioContext.onPause(() => {
that.setData({
playing: false
})
})
//播放进度
innerAudioContext.onTimeUpdate(() => {
that.data.duration = Math.ceil(innerAudioContext.duration);
that.data.curSecond = Math.ceil(innerAudioContext.currentTime);
that.data.currentSecond = format(innerAudioContext.currentTime);
that.setData({
duration: that.data.duration,
curSecond: that.data.curSecond,
currentSecond: that.data.currentSecond
})
})
//播放结束
innerAudioContext.onEnded(() => {
that.setData({
playing: false
})
that.nextFun(); //调用下一首
})
//播放错误
innerAudioContext.onError((res) => {
wx.showToast({
title: '错误:' + res.errMsg,
icon: "none"
})
})
},
/**
* 生命周期函数--监听页面卸载
*/
onUnload: function () {
// 停止音频播放
innerAudioContext.stop();
this.setData({
playing: false
})
},
}
以上代码仅供参考,入行不到两年,请多指教共同进步哟~