Chrome中Soundcloud Widget API报错:AudioContext无法启动
解决Chrome中Soundcloud Widget自定义播放按钮无法播放的问题
这个问题我之前也踩过坑!确实是Chrome针对音频播放的政策更新导致的——现在浏览器严格要求AudioContext必须在用户主动交互(比如点击、触摸)之后才能初始化或恢复,禁止页面加载时自动启动音频上下文。
问题原因分析
- Soundcloud自带的播放按钮能正常工作(即使报错),是因为它在iframe内部,点击操作属于iframe上下文内的用户手势,触发后iframe里的AudioContext会自动尝试恢复,所以能播放。
- 你的自定义按钮在主页面,点击事件是主页面的用户手势,但widget是页面加载时就初始化的,此时iframe里的AudioContext已经被创建但处于暂停状态,调用
widget.play()时,跨上下文的操作无法触发iframe内AudioContext的恢复,所以直接报错且无法播放。
解决方案
最稳妥的方法是把widget的初始化逻辑移到用户第一次点击自定义按钮的回调里,这样整个widget的AudioContext会在用户手势的触发下创建,完全符合Chrome的政策要求。修改后的代码如下:
<!-- Own Play Button --> <div id="playBtn">Play</div> <!-- SC Widget --> <iframe id="sc-widget" src="https://w.soundcloud.com/player/?url=http://api.soundcloud.com/tracks/406078437" scrolling="no" frameborder="no"></iframe> <!-- JS --> <script src="/src/vendors/jquery-3.3.1/jquery.min.js"></script> <script src="/src/vendors/sc-widget-api/sc-widget-api.js"></script> <script> $(document).ready(function() { let widget; // 先声明widget变量,避免重复初始化 $('#playBtn').on('click', function() { if (!widget) { // 第一次点击时初始化widget,此时处于用户手势回调中 var widgetIframe = document.getElementById('sc-widget'); widget = SC.Widget(widgetIframe); widget.bind(SC.Widget.Events.READY, function() { // widget就绪后立即播放 widget.play(); }); } else { // 非第一次点击,直接播放 widget.play(); } }) }); </script>
备选方案(临时兼容)
如果不想改动初始化逻辑,也可以在点击事件中先激活主页面的音频上下文,再调用播放,不过这个方法依赖浏览器的权限判断逻辑,稳定性稍差:
$('#playBtn').on('click', function() { // 先激活主页面的音频上下文,触发用户权限 const audioCtx = new (window.AudioContext || window.webkitAudioContext)(); audioCtx.resume().then(() => { widget.play(); }); })
注意事项
- 确保所有触发音频播放的操作都直接绑定在用户交互事件(click/touchstart等)的回调中,不要通过异步延迟或间接调用触发。
- Chrome的这个政策是为了防止网页自动播放音频打扰用户,所有现代浏览器都在逐步跟进类似规则,所以尽量遵循用户手势触发的原则开发。
内容的提问来源于stack exchange,提问作者KainLaVey
相关产品推荐
相关产品推荐

