HTML5音频停止功能


147

单击导航中的每个链接,我正在播放一个小型音频剪辑

HTML代码:

<audio tabindex="0" id="beep-one" controls preload="auto" >
    <source src="audio/Output 1-2.mp3">
    <source src="audio/Output 1-2.ogg">
</audio>

JS代码:

$('#links a').click(function(e) {
    e.preventDefault();
    var beepOne = $("#beep-one")[0];
    beepOne.play();
});

到目前为止,一切正常。

问题是,当声音剪辑已经在运行时,我单击任何链接都不会发生任何事情。

我尝试停止单击链接时已经播放的声音,但是HTML5的音频API中没有直接的事件

我尝试了以下代码,但无法正常工作

$.each($('audio'), function () {
    $(this).stop();
});

有什么建议吗?

Answers:


350

相反,stop()您可以尝试:

sound.pause();
sound.currentTime = 0;

这应该具有预期的效果。


6
这在Chrome中不起作用。音频元素会不断加载音频,这不应该发生。
Pieter 2014年

3
在Chrome中,<audio>保持加载的preload属性也被强制设置为,none并且<source>的src被剥离。
先锋天空

6
这行得通,谢谢。附带一提,我很想知道w3c为什么决定在规范中不包括stop方法。
Reahreic

25

首先,您必须为音频元素设置一个id

在您的js中:

var ply = document.getElementById('player');

var oldSrc = ply.src;//只记得旧的来源

ply.src = "";//要停止播放器,您无须替换任何源


4
音频流的最佳解决方案
Hossein 2014年

1
好..这将对音频源文件提出另一个网络请求
Al Mahmud

音频要等到加载后才能播放,这会导致播放音频时出现不必要的延迟。
阿比(Abhi)2015年

播放互联网广播和Firefox之类的流时,该问题的一种很好的解决方案是在切换暂停/播放时重复最后一块。非常感谢。
namikiri

14

这是我做stop()方法的方式:

代码中的某处:

audioCh1: document.createElement("audio");

然后在stop()中:

this.audioCh1.pause()
this.audioCh1.src = 'data:audio/wav;base64,UklGRiQAAABXQVZFZm10IBAAAAABAAEAVFYAAFRWAAABAAgAZGF0YQAAAAA=';

这样,我们不会产生其他请求,旧的请求会被取消,并且音频元素处于未清理状态(已在Chrome和FF中测试):>


10

我有同样的问题。如果是广播电台,则应停止播放,并继续播放直播。我看到的所有解决方案都有一个缺点

  • player.currentTime = 0 继续下载流。
  • player.src = ''引发error事件

我的解决方案:

var player = document.getElementById('radio');
player.pause();
player.src = player.src;

和HTML

<audio src="http://radio-stream" id="radio" class="hidden" preload="none"></audio>

