audio报错DOMException: play() failed because the user didn‘t interact with the document first

2023-05-16

chrome66版本之后禁掉了声音的自动播放,这句报错提示,调用play方法之前,请先与页面进行交互。
我们自己来封装一个可以自动播放的Audio,功能包含:自动播放、暂停、循环播放。
1、封装一个audio对象

export class AudioWithIE {
    private _audio: HTMLAudioElement
    private _source: HTMLElement
    playSoundSecond: number  // 播放时长,用来计算循环播放次数

    constructor(playSoundSecond) {
        this._audio = document.createElement('audio')
        this._audio.setAttribute("autoplay", "autoplay")
        this._source = document.createElement('source')
        this._audio.appendChild(this._source)
        document.body.appendChild(this._audio);
        this.playSoundSecond = playSoundSecond
    }
	
	// 计算循环播放次数
    async countAudioTime() {
        let _this = this
        while (isNaN(_this._audio.duration) || _this._audio.duration === Infinity) {
            // 延迟一会 不然网页都卡死
            await new Promise(resolve => setTimeout(resolve, 200));
            // 设置随机播放时间,模拟调进度条
            _this._audio.currentTime = 10000000 * Math.random()
        }
        // this._audio.duration 获取声音文件的时长
        if (this.playSoundSecond > Math.round(this._audio.duration)) {
            const count = Math.ceil(this.playSoundSecond / this._audio.duration)
            this._audio.setAttribute('loop', 'loop')  // 设置循环播放属性:loop
            let timer = null
            let i = 0
            timer = setInterval(()=>{
                i++
                if (i >= count) {
                    clearInterval(timer)
                    this._audio.removeAttribute('loop')
                    this.pause()
                }
            }, Math.round(this._audio.duration)*1000) 
        }
    }
    // 暂停
    pause() {
        if (this._audio.getAttribute('loop')) {
            this._audio.removeAttribute('loop')
        } 
        this._audio.pause()
    }
	// 初始化播放 传值一个声音文件地址
   init(fileName: string): Promise<any> {
        let fileUrl = '/' + fileName
        this._source.setAttribute("src", fileUrl)
        this._audio.load()
        this._audio.autoplay = true;
        return new Promise((resolve, reject) => {
        	// 监测声音文件是否加载完毕
            this._audio.addEventListener("canplaythrough", event => {
            	// 都为4 说明网络稳定的状态下可播放声音文件
                if (this._audio.readyState == this._audio.HAVE_ENOUGH_DATA) {
                    this._audio.play()
                    .then(()=>{
                        console.log('声音播放成功');
                        this._audio.play()
                        resolve(undefined)
                    })
                    .catch((err)=>{
                        if (err.name == 'NotAllowedError') {
                            console.log('声音播放失败');
                            reject()
                        }
                    })
                }
            });
        })  
    }
}

2、实现Audio对象

// 如果在声音播放前未进行交互,出现提示框,让用户点击
<transition name="audio-notify-fade">
   <el-card v-show="isShwoAudioNofify" class="audio-notify-box-card" id="audio-notify">
        <div class="title">
            <i class="el-icon-warning"></i>
            <span> 提示 </span>
        </div>
        <div class="content">请开启声音自动播放</div>
        <div class="footer">
            <el-button size="mini" type="warning" @click="hiddenAudioNofity">确定</el-button>
        </div>
    </el-card>
</transition>

// ts部分
// 实现audio对象
get audio() {
   	return new AudioWithIE(this.alarmConfig.playSoundSecond)
}

// 60s内如果页面没有任何click操作,出现提示框。
isShwoAudioNofify: boolean = false
isHandleClick: boolean = false

mounted() {
	this.initNotify()
    this.initAudio()
}
imitateClick() {
   this.isHandleClick = true
    if (this.isShwoAudioNofify) this.isShwoAudioNofify = false
}
initAudio() {
    document.addEventListener('click', this.imitateClick)
    let i = 0
    let timer = setInterval(()=>{
        i++
        if (i == 60) {
            clearInterval(timer)
            window.removeEventListener('click', this.imitateClick)
            if (!this.isHandleClick) {
                this.isShwoAudioNofify = true
            }
        }
    },1000)
}

initNotify() {
    let audioNotify = document.getElementById('audio-notify')
    document.body.appendChild(audioNotify)
}

