微信小程序开发———音乐播放器
Posted 凉沫love
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了微信小程序开发———音乐播放器相关的知识,希望对你有一定的参考价值。
目录
一 小程序主体功能介绍
本小程序主要实现,音乐的播放、暂停,下一曲的切换,以及播放列表和当前播放歌曲的详细信息查看等。
二 常用组件和API介绍
1.音频API
1.1 介绍
创建音频时需要先创建一个对象实例,从而引用该对象的方法和属性。
var audioCtx=wx.createInnerAudioContext()
1.2 常用属性方法
属性
src:音频资源的地址;
autoplay:是否自动播放,默认false;
loop: 是否循环播放,默认为false;
startTime: 开始播放的位置,默认为0;
currentTime: 当前播放的位置;
duration: 音频的长度;
paused:当前暂停或停止的状态;
方法
play(): 播放;
stop(): 停止,再播放重头开始;
pause(): 暂停,再播放从当前位置开始;
seek(): 跳到指定的位置;
onError(): 音频播放错误事件;
onEnded(): 音频自然播放结束事件;
onPlay(): 音频播放事件;
onTimeUpdate(): 音频播放进度更新事件;
2.常用组件
2.1 swiper组件
介绍
swiper组件是滑块视图容器,经常用于实现轮播图,在音乐播放器小程序中可以实现标签页的切换。
属性
属性 | 类型 | 说明 |
indicator-dots | Boolean | 是否显示页面的指示点,默认为false |
indicator-color | Color | 指示点的颜色 |
indicator-active-color | Color | 选中的指示点颜色 |
autoplay | Boolean | 是否自动切换,默认为false |
current | Number | 当前所在滑块的index,默认为0 |
current-item-id | String | 当前所在滑块的item-id |
interval | Number | 自动切换时间间隔(ms) |
duration | Number | 滑动动画时长(ms) |
bindchange | EventHandle | current改变时会触发change事件 |
circular | Boolean | 是否采用衔接滑动,默认false |
代码使用
<swiper current="1">
<swiper-item >0</swiper-item>
<swiper-item >1</swiper-item>
<swiper-item >2</swiper-item>
</swiper>
2.2 include代码引用
介绍
当一个wxml文件中代码过多,或wxml中有部分相同的代码时,可以将他们分离开,用include进行引入。
代码使用
<include src="header.wxml"/>
<view>body</view>
<include src="footer.wxml" />
2.3 scroll-view组件
介绍
scroll-view组件用于实现可滚动视图区域。一般来说,当页面高度超出了显示区域的高度时,先设置外层容器高度,使其低于内部容器高度,然后在外层容器样式中设置滚动方向即可。
属性
属性 | 说明 |
scroll-x | 允许横向滚动,默认为false |
scroll-y | 允许纵向滚动,默认为false |
scroll-top | 设置竖向滚动条的位置 |
scroll-left | 设置横向滚动条的位置 |
bindscrolltoupper | 滚动到顶部/左边触发的事件 |
bindscrolltolower | 滚动到底部/右边触发的事件 |
代码使用
<scroll-view scroll-x scroll-y style="height:200px" bindscroll="scroll">
<view style="width:200%; height:400px; background:#ccc"></view>
</scroll-view>
在.js页面中可以添加scroll处理函数,来查看具体数值
scroll:function(e){
console.log(e.detail)
}
2.4 slider组件
介绍
slider组件是小程序表单组件中的一种,用于滑动选择某一个值,在本项目中将用来实现播放器的进度条
属性
属性 | 说明 |
min | 最小值,默认为0 |
max | 最大值,默认为100 |
step | 步长,取值大于0 |
value | 当前取值,默认为0 |
activeColor | 已选择的颜色,默认为#1aad19 |
backgroundColor | 背景条颜色,默认为#e9e9e9 |
block-size | 滑块的大小 |
block-color | 滑块的颜色,默认为#ffffff |
show-value | 是否显示当前value,默认为false |
bindchange | 完成一次拖动后触发的事件 |
bindchanging | 拖动过程中触发的事件 |
三 整体布局
1. 数据定义
1.1 路径
pages/index/index.js 文件的data对象定义基础数据playlist
1.2 数据
data: {
item:0,
tab:0,
// 播放列表
playlist:[{
id:1,
title:"纪念",
singer:"雷心雨",
src:"/images/1.mp3",
coverImgUrl:"/images/cover.jpg"
},{
id:2,
title:"雪落下的声音",
singer:"郁可唯",
src:"/images/2.mp3",
coverImgUrl:"/images/cover2.jpg"
},{
id:3,
title:"只要平凡",
singer:"张杰",
src:"/images/3.mp3",
coverImgUrl:"/images/cover3.jpg"
}
,{
id:4,
title:"我会很勇敢",
singer:"张雅莉",
src:"/images/4.mp3",
coverImgUrl:"/images/cover4.jpg"
} ],
state:"paused",
// 播放的索引值
playIndex:0,
//设置的默认值
play:{
// 当前时间
currentTime:'00.00',
// 总时间
duration:'00.00',
// 播放进度
percent:0,
title:'',
singer:'',
coverImgUrl:"/images/cover.jpg",
}
},
2. 主体页面
2.1 布局页面index.wxml
<!--index.wxml-->
<!-- 标签页标题 -->
<view class="tab">
<view class="tab-item {{tab==0 ? 'active' : ''}} " bindtap="changeItem" data-item="0">音乐推荐</view>
<view class="tab-item {{tab==1 ? 'active' : ''}}" bindtap="changeItem" data-item="1">播放器</view>
<view class="tab-item {{tab==2 ? 'active' : ''}} " bindtap="changeItem" data-item="2">播放列表</view>
</view>
<!-- 内容区域 -->
<view class="content" >
<swiper current="{{item}}" bindchange="changeTab">
<swiper-item >
<include src="info.wxml"></include>
</swiper-item>
<swiper-item >
<include src="play.wxml"></include>
</swiper-item>
<swiper-item>
<include src="playlist.wxml"></include>
</swiper-item>
</swiper>
</view>
<!-- 底部播放器 -->
<view class="player">
<image class="player-cover" src="{{play.coverImgUrl}}"></image>
<view class="player-info">
<view class="player-info-title">{{play.title}}</view>
<view class="player-info-singer">{{play.singer}}</view>
</view>
<!-- 切换到播放列表 -->
<view class="player-controls">
<image src="/images/play-1.jpg" bindtap="changePage" data-page="2"></image>
<!-- 播放或暂停 -->
<image wx:if="{{state=='paused'}}" src="/images/play-2.jpg"
bindtap="play"></image>
<image wx:else src="/images/play-4.jpg" bindtap="pause"></image>
<!-- 下一曲 -->
<image src="/images/play-3.jpg" bindtap="next"></image>
</view>
</view>
2.2 样式部分
page{
display: flex;
flex-direction: column;
background-color: #c8f5fd;
color: rgb(22, 17, 13);
height: 100%;
}
.tab{
display: flex;
}
.tab-item{
flex: 1;
font-size: 10pt;
text-align: center;
line-height: 72rpx;
border-bottom: 6rpx solid #eee;
}
.tab-item.active{
color:#584acf;
border-bottom-color:#7c6fee;
}
.content{
flex: 1;
}
.content>swiper{
height:100%;
}
.player{
background: rgb(156, 209, 240);
border-top: 1rpx solid #a8ddf8;
height: 112rpx;
}
/* 底部播放器 */
.player{
display: flex;
align-items: center;
background:rgb(117, 185, 224);
border-top: 1rpx solid #7c8dec;
height: 112rpx;
}
/* 覆盖图片设置 */
.player-cover{
width:80rpx;
height: 80rpx;
margin-left: 15rpx;
border-radius: 10rpx;
border:2rpx solid rgb(204, 200, 200);
}
/* 歌曲信息设置 */
.player-info{
flex:1;
font-size: 10pt;
line-height: 38rpx;
margin-left: 20rpx;
padding-bottom:8rpx;
}
.player-info-singer{
color:rgb(189, 214, 245);
margin-top: 5rpx;
font-size:9pt;
}
/* 控制按钮设置 */
.player-controls image{
width: 80rpx;
height: 80rpx;
margin-right: 10rpx;
}
2.3 底部播放、切换功能函数实现
audioCtx:null,
onReady: function () {
this.audioCtx=wx.createInnerAudioContext()
//默认选中第1曲
this.setMusic(0)
},
setMusic:function(index){
var music=this.data.playlist[index]
this.audioCtx.src=music.src
this.setData({
playIndex:index,
'play.title':music.title,
'play.singer':music.singer,
'play.coverImgUrl':music.coverImgUrl,
'play.currentTime':'00:00',
'play.duration':'00:00',
'play.percent':0
})
},
play:function(){
this.audioCtx.play()
this.setData({state:'running'})
},
pause:function(){
this.audioCtx.pause()
this.setData({state:'paused'})
},
next:function(){
var index=this.data.playlist>=this.data.playlist.length-1?0:this.data.playIndex+1
this.setMusic(index)
if(this.data.state=='running'){
this.play()
}
},
3. 运行效果
四 播放器页面
1.布局部分
<view class="content-play">
<!-- 显示音乐信息 -->
<view class="content-play-info">
<view>{{play.title}}</view>
<view>—— {{play.singer}} ——</view>
</view>
<!-- 显示专辑封面 -->
<view class="content-play-cover">
<image src="{{play.coverImgUrl}}" style="animation-play-state:{{state}}"></image>
</view>
<!-- 显示播放进度 -->
<view class="content-play-progress">
<text>{{play.currentTime}}</text>
<view>
<!-- activeColor已选择的不生效 -->
<slider bindchange="sliderChange" activeColor="#d33a31" block-size="12" backgroundColor="#ccc" value="{{play.percent}}"></slider>
</view>
<text>{{play.duration}}</text>
</view>
</view>
2. 样式部分
/* 播放器页面设置 */
.content-play{
display: flex;
flex-direction: column;
justify-content: space-around;
height: 100%;
text-align: center;
background-color: rgb(203, 235, 243);
}
.content-play-info{
color: rgb(7, 59, 102);
font-size: 11pt;
}
.content-play-cover image{
animation:rotateImage 10s linear infinite ;
width: 400rpx;
height:400rpx;
border-radius: 50%;
border:1rpx solid rgb(245, 241, 241);
}
@keyframes rotateImage{
from{
transform: rotate(0deg);
}
to{
transform: rotate(360deg);
}
}
/* 进度条设置 */
.content-play-progress{
display: flex;
align-items: center;
font-size: 9pt;
margin: 0 35rpx;
text-align: center;
}
.content-play-progress >view{
flex: 1;
}
3. 运行效果
五 播放列表页面
1.布局部分
<scroll-view class="content-playlist" scroll-y>
<view class="playlist-item" wx:for="{{playlist}}" wx:key="id" bindtap="change" data-index="{{index}}">
<image class="playlist-cover" src="{{item.coverImgUrl}}"></image>
<view class="playlist-info">
<view class="playlist-info-title">{{item.title}}</view>
<view class="playlist-info-singer">{{item.singer}}</view>
</view>
<view class="playlist-controls">
<text wx:if="{{index==playIndex}}">正在播放</text>
</view>
</view>
</scroll-view>
2.样式部分
/* 播放列表 */
.content-playlist{
background-color: rgb(175, 231, 247);
}
.playlist-item{
/* 每遍历一个会自动换行 */
display: flex;
align-items: center;
border-bottom: 2rpx solid rgb(253, 250, 250);
height: 112rpx;
}
.playlist-cover{
width:80rpx;
height:80rpx;
margin-left: 15rpx;
border-radius: 10rpx;
border: 1rpx solid rgb(248, 245, 245);
}
.playlist-info{
/* 字体为垂直排列 */
flex: 1;
font-size: 10pt;
margin-right: 25rpx;
margin-left: 10rpx;
color: #000;
}
3.运行效果
4.全部功能实现代码index.js
// index.js
// 获取应用实例
const app = getApp()
Page({
// 页面初始数据
data: {
item:0,
//记录当前页的索引
tab:0,
// 播放列表
playlist:[{
id:1,
title:"纪念",
singer:"雷心雨",
src:"/images/1.mp3",
coverImgUrl:"/images/cover.jpg"
},{
id:2,
title:"雪落下的声音",
singer:"郁可唯",
src:"/images/2.mp3",
coverImgUrl:"/images/cover2.jpg"
},{
id:3,
title:"只要平凡",
singer:"张杰",
src:"/images/3.mp3",
coverImgUrl:"/images/cover3.jpg"
}
,{
id:4,
title:"我会很勇敢",
singer:"张雅莉",
src:"/images/4.mp3",
coverImgUrl:"/images/cover4.jpg"
} ],
state:"paused",
// 播放的索引值
playIndex:0,
//设置的默认值
play:{
// 当前时间
currentTime:'00.00',
// 歌曲总时间
duration:'00.00',
// 播放进度
percent:0,
title:'',
singer:'',
coverImgUrl:"/images/cover.jpg",
}
},
// 保存在page里面了,音频对象
audioCtx:null,
changeItem:function(e){
//设置获取item的值,来实现页面切换
this.setData({
item:e.target.dataset.item
})
},
changeTab:function(e){
this.setData({
//当前页的索引
tab:e.detail.current
})
},
// 手动控制进度
sliderChange:function(e){
var second=e.detail.value *this.audioCtx.duration / 100
//跳到指定位置
this.audioCtx.seek(second)
},
onReady:function(){
//获取音频播放对象
this.audioCtx=wx.createInnerAudioContext()
var that=this
// 播放失败检测
this.audioCtx.onError(function(){
console.log("播放失败:"+that.audioCtx.src)
})
// 播放完成自动转为下一曲
this.audioCtx.onEnded(function(){
that.next()
})
// 格式化时间
function formatTime(time){
var minute=Math.floor(time/60)%60;
var second=Math.floor(time)%60;
return(minute<10? '0'+minute:minute)+":"+
(second<10?'0'+second:second)
}
//自动更新播放进度
// 旧版本里面需要先调用onplay,要不无法启动onTimeUpdate
this.audioCtx.onPlay(function(){})
this.audioCtx.onTimeUpdate(function(){
that.setData({
//获取总时间
'play.duration':formatTime(that.audioCtx.duration),
//当前歌曲播放的时长
'play.currentTime':formatTime(that.audioCtx.currentTime),
'play.percent':that.audioCtx.currentTime/that.audioCtx.duration*100
})
})
this.setMusic(0)
},
setMusic:function(index){
var music=this.data.playlist[index]
this.audioCtx.src=music.src
this.setData({
playIndex:index,
'play.title':music.title,
'play.singer':music.singer,
"play.coverImgUrl":music.coverImgUrl,
"play.currentTime":'00:00',
"play.duration":'00:00',
"play.percent":0
})
},
play:function(){
this.audioCtx.play()
this.setData({
state:"running"
})
},
pause:function(){
this.audioCtx.pause()
this.setData({
state:"paused"
})
},
next:function(){
var index=this.data.playIndex >=this.data.playlist.length-1 ? 0 : this.data.playIndex+1
this.setMusic(index)
if(this.data.state=="running"){
this.play()
}
},
// 播放列表中的换曲功能
change:function(e){
this.setMusic(e.currentTarget.dataset.index);
this.play();
}
})
以上是关于微信小程序开发———音乐播放器的主要内容,如果未能解决你的问题,请参考以下文章