web 页面音乐的无法自动播放问题探索
找到一个 程序员表白神器 的动画页面,看着画面非常好,结合其他的一些 表白 动画页面是可以有音乐的,就想着给它加一个。结果翻开代码一看,已经添加了,并且还设置了自动播放:
<body>
<audio autoplay="autoplay">
<source src="renxi.mp3" type="audio/mp3">
</audio>
...
都知道的一个事实是,最近(有可能是好几年之前了)浏览器都做了更新,不允许页面一进来就播放音乐,需要有用户的互动操作才能播放。所以这个自动播放播放了个寂寞。
在页面加载之后使用 js 播放音乐也是不行的。原因就想上面说的,浏览器禁用了,这时会报错:
Uncaught (in promise) DOMException: play() failed because the user didn't interact with the document first.
https://goo.gl/xX8pDD
可以用一个按钮的点击来触发音乐播放。这个动画页面一开始恰好有一个按钮,找到这个按钮的点击事件并添加播放就好:
$("audio")[0].play();
html 直接定位显示,这个 ? 的开始按钮是被画到 canvas 画布里的。直接放在 canvas 的点击事件上也可以,但最好能够是在点击 ? 开始按钮时触发。
canvas.click(function(e) {
var offset = canvas.offset(), x, y;
x = e.pageX - offset.left;
y = e.pageY - offset.top;
if (seed.hover(x, y)) {
hold = 0;
canvas.unbind("click");
canvas.unbind("mousemove");
canvas.removeClass('hand');
$('audio')[0].play();
}
})
其中的 seed.hover(x, y)
根据 canvas
上的坐标点背景图片颜色为红色来识别 ? 开始按钮,结合 canvas.click()
canvas 点击事件,就能组合成 ? 开始按钮的点击事件处理。
此时还想点击的时候就触发全屏显示,正好其中一个样例有现成的,直接拿过来用:
function kaishi() {
document.getElementsByTagName("audio")[0].play();
var docElm = document.documentElement;
//W3C
if (docElm.requestFullscreen) {
docElm.requestFullscreen();
}
//FireFox
else if (docElm.mozRequestFullScreen) {
docElm.mozRequestFullScreen();
}
//Chrome等
else if (docElm.webkitRequestFullScreen) {
docElm.webkitRequestFullScreen();
}
//IE11
else if (elem.msRequestFullscreen) {
elem.msRequestFullscreen();
}
}
...
canvas.click(function(e) {
var offset = canvas.offset(), x, y;
x = e.pageX - offset.left;
y = e.pageY - offset.top;
if (seed.hover(x, y)) {
hold = 0;
canvas.unbind("click");
canvas.unbind("mousemove");
canvas.removeClass('hand');
kaishi()
}
})
完美!
在快结束的时候,突然发现一个奇怪的现象:程序员表白神器 页面上点击查看演示,打开的演示 demo 页面会自动播放音乐。刷新 demo 页面后就不会自动播放了,但如果是在刷新 demo 页面,底栏进度条加载到 80-90 的时候点击页面,此时音乐也会播放。源码应该是一样的,demo 页面就是在当前页面中通过 iframe 引入了这个源码页面:
<div id="iframe-wrap">
<iframe id="iframe" src="https://www.jq22.com/demo/love-141127195922" frameborder="0" width="100%" height="758px"></iframe>
</div>
暂时没有找到原因。
PS
jquery 播放 mp3 代码为 $('audio')[0].play();
。因为通过 $('audio')
标签获取到的是一个标签元素数组。
通过按钮控制暂停和播放(参考:jquery播放mp3):
$("#playButton").click(function() {
var audio = document.getElementById("myAudio");
if (audio.paused) {
audio.play();
$(this).text("暂停");
} else {
audio.pause();
$(this).text("播放");
}
});
另外,还可以参考:HTML页面激活态:为何音频无法自动播放?,定时判断页面是否属于激活可播放状态:
<script>
const t = setInterval(() => {
if (navigator.userActivation.hasBeenActive){
// 页面进入粘性激活态
const v = document.createElement('video')
v.src = './test.mp4'
v.autoplay = true
document.body.appendChild(v)
clearInterval(t)
}
}, 1000);
</script>
但因为激活需要用户的互动操作,比如点击,所以感觉没用上。