网络知识 娱乐 微信小程序开发———音乐播放器

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

目录

一 小程序主体功能介绍

二 常用组件和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

代码使用

  
      0
      1
      2
  

2.2 include代码引用

介绍

当一个wxml文件中代码过多,或wxml中有部分相同的代码时,可以将他们分离开,用include进行引入。

代码使用


body

2.3 scroll-view组件

介绍

scroll-view组件用于实现可滚动视图区域。一般来说,当页面高度超出了显示区域的高度时,先设置外层容器高度,使其低于内部容器高度,然后在外层容器样式中设置滚动方向即可。

属性

属性说明
scroll-x

允许横向滚动,默认为false

scroll-y允许纵向滚动,默认为false
scroll-top设置竖向滚动条的位置
scroll-left设置横向滚动条的位置
bindscrolltoupper滚动到顶部/左边触发的事件
bindscrolltolower

滚动到底部/右边触发的事件

代码使用


  

在.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




 
  <view class="tab-item {{tab==0 ? 'active' : ''}} " bindtap="changeItem"  data-item="0">音乐推荐
  <view class="tab-item  {{tab==1 ? 'active' : ''}}"   bindtap="changeItem" data-item="1">播放器
  <view class="tab-item  {{tab==2 ? 'active' : ''}} " bindtap="changeItem" data-item="2">播放列表




    <swiper current="{{item}}"  bindchange="changeTab">
      
        
      
      
        
      
      
        
      
    



  <image class="player-cover"  src="{{play.coverImgUrl}}">
  
    {{play.title}}
    {{play.singer}}
  
  
  
    
    
    <image wx:if="{{state=='paused'}}" src="/images/play-2.jpg"
    bindtap="play">
    
    
   
  

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.布局部分



  
    {{play.title}}
    —— {{play.singer}} ——
  
  
  
    <image src="{{play.coverImgUrl}}" style="animation-play-state:{{state}}">
  
  
  
    {{play.currentTime}}
    
    
      <slider bindchange="sliderChange" activeColor="#d33a31" block-size="12" backgroundColor="#ccc" value="{{play.percent}}">
    
    {{play.duration}}
  
  

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.布局部分


  <view class="playlist-item" wx:for="{{playlist}}" wx:key="id" bindtap="change" data-index="{{index}}">
    <image class="playlist-cover" src="{{item.coverImgUrl}}">
    
      {{item.title}}
      {{item.singer}}
    
    
    <text wx:if="{{index==playIndex}}">正在播放
    
  

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=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();
  }
})

图片、音乐以及源码资源连接

链接: https://pan.baidu.com/s/1TS2fefu1hb5aEf7FSvqTHA 提取码: ibg5