zoukankan      html  css  js  c++  java
  • 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;
        },
  • 相关阅读:
    Docker 学习4 Docker容器虚拟化网络概述
    Ceph 命令
    Day_09【常用API】扩展案例1_程序中使用一个长度为3的对象数组,存储用户的登录名和密码……
    Day_08【面向对象】扩展案例4_年龄为30岁的老王养了一只黑颜色的2岁的宠物……
    Day_08【面向对象】扩展案例3_使用多态的形式创建缉毒狗对象,调用缉毒方法和吼叫方法
    Day_08【面向对象】扩展案例2_测试旧手机新手机类,并给新手机实现玩游戏功能
    Day_08【面向对象】扩展案例1_测试项目经理类和程序员类
    用两个栈实现队列
    二叉树前序、中序、后序遍历相互求法
    洗牌
  • 原文地址:https://www.cnblogs.com/Small-Windmill/p/15008885.html
Copyright © 2011-2022 走看看