歡迎您光臨深圳塔燈網(wǎng)絡(luò)科技有限公司!
          電話圖標(biāo) 余先生:13699882642

          網(wǎng)站百科

          為您解碼網(wǎng)站建設(shè)的點點滴滴

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

          發(fā)表日期:2019-11 文章編輯:小燈 瀏覽次數(shù):5329

          需求描述:

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


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

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

          ?? 使用小程序 BackgroundAudioManager,需要在 app.json配置相關(guān)參數(shù)

          "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標(biāo)簽,但是為了能夠滿足退出當(dāng)前頁面或者關(guān)閉小程序,音頻仍需播放的需求,改成了背景音頻-->
                          <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">
                          <!-- 列表圖標(biāo)-->
                          <image class="apd-btn-list" src="../../img/player/ico-list.png" bindtap="jumpAudioList"></image>
                          <!-- 上一條圖標(biāo)-->
                          <image class="{{hasPre ? 'apd-btn-left' : 'apd-btn-left apd-btn-no'}}" bindtap="playPer" src="../../img/player/ico-left.png"></image>
                          <!-- 暫停和播放圖標(biāo)-->
                          <image class="apd-btn-player" bindtap="ppAudio" src="{{isPlay ? '../../img/player/ico-pause.png' : '../../img/player/ico-player.png'}}"></image>
                          <!-- 下一條圖標(biāo)-->
                          <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  //創(chuàng)建背景音樂
          Page({
            /**
             * 頁面的初始數(shù)據(jù)
             */
            data: {
              isTry: null,  // 是否是試聽狀態(tài)
              idx: 0, // 當(dāng)前音頻(第一個-上一條按鈕不能點擊,最后一條,下一條按鈕不能點擊)
              albumCode: '',  // 當(dāng)前音頻標(biāo)識
              opusName: '',  // 當(dāng)前專輯名字
              musicSrc: '',  
              singler: '',  // 當(dāng)前作者
              audioMsg: {},  // 音頻信息(作者,封面,名字--僅展示)
              opusSalt: '',  // 當(dāng)前音頻id
              isEnd: false, // 最后一條音頻結(jié)束時控制
              endVideoTime: '', // 最后一條音頻時長
              isPlay: true,  // 是否暫停音樂
              isStop: false,  // 是否停止音樂
              slideLen: 0, // 進度條初始值
              music: {  // 音頻信息--用來處理數(shù)據(jù)
                start: '00:00',
                leave:'',
                long: '',
                length: ''
              },
              hasPre: true,  // 是否有上一條音頻
              hasNxt: true,  // 是否有下一條音頻
              musicList: [], // 用來存儲音頻列表,存儲到本地,點擊上一條、下一條音頻時,不調(diào)用接口
              perMusicMsg: {},  // 進入頁面之后,就將上一條音頻,下一條音頻信息提取出來,方便直接點擊按鈕
              nxtMusicMsg: {},  // 同上
              isStopSlider: false  // 是否停止?jié)L動條隨著音頻播放改變長度  -- 防止拖動滾動條時發(fā)生回退現(xiàn)象!!!
            },
          
            /**
             * 生命周期函數(shù)--監(jiān)聽頁面加載
             */
            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,
              })
            },
          
            /**
             * 生命周期函數(shù)--監(jiān)聽頁面初次渲染完成
             */
            onReady: function () {
              // 正在播放-進入(重新進入當(dāng)前頁面時)
              // this.data.opusSalt === App.globalData.opusSalt  判斷從列表進入時,想要播放的和正在播放的是否為同一條音頻
              if(bgMusic.src && this.data.opusSalt === App.globalData.opusSalt) {
                this.audioInitAgain()
              } else {
                // 進入的和之前播放的不是同一條音頻  存儲將要播放的音頻id,并獲取將要播放的音頻數(shù)據(jù),然后播放
                App.globalData.opusSalt = this.data.opusSalt
                this.getAudioSrc()
              }
              // 試聽只能聽第一條,上一條,下一條按鈕不可點擊
              if(this.data.isTry) {
                this.setData({
                  hasPre: false,
                  hasNxt: false
                })
              } else {
                this.musicListHandle()
              }
            },
          
            // 跳轉(zhuǎn)專輯列表-- 返回上一頁面
            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
              // 最后一條音樂存儲一下音樂時長--- 播放結(jié)束后,不自動跳轉(zhuǎn)下一條音頻,播放按鈕變?yōu)闀和#瑵L動條置0,endVideoTime展示該音頻時長
              this.setData({
                endVideoTime: this.data.music.long
              })
              this.audioInitPlay()
            },
            // 音頻-暫停/播放
            // isPlay: true: 播放狀態(tài)  false:暫停狀態(tài)
            // isStop:true :當(dāng)不在播放頁面時,點擊關(guān)閉懸浮框的關(guān)閉按鈕  false: 懸浮框未關(guān)閉  --- 實際監(jiān)聽時,監(jiān)聽不到懸浮框關(guān)閉,但依然保留了該字段
            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;
          
              // 音頻跳轉(zhuǎn)到指定位置
              bgMusic.seek(time)
            },
            /**
             * !!! 解決滑動播放條時的卡頓問題  --- end
             */
            // 開始播放-首次進入
            audioInitPlay: function () {
              App.globalData.opusSalt = this.data.opusSalt
          
              //監(jiān)聽音樂自然播放結(jié)束
              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()
                }
              })
          
              //監(jiān)聽音樂播放
              bgMusic.onPlay(() => {
                console.log('onPlay')
                if(this.data.music.start == "00:00") {
                  this.setData({
                    "music.leave": util.formatM(bgMusic.duration),
                    isPlay: true
                  })
                }
                this.playAudio()
              })
          
              // 監(jiān)聽背景音頻暫停事件
              bgMusic.onPause(() => {
                this.setData({
                  isPlay: false
                })
                // App.globalData.opusSalt = 0
              })
          
              //監(jiān)聽背景音頻停止事件  --- 實際監(jiān)聽時,監(jiān)聽不到懸浮框關(guān)閉,但依然保留了該字段
              bgMusic.onStop(() => {
                this.stopAudio()
                App.globalData.opusSalt = 0
              })
            },
            // 開始播放-重復(fù)進入
            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)
                  //監(jiān)聽音樂播放
                  bgMusic.onPlay(() => {
                    this.playAudio()
                  })
                }, 30)
              } else {
                bgMusic.onTimeUpdate(() => {
                  this.audioTimeUpdated(bgMusic)
                })
              }
            },
            //暫停
            pauseAudio: function () {
              bgMusic.pause(); 
            },
            // 繼續(xù)播放
            playAudio: function () {
              // 監(jiān)聽音頻播放進度
              bgMusic.onTimeUpdate(() => {  
                this.audioTimeUpdated(bgMusic)
              })
              bgMusic.play() //播放音樂
            },
            // 背景音樂浮窗關(guān)閉,重置數(shù)據(jù)  -- 實際監(jiān)聽不到懸浮框關(guān)閉事件
            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`
              })
            },
            // 音樂數(shù)據(jù)處理
            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()
          開始播放-重復(fù)進入 audioInitAgain()
          暫停 pauseAudio()
          繼續(xù)播放 playAudio()

          函數(shù)作用都已經(jīng)在注釋里標(biāo)注了,有疑問的地方歡迎留言~~


          本頁內(nèi)容由塔燈網(wǎng)絡(luò)科技有限公司通過網(wǎng)絡(luò)收集編輯所得,所有資料僅供用戶學(xué)習(xí)參考,本站不擁有所有權(quán),如您認(rèn)為本網(wǎng)頁中由涉嫌抄襲的內(nèi)容,請及時與我們聯(lián)系,并提供相關(guān)證據(jù),工作人員會在5工作日內(nèi)聯(lián)系您,一經(jīng)查實,本站立刻刪除侵權(quán)內(nèi)容。本文鏈接:http://www.cjxv.cn/25259.html
          相關(guān)小程序
           八年  行業(yè)經(jīng)驗

          多一份參考,總有益處

          聯(lián)系深圳網(wǎng)站公司塔燈網(wǎng)絡(luò),免費獲得網(wǎng)站建設(shè)方案及報價

          咨詢相關(guān)問題或預(yù)約面談,可以通過以下方式與我們聯(lián)系

          業(yè)務(wù)熱線:余經(jīng)理:13699882642

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

          主站蜘蛛池模板: 大片毛片女女女女女女女| 欧美国产日本高清不卡| 国产乱码一二三区精品| 亚洲人成网站看在线播放| 国内不卡1区2区| 人妻少妇久久中文字幕| 色五月在线视频| 国产精品青青青高清在线| 一级毛片一级毛片一级毛片| 日本一区二区三区四区公司| 亚洲1234区乱码| 欧美婷婷六月丁香综合色| 亚洲熟妇少妇任你躁在线观看| 白丝女班长被弄得娇喘不停| 午夜羞羞视频在线观看| 色噜噜狠狠狠色综合久| 国产午夜不卡在线观看视频666| 中文字幕日韩精品麻豆系列| 国内精品久久久久久久久| GOGOGO免费高清在线中国| 女人张开腿让男人桶个爽| 一本色道久久88精品综合| 成人午夜福利视频| 中文字幕精品在线| 无码国产乱人伦偷精品视频| 久久久久久久综合综合狠狠| 日本边吃奶边摸边做在线视频| 亚州1区2区3区4区产品乱码2021| 欧美乱大交xxxxx免费| 亚洲国产一区在线观看| 欧美性色一级在线观看| 亚洲欧洲美洲无码精品VA| 正在播放黑人巨大视频| 亚洲精品91在线| 污视频软件大全| 亚洲第一区精品观看| 热久久国产精品| 亚洲综合色婷婷在线观看| 波多野结衣无内裤护士| 亚洲福利精品一区二区三区| 欧美综合婷婷欧美综合五月|