解决浏览器中不支持音频自动播放的方法

需求

事情是这个样子的,有这样一个需求,就是阿Sir在审核警情的时候,他期望四面八方推送过来的警情能够有个友好的提示,比如光明区大风厂派出所王二提交了一个警情审核,市局的赵东来局长在喝茶时,突然,只听电脑屏幕咚地一声(壁咚一声圈起来,楼下要考),哦,来新单了,请及时处理。。。。。。

思路

大致是这样子的,后端给一个消息的接口,前端这边给定一个时间去轮询,当轮询到有新消息的时候,奏乐,壁咚壁咚壁咚。。。。。然后弹窗提示,哦,来新单啦,请及时处理。

实现

provide/inject地灵活运用

一种组件间通信的方式,允许祖先组件在子孙组件中注入一个依赖,不管层级嵌套有多深,它都能进行通信交互,具体的参见: https://cn.vuejs.org/v2/api/#provide-inject

所以我们这边把壁咚声安排一下吧, 在App.vue中祭出如下短小精悍的代码

provide: {
    audio: new Audio(require('@/assets/msg.mp3'))
  }

mixins地灵活运用

mixins混入,一方面是为了精简代码,另一方面是为了偷懒,我是这么认为的。在很多的组件里代码都长的差不多,那这个时候你就可以考虑混入了。在组件中,它接收一个混入对象的数组,Mixin 钩子按照传入顺序依次调用,并在调用组件自身的钩子之前被调用, 具体的参见:https://cn.vuejs.org/v2/api/#mixins

所以我们可以创建一个mixins文件夹,在下面创建一个notice.js, 大致的意思就是,创建了一个定时器,每隔30秒去轮询一下消息的接口,然后根据返回的接口,如果有新消息,就根据类型去提示对应的消息,比如说警情那么是待审核,比如说银行啊之类的那就是派单去追查。

import { get as getNotice } from '@/api/notice'

export default {
  data() {
    return {
      timer: null
    }
  },
  inject: ['audio'],
  async mounted() {
    await this.pollingNotice(this.noticeType)
    this.timer = setInterval(async () => {
      await this.pollingNotice(this.noticeType)
    }, 30000)
  },
  beforeDestroy() {
    clearInterval(this.timer)
  },
  methods: {
    async pollingNotice(type) {
      const {
        data: { count }
      } = await getNotice({ type })
      const message =
        type === 'alarm'
          ? `有${count}条警情待审核!`
          : `有${count}条信息待追查!`
      if (count > 0) {
        this.audio.play()
        this.$notify.info({
          title: '消息',
          message
        })
      }
    }
  }
}

纳尼,壁咚不出来了

遗憾的是,并没有壁咚的声音,啊这。我若有所思地打开控制台。看到了这句话,给它一个特写play() failed because the user didn't interact with the document first。大致的意思是需要引导用户去交互,也就是要引导用户先去触发一次交互。通过查询相关资料,Chrome在2018年4月份发布的66版本关掉了声音自动播放,哦,原来是这样子啊。

不行的,阿Sir说了,一定得壁咚一下

这里我想到的一个做法是,先去检测用户的浏览器是否支持自动播放,如果不支持的话,我弹出一个框,让用户点一下,那么下次就有壁咚声了,233333333。

这里祭出一个npm包-can-autoplay,https://www.npmjs.com/package/can-autoplay, 它不仅可以检测视频还可以检测音频。使用时核心代码如下:

canAutoplay.audio().then(({result}) => {
  if (result === true) {
    // Can auto-play
  } else {
    // Can not auto-play
  }
})

应用到我们这里就是

canAutoPlay.audio().then(({ result }) => {
      if (result === true) {
        console.log('can auto play!')
      } else {
        this.$alert(
          '检测到您的浏览器不支持媒体自动播放,是否同意播放测试音',
          '提示',
          {
            confirmButtonText: '确定',
            callback: action => {
              this.audio.play()
            }
          }
        )
      }
    })

胆子大一点,流氓一点,取消我都不安排给阿Sir点,23333333333。

参考文献

https://developers.google.com/web/updates/2017/06/play-request-was-interrupted

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
播放音频时,浏览器可能会阻止自动播放,这是为了防止过多的媒体文件自动播放对用户造成干扰。为了解决这个问题,可以在用户与页面进行交互后手动触发音频的播放事件。以下是一些解决方法: 1. 用户手动触发播放事件 可以为页面上的某个元素(如按钮)添加点击事件,当用户点击该元素时,触发音频的播放事件。例如: ```javascript var audio = document.getElementById("myAudio"); var playButton = document.getElementById("playButton"); playButton.addEventListener("click", function() { audio.play(); }); ``` 2. 使用 `setTimeout` 可以使用 `setTimeout` 函数在页面加载完成后延迟一段时间再播放音频。例如: ```javascript var audio = document.getElementById("myAudio"); setTimeout(function() { audio.play(); }, 1000); ``` 这样做的缺点是,无法确保用户已经与页面进行交互,因此可能仍然会被浏览器拦截。 3. 使用 `Promise` 可以使用 `Promise` 在用户与页面交互后再播放音频。例如: ```javascript var audio = document.getElementById("myAudio"); document.addEventListener("click", function() { audio.play().then(function() { console.log("播放成功"); }).catch(function(error) { console.log("播放失败"); }); }); ``` 这样做的优点是,确保用户与页面进行交互后才会播放音频,可以避免被浏览器拦截。但是,需要注意的是,该方法只能在支持 `Promise` 的浏览器使用。 总之,为了避免浏览器拦截播放音频,最好在用户与页面进行交互后再播放音频

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值