微信小程序&&简单的音乐播放器

z

博客班级 https://edu.cnblogs.com/campus/zjcsxy/SE2020
作业要求 https://edu.cnblogs.com/campus/zjcsxy/SE2020/homework/11334
作业目标
  • 编写一个小程序,可以全新编写,也可以学习别人的小程序进行修改
  • 熟悉git代码管理流程,将源代码上传到到github
  • 在博客园班级中写一篇相应的博文
作业源代码  https://github.com/Saulger/music-player
学号 31801148-杨守概
院系 浙大城市学院计算机专业

 

·前言

第一次学习写微信小程序,之前没有一点基础,连web也只是略懂皮毛,所以写wxml和wxss的时候花了大量时间去学习布局以及样式。JS也是让我泪流满面,也是让我认识到自身的不足。拿到这个作业的时候,我第一反应就是我想做一个音乐的播放器,后来去网上查阅大量的样例,一开始我根本无从下手,与其等死不如花时间从最基础开始学起,主要参考网站是https://developers.weixin.qq.com/miniprogram/dev/framework/quickstart/。最后根据自己理想中的布局做了一个简单的音乐播放器。

·页面展示

 

 

 

 

 

 

 

 

 ·文件结构

 

 

 index为进入小程序的主页,List为音乐列表页,Play为音乐播放的效果页,SongData.js为储存的音乐信息。

·详细介绍

index.wxml

<swiper class="top" indicator-dots="{{indicator_dots}}"
autoplay="{{autoplay}}" interval="{{interval}}" duration="{{duration}}" circular="{{circular}}">
    <block wx:for="{{imgurls}}" wx:key="{{index}}">
        <swiper-item>
            <image src="{{item}}" class="top_image"/>
        </swiper-item>
    </block>
</swiper>       //上方图片轮播动画实现
<view class="ownList"> <text class="ownlist">-----歌曲列表-----</text> </view>
<scroll-view scroll-y="true" > //下拉框的实现 <view class="songlist"> <block wx:for="{{songlist}}" wx:key="song_id"> <view class="songitem"> <view class="song-index">{{index+1}}</view> <navigator url="/pages/Play/Play?songid={{index}}" class="song-detail"> <view class="song-title">{{item.name}}</view> <view class="song-subtitle">{{item.singer}} - {{item.seconds}}</view> </navigator> <navigator url="/pages/Play/Play?songid={{index}}" class="song-play"><image src="/Images/play.png" /></navigator> </view> </block> </view> <loading hidden="{{!loading}}"> 正在加载音乐…… </loading> </scroll-view>

index.js

var config = require('../../utils/SongData.js'); 
Page({
  data: {
    imgurls:[
      'https://ss3.bdstatic.com/70cFv8Sh_Q1YnxGkpoWK1HF6hhy/it/u=47017426,376938455&fm=26&gp=0.jpg',
      'https://ss3.bdstatic.com/70cFv8Sh_Q1YnxGkpoWK1HF6hhy/it/u=2656019328,2056784029&fm=26&gp=0.jpg',
      'https://ss2.bdstatic.com/70cFvnSh_Q1YnxGkpoWK1HF6hhy/it/u=2442328894,1339802770&fm=26&gp=0.jpg',
      'https://ss1.bdstatic.com/70cFvXSh_Q1YnxGkpoWK1HF6hhy/it/u=3719062759,3237893044&fm=26&gp=0.jpg'
    ],
    indicator_dots:true,    //指示点
    autoplay:true,          //自动播放
    circular:true,          //是否采用衔接滑动
    interval:3000,          //自动切换时间间隔
    duration:1000,          //滑动动画时长
    songlist: []            //音乐列表
  },
  //页面加载事件
  onLoad: function (options) {
    this.setData({
      songlist: config.Data
    })
  }
})

最难的就是播放界面的实现了,进度条采用slider组件,value为进度条进度,activeColor为覆盖的颜色,block-size和block-color分别为进度条上的点的大小与颜色。

<view class="container">
  <view class="background" style="background-image:url({{songImg}})"></view>
    <view class="rotate-disk-container">
      <view class="rotate-disk {{pauseStatus === false ? 'rotate-360' : 'rotate-360-paused'}}">      //中间圆形图片旋转的实现
        <image class="image" src="{{songImg}}"></image>
      </view>
    </view>
    <view class="title-container">
      <view class="text">
        <view><text class="name">{{songTitle}}----</text></view>
        <view><text class="singer">{{singerName}}</text></view>
      </view>
    </view>
    <view class="slider-container">
      <text class="slider-time">{{songState.currentPosition}}</text>
      <slider                                                    //下方时间条
          value="{{sliderValue}}"
          bindchange="bindSliderchange"
          activeColor="#13beec"
          style="width: 62%;margin: 0;"
          block-size="12"
          block-color="green"
        />
      <text class="slider-time">{{songTime}}</text>
    </view>
    <view class="operation-container">
      <image src="/Images/prev.png" class="icon-prev" bindtap="bindTapPrev"></image>
      <image
        src="{{pauseStatus === false ? '/Images/pause.png' : '/Images/start.png'}}"         //这里实现播放和暂停图片的切换
        class="icon-play" bindtap="bindTapPlay"
        >
        </image>
      <image src="/Images/next.png" class="icon-next" bindtap="bindTapNext"></image>
    </view>
