音乐小程序案例(二)

234 阅读4分钟

一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第8天,点击查看活动详情

音乐小程序的设计(二)

案例目的

      (一) 掌握微信小程序中swiper组件、scroll-view组件、image组件、slider组件和include代码引用的使用。

      (二) 掌握微信小程序中音频API的使用;

       步骤6: 实现底部播放器效果。底部播放器显示播放音乐的的名字、演唱者和封面,这些是动态变换的,需要与数据进行绑定。

       (1)在项目的pages/index/index.js中的data中添加如下数据。

state: 'paused',   //控制播放状态
    playIndex: 0,      //存播放音乐在playlist中的下标
    play: {      //播放音乐的信息
      currentTime: '00:00',
      duration: '00:00',
      percent: 0,
      title: '',
      singer: '',
      coverImgUrl: '',
    }

       (2)在项目的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/01.png" bindtap="changePage" data-page="2" />
    <!-- 播放或暂停 -->
    <image wx:if="{{state=='paused'}}" src="/images/02.png" bindtap="play" />
    <image wx:else src="/images/02stop.png" bindtap="pause" />
    <!-- 下一曲 -->
    <image src="/images/03.png" bindtap="next" />
  </view>
</view>

       (3)在项目的pages/index/index.wxss中修改底部播放器样式代码如下。


/* 底部播放器 */

.player{
  display: flex;
  align-items: center;
  background:#eee;
  border-top: 1px solid #252525;
  height: 112rpx;
}
.player-cover{
  width: 80rpx;
  height: 80rpx;
  margin-left:15rpx;
  border-radius: 10rpx;
  border:1px solid #333;
}

.player-info{
  flex:1;
  font-size: 10pt;
  line-height: 38rpx;
  margin-left:20rpx;
  padding-bottom: 8rpx;
}

.player-info-title{
  color:#f00;
}

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

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

image.png

       步骤7:实现底部播放器上音乐信息的显示和各个按钮的功能。

// 播放功能的实现
  audioCtx:null,
  onReady:function(){
    this.audioCtx = wx.createInnerAudioContext()
    // 默认选择第1曲
    this.setMusic(0)
    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() {
      // console.log(that.audioCtx.duration)
       that.setData({
         'play.duration': formatTime(that.audioCtx.duration),
         'play.currentTime': formatTime(that.audioCtx.currentTime),
         'play.percent': that.audioCtx.currentTime / that.audioCtx.duration * 100
       })
     })
    // 格式化时间
    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)
    }
    // 在微信小程序使用seek()后,onTimeUpdate监听失效解决方案
    this.audioCtx.onSeeked(() => {
      console.log("onSeeked:"+that.audioCtx.paused);
      // that.seek = false;
    })
  },
  // 设置播放音乐信息
  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
    })
  },
  changePage(e){

    this.setData({

      tab:e.target.dataset.page,

      item:e.target.dataset.page

    })

  },

  // 播放功能

  play(){

    var that=this

    // this.audioCtx.play()

    // 而当拖动进度或者播放完毕后重新播放,

    //都会触发onWaiting,然后onTimeUpdate就挂了.

    //切歌和重新播放音频要想保证onTimeUpdate正常更新,

    //setTimeout(() => {},时间)时间设置够长就不会触发onwaiting解决切换歌曲onTimeUpdate失效问题

    setTimeout(() => {

      that.audioCtx.play()//播放音乐

      }, 500)

    this.setData({

      state:'running'

    })

  },

  // 暂停功能

  pause(){

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

  }

       运行小程序,底部播放器所有功能都实现。

       步骤8 : 实现播放器页面。

       (1)在项目的pages/index/play.wxml文件中添加如下代码。理解红色代码的含义。

<!-- 播放器 -->

<view class="content-play">

  <!-- 显示音乐信息 -->

  <view class="content-play-info">

    <text>{{play.title}}</text>

    <view>—— {{play.singer}} ——</view>

  </view>

  <!-- 显示专辑封面 -->

  <!-- 语法:animation-play-state: paused|running;

paused 规定动画已暂停。

running 规定动画正在播放。

  -->

  <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" backgroundColor="#dadada" value="{{play.percent}}" />

    </view>

    <text>{{play.duration}}</text>

  </view>

</view>

       (2)在项目的pages/index/index.wxss文件中添加如下代码。


/* 播放器页面 */

.content-play{

  display: flex;

  flex-direction: column;

  justify-content: space-around;

  height:100%;

  text-align: center;

}

.content-play-info>text{

  font-size: 16pt;

}

.content-play-info>view{

  color: yellow;

  font-size: 11pt;

}

.content-play-cover>image{

  animation: rotateImage 10s linear infinite;

  width:400rpx;

  height:400rpx;

  border-radius: 50%;

  border:1px solid #fff;

}

/*

语法:animation-play-state: paused|running;

paused 规定动画已暂停。

running 规定动画正在播放。

 */

@keyframes rotateImage{

  from{

    transform: rotate(0deg);

  }

  to{

    transform: rotate(360deg);

  }

}

.content-play-progress{

  display: flex;

  align-items: center;

  margin:0 35rpx;

  font-size:10pt;

  text-align: center;

}

.content-play-progress>view{

  flex:1;

}

       (3)在项目的pages/index/index.js文件中添加如下代码实现滑块调节歌曲进度功能。

// 滚动条调节歌曲进度

  sliderChange: function(e) {

    var second = e.detail.value * this.audioCtx.duration / 100

    this.audioCtx.seek(second)

  }

       步骤9:实现播放列表。

       (1)在项目的pages/index/playlist.wxml文件中添加如下代码。理解红色代码的含义。

<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)在项目的pages/index/indx.wxss文件中添加如下代码。


/* 播放列表 */

.content-playlist{

  height: 100%;

}

.playlist-item{

  display: flex;

  align-items:center; /* 垂直方向居中 */

  border-bottom: 1rpx solid #ddd;

  height: 112rpx;

}

.playlist-cover{

  width: 80rpx;

  height:80rpx;

  margin-left:15rpx;

  border-radius: 8rpx;

  border:1px solid #fff;

}

.playlist-info{

  flex:1;

  font-size:10pt;

  line-height: 38rpx;

  margin-left: 20rpx;

  padding-bottom: 8rpx;

}

.playlist-info-singer{

  color:#888;

}

.playlist-controls{

 font-size: 10pt;

 margin-right:20rpx;

 color:red;

}

       (3)在项目的pages/index/index.js文件中添加如下代码实现单击播放列表和单击热门音乐进行播放功能

change(e){

     this.setMusic(e.currentTarget.dataset.index)

     this.play()

  }

image.png

image.png

image.png

尾言

      到此整个音乐小程序实现完成,运行小程序可以查看效果。,如果觉得还不错的话,欢迎点赞收藏哦。