iPad 上的 iOS 禁用 Web 音频 API

Posted

技术标签:

【中文标题】iPad 上的 iOS 禁用 Web 音频 API【英文标题】:iOS on iPad Disabling Web Audio API 【发布时间】:2016-05-25 08:09:19 【问题描述】:

请注意:此问题已于 2016 年 11 月在 ios 10.1.1 中修复。谢谢苹果!

我无法在 iPad 上通过 Web Audio API 播放任何音频。这是使用最新版本的 iOS(自 9.3.2 - 当前为 10.1)。

测试用例

这是我设置的a bare-bones test(代码如下)。对我来说,所有测试都不适用于 iPad。在 iPhone 或其他兼容的浏览器上没有问题。有another test page here(来自威廉马龙)。这些声音都没有在尝试过的三台 iPad 上播放。最后this game 使用了Web Audio API(感谢Derek)并且也被静音了。

如果您在 iPad 上阅读此内容,请尝试 bare-bones test 并在 cmets(或 contact me privately)中报告,如果加载,然后播放,可以正常工作并播放声音。请包含 iOS 版本号(设置 -> 常规 -> 关于 -> 版本)。

任何见解或反馈将不胜感激!

这里是测试代码:

<!DOCTYPE html>
<html>
<head>
    <title>Web Audio API - iPad Test</title>
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <script src="./jquery-2.2.3.min.js"></script>
    <style>
        section  padding:10px; margin:0 0 10px; background:DarkSeaGreen 
        a  cursor:pointer; display:block; background: DarkSeaGreen; padding:10px; margin:0 0 3px 
    </style>
</head>
<body>
    <script>
        var app = ;
        $(document).ready(function() 
            // Do we have Web Audio API?
            try 
                window.AudioContext = window.AudioContext || window.webkitAudioContext;
                audioContext = new AudioContext();
             catch (e) 
                alert('Web Audio API is not supported in this browser');
            
            $('#loadClick').on('click',function()load('./ipad_test.mp3'));
            $('#playTouchEnd').on('touchend',play);
            $('#playTouchStart').on('touchstart',play);
            $('#playClick').on('click',play);
            $('#unlockTouchEnd').on('touchend',unlock);
            $('#unlockTouchStart').on('touchstart',unlock);
            $('#unlockClick').on('click',unlock);
        );
        function unlock() 
            // play empty buffer to unmute audio
            var buffer = audioContext.createBuffer(1, 1, 22050);
            var source = audioContext.createBufferSource();
            source.audioContext = buffer;
            source.connect(audioContext.destination);
            source.start(0);
            $('#messages').append('<p>Unlocked.</p>');
        
        function load(file) 
            if(app.loaded) 
                $('#messages').append('<p>Already loaded.</p>');
                return;
            
            var request = new XMLHttpRequest();
            request.open ('GET', file, true);
            request.responseType = 'arraybuffer';
            request.onload = function () 
                audioContext.decodeAudioData(
                        request.response,
                        function (buffer) 
                            app.buffer = buffer;
                            $('#messages').append('<p>Loaded.</p>');
                            app.loaded = 1;
                        ,
                        function()alert('Load error.');
                )
            ;
            request.send();
        
        function play() 
            if(!app.loaded) 
                $('#messages').append('<p>Please load before playing.</p>');
                return;
            
            var sourceNode = audioContext.createBufferSource();
            sourceNode.buffer = app.buffer;
            sourceNode.connect (audioContext.destination);
            sourceNode.start(0);
            $('#messages').append('<p>Playing.</p>');
        
    </script>
    <h1>Web Audio API Test</h1>
    <p>Unlock should not be needed at all, but offers an alternative way to try and get the audio going. Load and then play should be all any compatible device needs. Refresh to start again.</p>
    <a id="unlockTouchEnd">Unlock (touchend)</a>
    <a id="unlockTouchStart">Unlock (touchstart)</a>
    <a id="unlockClick">Unlock (click)</a>
    <a id="loadClick" style="background:#c0c0c0">Load (click)</a>
    <a id="playTouchEnd">Play Audio (touchend)</a>
    <a id="playTouchStart">Play Audio (touchstart)</a>
    <a id="playClick">Play Audio (click)</a>
    <section id="messages"></section>
</body>
</html>

背景

Apple documentation makes it clear 必须从用户操作启动音频,Web 音频 API 才能工作。他们说:

注意:在 iOS 上,Web Audio API 要求声音由明确的用户操作触发,例如点击。从 onload 事件调用 noteOn() 不会播放声音。

网上有很多关于这个问题的帖子,最新的是 2015 年秋季的 iOS 9.0 到 9.2:

Thread from HTML 5 Game Devs(2015年秋季题) William Malone(2015年秋季题) Paul Bakaus(解锁技巧) Adrian Holovaty(2015年秋季题)

他们建议从 touchstart 事件中触发音频以解锁 iOS 音频(或在当时出现问题时使用 touchend)。我已经尝试了所有建议的技术,但无法使用 touchstart、touchend 或 click to work。 iPad 上的音频始终处于静音状态。

【问题讨论】:

可能是个愚蠢的问题,但是您检查过静音开关了吗?在 iOS 设备上使用 Web Audio 时,这种情况发生在我身上很多次。我忘记了我将手机设置为振动,并且浏览器不会播放任何声音。 我们从 iPhone 6s 上得到了同样的行为报告,但我们的 iPad Mini 工作正常 (9.3.2)。您是否在测试 mp3 上尝试过不同的采样率或比特率,看看是否会有所不同?还是内容类型?我们内部没有显示此行为的测试设备,但如果我为您的测试页面创建了一些变体,您能否在您的 iPad 上查看它们? 嗨 Nigel,这是一个包含几个变体的测试页面:gopherwoodstudios.com/wa 如果您知道一个网站,您的设备上的网络音频 api /does/ 适用于 mp3,请告诉我 - 我我很想知道是否有特定的标题或格式可以在这些 iOS 设备上播放。我已经在我的 iPad Mini 上尝试了所有这些,它们都可以正常工作。 奇怪的是,我之前提到的 iPhone 6s 问题竟然是手机被设置为“振动”。此设置允许播放视频等,但显然将音频 api 静音,以便使用它的网页静音。这是一个我知道使用网络音频 api 的游戏 - 如果它在你的设备上运行,我将提取它的所有标题和格式信息并创建一个更简单的测试:pbskids.org/naturecat/game.html?racing-rapids 嗯,我的想法不多了。如果您想测试它,我使用 aac 而不是 mp3 添加了一个测试:gopherwoodstudios.com/wa/aac/test.htm 如果所有这些不同的格式都不起作用,我最初的预感很可能是一个奇怪的文件类型问题是不正确的其他正在进行中。 :-) 【参考方案1】:

Apple 在 2016 年 11 月的 iOS 10.1.1 中修复了此问题。感谢 Apple!

【讨论】:

以上是关于iPad 上的 iOS 禁用 Web 音频 API的主要内容,如果未能解决你的问题,请参考以下文章

iOS Web 应用上的 HTML5 音频

使用 Flash cs6 创建的 iPad 应用程序上的音频和动画不同步

无论如何要在 ipad 上自动播放在线内容音频文件

音频无法在所有 iOS 设备上播放

ipad上的背景音频不会停止

Web Audio API 演示在 iOS 上不起作用