这适用于Chrome和Firefox。但是,在Firefox中,它导致以下错误(在控制台中)[ Security Error: Content at https://localhost/url.html may not load data from blob:https://localhost/cac32534-78b0-4a62-8355-cc8f1e708d64.]似乎没有负面影响,因为此后代码继续执行(与未捕获的Exception不同)。
BReddy

6

此方法有效:

audio.pause();
audio.currentTime = 0;

但是,如果您不想每次停止音频时都必须编写这两行代码,则可以执行以下两项操作之一。我认为第二个更合适,我不确定为什么“ javascript标准之神”没有制定该标准。

第一种方法:创建一个函数并传递音频

function stopAudio(audio) {
    audio.pause();
    audio.currentTime = 0;
}

//then using it:
stopAudio(audio);

第二种方法(受支持):扩展Audio类:

Audio.prototype.stop = function() {
    this.pause();
    this.currentTime = 0;
};

我在一个名为“ AudioPlus.js”的javascript文件中拥有此文件,该文件在处理音频的任何脚本之前都包含在html中。

然后,您可以在音频对象上调用stop函数:

audio.stop();

最终的铬问题与“ canplaythrough”:

我尚未在所有浏览器中都进行过此测试,但这是我在Chrome中遇到的一个问题。如果尝试在连接了“ canplaythrough”事件监听器的音频上设置currentTime,则将再次触发该事件,这可能会导致不良结果。

因此,与您确实要确保不再触发该事件侦听器的所有情况类似,解决方案是在第一次调用之后删除该事件侦听器。像这样:

//note using jquery to attach the event. You can use plain javascript as well of course.
$(audio).on("canplaythrough", function() {
    $(this).off("canplaythrough");

    // rest of the code ...
});

奖金:

请注意,您可以向Audio类(或与此相关的任何本机javascript类)添加更多自定义方法。

例如,如果您想要一种“重新启动”方法来重新启动音频,则它可能类似于:

Audio.prototype.restart= function() {
    this.pause();
    this.currentTime = 0;
    this.play();
};

function stopAudio(audio) { audio.pause(); this.audioStream.src = ""; } 这样做最终对我有用,并删除了在页面上播放音频时在Chrome浏览器中显示的扬声器图标。已在Chrome 59.0.3071.109版上测试
lasec0203

通常,我不建议扩展这样的原型。大量音频的应用程序可能在不同情况下具有不同的停止功能,并且弄乱原型很可能会导致长期的恕我直言
Milearon

5

通过我自己的JavaScript函数来切换播放/暂停-由于我正在处理广播流,因此我希望它清除缓冲区,以使侦听器最终不会与广播电台不同步。

function playStream() {

        var player = document.getElementById('player');

        (player.paused == true) ? toggle(0) : toggle(1);

}

function toggle(state) {

        var player = document.getElementById('player');
        var link = document.getElementById('radio-link');
        var src = "http://192.81.248.91:8159/;";

        switch(state) {
                case 0:
                        player.src = src;
                        player.load();
                        player.play();
                        link.innerHTML = 'Pause';
                        player_state = 1;
                        break;
                case 1:
                        player.pause();
                        player.currentTime = 0;
                        player.src = '';
                        link.innerHTML = 'Play';
                        player_state = 0;
                        break;
        }
}

事实证明,仅清除currentTime并不能在Chrome下剪切它,也需要清除源并将其重新加载。希望对您有所帮助。


4

附带说明,由于我最近使用的是接受的答案中提供的stop方法,因此请根据以下链接:

https://developer.mozilla.org/zh-CN/docs/Web/Guide/Events/Media_events

通过手动设置currentTime,可以在音频元素上触发“ canplaythrough”事件。在链接中提到了Firefox,但是在Chrome上手动设置currentTime后遇到了此事件。因此,如果您有与此事件相关的行为,则可能会导致音频循环。


3

有时在Chrome浏览器中不起作用,

sound.pause();
sound.currentTime = 0;

就这样改变

sound.currentTime = 0;
sound.pause();

2

shamangeorge写道:

通过手动设置currentTime,可以在音频元素上触发“ canplaythrough”事件。

确实会发生这种情况,暂停也会触发该pause事件,这两种情况都使该技术不适合用作“停止”方法。此外,如果设置src为zaki所建议的设置,则会使播放器尝试将当前页面的URL加载为媒体文件(并且失败)(如果autoplay启用)- 不允许设置srcnull;它将始终被视为URL。缺少销毁播放器对象的方法,似乎似乎没有提供“停止”方法的好方法,因此,我建议仅放下专用的停止按钮,并提供暂停和后退按钮-停止按钮实际上不会添加任何功能。


1

这种方法是“强力”,但在使用“允许”的情况下可以使用。<audio></audio>用div 包围您的“ player” 标签(此处的ID为“ plHolder”)。

<div id="plHolder">
     <audio controls id="player">
     ...
     </audio>
<div>

然后,此javascript应该可以工作:

function stopAudio() {
    var savePlayer = $('#plHolder').html(); // Save player code
    $('#player').remove(); // Remove player from DOM
    $('#FlHolder').html(savePlayer); // Restore it
}

zaki在上面的回答中解释了同样的事情,没有使用jquery。
Alok Jain 2015年

我没有进行实验,但是我不确定如果有多个<source>标签,他的方法是否可以工作。
user3062615 2015年

#FlHolder对于#plHolder
Pioneer Skies

1
回复@ alok-jain的评论:我认为此答案与@zaki的答案完全不同。在这里,我们正在重新渲染DOM中的元素,在另一个答案中,他只是“空白” src了玩家的属性。
先锋天空

0

我认为最好检查音频是否处于播放状态并重置currentTime属性。

if (sound.currentTime !== 0 && (sound.currentTime > 0 && sound.currentTime < sound.duration) {
    sound.currentTime = 0;
}
sound.play();

0

对我来说,代码工作正常。(IE10 +)

var Wmp = document.getElementById("MediaPlayer");                
    Wmp.controls.stop();

<object classid="clsid:6BF52A52-394A-11D3-B153-00C04F79FAA6"
    standby="Loading áudio..." style="width: 100%; height: 170px" id="MediaPlayer">...

希望能有所帮助。


0

我想做的是使用Angular2完全删除控件,然后在下一首歌曲具有音频路径时重新加载该控件:

<audio id="audioplayer" *ngIf="song?.audio_path">

然后,当我想在代码中卸载它时,请执行以下操作:

this.song = Object.assign({},this.song,{audio_path: null});

分配下一首歌曲后,将完全从头开始重新创建控件:

this.song = this.songOnDeck;

0

解决此错误的简单方法是捕获错误。

audioElement.play()返回一个promise,因此以下带有.catch()的代码足以解决此问题:

function playSound(sound) {
  sfx.pause();
  sfx.currentTime = 0;
  sfx.src = sound;
  sfx.play().catch(e => e);
}

注意:为了向后兼容,您可能需要用匿名函数替换arrow函数。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.