Chrome 66 禁止声音自动播放,该怎么办?

我有个功能,就是网站中用户收到其他用户发送的消息时,会播放提示语音,但是突然有一天有个错误:

DOMException: play() failed because the user didn't interact with the document first.

懵B吧,看字面意思就是说用户还没有和浏览器进行交互,不能播放,也就是说只有用户进行了点击页面等等操作,才可以进行播放语音。

懵B吧,怎么搞。

今天说一个可以解决的方法,当然不排除以也不可用,解决方案就是通过iframe引入一个线上音频,再将iframe插入到页面,就可以自动播放了。

 废话不多说,直接上代码:

<iframe src="这里是线上音频地址" allow="autoplay 'src'"></iframe>
重点:iframe的allow属性一定要是autoplay
 
就这么简单,以下是完整的vue版本的示例,实现的功能就是用户收到信息后播放通知音频
组件:index.vue
<template>
    <iframe
        v-show="visible"
        src="//video-static.com/FlQUl4Tvbu7Akyk8m7lySW"
        allow="autoplay 'src'"></iframe>
</template>

<script>
export default {
    data() {
        return {
            duration: 3000,
            closed: false,
            visible: false
        }
    },
    watch: {
        closed(newVal) {
            if (newVal) {
                this.visible = false
            }
        }
    },
    mounted() {
        this.startTimer()
    },
    methods: {
        close() {
            this.closed = true
            if (typeof this.onClose === 'function') {
                this.onClose(this)
                this.$destroy(true)
                this.$el.parentNode.removeChild(this.$el)
            }
        },
        startTimer() {
            if (this.duration > 0) {
                this.timer = setTimeout(() => {
                    if (!this.closed) {
                        this.close()
                    }
                }, this.duration)
            }
        }
    }
}
</script>

index.js

import Vue from 'vue'
import Index from './index.vue'
let IframeConstructor = Vue.extend(Index)

let instance
let instances = []
let seed = 1

const AudioIframe = function(options) {
    if (Vue.prototype.$isServer) return
    options = options || {}
    let id = 'iframe_' + seed++

    options.onClose = function() {
        AudioIframe.close(id)
    }
    instance = new IframeConstructor({
        data: options
    })
    instance.id = id
    instance.$mount()
    document.body.appendChild(instance.$el)
    instance.visible = true
    instances.push(instance)
    return instance
}

AudioIframe.close = function(id) {
    let len = instances.length
    let index = -1
    for (let i = 0; i < len; i++) {
        if (id === instances[i].id) {
            index = i
            instances.splice(i, 1)
            break
        }
    }
}

export default AudioIframe

调用方法

let audioEl = this.$refs.msgAudio
let audioEl = this.$refs.msgAudio
const audioPromise = audioEl.play() // 返回的是Promise
if (audioPromise && audioPromise instanceof Promise) {
     audioPromise.then(_ => {}).catch(_ => {
            audioNotify()  // 当播放被禁止时,在这里调用iframe方式进行播放
     })
}

猜你喜欢

转载自www.cnblogs.com/zhengzhigang/p/12932383.html
66