【问题标题】:IOS WebAudio only works on headphonesIOS WebAudio 仅适用于耳机
【发布时间】:2014-02-03 00:52:20
【问题描述】:

一段时间以来,我一直遇到一个问题,在某些 ios 设备上,我的 webaudio 系统似乎只能与耳机一起使用,而与其他设备(完全相同的操作系统、型号等)一样,音频通过扬声器播放得非常好或耳机。我已经寻找解决方案,但没有找到关于这个确切问题的任何内容。我唯一能想到的可能是音频通道问题或其他问题。

我该如何解决这个问题?

【问题讨论】:

  • 我确实读过一些关于它可能是耳机插孔问题的信息,但是我已经在全新设备上看到了这一点,并且看到它在旧/重度使用的设备上也能正常工作。我也试过切换静音..没有区别。
  • 这个。是。极好的。我一直在试图弄清楚为什么我没有从我们的 QA 实验室的 iPad 上的一个 Web 应用程序中听到任何声音 - 从 Web 检查员那里,我看到所有内容都通过触摸事件正确初始化,并且一切正常加载。我读了你的帖子,插上耳机,震惊了。我只能在运行 iOS 7.0.4 的 iPad3 (retina) 上重新创建它,而有问题的 web 应用程序正在使用 CreateJS/SoundJS。奇怪的是 - 去webaudioapi.com/samples,播放一些样本,然后返回我的 web 应用程序修复了声音......直到我清除了缓存。
  • 好吧,原来是侧滑开关设置为控制静音,被静音了。但这并不能解释为什么在切换站点后声音开始播放,因为直到现在我才意识到切换存在。即使是现在,我也可以在切换取消静音然后更改为切换静音时播放网络音频声音。
  • 是的,这确实让我有些头疼。老实说,我现在什至不记得我们是否解决了它,但我确实记得添加了增益节点,我认为我记得它有助于解决问题。
  • 这可能与 Web 音频在用户点击屏幕之前被静音这一事实有关吗?见paulbakaus.com/tutorials/html5/web-audio-on-ios

标签: ios safari volume


【解决方案1】:

这可能是因为 iPhone 的侧边开关处于“静音”状态。这非常令人困惑 - HTML5 <audio> 标签在手机静音时仍然可以正常播放,但 WebAudio 不能。为什么?谁知道。但这是我目前还没有找到解决办法的限制。

【讨论】:

  • 是的,在我使用 soundmanager2 的网络应用程序上,我发现 iPhone 的侧面静音开关导致声音无法通过扬声器播放。谢谢!
  • 有解决办法,请看我的回答。
【解决方案2】:

遇到同样的问题,终于明白问题了。

如果手机处于静音状态,WebView 确实不会在内部扬声器上播放声音。

当我深入挖掘时,我发现了一个解决方法:) 原帖 => https://stackoverflow.com/a/37874619/8064246

do {
    try AVAudioSession.sharedInstance().setCategory(AVAudioSessionCategoryPlayback)
    //print("AVAudioSession Category Playback OK")
    do {
        try AVAudioSession.sharedInstance().setActive(true)
        //print("AVAudioSession is Active")
    } catch _ as NSError {
        //print(error.localizedDescription)
    }
} catch _ as NSError {
    //print(error.localizedDescription)
}

【讨论】:

  • 这是一个客观的 c 解决方案。发帖人询问的是网络音频。
【解决方案3】:

@Alastair 是正确的,静音切换开关会静音 WebAudio,但不会静音 HTML5 标签。多亏了他的工作,我设法为网络找到了一个解决方法,即使在静音切换开关打开的情况下,它也能让 WebAudio 播放。我会将此作为对他的回复的评论发布,但我没有声誉。

为了播放 WebAudio,您还必须在用户操作期间播放至少一个 WebAudio 声源节点和一个 HTML5 标签。如果这些声音是短暂的沉默,那很好。我发现这个独立的代码不需要任何额外的文件就可以工作:

编辑 19 年 11 月 29 日: 删除了残留的打字稿 typedef。谢谢@Joep。我还意识到下面的代码已经过时了,而且很糟糕。只是把它当作一个例子。编辑这篇文章促使我为此创建了一个开源解决方案。您可以在此处查看它的演示:https://spencer-evans.com/share/github/unmute/ 并在此处查看 repo:https://github.com/swevans/unmute

/**
 * PLEASE DONT USE THIS AS IT IS, THIS IS JUST EXAMPLE CODE.
 * If you want a drop in solution I have a script on git hub
 * Demo:
 * @see https://spencer-evans.com/share/github/unmute/
 * Github Repo:
 * @see https://github.com/swevans/unmute
 */
