• <ul id="cgeq2"></ul>
  • 歡迎您光臨深圳塔燈網絡科技有限公司!
    電話圖標 余先生:13699882642

    網站百科

    為您解碼網站建設的點點滴滴

    微信小程序-音樂播放器+背景播放

    發表日期:2019-11 文章編輯:小燈 瀏覽次數:5465

    需求描述:

    1.正常播放音頻
    2.可以滑動進度條
    3.可以切換上一條,下一條音頻
    4.退出當前頁或關閉小程序之后仍然可以正常播放
    5.試聽功能進入該播放頁不可以播放上一條,下一條
    6.退出該頁面或小程序之后,再次回到該頁面,播放條自動到當前播放進度


    圖二圖三是關閉小程序之后微信頁面的展示,可以通過懸浮關閉該音頻。

    參考文檔
    [小程序官方文檔--背景音頻]

    ?? 使用小程序 BackgroundAudioManager,需要在 app.json配置相關參數

    "requiredBackgroundModes": [
        "audio"
      ]
    代碼
        <view class="vp-book-adPlayer">
            <view class="adp-wrapper">
                <view class="apd-progress">
                    <!-- <audio class="apd-pro-audio" src="{{music.src}}" action="{{audioAction}}" bindplay="audioPlayed" bindtimeupdate="audioTimeUpdated" controls></audio> -->
                    <!-- 之前用的是audio標簽,但是為了能夠滿足退出當前頁面或者關閉小程序,音頻仍需播放的需求,改成了背景音頻-->
                    <slider class="apd-pro-slider" value="{{slideLen}}" bindchanging="stopSlider" bindchange="timeSliderChanged" selected-color="#20a3ff" block-size="12" block-color="#20a3ff" step="0.01"/>
                    <view class="apd-pro-timer">
                        <view class="apd-pro-start">{{music.start}}</view>
                        <view class="apd-pro-leave">{{music.leave}}</view>
                    </view>
                </view>
                <view class="apd-btn-box">
                    <!-- 列表圖標-->
                    <image class="apd-btn-list" src="../../img/player/ico-list.png" bindtap="jumpAudioList"></image>
                    <!-- 上一條圖標-->
                    <image class="{{hasPre ? 'apd-btn-left' : 'apd-btn-left apd-btn-no'}}" bindtap="playPer" src="../../img/player/ico-left.png"></image>
                    <!-- 暫停和播放圖標-->
                    <image class="apd-btn-player" bindtap="ppAudio" src="{{isPlay ? '../../img/player/ico-pause.png' : '../../img/player/ico-player.png'}}"></image>
                    <!-- 下一條圖標-->
                    <image class="{{hasNxt ? 'apd-btn-right' : 'apd-btn-right apd-btn-no'}}" bindtap="playNxt" src="../../img/player/ico-right.png"></image>
                </view>
            </view>
        </view>
        
        
        
        // pages/audioPlayer/audioPlayer.js
    const api = require('../../service/http.js');
    const util = require('../../utils/util.js')
    var App = getApp()
    const bgMusic = App.bgMusic  //創建背景音樂
    Page({
      /**
       * 頁面的初始數據
       */
      data: {
        isTry: null,  // 是否是試聽狀態
        idx: 0, // 當前音頻(第一個-上一條按鈕不能點擊,最后一條,下一條按鈕不能點擊)
        albumCode: '',  // 當前音頻標識
        opusName: '',  // 當前專輯名字
        musicSrc: '',  
        singler: '',  // 當前作者
        audioMsg: {},  // 音頻信息(作者,封面,名字--僅展示)
        opusSalt: '',  // 當前音頻id
        isEnd: false, // 最后一條音頻結束時控制
        endVideoTime: '', // 最后一條音頻時長
        isPlay: true,  // 是否暫停音樂
        isStop: false,  // 是否停止音樂
        slideLen: 0, // 進度條初始值
        music: {  // 音頻信息--用來處理數據
          start: '00:00',
          leave:'',
          long: '',
          length: ''
        },
        hasPre: true,  // 是否有上一條音頻
        hasNxt: true,  // 是否有下一條音頻
        musicList: [], // 用來存儲音頻列表,存儲到本地,點擊上一條、下一條音頻時,不調用接口
        perMusicMsg: {},  // 進入頁面之后,就將上一條音頻,下一條音頻信息提取出來,方便直接點擊按鈕
        nxtMusicMsg: {},  // 同上
        isStopSlider: false  // 是否停止滾動條隨著音頻播放改變長度  -- 防止拖動滾動條時發生回退現象!!!
      },
    
      /**
       * 生命周期函數--監聽頁面加載
       */
      onLoad: function (options) {
        let book
        try {
          let value = wx.getStorageSync('ai_cloud_book')
          if (value) {
            book = JSON.parse(value)
          }
        } catch (e) {
          // Do something when catch error
        }
        this.setData({
          albumCode: decodeURIComponent(options.albumCode),
          musicSrc: decodeURIComponent(options.playerUrl),
          opusName: decodeURIComponent(options.playerName),
          singler: decodeURIComponent(options.playerSinger),
          isTry: Boolean(Number(options.isTry)),
          audioMsg: book,
          opusSalt: options.opusSalt,
          idx: Number(options.idx),
          'music.long': util.formatM(options.playerLong),
          'music.length': options.playerLong,
        })
      },
    
      /**
       * 生命周期函數--監聽頁面初次渲染完成
       */
      onReady: function () {
        // 正在播放-進入(重新進入當前頁面時)
        // this.data.opusSalt === App.globalData.opusSalt  判斷從列表進入時,想要播放的和正在播放的是否為同一條音頻
        if(bgMusic.src && this.data.opusSalt === App.globalData.opusSalt) {
          this.audioInitAgain()
        } else {
          // 進入的和之前播放的不是同一條音頻  存儲將要播放的音頻id,并獲取將要播放的音頻數據,然后播放
          App.globalData.opusSalt = this.data.opusSalt
          this.getAudioSrc()
        }
        // 試聽只能聽第一條,上一條,下一條按鈕不可點擊
        if(this.data.isTry) {
          this.setData({
            hasPre: false,
            hasNxt: false
          })
        } else {
          this.musicListHandle()
        }
      },
    
      // 跳轉專輯列表-- 返回上一頁面
      jumpAudioList: function() {
        wx.navigateBack()
      },
      // 獲取音頻信息
      getAudioSrc: function() {
        bgMusic.src = this.properties.musicSrc
        bgMusic.title = this.data.opusName
        bgMusic.epname = this.data.opusName
        bgMusic.singer = this.data.singer
        // 最后一條音樂存儲一下音樂時長--- 播放結束后,不自動跳轉下一條音頻,播放按鈕變為暫停,滾動條置0,endVideoTime展示該音頻時長
        this.setData({
          endVideoTime: this.data.music.long
        })
        this.audioInitPlay()
      },
      // 音頻-暫停/播放
      // isPlay: true: 播放狀態  false:暫停狀態
      // isStop:true :當不在播放頁面時,點擊關閉懸浮框的關閉按鈕  false: 懸浮框未關閉  --- 實際監聽時,監聽不到懸浮框關閉,但依然保留了該字段
      ppAudio: function (e) {
        let _isPlay = this.data.isPlay
        let _isStop = this.data.isStop
        if(_isStop) {
          this.getAudioSrc()
          this.setData({
            isPlay: true,
            isStop: false
          })
          return
        }
        if(_isPlay) {
          this.pauseAudio()
        } else if(this.data.isEnd){
          // 最后一條音頻 - 再次播放需要重新初始化
          this.setData({
            isEnd: false
          })
          this.getAudioSrc()
        } else {
          this.playAudio()
        }
        this.setData({
          isPlay: !_isPlay
        })
      },
      // 音頻實時信息  -->  
      audioTimeUpdated: function (e) {
        const startTime = e.currentTime
        const leaveTime = e.duration - startTime
        this.setData({
          "music.start": util.formatM(startTime),
          "music.leave": util.formatM(leaveTime)
        })
        if(!this.data.isStopSlider) {
          const proLen = (e.currentTime / e.duration * 100).toFixed(2)
          this.setData({
            slideLen: proLen
          })
        }
      },
      /**
       * !!! 解決滑動播放條時的卡頓問題 !!! --- start
       */
      // 禁止播放條隨著音樂播放滾動
      stopSlider: function () {
        this.setData({
          isStopSlider: true
        })
      },
      // 音頻播放條改變 - 手動滑動滾動條停止
      timeSliderChanged: function (e) {
        this.setData({
          isStopSlider: false
        })
        if (!this.data.music.length)
          return;
    
        var time = this.data.music.length * e.detail.value / 100;
    
        // 音頻跳轉到指定位置
        bgMusic.seek(time)
      },
      /**
       * !!! 解決滑動播放條時的卡頓問題  --- end
       */
      // 開始播放-首次進入
      audioInitPlay: function () {
        App.globalData.opusSalt = this.data.opusSalt
    
        //監聽音樂自然播放結束
        bgMusic.onEnded(() => {  
          // 如果沒有下一個直接賦值并禁止播放
          if(!this.data.hasNxt) {
            let _endTime = this.data.endVideoTime
            let idx = 0
            let _timer = setInterval(()=>{
              if(idx > 1) {
                clearInterval(_timer)
              }
              this.setData({
                isPlay: false,
                isEnd: true,
                "music.start": "00:00",
                "music.leave": _endTime
              })
              console.log(this.data.music)
              idx ++
            }, 50)
          } else {
            this.playNxt()
          }
        })
    
        //監聽音樂播放
        bgMusic.onPlay(() => {
          console.log('onPlay')
          if(this.data.music.start == "00:00") {
            this.setData({
              "music.leave": util.formatM(bgMusic.duration),
              isPlay: true
            })
          }
          this.playAudio()
        })
    
        // 監聽背景音頻暫停事件
        bgMusic.onPause(() => {
          this.setData({
            isPlay: false
          })
          // App.globalData.opusSalt = 0
        })
    
        //監聽背景音頻停止事件  --- 實際監聽時,監聽不到懸浮框關閉,但依然保留了該字段
        bgMusic.onStop(() => {
          this.stopAudio()
          App.globalData.opusSalt = 0
        })
      },
      // 開始播放-重復進入
      audioInitAgain: function() {
        // true - 暫停中  false - 播放中
        this.setData({
          endVideoTime: util.formatM(bgMusic.duration)
        })
        console.log(this.data.endVideoTime)
        if(bgMusic.paused) {
          bgMusic.play()
          let timer = setTimeout(() => {
            clearTimeout(timer)
            //監聽音樂播放
            bgMusic.onPlay(() => {
              this.playAudio()
            })
          }, 30)
        } else {
          bgMusic.onTimeUpdate(() => {
            this.audioTimeUpdated(bgMusic)
          })
        }
      },
      //暫停
      pauseAudio: function () {
        bgMusic.pause(); 
      },
      // 繼續播放
      playAudio: function () {
        // 監聽音頻播放進度
        bgMusic.onTimeUpdate(() => {  
          this.audioTimeUpdated(bgMusic)
        })
        bgMusic.play() //播放音樂
      },
      // 背景音樂浮窗關閉,重置數據  -- 實際監聽不到懸浮框關閉事件
      stopAudio: function() {
        this.setData({
          isStop: true,
          isPlay: false,
          "music.start": "00:00",
          "music.leave": this.data.music.long,
          slideLen: 0
        })
      },
      // 上一首
      playPer() {
        if(!this.data.hasPre) return
        wx.redirectTo({
          url: `XX/audioPlayer?albumCode=${encodeURIComponent(this.data.albumCode)}&playerUrl=${encodeURIComponent(this.data.perMusicMsg.opusUrl)}&playerName=${encodeURIComponent(this.data.perMusicMsg.opusName)}&playerSinger=${encodeURIComponent(this.data.singer)}&playerLong=${this.data.perMusicMsg.opusLength}&opusSalt=${this.data.perMusicMsg.opusSalt}&idx=${this.data.idx - 1}&isTry=0`
        })
      },
      // 下一首
      playNxt() {
        if(!this.data.hasNxt) return
        wx.redirectTo({
          url: `XXX/audioPlayer?albumCode=${encodeURIComponent(this.data.albumCode)}&playerUrl=${encodeURIComponent(this.data.nxtMusicMsg.opusUrl)}&playerName=${encodeURIComponent(this.data.nxtMusicMsg.opusName)}&playerSinger=${encodeURIComponent(this.data.singer)}&playerLong=${this.data.nxtMusicMsg.opusLength}&opusSalt=${this.data.nxtMusicMsg.opusSalt}&idx=${this.data.idx + 1}&isTry=0`
        })
      },
      // 音樂數據處理
      musicListHandle() {
        try {
          let value = wx.getStorageSync('ai_cloud_book_album')
          if (value) {
            let _book = JSON.parse(value)
            let _hasPer = Boolean(this.data.idx)  
            let _hasNxt = this.data.idx === _book.length - 1 ? 0 : 1
            let _perMusicMsg = {}
            let _nxtMusicMsg = {}
            if(_hasPer) _perMusicMsg = _book[this.data.idx - 1]
            if(Boolean(_hasNxt)) _nxtMusicMsg = _book[this.data.idx + 1]
            this.setData({
              musicList: _book,
              hasPre: _hasPer,
              hasNxt: Boolean(_hasNxt),
              perMusicMsg: _perMusicMsg,
              nxtMusicMsg: _nxtMusicMsg
            })
          }
        } catch (e) {
          // Do something when catch error
        }
        // wx.setStorageSync("ai_cloud_book_album", JSON.stringify(this.data.listenList))
      }
    })
        
        

    音頻-暫停/播放(信息配置) ppAudio()
    音頻實時信息 audioTimeUpdated()
    音頻播放條改變 timeSliderChanged()
    開始播放-首次進入 audioInitPlay()
    開始播放-重復進入 audioInitAgain()
    暫停 pauseAudio()
    繼續播放 playAudio()

    函數作用都已經在注釋里標注了,有疑問的地方歡迎留言~~


    本頁內容由塔燈網絡科技有限公司通過網絡收集編輯所得,所有資料僅供用戶學習參考,本站不擁有所有權,如您認為本網頁中由涉嫌抄襲的內容,請及時與我們聯系,并提供相關證據,工作人員會在5工作日內聯系您,一經查實,本站立刻刪除侵權內容。本文鏈接:http://www.juherenli.com/25259.html
    相關小程序
     八年  行業經驗

    多一份參考,總有益處

    聯系深圳網站公司塔燈網絡,免費獲得網站建設方案及報價

    咨詢相關問題或預約面談,可以通過以下方式與我們聯系

    業務熱線:余經理:13699882642

    Copyright ? 2013-2018 Tadeng NetWork Technology Co., LTD. All Rights Reserved.    

    国产午夜精品一区二区三区嫩草 | 日韩一区二区三区精品| 精品一区二区三区东京热| 国产亚洲精品AA片在线观看不加载| 国产精品自在线拍国产手机版| 中文字幕精品一区影音先锋| 久久久久九九精品影院| 精品久久久BBBB人妻| 国产精品岛国久久久久| 久久午夜精品视频| 99精品国产高清一区二区三区| 国产产在线精品亚洲AAVV| 国产精品自产拍在线观看| 午夜精品美女自拍福到在线| 久久国产精品免费一区| 精品女同一区二区三区免费播放 | 91精品国产综合久久婷婷| 老司机免费午夜精品视频| 精品国产日韩亚洲一区91| 亚洲中文字幕久久精品无码VA | 91精品美女在线| 国产内地精品毛片视频| 免费久久精品国产片香蕉| 最新国语自产精品视频在| 亚洲国产午夜精品理论片在线播放 | 久久久久久国产精品三级| 538prom精品视频我们不只是| 精品人妻少妇一区二区三区在线 | 亚洲伊人久久精品影院| 精品国产午夜福利在线观看| 亚洲国产精品成人网址天堂| 国产99视频精品免费视频7| 国产精品二区三区免费播放心| 美女精品永久福利在线| 成人无码精品一区二区三区| 久久久国产精品无码一区二区三区| 国产成人精品必看| 国语自产精品视频在线看| 日本精品视频在线播放| 国产成人精品一区二三区| 精品国内自产拍在线视频|