1. 程式人生 > 其它 >VUE移動端音樂APP學習【二十七】:player核心的修改優化

VUE移動端音樂APP學習【二十七】:player核心的修改優化

One.

缺陷:當開啟播放器快速切換歌曲時,按下暫停播放,發現歌詞和背景音樂都仍在播放,這顯示是不符合預期的。

原因:程式碼watch currentSong的變化以後做清理操作,然後執行audio.play()和獲取歌曲。這裡就存在一個問題——當我們快速切換的時候,canplay事件觸發產生的相關操作可能在1s內就完成,也就是說,有可能先執行audio.pause()再執行watch時的audio.play(),所以就導致顯示為暫停,但是它歌曲仍然在播放。

解決:因為我們是延時執行,但是在切換的時候,currentSong是快速變化的,我們要保證setTimeout裡的邏輯只執行一次。

 clearTimeout(this
.timer); this.timer = setTimeout(() => { this.$refs.audio.play().catch((error) => { this.togglePlaying(); // eslint-disable-next-line no-alert alert('播放出錯,暫無該歌曲資源'); }, 1000); // 這裡不直接呼叫currentSong.getLyric() this.getLyric();

這樣就可以保證無論currentSong變化多少次,只執行最後一次的setTimeout的,之前的setTimeout都會被清除掉。

但是光有這個邏輯也是不夠的,還要修改ready的觸發事件canplay改為play,就不能很快切換,保證先執行play才會觸發ready,然後audio.pause肯定在這之後執行。

    <audio ref="audio" :src="currentSong.url" @play="ready" @error="error" @timeupdate="updateTime" @ended="end"></audio>

Two.

缺陷:在多次切換過程中,還有可能出現歌詞混亂對應不上歌曲的問題。

原因:因為getLyric方法是非同步操作,當它執行到回撥獲取歌詞的時候我們就有可能切換到下一首歌了,之前的歌詞又會被new一次,相當於new了兩次。

解決:我們要加個判斷:當前的歌詞內容是否等於獲取到的歌詞內容,如果相等就什麼都不做。這樣就保證了歌詞不會亂掉。

this.currentSong.getLyric().then((lyric) => {
        if (this.currentSong.lyric !== lyric) {
          return;
        }
        this.currentLyric = new Lyric(lyric, this.handleLyric);
        if (this.playing) {
          this.currentLyric.play();
        }
      }).catch(() => {
        this.currentLyric = null;
        this.playingLyric = '';
        this.currentLineNum = 0;
      });

Three.

缺陷:如果當前播放列表只有一首歌的時候,點下一首,按鈕不會再觸發ready。

原因:列表長度為1時,會呼叫loop方法,loop會把currentTime切到開始,play事件就不會觸發了。

解決:在呼叫loop時直接return。

next() {
      // 如果沒有ready好的話就直接返回
      if (!this.songReady) {
        return;
      }
      if (this.playlist.length === 1) {
        this.loop();
        return;
      } else {
        ......
  
      }
      this.songReady = false;
    },