最近在学习微信小程序的UI组件,audio音频方面想做一个类似网易云的播放效果。基础需求:
1、能控制音频开始、暂停、停止
2、音乐播放,封面旋转,音乐暂停封面停止旋转
3、能显示歌曲的播放时间和进度条
4、能通过进度条控制音乐的播放进度
先上一张效果图
直接放代码,代码里面写了比较多的注释。
wxml:
<view class='item'> <text>音乐播放器</text> <image class='audio_post{{music_on?" music_on":""}}' style="animation-play-state:{{music_playing?'running':'paused'}}" src='http://y.gtimg.cn/music/photo_new/T002R300x300M000003rsKF44GyaSk.jpg?max_age=2592000' ></image> <view class='audio_progress'> <slider block-size='14' bindchange='audioChange' bindchanging='audioChanging' value='{{sliderValue}}'></slider> <view>{{musicTime}}</view> </view> <view class='audio_control'> <button type='primary' bindtap='playMusic'>播放</button> <button type='primary' bindtap='pauseMusic'>暂停</button> <button type='primary' bindtap='stopMusic'>停止</button> </view> </view>
wxss:
.item { width: 100%; padding-bottom: 30rpx; display: flex; flex-direction: column; justify-content: center; } .item text { font-size: medium; } .audio_progress{ width: 100%; display: flex; flex-direction: row; justify-content: space-around; } .audio_progress slider{ width: 80%; } .audio_progress view{ padding: 18rpx; } .audio_post{ width: 300rpx; height: 300rpx; margin: 50rpx auto; border-radius: 50%; } /* 旋转的样式 */ .music_on{ animation: audio-rotate 8s linear infinite; } .audio_control{ display: flex; flex-direction: row; justify-content:space-around; } .audio_control button{ width:200rpx; height:80rpx; line-height:80rpx; } /* 旋转动画 */ @keyframes audio-rotate { 0% { transform: rotateZ(0deg); } 100% { transform: rotateZ(360deg); } }
js
//InnerAudioContext实例 var audioCxt; //动画 var audioAnimation; audioCxt = wx.createInnerAudioContext(); audioCxt.src = 'http://ws.stream.qqmusic.qq.com/M500001VfvsJ21xFqb.mp3?guid=ffffffff82def4af4b12b3cd9337d5e7&uin=346897220&vkey=6292F51E1E384E06DCBDC9AB7C49FD713D632D313AC4858BACB8DDD29067D3C601481D36E62053BF8DFEAF74C0A5CCFADD6471160CAF3E6A&fromtag=46'; Page({ /** * 页面的初始数据 */ data: { audioAnimation : null, //音乐是不是开始 music_on : true, //音乐是不是在播放 music_playing :false, //显示的时间 musicTime : '00:00', sliderValue : 0 }, /** * 生命周期函数--监听页面初次渲染完成 */ onReady: function () { //音乐播放结束触发 audioCxt.onEnded((res) =>{ //修改属性。去除css状态 this.data.music_on = false; this.setData({ music_on: this.data.music_on }) //重新播放 audioCxt.seek(0); this.setData({ musicTime: '00:00', sliderValue: 0 }) }), //在播放状态,绑定播放进度更新事件。然后控制进度条和时间显示 audioCxt.onPlay((res) =>{ audioCxt.onTimeUpdate(this.timeUpdate) }) }, //播放按钮事件 playMusic : function(){ this.data.music_on = true; this.data.music_playing = true; audioCxt.play(); //图片添加css样式,旋转样式 this.setData({ music_on: this.data.music_on, music_playing: this.data.music_playing }) }, //暂停按钮事件 pauseMusic : function(){ this.data.music_on = true; this.data.music_playing = false; audioCxt.pause(); this.setData({ music_on: this.data.music_on, music_playing: this.data.music_playing }) }, //停止按钮事件 stopMusic : function(){ audioCxt.stop(); this.data.music_on = false; this.setData({ music_on: this.data.music_on }) }, //进度条改变后触发事件 audioChange : function(e){ var length = audioCxt.duration; var percent = e.detail.value; //用进度条百分比 * 整个音乐长度 var musicTime = Math.round(length/100*percent); audioCxt.seek(musicTime); //因为在拖动进度条时,去除了时间绑定,所以进度改变后重新绑定 audioCxt.onTimeUpdate(this.timeUpdate); this.setData({ musicTime: this.musicTimeFormat(musicTime) }) }, //进度条拖动过程中触发事件 audioChanging : function(e){ //因为在进度条拖动的时候,还会在timeUpdate里面修改进度条的value,倒置拖动受影响,所以当拖动的时候需要取消绑定 audioCxt.offTimeUpdate(); //拖动时修改时间显示 var length = audioCxt.duration; var percent = e.detail.value; var musicTime = Math.round(length / 100 * percent); this.setData({ musicTime: this.musicTimeFormat(musicTime) }) }, //将秒钟转化为mm:ss的时间格式 musicTimeFormat : function(time){ var second = Math.floor(time % 60); if(second<10){ second = '0' + second; } var minute = Math.floor(time / 60); if (minute < 10) { minute = '0' + minute; } return minute + ':' + second; }, //播放的时候,更新进度条和时间显示 timeUpdate : function(){ var time = audioCxt.currentTime; var percent = Math.round(time / audioCxt.duration * 100); this.setData({ musicTime: this.musicTimeFormat(time), sliderValue: percent }) } })
总结几个难点吧。
1、audio控件小程序已经不再更新了。都使用InnerAudioContext这个对象来控制音频。这个方法没有默认界面,需要自己写界面。
2、封面的旋转使用的css中的keyframes来进行的,用animation也尝试过,感觉比较复杂并且不好操作。用css来实现比较简单方便。
3、style="animation-play-state:{{music_playing?'running':'paused'}}" 这一个属性能控制动画暂停。有帖子说在IOS真机上会出现问题,没有苹果手机没进行测试。这个属性文档里面都没有找到。
4、进度条和播放的状态要进行双向绑定,播放的时候进度条的value要改变,进度条拖动的时候播放的时间也要进行改变。
5、自己有时候写变量还是不太规范。没形成自己的一套规则。
大家有什么疑问欢迎留言提问,多多交流。