项目场景:
Unity版本 2021.1.0
平台:WebGL
适配在PC,android,ios系统
问题描述
unity发布出来的webgl有一个功能是播放语音介绍,一开始用的是unity自带的AudioSource,在PC和安卓手机上一切正常,但是后面甲方因为用的苹果手机发现并没有声音,于是发现这个问题,记录下来以便帮助后面遇到此坑的朋友。
一开始解决的思路,尝试过目前网上分享的方法但是没有作用,将mp3格式转换为wav不行。后来转换思路通过html来播放音频,但是又遇到坑,一样在PC和安卓上没问题,在iOS上报这样的错误:
NotAllowedError: The request is not allowed by the user agent or the platform in the current context, possibly because the user denied permission.
我并没有让音频在一运行时就自动播放,而是点击按钮触发,在尝试了若干次后终于发现问题。
我发现点击html上定义的按钮可以正常触发音频播放,但是通过点击unity场景里的按钮给index.html调用html上播放音频的函数就会报错,而且仅在第一次报错,也就是说 ,只要通过html上的按钮触发过播放音频后,即使再通过unity场景里的按钮触发也不会报错。但是如果没有通过html的按钮触发过,那么通过unity场景里的按钮触发就会一直报错。
这两种触发方式的区别在于,一个是用户点击html上的按钮触发,一个是用户点击unity场景里的按钮调用html上的函数。
网上分享的解释大概是 浏览器不允许站点在没有用户交互的情况下自动播放音频或视频(我有交互而且也没要求自动播放啊!!!)
解决方案:
写一下我的解决方法,写的不好抛砖引玉,不过可以解决问题。
在unity打包出的webgl里面新建一个Audios文件夹,放入音频文件Bird.mp3(根据实际情况)
在unity打包出的webgl里面打开index.html
在body里面上代码
<audio id="audioBoom" class="audio-hide" src="Audios/Bird.mp3"></audio>(根据实际情况)
function PlayMusicWeb() //网页上用户有交互时调用
{
if( window.isFirst)
{
document.getElementById('audioBoom').muted=true;
document.getElementById('audioBoom').load();// 播放
}
else
{
document.getElementById('audioBoom').muted=false;
}
}
function PlayMusicUnity() //unity场景里面点击按钮触发 调用这个方法
{
document.getElementById('audioBoom').muted=false;
document.getElementById('audioBoom').load() // 播放
document.getElementById('audioBoom').play() // 播放
}
在html最下面写代码
<script>
window.isFirst=true; //定义一个全局boolean变量
var canvas = document.querySelector("#unity-canvas");
//移动端 触摸时
canvas.ontouchstart = () =>
{
PlayMusicWeb();
};
//移动端 触摸结束
canvas.ontouchend=()=>{
window.isFirst=false;
};
//PC端 鼠标移动时
canvas.onmousemove=()=>{
if((document.getElementById('audioBoom').played))
{
return;
}
PlayMusicWeb();
};
//PC端 鼠标移动结束
canvas.onmouseleave=()=>{
if((document.getElementById('audioBoom').played))
{
return;
}
window.isFirst=false;
}
</script>
通过一个变量isFirst记录一下 在调用PlayMusicWeb()方法时候会根据是否是第一次去处理,不加这个你会发现,声音是正常播放但是每次一触摸屏幕或者移动鼠标,音频就会重新load重新播放。
记录此坑