7

当网站上出现新消息时,我需要播放声音。它在 Chrome 和 Safari 上运行良好,但我无法在 Safari 移动设备上运行。我看到必须使用用户操作来初始化声音,所以我尝试了:

var sound = new Audio('./path/to/my/sound.mp3');
var hasPlayed = false;

$('body').bind('click touchstart', function() {
  sound.load();
});    

sound.addEventListener('play', function() {
  hasPlayed = true;
});

var playSound = function() {
  if(hasPlayed) {
    sound.currentTime = 0;
  }
  sound.play();
}

不幸的是,声音仍然没有播放。我也尝试过使用Buzz库,问题是一样的。

所以,问题是:如何在移动浏览器上以编程方式播放声音?

4

2 回答 2

7

首先:iOS(5.01、5.1)上的 Mobile Safari 中的 HTML5 音频支持相当有限。但我设法让一些小的“事件类型”声音在我的 iPad 2 网络应用程序中工作。由于您只为您的应用程序讨论一个声音文件,因此您不必依赖音频精灵技巧(即将多个 MP3 合并到一个 MP3 文件中,并根据您想要的声音更改合并文件中的播放位置被播放)。

正如您所注意到的,您无法在 Mobile Safari 中自动播放音频,也就是说,如果用户没有点击某个元素。从技术上讲,音频必须在与单击事件相同的调用堆栈中播放(而不是加载)。但是,当 Mobile Safari 创建音频对象时,您可能会遇到 0.5 秒的延迟。这是解决此“问题”的方法:

  • 在您的应用程序开始时(在加载/初始化时),向 HTML 文档添加一个单击处理程序,该处理程序会在用户单击/点击应用程序中的任何位置时立即开始播放您的音频文件。这将强制 Safari 开始加载音频。
  • 监听音频准备好播放时触发的“播放”事件,并立即暂停。
  • 现在在需要时再次开始播放音频(无延迟)。

下面是一些快速的 JavaScript 代码:

function initAudio() {
    var audio = new Audio('./path/to/my/sound.mp3');
    audio.addEventListener('play', function () {
        // When the audio is ready to play, immediately pause.
        audio.pause();
        audio.removeEventListener('play', arguments.callee, false);
    }, false);
    document.addEventListener('click', function () {
        // Start playing audio when the user clicks anywhere on the page,
        // to force Mobile Safari to load the audio.
        document.removeEventListener('click', arguments.callee, false);
        audio.play();
    }, false);
}
于 2012-07-06T09:30:30.717 回答
2

对于那些遇到这个问题并且 Jeroen 的解决方案在这里不起作用的人来说,这是一个有效的解决方案,并确保正确执行正确的范围界定。

确保在页面加载时调用 initAudio。即在您的 Init 函数或 document.ready ($(function(){});) 中的 jquery

function initAudio(){
    var audio = new Audio('./path/to/my/sound.mp3');
    var self = this;
    //not sure if you need this, but it's better to be safe
    self.audio = audio;
    var startAudio = function(){
                         self.audio.play();
                         document.removeEventListener("touchstart", self.startAudio, false);
                     }
    self.startAudio = startAudio;

    var pauseAudio = function(){
                         self.audio.pause();
                         self.audio.removeEventListener("play", self.pauseAudio, false);
                     }
    self.pauseAudio = pauseAudio;

    document.addEventListener("touchstart", self.startAudio, false);
    self.audio.addEventListener("play", self.pauseAudio, false);
}
于 2014-02-18T20:41:52.880 回答