微信小程序入門-音樂播放器

            萌新,隨便作作,只是瞭解一下微信小程序,但願能夠給看到的胖友一點參考。                         
css

            以前在網上看到這我的入門四天作完一個,我五天作完了,比他好看,忽然有一點自信               
html

            而後發現本身特別不樂意從新看本身的代碼,總以爲寫的很亂。                                                 
前端

            應該更認真的推敲思路和注意規範,嗯,加油。                                                                          git

 運行截圖

  先放個圖看看吧=。=分別是index頁、list頁和play頁。雖然不是特別的好看,可是也OK。github

  不要問我MUMU是啥,就是music取倆字母隨便起個名字。ajax

  而後歌詞滾動特別差,從別人那裏直接copy又改了的,仍是不滿意,可是也沒什麼頭緒了。正則表達式

  素材所有源自網絡,也沒有商用,僅本身學習用,若是仍是須要刪除請聯繫我。數據庫

1、微信小程序入門

 1.起步

  從零開始,直接按官方文檔裏走就沒問題了,很是簡單,包括申請帳號/安裝/編譯/代碼構成/宿主環境/協同工做和發佈/開發指南等等。json

  微信開發者工具下載地址:點擊跳轉小程序

 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-master\dist\style\weui.wxss文件導入到小程序項目的某個目錄下

    ②在app.wxss中加入weui.wxss的引用 @import 'style/weui.wxss';(這裏導入到了style目錄)

  注:weui-wxss-master中src裏面是一個example項目,能夠打開該項目預覽各個控件的效果

2、開發音樂播放器

 1.構思

  數據:只作前端,不搞數據庫,那麼就在js裏用ajax那種請求從網上獲取數據。(或者用微信小程序的雲開發,我還沒了具體瞭解)

  頁面:作一個簡單的播放器,須要至少兩個頁,音樂列表頁和正在播放頁。

 2.準備數據

  這裏用騰訊雲的對象存儲來存儲數據。存裏的每一個文件都生成一個地址,訪問這個地址就直接獲取文件。

  (這騰訊雲,你能夠免費存一陣數據,可是獲取數據是要花錢的,咱本身玩,訪問次數很少,花了一塊多……)

  按本身喜愛存裏點mp3和圖片和lrc什麼的。

  而後存一個json做爲音樂庫,裏面包括以前存的mp三、圖片的地址。

  這樣咱們作的播放器就先獲取這個json文件,而後從裏面讀放哪首歌,而後拿着那個歌的mp3地址再獲取一下真正的mp3文件,就能用了。

