记录一下本次播放器的写法
记录一下本次播放器的微信小程序原生写法,暂时是实现了,不知道还有没有其他更好的方式,还有个小bug第一次滑动进度条的时候,因为没有获取到时间,跳转位置不是很正确。
结构及样式
<!-- 播放器 -->
<view class="video">
<view class="video-btn" bind:tap="handelVdeioFn">
<view wx:if="{{!isPlay}}" class="iconfont icon-24gf-playCircle"></view>
<view wx:else class="iconfont icon-zanting"></view>
</view>
<view class="video-loading">
<slider bindchange="handelSliderChangeFn" bindchanging="handelSliderStartFn" max="{{sliderMax}}" value="{{sliderCurrent}}" activeColor="#fed615" block-size="12" block-color="#fed615"/>
</view>
<view class="video-time">{{currentTime}}/{{duration}}</view>
</view>
.video-box{
padding: 25rpx;
}
.video-box .video{
display: flex;
justify-content: space-between;
align-items: center;
padding: 0 15rpx;
width: 100%;
height: 75rpx;
border-radius: 60rpx;
background-color: #019d76;
}
.video-btn:active{
opacity: 0.8;
}
.video .iconfont{
font-size: 50rpx;
color: white;
}
.video-loading{
flex:1
}
.video-time{
color: white;
font-size: 25rpx;
}
js
/**
* 页面的初始数据
*/
data: {
isPlay: false, // 是否播放
duration: '00:00',// 总时长
currentTime: '00:00',// 当前播放进度
innerAudioContext: null, // 音频对象
sliderMax: 100,// 读条最大值
sliderCurrent: 0,// 读条当前值
isDraggingSlider: false, // 是否在拖动读条
},
// 开启/关闭音频
handelVdeioFn() {
// 切换开启/关闭按钮
this.setData({ isPlay: !this.data.isPlay })
// 省略this.data
const innerAudioContext = this.data.innerAudioContext
// 判断当前状态
if (this.data.isPlay) {
innerAudioContext.play() // 播放
} else {
innerAudioContext.pause() // 暂停(下次播放会从暂停处开始)
}
},
// 拖动进度条事件开始事件
handelSliderStartFn() {
// 设置当前状态为拖动中
this.setData({ isDraggingSlider: true });
},
// 拖动进度条事件
handelSliderChangeFn(e) {
console.log(e);
// 省略this.data
const innerAudioContext = this.data.innerAudioContext
// 先暂停(不先暂停直接跳转进度监控会失效)
innerAudioContext.pause()
// 根据进度条的值来跳转
innerAudioContext.seek(e.detail.value)
// 延迟400毫秒后播放(不延迟进度监控也会失效,延迟太久播放时间会不正确)
setTimeout(() => {
this.setData({
isDraggingSlider: false, // 设置拖动状态结束
isPlay:true, // 切换为播放图标
})
// 开始播放
innerAudioContext.play()
}, 400)
},
/**
* 生命周期函数--监听页面加载
*/
onLoad(options) {
// 创建音频上下文对象
this.data.innerAudioContext = wx.createInnerAudioContext();
const innerAudioContext = this.data.innerAudioContext
// 音频资源的地址
innerAudioContext.src = 'https://freetyst.nf.migu.cn/public%2Fproduct9th%2Fproduct46%2F2023%2F05%2F0611%2F2018%E5%B9%B408%E6%9C%8824%E6%97%A511%E7%82%B918%E5%88%86%E7%B4%A7%E6%80%A5%E5%86%85%E5%AE%B9%E5%87%86%E5%85%A5SONY192%E9%A6%96%2F%E5%85%A8%E6%9B%B2%E8%AF%95%E5%90%AC%2FMp3_64_22_16%2F6005970UKTA110755.mp3?Key=6bb3abbdf9c64505&Tim=1702875394130&channelid=01&msisdn=b2b46f01b426420eb9acb247e3ec89cb'
// 监听音频播放进度更新事件
innerAudioContext.onTimeUpdate(() => {
// 当进度条在拖动时,不要更新进度
if (!this.data.isDraggingSlider) {
this.setData({
currentTime: getTimes(innerAudioContext.currentTime),
duration: getTimes(innerAudioContext.duration),
sliderCurrent: Math.round(innerAudioContext.currentTime),
sliderMax: Math.round(innerAudioContext.duration),
})
}
})
// 监听音频自然结束事件
innerAudioContext.onEnded(() => {
// 跳转至0 (不这样第二次播放进度就又不监听了)
this.data.innerAudioContext.seek(0)
// 这次延迟是为了显示完最后一秒
setTimeout(()=>{
this.setData({
isPlay: false, // 是否播放
currentTime: '00:00',// 当前播放进度
sliderCurrent: 0,// 读条当前值
})
},500)
})
},
/**
* 生命周期函数--监听页面隐藏
*/
onHide() {
// 页面隐藏时停止音频播放并移除监听器
this.data.innerAudioContext.pause();
this.data.innerAudioContext.offTimeUpdate();
this.data.innerAudioContext.destroy()
},
/**
* 生命周期函数--监听页面卸载
*/
onUnload() {
// 页面卸载时移除监听器,防止内存泄漏
this.data.innerAudioContext.offTimeUpdate();
this.data.innerAudioContext.destroy()
},
})
// getTimes
export const getTimes=(t)=> {
let h = parseInt(t / 60 / 60 % 24)
let m = parseInt(t / 60 % 60)
let s = parseInt(t % 60)
//三元表达式 补零 如果小于10 则在前边进行补零 如果大于10 则不需要补零
h = h < 10 ? '0' + h : h
m = m < 10 ? '0' + m : m
s = s < 10 ? '0' + s : s
// return `${h}:${m}:${s}`
return `${m}:${s}`
}