一 概述

  • 常用组件及API介绍
  • 播放器页面任务
  • 播放器页面任务
  • 数据准备
  • 音乐播放功能
  • 播放器页面

二 常用组件及API介绍

2.1 音频API

介绍
  • 微信小程序提供了播放音频的API,掌握这个API的使用方法是实现音乐播放的关键。

  • 在使用音频API时,需要通过如下代码创建一个InnerAudioContext实例,audioCtx就是一个InnerAudioContext实例,也就是一个对象,利用这个对象的属性和方法可以完成具体的工作

    var audioCtx=wx.createInnerAudioContext()
    
常用属性和方法
类型名称说明
属性src音频资源的地址,用于直接播放
startTime开始播放的位置(s),默认为0
autoplay是否自动开始播放,默认为false
loop是否循环播放,默认为false
volume音量。范围0~1。默认为1
duration音频的长度(s)。在当前有合法的src时返回(只读)
currentTime音频的播放位置(s)。在当前有合法的src时返回(只读)
paused当前是否暂停或停止状态(只读)
方法play()播放
pause()暂停(暂停后的音频再播放会从暂停处开始播放)
stop()停止(停止后的音频再播放会从头开始播放)
seek()跳转到指定位置
destroy销毁当前实例
onCanPlay()音频进入可以播放状态的事件(参数为回调函数)
onPlay()音频播放事件(参数为回调函数)
onPause()音频暂停事件(参数为回调函数)
onStop()音频停止事件(参数为回调函数)
onEnded()音频自然播放至结束的事件(参数为回调函数)
onSeeked()音频进行跳转操作的事件(参数为回调函数)
onTimeUpdate()音频播放进度更新事件(参数为回调函数)
onError()音频播放错误事件(参数为回调函数)
如何使用
onReady: function () {
    //创建InnerAudioContext实例
    var audioCtx=wx.createInnerAudioContext()
    //设置音频资源地址
    audioCtx.src='http://music.163.com/song/media/outer/url?id=5254524.mp3'
    //当开始播放时,输出调试信息
    audioCtx.onPlay(function(){
      console.log('开始播放')
    })
    //当发生错误时,输出信息
    audioCtx.onError(function(res){
      console.log(res.errMsg) //错误信息
      console.log(res.errCode) //错误码
    })
    //开始播放
    audioCtx.play()
  },

2.2 slider组件

说明

slider组件是小程序表单组件中的一种,用于滑动选择某一个值,在本项目中将用来实现播放器的进度条

常用属性
属性类型说明
minNumber最小值,默认为0
maxNumber最大值,默认为100
stepNumber步长,取值大于0,可被(max-min)整除,默认为1
valueNumber当前取值,默认为0
activeColorColor已选择的颜色,默认为#1aad19
backgroundColorColor背景条的颜色,默认为#e9e9e9
block-sizeNumber滑块的大小,取值范围为12~28,默认为28
block-colorColor滑块的颜色,默认为#ffffff
show-valueBoolean是否显示当前value,默认为false
bindchangeEventHandle完成一次拖动后触发的事件
bindchangingEventHandle拖动过程中触发的事件
基本使用

布局文件中:

<slider bindchanging="sliderChanging" show-value />

代码中:

sliderChanging:function(e)
{
   console.log(e.detail.value)
}

三 播放器页面任务

  • 音乐信息:显示当前播放曲目的标题和艺术家
  • 专家封面:当音乐播放时,专辑封面会顺时针旋转
  • 播放进度:显示当前曲目的播放时长和总时长,并提供一个进度条,当音乐播放时进度条就会增长,用户也可以手动改变进度条的进度来跳转播放进度

四 数据准备

4.1 音乐外链平台

刘志进实验室-音乐直链搜索

4.2 定义基础数据

路径
pages/index/index.js文件的data对象定义基础数据playlist
数据
data: {
    item:0,
    tab:0,
    playlist:[{
      id:1,title:'钢琴协奏曲',singer:'肖邦',
      src:'http://music.163.com/song/media/outer/url?id=419485661.mp3',
      coverImgUrl:'../../images/music.png'
    },{
      id:2,title:'奏鸣曲',singer:'莫扎特',
      src:'http://music.163.com/song/media/outer/url?id=1394618521.mp3',
      coverImgUrl:'../../images/music.png'
    },{
      id:3,title:'欢乐颂',singer:'贝多芬',
      src:'http://music.163.com/song/media/outer/url?id=383064.mp3',
      coverImgUrl:'../../images/music.png'
    },{
      id:4,title:'爱之梦',singer:'李斯特',
      src:'http://music.163.com/song/media/outer/url?id=5276814.mp3',
      coverImgUrl:'../../images/music.png'
    },
    ],
    state:'paused',
    playIndex:0,
    play:{
      currentTime:'00:00',
      duration:'00:00',
      percent:0,
      title:'',
      singer:'',
      coverImgUrl:'../../images/music.png'
    }
  },
