前言
准备做web端的消息通知, 通过Notification 做系统消息的弹框,发现自动播放声音问题。 出于好奇对W3C 关于 autoplay 例子进行参考... 更多可参考github链接,更多消息提示demo
关于audio自动播放问题
// 此代码可以放入 source 面板 Snippets 中运行, 不要放入控制台去运行, 控制台可以直接播放, 因为涉及鼠标回撤键, 鼠标事件,触发执行。
let audio = document.createElement('audio');
audio.autoplay="autoplay";
audio.meted = false;
audio.src = 'http://127.0.0.1:3003/notice_test.mp3';
audio.play();
// Uncaught (in promise) DOMException: play() failed because the user didn't interact with the document first.
发现谷歌浏览器在高版本中禁用 声音的自动播放问题,必须人为的去触发事件, 鼠标事件或键盘事件等还有控制台, 直接执行上面代码会直接报错
在w3c 网站上去查看audio autoplay 属性时, 发现点击链接打开页面可以进行自动播放。 但刷新页面时, 不会再次播放。 还有一个规律就是, 只要首次播放了声音, javascript 代码就可以完成上述代码的直接播放。 出于好奇, 模拟了w3c代码实现, 代码如下
# 涉及表单提交 启动服务
npx http-server . -p $port
- index.html
<form id="codeForm" autocomplete="off" style="margin:0px;display:none;" action="/b.html" method="get" accept-charset="utf-8" target="iframeResult">
<input type="hidden" name="code" id="code" value=""/>
</form>
<div id="iframecontainer">
<div id="iframe">
<div id="iframewrapper">
<iframe frameborder="0" id="iframeResult" name="iframeResult"></iframe>
</div>
</div>
</div>
<script>
submitTryit();
function submitTryit() {
if (window.editor) {window.editor.save();}
let text = document.getElementById("textareaCode").value;
let ifr = document.createElement("iframe");
ifr.setAttribute("frameborder", "0");
ifr.setAttribute("id", "iframeResult");
ifr.setAttribute("name", "iframeResult");
document.getElementById("iframewrapper").innerHTML = "";
document.getElementById("iframewrapper").appendChild(ifr);
let t = text;
t=t.replace(/=/gi,"w3equalsign");
t=t.replace(/\+/gi,"w3plussign");
//document.write(t);
var pos=t.search(/script/i);
while (pos>0) {
t=t.substring(0,pos) + "w3" + t.substr(pos,3) + "w3" + t.substr(pos+3,3) + "tag" + t.substr(pos+6);
pos=t.search(/script/i);
}
document.getElementById("code").value=t;
document.getElementById("codeForm").action = "/b.html";
document.getElementById('codeForm').method = "get";
document.getElementById('codeForm').acceptCharset = "utf-8";
document.getElementById('codeForm').target = "iframeResult";
document.getElementById("codeForm").submit();
}
</script>
- b.html
<audio controls="controls" autoplay="autoplay">
<source src="/1702.mp3" type="audio/mpeg"/>
</audio>
w3c 例子其实a链接打开新标签的时候 鼠标事件被传递到新开的标签, 因此form表单自动提交, iframe 嵌入b.html 完成的自动播放。 页面刷新时不会自动播放, 如果javascript 直接执行auto.play() 则会报错。 关于audio 播放问题, google 一下, 暂时还没找出更好的办法, 据说可以hack 但出于见识, 不知道具体的实施方案。如有大牛,可以给出试例。