@Watch('audioFileName')
watchFileName(newVal) {
	if (!!newVal) 
		this.audioPlay(newVal)
}
// 播放方法
async audioPlay(fileName: string) {
   this.audio.countAudioTime()
   try {
        await this.audio.init(fileName)
        this.isPlayed = true
    } catch(err){
        this.isShwoAudioNofify = true
    }
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

audio报错DOMException: play() failed because the user didn‘t interact with the document first 的相关文章

  • 按频率对波形进行颜色编码[关闭]

    Closed 这个问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 help closed questions 目前不接受答案 我想按本地频率内容显示每个部分中颜色编码的音频波形 基本上与 Serato Traktor 或任何其他
  • 实时录制/将音频数据转换为 WAV

    我在音频信号处理方面是新手 目前 我已将设备连接到我的电脑 该电脑从麦克风 播放轨道向我发送音频数据 我已经使用 Steinberg ASIO SDK 2 3 创建了主机应用程序 该应用程序连接到设备并在重复回调中返回原始数据 信号是 24
  • 实时获取 macOS 输出设备音频缓冲区

    我试图tapmacOS 上当前选择的输出音频设备 因此我基本上有一个直通侦听器 可以监视当前正在输出的音频流而不影响它 我想将这些数据实时复制到环形缓冲区 以便我可以单独对其进行操作 Apple 文档和 过时 SO 答案的结合令人困惑 我是
  • 使 PlaySound 非阻塞

    我一直在测试声音 我注意到PlaySound正在阻塞 即它会等到声音播放完毕才返回 include
  • 比较两个不同的音频文件不起作用

    我想比较两个音频文件 例如 mp3 和 wav 我用musicg https code google com p musicg 通过指纹进行比较 Wave record1 new Wave music1 toString Wave reco
  • 如何在多个 HTML 页面上播放背景音频?

    是否有解决方案可以让背景音频 音乐在网站上的多个页面上播放 而无需在每个页面加载时重新启动 该网站当前使用框架集 但我正在寻找替代方案 如果不让整个网站都 AJAX 我认为框架是唯一的方法 如果您需要的话 这里有一个关于制作 ajax 站点
  • 使用 AVAudioEngine 重复播放音频文件

    我正在使用 Swift 和 Xcode 6 开发一个 iOS 应用程序 我想做的是使用 AVAudioEngine 播放音频文件 到目前为止一切正常 但是我怎样才能不停止地播放它 我的意思是 当它结束播放时它会再次开始 这是我的代码 CON
  • 将非规范化数字刷新为零

    我在网上搜索过 但没有结果 Xcode 和 Visual C 有没有办法将非规范化数字视为 0 我本以为 IDE 首选项中有一个选项可以打开此选项 但似乎找不到它 我正在做一些跨平台音频工作 需要停止某些处理器占用资源 Cheers 您正在
  • 使用 Javascript 播放音频元素 (html5)

    我正在尝试弄清楚如何触发从 javascript 播放音频 我得到了一些 html 看起来像 div class audio foo div
  • 如何使用 PJSIP 为 iOS 客户端应用程序捕获并翻译其他语言的传入音频流?

    我想在基于 VoIP 的 iOS 客户端应用程序中集成语言转换器 该应用程序将根据用户选择将实时传入音频流翻译为其他选定的语言 我正在使用 PjSip 开源库来支持 VoIP 呼叫 对于语言翻译 我想使用语音到文本和文本到语音开源库 现在我
  • 如何使用 Android 1.5 录制音频?

    如何使用 Android 录制一些音频 package com benmccann android hello import java io File import java io IOException import android me
  • OpenAL 初始化问题,仅限 iPod(?)

    我遇到了 OpenAL 问题 似乎只发生在 iPod 硬件上 奇怪的是它was工作正常 但现在不行了 我正在设置音频会话 AVAudioSession sharedInstance setCategory AVAudioSessionCat
  • 将声音添加到标记数组 - 谷歌地图 javascript

    我是新来的 所以我知道我没有任何可信度 我是一名艺术家 对编程很陌生 所以我理解是否没有人会承担这个任务 我发布这篇文章是因为这是一个简单的问题 S 这是创建多个标记的代码 主要来自谷歌开发者网站 它工作正常并为每个标记创建一个自定义图标
  • 如何从 URL 流式传输音频而不在设备上下载 mp3 文件

    如何在 Swift 中从 URL 流式传输音频而不在设备上下载 mp3 文件 我需要导入什么 我需要某些库吗 添加任何内容到 info plist 中吗 请评论你的代码 您可以使用 iOS AVPLayer 从 url 传输音频 var p
  • 严格标准:在 wordpress/wp-includes/class-oembed.php 第 116 行中,仅应通过引用传递变量

    我已经查看了很多类似的问题 但关于我的代码 我没有得到它 错误 Strict Standards Only variables should be passed by reference in wordpress wp includes c
  • SoundEffect 和 SoundEffectInstance 类之间的区别

    就像有问题一样 我不明白使用这些类有什么区别 每个类别的优点和局限性是什么 我读了很多教程 但仍然无法决定我应该做什么 为了让事情更清楚 我得到了 AudioModule AudioEmitterComponent 和 AudioListe
  • 如何在 python 中生成音符或和弦?

    有人能给我指出一个在 python 2 7 中生成音符和和弦的好库吗 我查看了 PythonInfoWiki 但运气不佳 PyAudio 只是崩溃了 似乎没有其他东西可以生成音调 我不知道这是否有帮助 但这里有一些代码可以根据给定的频率和振
  • 将声音图形化地表示为波

    我创建了一个记录和播放声音的应用程序 我正在寻找一种显示简单波形的方法 记录声音的表示 不需要动画 只需一个简单的图表 如果可以选择波的子集也很好 当然更好 也播放该部分 总而言之 我正在寻找什么 一种以图形方式将录制的声音表示为波的方法
  • 如何捕获正在播放的音频?

    有谁知道如何以编程方式捕获正在播放的声音 即来自声卡的所有声音 而不是麦克风等输入设备 假设您正在谈论 Windows 则基本上可以通过三种方法来实现此目的 首先是打开音频设备的主输出作为录音源 这只有在驱动程序支持时才可能实现 尽管现在大
  • 播放选定的音频,同时暂停/重置其他音频

    我有两个通过按钮的单击事件播放的音频元素 如果选择了另一个元素 我已成功地暂停其中一个元素 但还需要将暂停元素设置回 0 0 秒 即暂停和重置 我知道 Javascript 目前没有stop 导致的方法假设这将通过设置其来完成current

随机推荐