• 微信小程序入门-音乐播放器


                萌新,随便做做,只是了解一下微信小程序,希望可以给看到的胖友一点参考。                        

                之前在网上看到这个人入门四天做完一个,我五天做完了,比他好看,突然有一点自信              

                然后发现自己特别不乐意重新看自己的代码,总觉得写的很乱。                                               

                应该更认真的推敲思路和注意规范,嗯,加油。                                                                       

     运行截图

      先放个图看看吧=。=分别是index页、list页和play页。虽然不是特别的好看,但是也OK。

      不要问我MUMU是啥,就是music取俩字母随便起个名字。

      然后歌词滚动特别差,从别人那里直接copy又改了的,还是不满意,但是也没什么头绪了。

      素材全部源自网络,也没有商用,仅自己学习用,如果还是需要删除请联系我。

    一、微信小程序入门

     1.起步

      从零开始,直接按官方文档里走就没问题了,非常简单,包括申请账号/安装/编译/代码构成/宿主环境/协同工作和发布/开发指南等等。

      微信开发者工具下载地址:点击跳转

     2.微信开发者工具简介

      萌新看了直接就上手的简介。(我也只用到这些……)

     (1)开发工具界面

      ①项目目录

      ②编码区

      ③控制台

        Console查看错和打印等信息

        AppData查看app内各个变量的值

      ④模拟器

        保存项目/编译项目都可刷新模拟器,不卡,与真机略有区别(所以一定要真机试,很方便,不能全信模拟器,说不定就遇到什么模拟器正常但是真机却不行的坑)

     (2)主要目录文件

      看看一打开就自带的目录:

    • app.js  可以存放全局变量、方法
    • app.json    app的配置文件 页面路径一定要写进去
    • page 页面文件夹
    • index 启动页文件夹
    • index.wxml 启动页的页面 类似html  div->view
    • index.js 启动页的js 类似JavaScript 实现对页面的控制 变量可以被页面引用 没有dom操作
    • Index.wxss 类似css

      以下为萌新理解,很浅,也不一定对,若有其他理解,请大佬赐教:

      信前端开发的特点就是,开发一个页面需要四个文件,包括js、json、wxml、wxss,大家都在一个文件夹里,还和文件夹同名。json没太用,感觉是跟微信本身的界面相关的配置文件(写个"navigationBarTitleText": "List",小程序上面标题栏就叫这个了),wxml跟html类似,wxss相当于css,js里面可以写方法(还是应该叫函数)什么的,和普通JavaScript一样,但是里面的数据可以被wxml直接拿来用(就是js里有个数据叫name,它的值是1,那么你在wxml里写一个{{name}},这个地方就显示1,相似的用法我用过的有在jsp的页面里面获取session中的内容,还有Vue.js也是双花括号里面放名字)。

     3.引入weUI

      weUI就是微信自己的一套按钮什么的,萌新必备,方便还比较美观。

      预览:https://weui.io

      下载:https://github.com/Tencent/weui-wxss

      引用:

        ①将weui-wxss-masterdiststyleweui.wxss文件导入到小程序项目的某个目录下

        ②在app.wxss中加入weui.wxss的引用 @import 'style/weui.wxss';(这里导入到了style目录)

      注:weui-wxss-master中src里面是一个example项目,可以打开该项目预览各个控件的效果

    二、开发音乐播放器

     1.构思

      数据:只做前端,不搞数据库,那么就在js里用ajax那种请求从网上获取数据。(或者用微信小程序的云开发,我还没了具体了解)

      页面:做一个简单的播放器,需要至少两个页,音乐列表页和正在播放页。

     2.准备数据

      这里用腾讯云的对象存储来存储数据。存里的每个文件都生成一个地址,访问这个地址就直接获取文件。

      (这腾讯云,你可以免费存一阵数据,但是获取数据是要花钱的,咱自己玩,访问次数不多,花了一块多……)

      按自己喜好存里点mp3和图片和lrc什么的。

      然后存一个json作为音乐库,里面包括之前存的mp3、图片的地址。

      这样我们做的播放器就先获取这个json文件,然后从里面读放哪首歌,然后拿着那个歌的mp3地址再获取一下真正的mp3文件,就能用了。

      【本来是想公有云大家都可以打开链接感受一下,但发现有的人每次感受的太多了,于是我直接删库跑路关掉不用了。然后再免费给腾讯打个广告,这个活动还是非常划算的,就花一块钱用着玩呗->点我<-

    {
        "appname": "MUMU Music",
        "version": "1.0",
        "music": [
            {
                "name": "光年之外",
                "singer": "G.E.M",
                "time": 235,
                "downloadURL": "https://不告诉你省得你访问花我钱.cos.ap-beijing.myqcloud.com/musics/不告诉你省得你访问花我钱",
                "lrc": "https://不告诉你省得你访问花我钱.cos.ap-beijing.myqcloud.com/不告诉你省得你访问花我钱",
                "pic": "https://不告诉你省得你访问花我钱.cos.ap-beijing.myqcloud.com/不告诉你省得你访问花我钱"
            },
            {
                "name": "Life is like a Boat",
                "singer": "Rie fu",
                "time": 300,
                "downloadURL": "https://不告诉你省得你访问花我钱.cos.ap-beijing.myqcloud.com/不告诉你省得你访问花我钱",
                "lrc": "null",
                "pic": "https://不告诉你省得你访问花我钱.cos.ap-beijing.myqcloud.com/不告诉你省得你访问花我钱"
            },
            {
                "name": "I Will Return",
                "singer": "Skylar Grey",
                "time": 236,
                "downloadURL": "https://不告诉你省得你访问花我钱.cos.ap-beijing.myqcloud.com/不告诉你省得你访问花我钱",
                "lrc": "null",
                "pic": "https://不告诉你省得你访问花我钱.cos.ap-beijing.myqcloud.com/不告诉你省得你访问花我钱"
            },
            {
                "name": "青鸟",
                "singer": "生物股长",
                "time": 216,
                "downloadURL": "https://不告诉你省得你访问花我钱.cos.ap-beijing.myqcloud.com/不告诉你省得你访问花我钱",
                "lrc": "null",
                "pic": "https://不告诉你省得你访问花我钱.cos.ap-beijing.myqcloud.com/不告诉你省得你访问花我钱"
            },
            {
                "name": "大鱼",
                "singer": "周深",
                "time": 313,
                "downloadURL": "https://不告诉你省得你访问花我钱.cos.ap-beijing.myqcloud.com/不告诉你省得你访问花我钱",
                "lrc": "null",
                "pic": "https://不告诉你省得你访问花我钱.cos.ap-beijing.myqcloud.com/不告诉你省得你访问花我钱"
            },
            {
                "name": "小小恋歌",
                "singer": "新垣结衣",
                "downloadURL": "https://不告诉你省得你访问花我钱.cos.ap-beijing.myqcloud.com/不告诉你省得你访问花我钱",
                "lrc": "null",
                "pic": "https://不告诉你省得你访问花我钱.cos.ap-beijing.myqcloud.com/不告诉你省得你访问花我钱"
            }
        ]
    }
    
    musics.json
    musics.json

     3.开发

    (1)新建项目

      在微信开发者工具里面点左上角“项目”-“新建项目”,弹窗里填写信息,AppID可以用测试号(这里仅仅自己开发着玩所以无所谓,想要让别人你的小程序也用就去注册一个),点击新建就好了。

    (2)写代码

      首先项目给了一个获取用户信息的页(index),咱也懒得改,直接留着作为启动页(?),下面加个按钮跳转到列表页。

       先不着急写别的页面,我想app打开之后就先把我那大json获取到,反正之后会经常用,直接作为全局变量留着了。全局变量是app.js里的globalData,在里面声明一个名字叫musicLib,在下面写个微信小程序写法的请求数据的一段代码(wx.request,详情参考官方文档),然后把获取到的结果给musicLib存住(this.globalData.musicLib = res.data,萌新翻译:这页的globalData里的musicLib的值是请求结果中的数据)。

    //app.js
    App({
      globalData: {
        userInfo: null, //用户信息
        musicLib: [], //音乐库
        bgm: 0, //是否有背景音乐
        playing: 0, //背景音乐是否正在播放
        index: null, //当前背景音乐标号
        height: 0 //屏幕高度
      },
      onLaunch: function() {
        // 展示本地存储能力
        var logs = wx.getStorageSync('logs') || []
        logs.unshift(Date.now())
        wx.setStorageSync('logs', logs)
    
        // 登录
        wx.login({
          success: res => {
            // 发送 res.code 到后台换取 openId, sessionKey, unionId
          }
        })
        // 获取用户信息
        wx.getSetting({
          success: res => {
            if (res.authSetting['scope.userInfo']) {
              // 已经授权,可以直接调用 getUserInfo 获取头像昵称,不会弹框
              wx.getUserInfo({
                success: res => {
                  // 可以将 res 发送给后台解码出 unionId
                  this.globalData.userInfo = res.userInfo
    
                  // 由于 getUserInfo 是网络请求,可能会在 Page.onLoad 之后才返回
                  // 所以此处加入 callback 以防止这种情况
                  if (this.userInfoReadyCallback) {
                    this.userInfoReadyCallback(res)
                  }
                }
              })
            }
          }
        })
        //获取音乐库
        wx.request({
          url: 'https://music-1300015560.cos.ap-beijing.myqcloud.com/musics.json',
          success: res => {
            this.globalData.musicLib = res.data
          }
        })
    
        let that = this; //获取屏高
        wx.getSystemInfo({
          success: function(res) {
            that.globalData.height = res.windowHeight;
          }
        })
      }
    })
    app.js

      然后在目录里新建个list页的文件夹,建好4个同名文件(似乎文件自动就给建了,时间太久记得不太清)。一定要在app,json里加上新页面的路径。

      接下来在index页写个跳转到list页,在index的wxml中写个钮,绑定点击事件,然后在js里写事件。事件各种各样可以参考文档,这里我绑了俩事件,一个是点击按钮时的事件,一个是结束点击后的事件(<image class="golistBtn" bindtouchstart="logo" bindtouchend="golist"  src="{{logo}}">,按钮是个图片,logo方法是为了做个点击的效果换图片,golist方法是点完松手了把图片换回去,然后跳转到list页,{{logo}}是js里的一个值,我用logo方法改了地址,图片就变了),然鹅这个切换图片来的慢,长按能看见,点一下基本是看不清变化了orz后面的钮我都做了这种效果,都不明显,嘤嘤嘤。

     

     普通->按住

    <!--index.wxml-->
    <view class="container">
      <view class="userinfo">
        <button wx:if="{{!hasUserInfo && canIUse}}" open-type="getUserInfo" bindgetuserinfo="getUserInfo"> 获取头像昵称 </button>
        <block wx:else>
          <image bindtap="bindViewTap" class="userinfo-avatar" src="{{userInfo.avatarUrl}}" mode="cover"></image>
          <text class="userinfo-nickname" style="color:green">Hello,{{userInfo.nickName}}</text>
          <text class="userinfo-nickname" style="color:green">欢迎来听MUMU的歌单</text>
        </block>
      </view>
      <view class="appmotto">
        <image class="golistBtn" bindtouchstart="logo" bindtouchend="golist" src="{{logo}}"></image>
      </view>
      <view class="ft">
        <view>歌单内容来自网络,侵权请联系删除</view>
        <view>Email:tzy1996@foxmail.com</view>
        <view>APP from Hanana</view>
      </view>
    </view>
    index.wxml
    //index.js
    //获取应用实例
    const app = getApp()
    
    Page({
      data: {
        logo: "/images/play2.png",
        //...
      },
      
      //...
        
      //点击跳转至list
      golist: function () {
        this.setData({
          logo: "/images/play2.png"
        })
        wx.navigateTo({
          url: '../list/list'
        })
      },
    
      //logo
      logo: function (){
        this.setData({
          logo: "/images/play3.png"
        })
      },
      //...
    })
    index.js

      接下来写list页。页面wxml跟html基本一样,略有区别。其中把音乐列表展示出来的关键代码是wx:for,具体参考文档。

    <!--list.wxml-->
    <view class="page list">
    <!--歌曲列表-->
      <view class="page__bd">
        <view class="weui-panel weui-panel__access">
          <view class="weui-panel__bd">
            <navigator wx:for="{{musics.music}}" wx:for-item="music" url="../play/play?index={{index}}" class="weui-media-box weui-media-box_appmsg" hover-class="weui-cell_active" style="background-image:url({{index%2==0?bkimg0:bkimg1}})">
              <view class="weui-media-box__hd weui-media-box__hd_in-appmsg">
                <image class="weui-media-box__thumb" src="{{music.pic}}" mode="aspectFill" />
              </view>
              <view class="weui-media-box__bd weui-media-box__bd_in-appmsg">
                <view class="weui-media-box__title" style="color:green">{{music.name}}</view>
                <view class="weui-media-box__desc">{{music.singer}}</view>
              </view>
            </navigator>
          </view>
        </view>
      </view>
    </view>
    list.wxml

      在js中首先获取到全局变量,然后把值给当musis,然后在页面使用{{musics.music}},通过wx:for遍历出来。可以看到它自动生成的js中有很多空的方法,都可以写东西,只是这里没用到。

    // pages/list/list.js
    var app = getApp() //获取全局
    Page({
      /**
       * 页面的初始数据
       */
      data: {
        musics: [],
        bkimg1:"https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1565934170123&di=c7538649f607d13353451b3cec56a846&imgtype=0&src=http%3A%2F%2Fs6.sinaimg.cn%2Forignal%2F4122e7c9878630b2891e5",
        // bkimg0: "https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1565935519496&di=43b37e1b73c573fd0d089fec582462d7&imgtype=0&src=http%3A%2F%2Fimg5.duitang.com%2Fuploads%2Fitem%2F201302%2F16%2F20130216161327_rZtkz.thumb.700_0.jpeg"
        bkimg0:"https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1565935334857&di=386b8eb76388b0a6eef03003512e6f60&imgtype=0&src=http%3A%2F%2Fgss0.baidu.com%2F-Po3dSag_xI4khGko9WTAnF6hhy%2Fzhidao%2Fpic%2Fitem%2F55e736d12f2eb938f0e05797d5628535e4dd6fc1.jpg"
      },
    
      /**
       * 生命周期函数--监听页面加载
       */
      onLoad: function (options) {
        this.setData({
          musics: app.globalData.musicLib //全局变量给musics
        })
      },
    
      /**
       * 生命周期函数--监听页面初次渲染完成
       */
      onReady: function () {
    
      },
    
      /**
       * 生命周期函数--监听页面显示
       */
      onShow: function () {
    
      },
    
      /**
       * 生命周期函数--监听页面隐藏
       */
      onHide: function () {
    
      },
    
      /**
       * 生命周期函数--监听页面卸载
       */
      onUnload: function () {
    
      },
    
      /**
       * 页面相关事件处理函数--监听用户下拉动作
       */
      onPullDownRefresh: function () {
    
      },
    
      /**
       * 页面上拉触底事件的处理函数
       */
      onReachBottom: function () {
    
      },
    
      /**
       * 用户点击右上角分享
       */
      onShareAppMessage: function () {
    
      }
    })
    list.js

      接下来就是点击某一列,跳转到播放页。播放页需要知道该播放哪首歌,因此需要传一个歌曲的编号的参数。所以在list.wxml中,使用navigator作为列表的一行,直接设置url就可点击跳转,url是../play/play,后面加上?index={{index}},就把编号传到play页啦。

      接下来就是重要的play页,新建play文件夹、play的4个文件、在app.json里面加上路径,然后写页面。

    <!--play.wxml-->
    <view class="page">
      <view class="page__hd" >
        <text></text>
        <text style="color:#0e9630;font-size:20px">{{playdata.name}}</text>
        <text style="color:grey;font-size:12px">{{playdata.singer}}</text>
      </view>
      <view class="page__bd" animation="{{ani}}">
        <view class="box" bindtap="down">
          <view class="cd" style="transform: rotate({{angle}}deg);">
            <image class="pic" src="{{playdata.pic}}" mode="aspectFill"></image>
          </view>
        </view>
        <view class="lrc"  bindtap="up">
          <view class="paper">
            <scroll-view scroll-y="true" scroll-with-animation='true' scroll-top='{{marginTop}}' style="height:{{lrcH}}px">
              <view class='contentText'>
                <block wx:for='{{lrc}}'>
                  <text class="{{lrcRow == index ? 'currentTime' : ''}}">{{item[1]}}</text>
                </block>
              </view>
            </scroll-view>>
          </view>
        </view>
      </view>
      <view class="page__ft">
        <view class="playBtns">
          <view class="slider">
            <text class="time">{{timeNow/60 | Int}}:{{timeNow%60<10 ? "0" + (timeNow%60 | Int) : timeNow%60 | Int}}</text>
            <slider min="0" max="{{timeAll}}" value="{{timeNow | Int}}" class="sli" bindchanging="touchSli" bindchange="playHere" block-color="{{blockColor}}" activeColor="#f4ea2a" />
            <text class="time">{{timeAll/60 | Int}}:{{timeAll%60<=9? "0"+timeAll%60 : timeAll%60}}</text>
          </view>
          <view class="btns">
            <image class="preBtn" bindtouchstart="touchPreBtn" bindtouchend="pre" src="/images/pre{{btnE}}.png" mode="aspectFit"></image>
            <image class="playBtn" bindtouchstart="touchPlayBtn" bindtouchend="playOrpause" src="/images/play{{btnP}}.png" mode="aspectFit"></image>
            <image class="nextBtn" bindtouchstart="touchNextBtn" bindtouchend="next" src="/images/next{{btnT}}.png" mode="aspectFit"></image>
          </view>
        </view>
        <view class="ft">
          <text>APP From Hanana</text>
        </view>
      </view>
    </view>
    play.wxml

      js写的一言难尽,我暂时先放这,如果有人问的话我再想办法解释吧orz

      重要的代码是wx.getBackgroundAudioManager,是微信自己有的一个背景音乐管理的东西,设置里面的各种值就可以实现播放、暂停、从哪秒播放,还有backgroundAudioManager里的onTimeUpdate(function() {}),只要音乐在播放,他就运行里面的代码,据说一秒三次!所以歌词滚动、进度条更新、图片旋转都跟他有关。而且,因为是背景音乐管理器,所以即使退出这一页,bgm还在播放的,这样就可以在list页和play页进进出出,不过我当时没有在list页加上“正在播放”的标志,要是加上就完美了……

      进度条不难,图片和歌词上下滑动也不难,参考官方文档就好。就是歌词滚动和高亮让我纠结两天,后来也没心情弄了。

    // pages/play/play.js
    var app = getApp()
    Page({
    
      /**
       * 页面的初始数据
       */
      data: {
        playdata: [], //播放页显示的数据
        btnP: 0, //播放暂停按钮图片
        btnE: 0, //上一首按钮图片
        btnT: 0, //下一首按钮图片
        timeNow: 0, //当前时间
        timeAll: 0, //总时间
        blockColor: "white", //滑块颜色
        angle: 0, //旋转角度
        lrcRow: 0, //当前歌词行数
        lrc: null, //歌词
        marginTop: 0, //滚动行数
        line: 0, //高亮行
        ctime: 1, //时间校验
        lrcH: 60, //滚动歌词高度
        updown: 0 //cd歌词是否上移
      },
    
      /**
       * 生命周期函数--监听页面加载
       */
      onLoad: function(options) {
        var that = this
        var playdata = app.globalData.musicLib.music[options.index]
        //请求歌词
        this.getLRC(playdata)
        const backgroundAudioManager = wx.getBackgroundAudioManager()
        if (app.globalData.index == null || app.globalData.index != options.index) {
          app.globalData.index = options.index
          app.globalData.bgm = 1;
          app.globalData.playing = 1;
          //背景音乐播放
          //微信小程序旧版代码
          // wx.playBackgroundAudio({
          //   dataUrl: playdata.downloadURL,
          //   title: playdata.name,
          //   coverImgUrl: playdata.pic
          // })
          //微信小程序新版代码
          backgroundAudioManager.title = playdata.name
          backgroundAudioManager.epname = 'nnn'
          backgroundAudioManager.singer = playdata.singer
          backgroundAudioManager.coverImgUrl = playdata.pic
          // 设置了 src 之后会自动播放
          backgroundAudioManager.src = playdata.downloadURL
          backgroundAudioManager.onEnded(function() { //播放完毕
            app.globalData.bgm = 0
            app.globalData.playing = 0
            that.setData({
              btnP: app.globalData.playing,
              lrcRow: 0
            })
          })
        }
        backgroundAudioManager.onTimeUpdate(function() { //播放中
          that.setData({
            timeNow: backgroundAudioManager.currentTime, //更新进度条
            angle: backgroundAudioManager.currentTime * 0.65, //更新旋转角度
          })
          if (that.data.lrc.length > 1) { //如果有歌词
            if (that.data.lrcRow >= that.data.line) { //超过line行开始滚动
              that.setData({
                marginTop: (that.data.lrcRow - that.data.line) * 28.8
              })
            }
            // 文稿对应行颜色改变
            if (that.data.lrcRow != that.data.lrc.length - 1) { //
              var j = 0;
              for (var j = that.data.lrcRow; j < that.data.lrc.length; j++) {
                // 当前时间与前一行,后一行时间作比较, j:代表当前行数
                if (that.data.lrcRow == that.data.lrc.length - 2) {
                  //最后一行只能与前一行时间比较
                  if (parseFloat(backgroundAudioManager.currentTime + that.data.ctime) > parseFloat(that.data.lrc[that.data.lrc.length - 1][0])) {
                    that.setData({
                      lrcRow: that.data.lrc.length - 1
                    })
                    return;
                  }
                } else {
                  if (parseFloat(backgroundAudioManager.currentTime + that.data.ctime) > parseFloat(that.data.lrc[j][0]) && parseFloat(backgroundAudioManager.currentTime + that.data.ctime) < parseFloat(that.data.lrc[j + 1][0])) {
                    that.setData({
                      lrcRow: j
                    })
                    return;
                  }
                }
              }
            }
          }
        })
        this.setData({
          playdata: playdata,
          timeAll: playdata.time,
          btnP: app.globalData.playing,
          //timeNow: backgroundAudioManager.currentTime,
          angle: backgroundAudioManager.currentTime * 0.65,
          lrcH: app.globalData.height - 545
        })
    
      },
    
      /**
       * 上一首
       */
      pre: function() {
        var that = this
        var index = app.globalData.index
        if (index == 0) {
          index = (+app.globalData.musicLib.music.length);
        }
        index--
        app.globalData.index = index
        app.globalData.playing = 1
        var playdata = app.globalData.musicLib.music[index]
        //请求歌词
        this.getLRC(playdata)
        // wx.playBackgroundAudio({
        //   dataUrl: playdata.downloadURL,
        //   title: playdata.name,
        //   coverImgUrl: playdata.pic
        // })
        const backgroundAudioManager = wx.getBackgroundAudioManager()
        backgroundAudioManager.title = playdata.name
        backgroundAudioManager.epname = 'nnn'
        backgroundAudioManager.singer = playdata.singer
        backgroundAudioManager.coverImgUrl = playdata.pic
        backgroundAudioManager.src = playdata.downloadURL
        this.setData({
          playdata: playdata,
          timeAll: playdata.time,
          btnP: 1,
          btnE: 0,
          lrcRow: 0
        })
      },
    
      /**
       * 下一首
       */
      next: function() {
        var that = this
        var index = (+app.globalData.index) + 1
        if (index == app.globalData.musicLib.music.length) {
          index = 0;
        }
        app.globalData.index = index
        app.globalData.playing = 1
        var playdata = app.globalData.musicLib.music[index]
        //请求歌词
        this.getLRC(playdata)
        // wx.playBackgroundAudio({
        //   dataUrl: playdata.downloadURL,
        //   title: playdata.name,
        //   coverImgUrl: playdata.pic
        // })
        const backgroundAudioManager = wx.getBackgroundAudioManager()
        backgroundAudioManager.title = playdata.name
        backgroundAudioManager.epname = 'nnn'
        backgroundAudioManager.singer = playdata.singer
        backgroundAudioManager.coverImgUrl = playdata.pic
        backgroundAudioManager.src = playdata.downloadURL
        this.setData({
          playdata: playdata,
          timeAll: playdata.time,
          btnP: 1,
          btnT: 0,
          lrcRow: 0
        })
      },
    
      /**
       * 播放/暂停
       */
      playOrpause: function() {
        const backgroundAudioManager = wx.getBackgroundAudioManager()
        var playdata = this.data.playdata
        if (app.globalData.bgm == 0) { //在播放页放完一首后,点击播放继续放当前歌曲
          backgroundAudioManager.title = playdata.name
          backgroundAudioManager.epname = 'nnn'
          backgroundAudioManager.singer = playdata.singer
          backgroundAudioManager.coverImgUrl = playdata.pic
          backgroundAudioManager.src = playdata.downloadURL
          app.globalData.bgm = 1
          app.globalData.playing = 1
        } else if (app.globalData.playing == 0) { //播放
          //wx.playBackgroundAudio()
          backgroundAudioManager.play()
          app.globalData.playing = 1
        } else { //暂停
          //wx.pauseBackgroundAudio()
          backgroundAudioManager.pause()
          app.globalData.playing = 0
        }
        this.setData({
          btnP: app.globalData.playing
        })
      },
    
      /**
       * 触摸播放按钮切换图片
       */
      touchPlayBtn: function() {
        if (this.data.btnP == 0) {
          this.setData({
            btnP: 2
          })
        } else {
          this.setData({
            btnP: 3
          })
        }
      },
    
      /**
       * 触摸上一首按钮切换图片
       */
      touchPreBtn: function() {
        this.setData({
          btnE: 1
        })
      },
    
      /**
       * 触摸下一首按钮切换图片
       */
      touchNextBtn: function() {
        this.setData({
          btnT: 1
        })
      },
    
      /**
       * 切换播放进度(单位:秒)
       */
      playHere: function(event) {
        //微信小程序旧版代码
        // wx.seekBackgroundAudio({
        //   position: 30
        // })
        //微信小程序新版代码
        var that = this
        var playdata = that.data.playdata
        const backgroundAudioManager = wx.getBackgroundAudioManager()
        backgroundAudioManager.seek(event.detail.value)
        //进度前拉歌词处理
        if (backgroundAudioManager.currentTime < this.data.timeNow){
          for (var i = 1; i < that.data.lrc.length; i++) {
            if (that.data.lrc[i][0] > backgroundAudioManager.currentTime){
              that.setData({
                lrcRow: i - 1
              })
              break;
            }
          }
        }else{//进度后拉歌词处理
          for (var i = that.data.lrcRow; i < that.data.lrc.length; i++) {
            if (that.data.lrc[i][0] > backgroundAudioManager.currentTime) {
              that.setData({
                lrcRow: i
              })
              break;
            }
          }
        }
        backgroundAudioManager.onTimeUpdate(function () { //播放中
          that.setData({
            timeNow: backgroundAudioManager.currentTime, //更新进度条
            angle: backgroundAudioManager.currentTime * 0.65, //播放时旋转
            //marginTop: row * 28.9
          })
          if (that.data.lrc.length > 1) { //如果有歌词
            if (that.data.lrcRow >= that.data.line) { //超过line行开始滚动
              that.setData({
                marginTop: (that.data.lrcRow - that.data.line) * 28.8
              })
            }
            // 文稿对应行颜色改变
            if (that.data.lrcRow != that.data.lrc.length - 1) { //
              var j = 0;
              for (var j = that.data.lrcRow; j < that.data.lrc.length; j++) {
                // 当前时间与前一行,后一行时间作比较, j:代表当前行数
                if (that.data.lrcRow == that.data.lrc.length - 2) {
                  //最后一行只能与前一行时间比较
                  if (parseFloat(backgroundAudioManager.currentTime + that.data.ctime) > parseFloat(that.data.lrc[that.data.lrc.length - 1][0])) {
                    that.setData({
                      lrcRow: that.data.lrc.length - 1
                    })
                    return;
                  }
                } else {
                  if (parseFloat(backgroundAudioManager.currentTime + that.data.ctime) > parseFloat(that.data.lrc[j][0]) && parseFloat(backgroundAudioManager.currentTime + that.data.ctime) < parseFloat(that.data.lrc[j + 1][0])) {
                    that.setData({
                      lrcRow: j
                    })
                    return;
                  }
                }
              }
            }
          }
        })
        that.setData({
          blockColor: "white"
        })
      },
    
      /**
       * 拖动进度条滑块变色
       */
      touchSli: function(event) {
        var that = this
        const backgroundAudioManager = wx.getBackgroundAudioManager()
        backgroundAudioManager.onTimeUpdate(function() { //播放中 进度条不随播放变化
          that.setData({
            timeNow: event.detail.value
          })
        })
        that.setData({
          blockColor: "yellow"
        })
      },
    
      /**
       * cd向上滑动
       */
      up: function() {
        var that = this
        if (that.data.updown == 0) {
          that.setData({
            line: 4,
            lrcH: app.globalData.height - 350,//"330px",
            updown: 1
          })
          var animation = wx.createAnimation({
            duration: 500,//动画持续多少毫秒
            timingFunction: 'ease',//“运动”的方式,例子中的 'ease'代表动画以低速开始,然后加快,在结束前变慢  
            delay: 0//多久后动画开始运行
          })
          animation.translate(0, -180).step()
          that.setData({
            ani: animation.export()
          })
        }
      },
    
      /**
       * cd向下滑动
       */
      down: function() {
        var that = this
        if (that.data.updown == 1) {
          var animation = wx.createAnimation({
            duration: 500,//动画持续多少毫秒
            timingFunction: 'ease',//“运动”的方式,例子中的 'ease'代表动画以低速开始,然后加快,在结束前变慢  
            delay: 0//多久后动画开始运行
          })
          animation.translate(0, 0).step()
          that.setData({
            ani: animation.export()
          })
          that.setData({
            line: 0,
            lrcH: app.globalData.height - 545,
            updown: 0
          })
        }
      },
    
      /**
       * 获取歌词
       */
      getLRC: function(playdata) {
        var that = this
        if (playdata.lrc != null || playdata.lrc != "") {
          wx.request({
            url: playdata.lrc,
            success: function(res) {
              var lrc = that.sliceNull(that.parseLyric(res.data))
              that.setData({
                lrc: lrc
              })
            },
            fail: function(res) {
              that.setData({
                lrc: [
                  [0, "暂无歌词"]
                ]
              })
            },
            complete: function(res) {},
          })
        }
      },
    
      /**
       * 解析歌词 来自https://www.jianshu.com/p/34efd94647b7
       */
      parseLyric: function(text) {
        var result = []
        var lines = text.split('
    ') //切割每一行
        var pattern = /[d{2}:d{2}.d{2}]/g //用于匹配时间的正则表达式,匹配的结果类似[xx:xx.xx]
        //去掉不含时间的行
        while (!pattern.test(lines[0])) {
          lines = lines.slice(1);
        }
        //上面用'
    '生成数组时,结果中最后一个为空元素,这里将去掉
        if (lines[lines.length - 1].length == 0) {
          lines.pop()
        }
        lines.forEach(function(v /*数组元素值*/ , i /*元素索引*/ , a /*数组本身*/ ) {
          //提取出时间[xx:xx.xx]
          var time = v.match(pattern),
            //提取歌词
            value = v.replace(pattern, '');
          // 因为一行里面可能有多个时间,所以time有可能是[xx:xx.xx][xx:xx.xx][xx:xx.xx]的形式,需要进一步分隔
          time.forEach(function(v1, i1, a1) {
            //去掉时间里的中括号得到xx:xx.xx
            var t = v1.slice(1, -1).split(':');
            //将结果压入最终数组
            result.push([parseInt(t[0], 10) * 60 + parseFloat(t[1]), value]);
          });
        });
        //最后将结果数组中的元素按时间大小排序,以便保存之后正常显示歌词
        result.sort(function(a, b) {
          return a[0] - b[0];
        });
        return result;
      },
      
      //去除空白
      sliceNull: function(lrc) {
        var result = []
        for (var i = 0; i < lrc.length; i++) {
          if (lrc[i][1] == "") {} else {
            result.push(lrc[i]);
          }
        }
        return result
      },
    
      /**
       * 生命周期函数--监听页面初次渲染完成
       */
      onReady: function() {
    
      },
    
      /**
       * 生命周期函数--监听页面显示
       */
      onShow: function() {
    
      },
    
      /**
       * 生命周期函数--监听页面隐藏
       */
      onHide: function() {
    
      },
    
      /**
       * 生命周期函数--监听页面卸载
       */
      onUnload: function() {
    
      },
    
      /**
       * 页面相关事件处理函数--监听用户下拉动作
       */
      onPullDownRefresh: function() {
    
      },
    
      /**
       * 页面上拉触底事件的处理函数
       */
      onReachBottom: function() {
    
      },
    
      /**
       * 用户点击右上角分享
       */
      onShareAppMessage: function() {
    
      }
    })
    play.js

    三、总结

      微信小程序还是有自己的优势的吧。只是我不明白,我遇到很多软件,既有小程序又有app,但是小程序往往是阉割版,会提示你下载app来使用app。那么做了小程序就只是为了推广?

      做这个入门还是很简单的,不知道以后会不会有别的项目机会。官方文档写的都很清楚,再不会的话,网上也有各种博客参考,不难学,

      感谢阅读,我们下期再见(嗯?)

  • 相关阅读:
    SQL怎么随机提取出一条信息 mysql 获取随机记录
    css3 渐变 各浏览器兼容
    php的curl和socket的区别 转
    php获取本机真实IP地址
    SSH超时断开 ssh 老掉线
    php 获取远程服务器信息 get_headers 的使用
    如何删除右键菜单中的Catalyst(TM) Control Center选项
    多线程概念、案例!
    网络编程
    我的博客开通啦
  • 原文地址:https://www.cnblogs.com/unpro-mercy/p/11549194.html
Copyright © 2020-2023  润新知