基于微信小程序开发——音乐播放器

Posted WayneLJL

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了基于微信小程序开发——音乐播放器相关的知识,希望对你有一定的参考价值。

一、功能简介

      本系统开发用于体验客户注册登录后,可以随时查看当前网yi云音乐的咨询与最新消息,采用访问并请求网yi云音乐自主研发node.js开源网页资源的方法,搭建可选择播放音乐型小程序,可以实现最基本的音乐播放、收藏、搜索、以及增删歌单等操作。主要围绕登录用户与游客两个角色进行开发,游客在未注册的情况下只能查看资讯并试听歌曲,只有登录后才能管理歌单并添加歌曲至最喜爱歌单或自己需要的歌单。具体功能归纳如下:

(一)、游客、普通用户:

1.可以播放音乐、模糊搜索音乐

2.可以操作背景切换夜间模式与日常模式

3.可以查看音乐咨询、跳转到网yi云视频发现界面

(二)、普通用户:

1.可以将正在播放的音乐添加到最喜爱歌单

2.可以创建歌单、修改歌单、删除歌单

3.可以将搜索到的歌曲添加至用户所创歌单

二、开发环境描述

1.硬件:多媒体计算机

2.软件:(1)安装xmapp软件并连接到Apache服务器;

(2)安装navicat等数据库可视化操作工具并连接至mysql5.6版本以上的数据库;

(3)微信小程序调试基础库2.2版本以上,并采用云开发环境;

(4)Windows系列操作系统

三、演示效果视频

CourseBigHomework - 微信开发者工具

四、数据库设计

1.概念设计

        根据音乐播放系统的需求分析和功能概述,我简单将该播放系统的实体以及实体属性,并在这里采用E-R图的方式抽象成信息结构即概念模型,其中根据实体间联系,画出E-R图,如图所示:

2.逻辑设计

        将上一阶段已经设计好的基本E-R图,转换为与选用的数据库管理系统所支持的数据模型相符合的逻辑结构,即关系模型的转化。此处,根据本音乐播放系统的设置,将用户、歌曲、歌单、喜爱列表列为实体,转化为适当的关系模式,则具体属性与关系设置如下:

关系模式(关系模型)

(1)用户(用户编号,用户名,密码,性别,手机号,生日,地区,用户头像);

(2)歌曲(歌曲编号,歌曲名,歌曲作者,歌曲专辑,歌曲链接,歌曲图像链接,歌单编号);

(3)歌单(歌单编号,歌单名,歌单信息,歌单海报,用户编号);

(4)喜爱列表(喜爱歌曲编号,歌曲名称,歌曲作者,歌曲图像路径,歌曲链接,用户编号);

3.物理设计

        通过关系模型,我们能进一步确立实体间的相互关系,从而方便我们进行下一步操作,按照存储结构和存取方法我们构成了数据库物理结构,这里主要根据我们总结得出的关系模型,进行表结构的建立,做出具体表格结构示意图,由于系统结构庞大,表格体现选择以比赛项目信息表的部分典型字段为例,如下所示:

表1 最喜爱歌单信息likesonglist表

字段名

数据类型

长度

是否允许null值

约束

备注

likesong_id

int

10

主键、唯一

喜爱歌曲编号

likesong_name

varchar

50

歌曲名称

likesong_author

varchar

50

歌曲作者

likesong_image

varchar

100

歌曲图像路径

likesong_audio

varchar

100

歌曲链接

user_id

int

10

用户编号

        根据上述的需求分析,以及功能的确认与设计,我们这里采用对架构的理解,即在正式开始功能实现之前,对整体架构有一个模型似的认识,对每一个分区的实现效果进行区分,方便后期对项目制作时间的可行性分配,因此,这里我们采用常和数据库E-R图配套出线的总体设计图,来展示后面对过程中每一分区的功能实现。具体总体设计图如图所示:

 4.数据库操作设计(仅以部分效果为例)

        根据UI设计界面,传入静态数据后,分析逻辑思路,进行动态插入,连入数据库。

(1)首先是登录注册的数据库设计,注册即增添用户信息,发送请求,同时检测是否有相同用户登录,而登录即对用户信息进行匹配,返回结果。如上图所示。接着根据用户登录后的信息存入全局变量globalData,从而判断某些操作是否有权可以执行。

