为什么音频不会在播放时开始播放'按钮是否首先被点击?

时间:2014-07-30 15:44:29

标签: javascript html5 firefox html5-audio

我在Firefox中遇到音频问题。我在<audio>标签中有一个.ogg音频片段,当按下播放按钮时,Firefox不会开始播放该文件。但是,如果按下播放按钮,然后从时间线中选择时间,则音频将从所选时间开始播放。如果反复按下播放按钮(例如播放/暂停/播放),文件也将开始播放。

我还使用网络音频API通过AnalyserNode运行音频。然而,这个问题似乎与分析仪无关,因为可以在不影响此问题的情况下将其删除。它似乎与createMediaElementSource有关。如果我删除与此相关的JavaScript代码,问题就会消失。

音频文件来自同一个来源,因此我非常确定这不是CORS问题(如here所述)。正如我所说,音频将播放,但只有在时间线上选择了一个时间。

我包括下面问题的最简单示例。这可能需要从HTTP服务器(python -m http.serverpython -m SimpleHTTPServer或其他)运行,以避免任何CORS问题。出于这个原因,我不认为我可以在这里包含这个问题的JSFiddle演示。

这个问题似乎只是Firefox。它肯定不会影响Chrome,但我还没有真正测试过任何其他浏览器。

<audio id="audio" controls>
  <source src="piano-sonata-no13.ogg" type="audio/ogg" />
</audio>

<script>
    var audio_node = document.getElementById('audio');
    var audioctx = new (window.AudioContext || window.webkitAudioContext)();
    var analyser = audioctx.createAnalyser();

    window.addEventListener('load', function(e) {
        var source = audioctx.createMediaElementSource(audio_node);
        source.connect(analyser);
        source.connect(audioctx.destination);
    }, false);
</script>

编辑:可以在此处找到此问题的示例:http://mdn.github.io/media-source-buffer/

2 个答案:

答案 0 :(得分:0)

尝试用以下方法替换窗口“load”事件监听器:

audio_node.addEventListener('canplay', function(e) {
    var source = audioctx.createMediaElementSource(audio_node);
    source.connect(analyser);
    source.connect(audioctx.destination);
}, false);

答案 1 :(得分:0)

此问题似乎与Firefox bug

有关

它的要点是,好像createMediaElementSource目前在Firefox中有点破坏了,你不能将音频API用于createMediaStreamSource并让它按预期工作。

我找到了一个解决方法here(警告:页面自动播放音频),但据我所知,它仅在autoplay设置为true时有效。快速测试表明将audio.autoplay设置为true,并立即调用audio.pause()可能是此问题的可接受解决方法。这种方法的一个缺点是,当按下播放按钮时,音频不会从文件的最开头开始。

此解决方案看起来像这样:

<audio id="audio" controls>
  <source src="piano-sonata-no13.ogg" type="audio/ogg" />
</audio>

<script>
    var audio_node = document.getElementById('audio');
    audio_node.autoplay = true;
    // Alternatively, the autoplay attribute can be set on the <audio> tag
    var audioctx = new (window.AudioContext || window.webkitAudioContext)();
    var analyser = audioctx.createAnalyser();

    window.addEventListener('load', function(e) {
        var source = audioctx.createMediaElementSource(audio_node);
        source.connect(analyser);
        source.connect(audioctx.destination);
        audio_node.pause();
    }, false);
</script>