秋梦无痕

一场秋雨无梦痕,春夜清风冻煞人。冬来冷水寒似铁,夏至京北蟑满城。

Avatar

<audio>播放之iOS safari大坑

高高兴兴地在网页上放了一个audio:

<audio id="audio_bullet" autobuffer="autobuffer" preload="auto">
<source src="data:audio/mp3;base64,/+MgwAAQ2Sn8BUYQAAyQw8mmxiDgAIQ93fgmTtoMQxwAAJOc7oc5/8hGU55zv/6nO5AM44EP/Ln//wf3FDnOco7/wfg/EEp/8H3g/y5//8MK2gGP8OD/Uf+TxBE/8gh5Ms/+Vy4OeLn/4yLAFxm8FtwBhYAAyT/3fIsICBygB+O4WR/f8UcZQiCk3Ln//7VLcuHT5v///+m8zN5gaE+tMuf////lw0UimZk+bso0IOmyH//////lxmQmZ+T5fNzRadBk1Gl2g6xsqMC2Y3Q3kfn/4yDADBSBcxwBghgATSZtP65WVTz0OxGZZ/W/PPzy//bz2iGgdvY5TkFIVDq9CdgsUgifWQpZ5B+5coTdBcRjxZCjwxBn73q2iOZMLWCmMY/qF2SmFCo2JSXExA9l4mKFHFAZEUuJuv/jIsAVGCtHBAGCKAAQZkQiF6iIkEnGpRXFtKoo5AAHOIGG3P2Vn7S3Ew6JO7k1KbzeZzBKqhwKcdMlHRS83/9BqaiRyyKN/vmvp//5HWYWV4GeJC+2tuhSQ5FyCfYFNqohf/iVCgEPpP/jIMAQFyIO0AGCQADhsHhGKPQkkQaK5/DxroQyWkORh0+36WHz0IJ8bLTt//qScKip2Sc+zNW3//+2zPfOPYqdQe2fWKhNbg8pzUXoR/wacPVUOnlFldZiuhHtUAnE8sFXxFOo0Ydx/+MiwA4SiAZxk8AQACug1xKd1gqPBX8S/UDUkJQ1Kgst1YNB36wVPLDXrBVYKuncJhrlTqOVO/iXBoqG14KlQ1BUFvKgrwVdDVUSLfyMj/////////IyIyMjIwf9UVFRU/RUVUVFRUVU/+MgwB8Rc+FYDABE3VRUVP////+ioqoqKioqoqf/////VFRUMUwUEDBAwQIGCBggwMppVUxBTUUzLjk5LjVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVU=" />
</audio>


然后通过timer定时发子弹,发出声音。

开始测试:
Edge通过~
Chrome通过~
Firefox通过~
Android通过~
iPhone。。。emmm。。。不响,真的不响。。。

问了一下StackOverflow,说是:
iOS升级到12.2后,如需在UIWebView中自动播放视频、或者想通过JS调用方法的方式播放视频,必须将UIWebView中的“mediaPlaybackRequiresUserAction”设置为NO。这个属性的意思就是:是否需要用户操作才能播放视频,默认为YES。用户操作必须使用触发 touchend、click、doubleclick 或 keydown 事件等标准的事件才能触发。

emmm。。。interesting。。。

然后在网上找了一圈,据说的解决方案如下:

<script>
if ("wView" in window) {
	window.wView.allowsInlineMediaPlayback = "YES";
	window.wView.mediaPlaybackRequiresUserAction = "NO";
}
</script>


但是可耻的失败鸟。。。

最终的解决方案是,通过页面上的用户真实点击触发一下play函数,然后就再随便调用play函数就可以了。。。

上代码:

<script>
document.onload = function() {
	if (/AppleWebKit/.test(navigator.userAgent)) {
		document.addEventListener('touchstart', touchPlay, false);
	}
}

function touchPlay() {
	let e = document.getElementById("audio_bullet");
	e.muted = true;
	e.play();
	e.pause();
	e.muted = false;

	document.removeEventListener('touchstart', touchPlay);
}
</script>