(2)接着是首页对歌曲的搜索查找,根据所提供的信息,设置数据库语言limited来限制输出的条数。

(3)同样为搜索操作的还有自定义导航栏对歌曲信息的搜索、喜爱歌单通过用户编号对歌曲的搜索、个人界面对用户自定义歌单的搜索,以及用户歌单内歌曲信息的搜索。

(4)增添操作这里以增添歌单以及增添歌曲至歌单为例,当用户搜索出自己想要的歌曲时,可以通过加号动态添加至自己所需要添加的歌单,代码展示如下:

showList(e)
  var id = e.currentTarget.dataset.id;
  var app =getApp();
  var List = app.globalData.songList;
  let info =""
  for (let index = 0; index < List.length; index++) 
    info = info+List[index].songlist_id+"."+List[index].songlist_name+" ";
  wx.showModal(cancelColor: 'cancelColor',
    title:"请输入你想添加的歌单:",
    placeholderText:info,
    editable:true,
    success:(res)=>
    ......

         效果展示如下:

 (5)最后是关于歌单的增删改查,用户可以在个人信息界面对所有已经存在的歌单进行查看,并可以根据按钮进行修改操作,也可以通过加号动态弹出的信息框进行增添操作,最后通过删除按钮进行删除。效果图展示如下:

五、设计思路描述

1.登录注册页面设计

        本页面的UI采用英文叠加中文的样式,实现水印的特殊展示效果,并将页面主题表明在最上方,而输入框信息栏的切换与课上讲述的tabs文件夹类似,也是swiper组件与wxss样式的连用,使用户可以通过点击顶部选项卡来切换不同的登录方式,这里由于需要传值的部分只有手机号与密码,因此我直接使用data传值,而不是form表单的submit事件。如果用户没有账号,可以点击立即注册跳转到注册界面。部分代码如下: 

<van-popup wx:if=" poppable " custom-class="van-calendar__popup-- position "
close-icon-class="van-calendar__close-icon" show=" show " round=" round "
position=" position " closeable=" showTitle || showSubtitle "
close-on-click-overlay=" closeOnClickOverlay " bind:enter="onOpen" bind:close="onClose" bind:after-enter="onOpened"bind:after-leave="onClosed">
  <include src="./calendar.wxml" />
</van-popup>

        效果图展示如下:

 2.首页设计

        首页这里的设计页面顶部采用的是自定义导航栏与轮播图swiper叠用,内容部分由数据库查找歌曲按照自定义组件输出为推荐歌曲,通过request请求网yi云音乐的官方API获取热门歌单与推荐歌单的信息,再通过横向scroll-view组件进行滑动展示。部分代码展示如下:

onChange( detail )  
  var app = getApp();
  appinstance.globalData.isDarkSwitch = detail
  this.setData(checked: appinstance.globalData.isDarkSwitch)
  if (this.data.checked) this.setData(DarkColor: appinstance.globalData.isDarkColor)
  app.globalData.dark=true;
  wx.setNavigationBarColor(frontColor: '#ffffff',backgroundColor: '#000000');
  wx.setPageStyle(style:background:"black",color:"white");
  wx.setTabBarStyle(backgroundColor: '#000000',color:"#ffffff")
  app.globalData.dark=true; else this.setData(DarkColor:
  appinstance.globalData.isNotDarkColor)
  ......,

        效果图展示如下:

        同时我给搜索栏的歌曲以及推荐歌单的歌曲一起绑定的鼠标单击事件,点击后对点击的歌曲进行信息传值,并打开audio控件来进行歌曲播放。具体代码展示如下:

<view class="content-item" wx:for="searchSongList" wx:key="id">
    <view class="profile">
        <image class="profile-pic" src="item.song_image"></image>
        <view class="username">
            <text class="name">item.song_name</text>
        </view>
        <image src="/images/personal/增加.png"style="height: 60rpx;width: 60rpx;"bindtap= "showList" data-id="item.song_id"></image>
    </view>
    <view class="iconfont icon-arrow-right" style="color:#fff"></view>
</view>
<van-empty image="(SearchSingerList[0] || SearchSongList[0]) == undefined ? 'search' : ''" description="搜索内容显示区" />
</van-popup>

         效果图展示如下:

         最后便是暂停键的设置,audio组件有一个最大的鄙陋就是,当你通过其他方式来调用该组件进行播放时,它自己本身的暂停按钮便不会显示,因此,我们需要通过自定义一个暂停按钮来控制它进行暂停操作。具体代码展示如下:

timeupdateEvent(e)
    var progress = parseInt((e.detail.currentTime/e.detail.duration)*100)
    var minute = parseInt((e.detail.duration-e.detail.currentTime)/60);
    var second = parseInt((e.detail.duration-e.detail.currentTime)%60);
    if(second<10)this.setData(progress: progress+"%",remainTime:minute+":0"+second)
    elsethis.setData( progress: progress+"%",remainTime:minute+":"+second),

         效果图展示如下:

3.发现页面设计

        该页面的设计仅仅是模拟网yi云音乐的第二底部选项卡的效果,即可以根据自己的喜好查看视频,同样与首页类似,通过请求访问网yi云音乐专属的API网站,获取信息资源后,利用自定义组件循环展示所访问的信息。具体效果展示如下:

  

4.个人界面设计

        除了头像框与用户名在用户登录后会动态修改后,这个界面的会员开通部分,也可以模拟下滑拖动效果,尽可能的实现现实中已经存在的操作方法。顶端设计皆为静态操作,即没有进行额外的页面设计,而底部的组成,则主要由最喜欢的音乐与歌单部分构建,其中歌单部分采用了swiper组件,即可以动态滑轮切换,而创建已存在的歌单,也可以通过movable-view与movable-area进行滑动删除。具体页面展示效果如下所示:

5.歌单界面设计

        最后的设计,是喜爱歌单与我的歌单的界面设计,整体界面采用类似的展示布局,仅仅在每条数据的插入显示上有不同的效果,同时可以链接歌曲进行调用audio控件播放,依然采用了自定义组件通过json文件中usingcomponent进行引用。具体展示效果如下所示:

        部分代码如下:

<view class="favourite-container">
    <view class="SingNumber">
        <van-icon name="music" size="33" color="#00b26a" />
        <text class="count">共favouriteList.length首</text>
    </view>
    <Sing wx:for="favouriteList" wx:key="id" title="item.likesong_name" Auther="item.likesong_auther" bindtap="tapEvent" data-params="item"></Sing>
</view>

至此,该微信小程序设计的音乐播放器系统的基本功能与界面展示完毕。如对您有所帮助,望留下宝贵一赞!谢谢!

        需源码 请私信扣扣  1092644308

微信小程序开发———音乐播放器

目录

一 小程序主体功能介绍

二 常用组件和API介绍

音频API

常用组件

三 整体布局

数据定义

主体页面

运行效果

四 播放器页面

布局部分

样式部分

运行效果

五 播放列表页面

布局部分

样式部分

运行效果

全部功能实现代码index.js


一 小程序主体功能介绍

本小程序主要实现,音乐的播放、暂停,下一曲的切换,以及播放列表和当前播放歌曲的详细信息查看等。

二 常用组件和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-dotsBoolean是否显示页面的指示点,默认为false
indicator-colorColor指示点的颜色
indicator-active-colorColor选中的指示点颜色
autoplayBoolean是否自动切换,默认为false
currentNumber当前所在滑块的index,默认为0
current-item-idString当前所在滑块的item-id
intervalNumber自动切换时间间隔(ms)
durationNumber滑动动画时长(ms)
bindchangeEventHandlecurrent改变时会触发change事件
circularBoolean是否采用衔接滑动,默认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();
  }
})

以上是关于基于微信小程序开发——音乐播放器的主要内容,如果未能解决你的问题,请参考以下文章

微信小程序开发--『狗蛋TV』

微信小程序开发之视频播放器 弹幕 弹幕颜色自定义

微信小程序开发之录音机 音频播放 动画 (真机可用)

基于微信小程序共享停车位设计与实现SSM_car.rar(项目源码+数据库文件+微信小程序开发+后端java语言)

微信小程序_小程序开发框架

微信小程序开发—组件及API