最近在写一个移动端音乐播放器的时候遇到一个非常难受的问题,在PC可以正常调用audio标签的play方法,在在手机移动端上的绝大部分浏览器都不行。 原因很简单,就是因为浏览器的保护策略,当某个audio第一次被加载的时候,直接调用play方法浏览器会拦截这个请求,因为他觉得这是不礼貌的行为。

IOS 以及 安卓4.4 以上的原生浏览器都遇到了这个问题。官方的解释是只有当用户主动触发一次actions的时候,play方法才会生效,也就说只有当用户触发一些事件,才能 play()

于是在查询了一些资料之后,我选择利用html的touchstart事件来进行播放,但是这个方法其实也有缺点,当用户真正完全不触摸屏幕的时候,这个play依旧不能执行。

created() {
    this.touch = {}
    // HACK PLAY
    // run Once
    document.querySelector('html').ontouchstart = () => {
      if (this.songReady && window.ONCE_FLAG) {
        window.ONCE_FLAG = false
        this.$refs.audio.play()
      }
    }
  }
  // 

由于这个事件将会在用户触摸屏幕的时候不断触发,我使用了一个标签来让整个函数只执行一次,或者直接清空这个回调为null也是可以的。

总的来说因为这个安全机制,移动端播放音乐依旧无法非常完美。