nuxt.js框架中 audio标签的坑

2 篇文章 0 订阅
1 篇文章 0 订阅

一、前言

上星期接到一个需求,业主说要在移动端的考试系统中弄一个背景音乐上去,让人听着做题更舒服,并且做对题目和做错题目都需要有不同的音乐提示(业主不当产品经理留在小公司折磨我这种小员工实属浪费)。于是就想到用html5的audio标签。但是后来做的时候发现,audio标签在IOS(苹果)端的微信浏览器中存在着很多坑,而且要整合到nuxt.js当中又踩了坑,决定把这些坑和解决办法记下来。

二、第一坑——nuxt.config.js的配置

本以为直接放audio标签进去.vue文件中就完事了,结果报了下图的错。

明知道是缺了某个loader,但是又不知道怎么配置,后来参照着vue-cli对mp3的配置,如下图

这里不作多说,参照着这个配置,我在nuxt.config.js文件中配置了对mp3文件的处理方法

build: {
    /*
    ** You can extend webpack config here
    */
    extend (config, ctx) {
      // Run ESLint on save
      const vueLoader = config.module.rules.find((loader) => loader.loader === 'vue-loader');
     /* 把audio标签在编译时转成src属性 */
      vueLoader.options.transformToRequire = {
        audio: 'src'
      };
      /* 对mp3等格式的文件用url-loader进行处理 */
      config.module.rules.push({
        test: /\.(mp4|webm|ogg|mp3|wav|flac|aac)(\?.*)?$/,
        loader: 'url-loader',
        options: {
          limit: 10000,
          name: process.env.NODE_ENV === 'production'
            ? path.posix.join('./', 'media/[name].[hash:7].[ext]')
            : path.posix.join('./', 'media/[name].[hash:7].[ext]')
        }
      });
      if (ctx.isDev && ctx.isClient) {
        config.module.rules.push({
          enforce: 'pre',
          test: /\.(js|vue)$/,
          loader: 'eslint-loader',
          exclude: /(node_modules)/
        });
      }
    }
  }

ok,这样就可以把mp3文件放到assets目录下了,你也可以在assets目录下新建media诸如此类的文件夹,然后把mp3文件塞进去。

千算万算没想到nuxt框架竟然没有帮忙配好mp3格式的编译,而只是配了mp4(video标签)的格式的loader。

好了,现在就可以像下图一样开心的写代码了

<audio id="audio" ref="audio" loop="loop" autoplay="autoplay">
    <source src="@/assets/music/exam.mp3" type="audio/mpeg">
    您的浏览器不支持 audio 元素。
</audio>

这样他就能识别出"@/assets/music/exam.mp3"是什么东西。

三、第二坑——IOS端在微信浏览器中不能自动播放音乐

这个也是弄了我很久,查阅了很多资料,但其实很简单,网上说IOS端为了防止恶意浪费流量所以禁止了自动播放音乐。但是微信浏览器中,可以通过监听WeixinJSBridgeReady和invoke的方法兼容IOS。

首先引入微信提供的js-sdk的js文件:(在nuxt.config.js中配置) (src: 'https://res.wx.qq.com/open/js/jweixin-1.1.0.js')

事不宜迟先上代码:

<script type="text/ecmascript-6">
export default {
  computed: {
    /* <audio ref="audio"></audio> */
    audio () {
      return this.$refs.audio;
    }
  },
  mounted () {
    this.autoPlayMusic();
  },
  methods: {
    autoPlayMusic () {
      // 监听微信h5自动播放bgm
      if (window.WeixinJSBridge) {
        window.WeixinJSBridge.invoke('getNetworkType', {}, () => {
          this.audio.play();
        }, false);
      } else {
        document.addEventListener('WeixinJSBridgeReady', () => {
          window.WeixinJSBridge.invoke('getNetworkType', {}, () => {
            this.audio.play();
          });
        }, false);
      }
    }
  }
};
</script>

这样之后,就可以打开微信h5应用后就可以听到音乐了。

注意了,网上有些说法是

document.addEventListener('DOMContentLoaded', function () {
    document.addEventListener("WeixinJSBridgeReady", function () {
          let audio = document.getElementById('audio')
          audio.play()
    }, false)
})

但是查了一下发现,DOMContentLoaded这个方法表示页面加载完成之后就会触发,就是说,对于单页应用来说,一旦首屏加载完成了,那么它就触发,之后就不会出发了。但是我这个播放音乐组件是要等到它进去某个页面才会开始加载的,所以一开始用了这个方法怎么样也不响。

噢对了,如果eslint报错WeixinJSBridge is not defined的话,那么在eslint.js中加上这段话:

这就没问题了,这个表示如果出现WeixinJSBridge这个时,不进行监测(代表它是全局变量)

四、总结

还以为移动端兼容性比浏览器更容易解决,没想到就这个bug搞了我很久,特别是ios竟然不能自动播放,幸好还是解决了,最后上一下我的音乐播放组件(其实很简单的慕课网很多教程,不过多年之后感觉慕课网那个一下子就能做出来)

<template>
  <div class="audio-container">
    <!-- ct-icon-music就是一个光碟的图标,用的是iconfont里面的,可以自己去找 -->
    <span class="ct-icon-music" @click="handleClick" :class="isStop ? '' : 'active'"></span>
    <audio id="audio" ref="audio" loop="loop" autoplay="autoplay">
      <source src="@/assets/music/exam.mp3" type="audio/mpeg">
      您的浏览器不支持 audio 元素。
    </audio>
  </div>
</template>

<script type="text/ecmascript-6">
export default {
  data () {
    return {
      isStop: false
    };
  },
  computed: {
    audio () {
      return this.$refs.audio;
    }
  },
  mounted () {
    this.autoPlayMusic();
  },
  methods: {
    /* 点击光碟图标就会播放/暂停音乐 */
    handleClick () {
      this.isStop = !this.isStop;
      if (this.isStop) {
        this.audio.pause();
        this.$emit('stop');
      } else {
        this.audio.play();
        this.$emit('start');
      }
    },
    autoPlayMusic () {
      // 监听微信h5自动播放bgm
      if (window.WeixinJSBridge) {
        window.WeixinJSBridge.invoke('getNetworkType', {}, () => {
          this.audio.play();
        }, false);
      } else {
        document.addEventListener('WeixinJSBridgeReady', () => {
          window.WeixinJSBridge.invoke('getNetworkType', {}, () => {
            this.audio.play();
          });
        }, false);
      }
    }
  }
};
</script>

<style lang="scss" scoped>
.audio-container {
  position: fixed;
  top: 45px;
  right: .5rem;
  text-align: right;
  .ct-icon-music {
    display: inline-block;
    &.active {
      animation: musicRotate 1.5s linear infinite;
    }
  }
}
@keyframes musicRotate {
  from { transform: rotateZ(0); }
  to { transform: rotateZ(360deg); }
}
</style>

 

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值