{
    "appname": "MUMU Music",
    "version": "1.0",
    "music": [
        {
            "name": "光年以外",
            "singer": "G.E.M",
            "time": 235,
            "downloadURL": "https://music-1300015560.cos.ap-beijing.myqcloud.com/musics/gnzw/gnzw.mp3",
            "lrc": "https://music-1300015560.cos.ap-beijing.myqcloud.com/musics/gnzw/gnzw.lrc",
            "pic": "https://music-1300015560.cos.ap-beijing.myqcloud.com/musics/gnzw/gnzw.jpg"
        },
        {
            "name": "Life is like a Boat",
            "singer": "Rie fu",
            "time": 300,
            "downloadURL": "https://music-1300015560.cos.ap-beijing.myqcloud.com/musics/lilab/lilab.mp3",
            "lrc": "null",
            "pic": "https://music-1300015560.cos.ap-beijing.myqcloud.com/musics/lilab/lilab.jpg"
        },
        {
            "name": "I Will Return",
            "singer": "Skylar Grey",
            "time": 236,
            "downloadURL": "https://music-1300015560.cos.ap-beijing.myqcloud.com/musics/iwr/iwr.mp3",
            "lrc": "null",
            "pic": "https://music-1300015560.cos.ap-beijing.myqcloud.com/musics/iwr/iwr.jpg"
        },
        {
            "name": "青鳥",
            "singer": "生物股長",
            "time": 216,
            "downloadURL": "https://music-1300015560.cos.ap-beijing.myqcloud.com/musics/bb/bb.mp3",
            "lrc": "null",
            "pic": "https://music-1300015560.cos.ap-beijing.myqcloud.com/musics/bb/bb.jpg"
        },
        {
            "name": "大魚",
            "singer": "周深",
            "time": 313,
            "downloadURL": "https://music-1300015560.cos.ap-beijing.myqcloud.com/musics/bf/bf.mp3",
            "lrc": "null",
            "pic": "https://music-1300015560.cos.ap-beijing.myqcloud.com/musics/bf/bf.jpg"
        },
        {
            "name": "小小戀歌",
            "singer": "新垣結衣",
            "downloadURL": "https://music-1300015560.cos.ap-beijing.myqcloud.com/musics/cknu/cknu.mp3",
            "lrc": "null",
            "pic": "https://music-1300015560.cos.ap-beijing.myqcloud.com/musics/cknu/cknu.jpg"
        },
 {
            "name": "光年以外",
            "singer": "G.E.M",
            "time": 235,
            "downloadURL": "https://music-1300015560.cos.ap-beijing.myqcloud.com/musics/gnzw/gnzw.mp3",
            "lrc": "https://music-1300015560.cos.ap-beijing.myqcloud.com/musics/gnzw/gnzw.lrc",
            "pic": "https://music-1300015560.cos.ap-beijing.myqcloud.com/musics/gnzw/gnzw.jpg"
        },
        {
            "name": "Life is like a Boat",
            "singer": "Rie fu",
            "time": 300,
            "downloadURL": "https://music-1300015560.cos.ap-beijing.myqcloud.com/musics/lilab/lilab.mp3",
            "lrc": "null",
            "pic": "https://music-1300015560.cos.ap-beijing.myqcloud.com/musics/lilab/lilab.jpg"
        },
        {
            "name": "I Will Return",
            "singer": "Skylar Grey",
            "time": 236,
            "downloadURL": "https://music-1300015560.cos.ap-beijing.myqcloud.com/musics/iwr/iwr.mp3",
            "lrc": "null",
            "pic": "https://music-1300015560.cos.ap-beijing.myqcloud.com/musics/iwr/iwr.jpg"
        },
        {
            "name": "青鳥",
            "singer": "生物股長",
            "time": 216,
            "downloadURL": "https://music-1300015560.cos.ap-beijing.myqcloud.com/musics/bb/bb.mp3",
            "lrc": "null",
            "pic": "https://music-1300015560.cos.ap-beijing.myqcloud.com/musics/bb/bb.jpg"
        },
        {
            "name": "大魚",
            "singer": "周深",
            "time": 313,
            "downloadURL": "https://music-1300015560.cos.ap-beijing.myqcloud.com/musics/bf/bf.mp3",
            "lrc": "null",
            "pic": "https://music-1300015560.cos.ap-beijing.myqcloud.com/musics/bf/bf.jpg"
        },
        {
            "name": "小小戀歌",
            "singer": "新垣結衣",
            "downloadURL": "https://music-1300015560.cos.ap-beijing.myqcloud.com/musics/cknu/cknu.mp3",
            "lrc": "null",
            "pic": "https://music-1300015560.cos.ap-beijing.myqcloud.com/musics/cknu/cknu.jpg"
        }
    ]
}
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('\n') //切割每一行
    var pattern = /\[\d{2}:\d{2}.\d{2}\]/g //用於匹配時間的正則表達式,匹配的結果相似[xx:xx.xx]
    //去掉不含時間的行
    while (!pattern.test(lines[0])) {
      lines = lines.slice(1);
    }
    //上面用'\n'生成數組時,結果中最後一個爲空元素,這裏將去掉
    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

3、總結

  微信小程序仍是有本身的優點的吧。只是我不明白,我遇到不少軟件,有小程序,有app,可是小程序每每是閹割版,會提示你用app。那麼作了小程序就只是爲了推廣?

  作這個入門仍是很簡單的,不知道之後會不會有別的項目機會。官方文檔寫的都很清楚,再不會的話,網上也有各類博客參考,不難學,

  感謝閱讀,咱們下期再見(嗯?)

相關文章
相關標籤/搜索