持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第12天,点击查看活动详情
业务背景
Web Audio是应在web浏览器中处理音频的需求而产生的,它早已不是一个新鲜的概念,但并没有大规模使用却是一个不争的事实。除去不值一提的兼容性问题,我想原因大概有几个,首先是API居多,因为它要实现在浏览器产生、处理音频必须要有相应的接口,但和专业音频制作程序仍有一定差距,不是特别能吸引专业人士;然后就是要实现实时WebRTC、游戏级引擎的音频特效等所需要的专业知识(数字信号处理、通信原理等)所带来的学习成本也是让很多人望而却步。不过大势所趋,它还在处于不断发展中,相信未来前景还是不错的。
Web Audio提供的合成声音、添加特效、音频可视化功能,是在音频上下文完成的,它将不同的操作细化为对应的节点实现了模块化(Modular routing),各个节点又可以通过connect方法相连接,进行必要的处理后,最终输出到目标节点(音频上下文的destination属性,通常是声音输出设备如扬声器)。整个流程连接在一起形成一个音频路由图(audio routing graph)。
Web Audio Api简单工作流程为:
- 创建音频上下文(AudioContext或OfflineAudioContext)
- 在上下文中创建声音来源(如audio标签、xmlhttprequest请求得到的arraybuffer、oscillator振荡器产生的各种波形)
- 创建特效节点(如混响、各种滤波、平移、压缩)
- 选择音频的最终产出地(如系统扬声器)
- 将来源连到特效节点,将特效节点连到目的节点
提前说明,HTML5 Web Audio API存在一些兼容性问题和坑,使用时需要注意。本文的主要内容也是针对在项目业务中遇到的 Web Audio 的问题进行排查和总结。
1. 全局类名不同
- Chrome下是AudioContext
- iOS下是webkitAudioContext
2. iOS需要通过交互事件解锁播放
-
PC端Chrome可以直接播放
-
iOS默认是无法播放音频的,一定要有用户操作(如mousedown、touchstart)后来解锁第一次播放
- 例如在
touchstart
事件时,播放一个空音频,即可解锁音频播放。
- 例如在
如何实现浏览器中音频的自动播放
IOS跟Android以及微信自带的浏览器为了用户体验,默认是已经屏蔽了autoplay属性
1.触摸监听播放
严格意义上来讲,这不是自动播放,而是“仿真”、“模拟”、“虚假”的自动播放。原理是当用户触碰到屏幕就开始播放音频,以达到看起来好像是自动播放的假象。但如果用户就是打开页面,并没有触屏的话,那就不会播放了
<audio autoplay="autopaly" loop="loop" id="audios">
<source src="音频地址" type="audio/mp3" />
</audio>
<script>
document.addEventListener('touchstart', function() {
document.getElementById('audios').play()
})
</script>
复制代码
2.微信浏览器自动播放方案:WeixinJSBridgeReady
<audio autoplay="autopaly" loop="loop" id="audios">
<source src="音频地址" type="audio/mp3" />
</audio>
<script>
// 使用微信自带的WeixinJSBridgeReady事件
document.addEventListener('WeixinJSBridgeReady', function() {
document.getElementById('audios').play()
})
</script>
复制代码
然后将两种方法写在一起,就可以实现性能比较好的自动播放交互。
<audio src="音频地址" id="audios" autoplay preload loop="loop"></audio>
<script>
function audioAutoPlay(id){
var audio = document.getElementById(id),
play = function(){
audio.play();
document.removeEventListener("touchstart",play, false);
};
audio.play();
document.addEventListener("WeixinJSBridgeReady", function () {
play();
}, false);
document.addEventListener('YixinJSBridgeReady', function() {
play();
}, false);
document.addEventListener("touchstart",play, false);
}
audioAutoPlay('audios');
</script>
复制代码
移动端H5游戏中音频自动停止播放的问题及解决方法
问题分析:Context丢失
- 跳转到微信支付
- 来电话了
- 内存不足
1.检测Context丢失了
- 获取一个正在播放的音频
snd
- setTimeout设定定时器
- 如果两个时间
snd.seek()
获取的time都相同,说明播放被卡死了
2.解决方式
优化内存,并在卡死时
$(window).once('touchstart', ()=>{
sound.pause();
Howler.ctx.suspend();
Howler.ctx.resume();
sound.play();
})
复制代码