var isWebAudioUnlocked = false;
var isHTMLAudioUnlocked = false;

function unlock() {
    if (isWebAudioUnlocked  && isHTMLAudioUnlocked) return;

    // Unlock WebAudio - create short silent buffer and play it
    // This will allow us to play web audio at any time in the app
    var buffer = myContext.createBuffer(1, 1, 22050); // 1/10th of a second of silence
    var source = myContext.createBufferSource();
    source.buffer = buffer;
    source.connect(myContext.destination);
    source.onended = function()
    {
        console.log("WebAudio unlocked!");
        isWebAudioUnlocked = true;
        if (isWebAudioUnlocked && isHTMLAudioUnlocked)
        {
            console.log("WebAudio unlocked and playable w/ mute toggled on!");
            window.removeEventListener("mousedown", unlock);
        }
    };
    source.start();

    // Unlock HTML5 Audio - load a data url of short silence and play it
    // This will allow us to play web audio when the mute toggle is on
    var silenceDataURL = "data:audio/mp3;base64,//MkxAAHiAICWABElBeKPL/RANb2w+yiT1g/gTok//lP/W/l3h8QO/OCdCqCW2Cw//MkxAQHkAIWUAhEmAQXWUOFW2dxPu//9mr60ElY5sseQ+xxesmHKtZr7bsqqX2L//MkxAgFwAYiQAhEAC2hq22d3///9FTV6tA36JdgBJoOGgc+7qvqej5Zu7/7uI9l//MkxBQHAAYi8AhEAO193vt9KGOq+6qcT7hhfN5FTInmwk8RkqKImTM55pRQHQSq//MkxBsGkgoIAABHhTACIJLf99nVI///yuW1uBqWfEu7CgNPWGpUadBmZ////4sL//MkxCMHMAH9iABEmAsKioqKigsLCwtVTEFNRTMuOTkuNVVVVVVVVVVVVVVVVVVV//MkxCkECAUYCAAAAFVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV";
    var tag = document.createElement("audio");
    tag.controls = false;
    tag.preload = "auto";
    tag.loop = false;
    tag.src = silenceDataURL;
    tag.onended = function()
    {
        console.log("HTMLAudio unlocked!");
        isHTMLAudioUnlocked = true;
        if (isWebAudioUnlocked && isHTMLAudioUnlocked)
        {
            console.log("WebAudio unlocked and playable w/ mute toggled on!");
            window.removeEventListener("mousedown", unlock);
        }
    };
    var p = tag.play();
    if (p) p.then(function(){console.log("play success")}, function(reason){console.log("play failed", reason)});
}

window.addEventListener("mousedown", unlock);

【讨论】:

  • 令人厌恶的是,这是可能的或必要的。感谢您分享这可怕的事情。
  • 解决方案有效,但 Safari 的控制台显示“未处理的 Promise Rejection: NotAllowedError: 在当前上下文中,用户代理或平台不允许请求,可能是因为用户拒绝了权限。”我想添加一个错误监听器可以解决这个问题,知道怎么做吗?
  • @kslstn 我相信 chrome 和 safari 现在要求从 .play() 返回的承诺具有解析处理程序。并非所有浏览器都支持 Promise。您必须检查一个是否被退回,并且不能真正指望它们得到一致的支持或行为一致。也就是说,promise 很可能被拒绝,因为在用户交互处理程序之外调用了解锁。我更新了代码以抑制那些承诺错误。
  • 我将此脚本作为 unmute.js 加载到我的网站中,我在控制台中收到以下错误:SyntaxError: unexpected token: ':' unmute.js:27:22
  • @Joep 感谢您指出这一点。这是我不小心留下的一些打字稿代码。我更新了帖子并为您创建了一个开源解决方案。 LMK,如果你有任何问题。
【解决方案4】:

如果 iPhone 静音按钮被按下,意味着 iPhone 已静音,通过 Web Audio Api 播放的内容将被静音。

很遗憾,无法通过 Javascript 检查物理按钮(位于 iPhone 顶部的左边缘)是打开还是关闭。

这个问题完全独立于 iOS Safari 中的音频必须由用户操作启动才能取消静音这一事实。可以采取一些技巧来克服这一事实,包括此处 Spencer 建议的技巧,您是否使用用户启动的“任何动作或特定动作”来“播放”无声音频文件以允许随后播放音频文件不静音播放。

【讨论】:

  • 实际上绕过静音按钮的解决方案是同时播放html和网络音频。恢复用户交互只是为了确保音频一直“解锁”。
猜你喜欢
  • 2014-12-01
  • 2018-09-27
  • 1970-01-01
  • 1970-01-01
  • 2013-05-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多