</view>
播放功能这里用的是wx.playBackgroundAudio()。这里面需要音乐外链dataUrl,音乐外链本人用的是腾讯云,存入数据不需要钱但是读取数据是要钱的,存入音乐文件生成音乐链接即可。

Play.js


var app = getApp();
var util = require('../../utils/SongData.js');
Page({
  data: {
    songIndex: 0,
    songTitle:'',
    songUrl: '',
    songImg: '',
    songTime: '',
    pauseStatus: false,
    silderValue: 0,
    duration: 0,
    currentPosition: 0
  },
  onLoad: function (options) {
    var that = this; 
    var index = options.songid;
    var hash = util.Data[index];
    that.setData({
      songIndex: index,
      songUrl: hash.play_url,
      songTime: hash.seconds,
      songImg: hash.img,
      songTitle: hash.name,
      singerName: hash.singer
    });
    const audio = wx.getBackgroundAudioManager()
    audio.onEnded(function(){                 //播放结束自动播放下一首
      that.bindTapNext()
    })
  },
  onReady:function(e){
    this.play()
  },
  bindTapPlay:function() {
    if(this.data.pauseStatus === true){
      this.play()
      this.setData({
        pauseStatus: false
      })
    }else{
      wx.pauseBackgroundAudio()
      this.setData({
        pauseStatus: true
      })
    }
  },

  bindTapPrev: function(){         //上一首
    var that = this
    var length = util.Data.length
    var index = parseInt(that.data.songIndex)
    if(index == 0 ){                     //如果是第一首歌,则跳到最后一首
      index = length - 1
    }else{
      index = index - 1
    }

    this.setData({
     pauseStatus:false,
     songIndex: index,
     songTime: util.Data[index].seconds,
     songImg: util.Data[index].img,
     songTitle: util.Data[index].name,
     singerName: util.Data[index].singer
    })
    setTimeout(() => {
      if (that.data.pauseStatus === false) {
        that.play()
      }
    }, 1000)
   
  },
  bindTapNext: function(){    //下一首
    var that = this
    var length = util.Data.length
    var index = parseInt(that.data.songIndex)
    if(index == length - 1 ){            //如果是一首,则跳到第一首
      index = 0
    }else{
      index = index + 1
    }
    this.setData({
     pauseStatus: false,
     songIndex: index,
     songTime: util.Data[index].seconds,
     songImg: util.Data[index].img,
     songTitle: util.Data[index].name,
     singerName: util.Data[index].singer
    })
    setTimeout(() => {
      if (that.data.pauseStatus === false) {
        that.play()
      }
    }, 1000)
  },
  bindSliderchange: function(e) {             //更新进度条
    let value = e.detail.value
    let that = this
    wx.getBackgroundAudioPlayerState({
      success: function (res) {
        let {status, duration} = res
        if (status === 1 || status === 0) {
          that.setData({
            sliderValue: value
          })
          wx.seekBackgroundAudio({              //通过进度条长度与总时间的百分比同步歌曲进程
              position: Math.floor(e.detail.value * duration / 100),
          })
        }
      }
    })
  },
  play() {
    let index = this.data.songIndex
    wx.playBackgroundAudio({
      dataUrl: util.Data[index].play_url,
      title: util.Data[index].singer,
      coverImgUrl: util.Data[index].img
    })
    let that = this
    let timer = setInterval(function() {
      that.setDuration(that)
    }, 0)
    this.setData({timer: timer})
  },
  setDuration(that) {
    wx.getBackgroundAudioPlayerState({
      success: function (res) {
        let {status, duration, currentPosition} = res
        if (status === 1 || status === 0) {
          that.setData({
            currentPosition: that.stotime(currentPosition),
            duration: that.stotime(duration),
            sliderValue: Math.floor(currentPosition * 100 / duration),
          })
        }
      }
    })
  },
  stotime(s) {                     //转换时间的格式,将currentPosition和duration用时间的格式输出
    let t = ''
    if (s > -1) {
      let min = Math.floor(s / 60) % 60;
      let sec = Math.floor(s) % 60
      if (min < 10) { t += '0' }
      t += min + ':'
      if (sec < 10) { t += '0' }
      t += sec
    }
    return t
  },
})
 

·个人总结

第一次做这种类型的作业,也是第一次使用微信开发者工具,刚拿到课题的时候也是无从下手,所以前面几天主要是学习这类代码,在半知半解的状态下浏览借鉴了许多大佬的作品,根据自己心中布局完成了这次作业。过程也是被如何获取页面参数,切换上下首缠了很久,最后在同学的帮助下解决这个问题,才发现解决方法如此简单,也是让我意识到自己知识的薄弱。个人对这作品还是挺满意的,瑕疵就是一些功能没有实现吧,例如收藏,点赞,搜索这些功能,如果日后有时间还是会尝试更新以下的。

这次作业也是让我对前端UI的设计产生了极大的兴趣,不仅是html还是软件小程序的UI界面,都是我以后要去学习,毕竟计算机这个行业每秒都在迭代,每时每刻都有更好的替代,所以既然选了这个专业,便是要活到老,学到老。最后,希望大家能多指点!

 

posted @ 2020-10-21 21:55  Saulger  阅读(3266)  评论(0编辑  收藏  举报