解決瀏覽器中不支持音頻自動播放的方法


需求

事情是這個樣子的,有這樣一個需求,就是阿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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM