H5页面中音频播放问题解决方案

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第12天,点击查看活动详情

业务背景

Web Audio是应在web浏览器中处理音频的需求而产生的,它早已不是一个新鲜的概念,但并没有大规模使用却是一个不争的事实。除去不值一提的兼容性问题,我想原因大概有几个,首先是API居多,因为它要实现在浏览器产生、处理音频必须要有相应的接口,但和专业音频制作程序仍有一定差距,不是特别能吸引专业人士;然后就是要实现实时WebRTC、游戏级引擎的音频特效等所需要的专业知识(数字信号处理、通信原理等)所带来的学习成本也是让很多人望而却步。不过大势所趋,它还在处于不断发展中,相信未来前景还是不错的。

Web Audio提供的合成声音、添加特效、音频可视化功能,是在音频上下文完成的,它将不同的操作细化为对应的节点实现了模块化(Modular routing),各个节点又可以通过connect方法相连接,进行必要的处理后,最终输出到目标节点(音频上下文的destination属性,通常是声音输出设备如扬声器)。整个流程连接在一起形成一个音频路由图(audio routing graph)。

未标题-1.png 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. 跳转到微信支付
  2. 来电话了
  3. 内存不足

1.检测Context丢失了

  1. 获取一个正在播放的音频snd
  2. setTimeout设定定时器
  3. 如果两个时间 snd.seek() 获取的time都相同,说明播放被卡死了

2.解决方式

优化内存,并在卡死时

$(window).once('touchstart', ()=>{
    sound.pause();
    Howler.ctx.suspend();
    Howler.ctx.resume();
    sound.play();
})
复制代码

猜你喜欢

转载自juejin.im/post/7105756309378564133