主页:
播放页:
搜索页:
排行榜页:
小控件:
//env是基础地址js文件
import config from './env'
export default (url,method="GET",data={})=>{
return new Promise((resolve,reject)=>{
wx.request({
url: config.dev.baseUrl + url,
method,
data,
success(res){
// console.log(res.data);
if(res.statusCode == 200){
resolve(res.data)
}else{
wx.showToast({
title: '请求失败,请联系管理员',
})
reject('请求失败,请联系管理员')
}
},
fail(error){
wx.showToast({
title: '请求失败,请联系管理员',
})
reject('请求失败,请联系管理员')
}
})
})
}
import request from './request'
module.exports = {
// 获取banner
getBanner:()=> request('/banner','get',{type:'2'}),
// 推荐歌单
getrecommendMusic:()=> request('/personalized?limit=6','get',),
// 排行榜
getTopMusic:(idx)=>request(`/top/list?idx=${idx}`,'get'),
// 歌曲详情
getMusicDetail:(ids)=>request(`/song/detail?ids=${ids}`),
// 歌曲音频路径
getMusicUrl:(id)=>request(`/song/url?id=${id}`,'POST'),
// 热搜数据 /search/hot/detail
getHotMusicData:()=>request('/search/hot/detail'),
// 搜索歌曲 /search
getSearchMusic:(keywords,limit)=>request(`/search?keywords=${keywords}&limit=${limit}`),
//搜索歌曲关键字 /search/default
getSearchDefault:()=>request('/search/default'),
// 登录 网易云真实账号密码
login:(phone,password)=>request(`/login/cellphone?phone=${phone}&password=${password}`)
}
swiper
与scroll-view
)进行开发slice
函数进行分页操作。this.setData({
topList:hotMusicList.playlist,
todayMusic:hotMusicList.playlist.tracks.slice(0,size*page)
})
/ 获取歌曲详情
goMusicDetail(e){
let ids = e.currentTarget.dataset.id
wx.redirectTo({
url:`../play/play?ids=${ids}`
})
},
slider
,value
表示现在进度(0—100) <view class="progress">
<slider bindchange='sliderChange' activeColor='blue' block-size="12" value='{{ProValue}}' />
</view>
let value = (music.currentTime/music.duration)*100
// 转换时间格式,将秒转换成00:00格式
s_to_hs(s){
//计算分钟
//算法:将秒数除以60,然后下舍入,既得到分钟数
let h = Math.floor(s/60);
//计算秒
//算法:取得秒%60的余数,既得到秒数
s=Math.trunc(s%60);
//将变量转换为字符串
h+='';
s+='';
//如果只有一位数,前面增加一个0
h = (h.length==1)?'0'+h:h;
s = (s.length==1)?'0'+s:s;
return h+':'+s;
},
timer(){
// 定时器
setTimeout(() => {
music.currentTime
music.onTimeUpdate(() => {
let startTime = this.s_to_hs(music.currentTime)
let endTime = this.s_to_hs(music.duration)
let value = (music.currentTime/music.duration)*100
this.setData({
PlayStartTime:startTime,
PlayEndTime:endTime,
ProValue:value
})
})
}, 1000)
},
// ios静音模式下可以播放音频
wx.setInnerAudioOption({
obeyMuteSwitch: false,
success: function (e) {
console.log(e)
console.log('play success')
},
fail: function (e) {
console.log(e)
console.log('play fail')
}
music(){
music = wx.createInnerAudioContext();
if (wx.setInnerAudioOption) {
wx.setInnerAudioOption({
obeyMuteSwitch: false,
autoplay: true
})
}else {
music.obeyMuteSwitch = false;
music.autoplay = true;
}
music.src = this.data.musicUrl.url;
app.music = music
music.onPlay(()=>{
console.log('音乐播放');
this.setData({
isPlay:true
})
})
music.onStop(()=>{
console.log('音乐停止');
})
music.onPause(()=>{
console.log('音乐暂停');
this.setData({
isPlay:false
})
})
music.onError((res)=>{
console.log(music);
console.log(res.errMsg);
console.log(res.errCode);
})
music.onWaiting(()=>{
console.log('音频加载中...');
})
},
挂载APP实例上面,通过
app.music = music
app.music.play();//播放
app.music.pause();//暂停
value
,反向转换成秒数,将music.currentTime
修改成当前值 // 拖动进度条
sliderChange(e){
let val = e.detail.value
// console.log(music.duration);
let second = music.duration * val/100
this.setData({
PlayStartTime: this.s_to_hs(second)
})
music.currentTime = second;
this.timer();
},
animation-play-state
动画属性,使用监听音频函数music.onPlay
与music.onPause
来检测播放与暂停,改变animation-play-state
的paused
与running
的值<view class="imgUrl">
<image src="{{picUrl}}" mode="" class="{{isPlay? 'rotateImg':''}}" style="animation-play-state:paused" />
</view>
.imgUrl image{
width: 88%;
height: 88%;
border-radius: 50%;
align-self: center;
animation: rotateImg 10s linear infinite;
}
.rotateImg{
animation-play-state:running !important
}
@keyframes rotateImg {
from {
transform: rotate(0deg);
}
to {
transform: rotate(360deg);
}
wx:for
循环遍历,搜索输入歌曲名回车之后,wx:if
隐藏热门信息,展示歌曲列表<view class="hotMusicData" wx:if="{{isShow}}">
<text>热搜榜</text>
<view class="hotMusic" wx:for="{{hotMusicData}}" wx:for-index="hotIndex" wx:key="key">
<text class="hotIndex">{{hotIndex+1}}</text>
<view class="hotMusic_content">
<text>{{item.searchWord}}\n</text>
<text>{{item.content}}</text>
</view>
<text>{{item.score}}</text>
</view>
</view>
排行榜滑块使用微信组件scroll-view
项目初期看到尚硅谷的网易云微信小程序的项目,拿到了node的api后端接口,查看微信开发者文档,参考网易云音乐的页面写完了静态页面,封装api接口,统一管理所有api接口地址
退出播放页面返回主页面,下面出现播放暂停小控件,也能够控制音乐播放与暂停
,之前思路是跟vue一样使用插槽slot,但是后面实现起来各种bug,后面换的思路是让music
的音频实例让所有组件能够看到,想到了APP跟组件,直接挂载到app
上面,来控制音频的播放与暂停。progress
组件,不过使用定时器不断改变value值,进度条progress
会反复从开头滑动,最后选择了slider
;初次学习写微信小程序,很多东西写的很乱,差哪些页面就去写哪些页面,项目初期没有完整的规划,项目结构也不清晰,功能点也是按照网易云现有功能有啥就写啥,js的一些代码冗余性有点高,通用函数没有做到封装,整体看起来就是有点乱,一些功能点没有写出来,就只是还原的播放器的部分功能,以后还要多多学习。
网易云微信小程序
https://gitee.com/yuan_henry/wechat-app