playlist数据说明
  • id:每条记录的唯一标识
  • title:曲目标题
  • singer:艺术家
  • src:网络中的音频文件链接地址
  • coverImgUrl:专辑封面图片的链接地址
音乐状态属性
  • state:音乐的播放状态,paused表示暂停,running表示播放
  • playIndex:当前播放曲目在播放列表数组中的索引值
  • play:当前播放曲目的信息
  • currentTime:播放时长
  • duration:总时长
  • percent:播放进度
  • title:当前播放的曲目标题
  • singer:当前播放的曲目的艺术家
  • coverImgUrl:当前播放的曲目的专辑封面

五 音乐播放功能(底部播放器)

5.1 布局文件(pages/index/index.wxml)

<view class="player">
  <image class="player-cover" src="{{play.coverImgUrl}}" />
  <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/list.png" bindtap="changePage" data-page="2" />
    <!--播放-->
    <image wx:if="{{state=='paused'}}" src="../images/Play.png" bindtap="play"/>
    <image wx:else src="../images/Pause.png" bindtap="pause"/>
     <!--下一曲-->
     <image src="../images/rewind-right.png" bindtap="next"/>
</view>

5.2 样式文件(pages/index/index.wxss)

.player{
  display: flex;
  align-items: center;
  background: #222;
  border-top: 1px solid #252525;
  height: 112rpx;
}
.player-cover{
  width: 80rpx;
  height: 80rpx;
  margin-left: 15rpx;
  border-radius: 8rpx;
  border:1px solid #333;
}
.player-info{
  flex:1;
  font-size: 10pt;
  line-height: 38rpx;
  margin-left: 20rpx;
  padding-bottom: 8rpx;

}
.player-info-singer{
  color: #888;

}
.player-controls image{
  width:80rpx;
  height: 80rpx;
  margin-right: 15rpx;
}

5.3 逻辑文件(pages/index/index.js)

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()
    }
 }, 

5.4 效果

六 播放器页面

6.1 布局文件(pages/index/play.wxml)

<view class="content-play">
<!--显示音乐信息-->
<view class="content-play-info">
  <text>{{play.title}}</text>
  <view>——{{play.singer}}——</view>
</view>
<!--显示专辑封面-->
<view class="content-play-cover">
  <image src="{{play.coverImgUrl}}" style="animation-play-state:{{state}}"/>
</view>
<!--显示播放进度和时间-->
<view class="content-play-progress">
  <text>{{play.currentTime}}</text>
  <view>
    <slider bindchange="sliderChange" activeColor="#d33a31" block-size="12" bindchange="#dadada" value="{{play.percent}}" />
  </view>
  <text>{{play.duration}}</text>
</view>
</view>

6.2 样式文件(pages/index/index.wxss)

.content-play{
  display: flex;
  justify-content: space-around;
  flex-direction: column;
  height: 100%;
  text-align: center;
}
.content-play-info>view{
  color: #888;
  font-size: 11pt;
}
.content-play-cover image{
  animation:rotateImage 10s linear infinite;
  width: 400rpx;
  height: 400rpx;
  border-radius: 50%;
  border: 1px solid #333;
}
@keyframes rotateImage{
  from {
    transform:rotate(0deg);
  }
  to {
    transform:rotate(360deg);
  }
}
.content-play-progress{
  display: flex;
  align-items: center;
  margin:0 35rpx;
  font-size:9pt;
  text-align: center;
}
.content-play-progress>view{
  flex:1;
}

6.3 逻辑文件(播放进度)

 onReady: function () {
 this.audioCtx=wx.createInnerAudioContext()
 var that=this;
 //播放失败检测
 this.audioCtx.onError(function(){
  console.log('播放失败:'+that.audioCtx.src)
 })
 //播放完成自动换下一曲
 this.audioCtx.onEnded(function(){
   that.next()
  })
  //自动更新播放进度
  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
      })
  })
  //默认选择第1曲
  this.setMusic(0)
  //格式化时间
  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)
    }
  },
  
 sliderChange:function(e){
   var second=e.detail.value*this.audioCtx.duration/100
   this.audioCtx.seek(second)
  },  

6.4 效果图

Logo

CSDN联合极客时间,共同打造面向开发者的精品内容学习社区,助力成长!

更多推荐