188

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

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();
});

请问有什么建议吗?

4

16 回答 16

439

而不是stop()你可以尝试:

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

这应该有预期的效果。

于 2013-02-12T15:37:01.123 回答
34

首先你必须为你的音频元素设置一个 id

在你的 js 中:

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

var oldSrc = ply.src;// 只是为了记住旧的来源

ply.src = "";// 要停止播放器,您必须将源替换为空

于 2013-03-21T05:29:08.633 回答
15

我遇到了同样的问题。如果它是收音机,则停止应该停止流和 onplay直播。我看到的所有解决方案都有一个缺点

  • 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>
于 2017-09-12T09:37:19.403 回答
14

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

代码中的某处:

audioCh1: document.createElement("audio");

然后在 stop() 中:

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

这样我们就不会产生额外的请求,旧的请求被取消,我们的音频元素处于干净状态(在 Chrome 和 FF 中测试):>

于 2015-04-12T11:49:55.887 回答
9

此方法有效:

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();
};
于 2017-01-01T08:24:08.280 回答
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 下将其删除,还需要清除源并将其重新加载。希望这会有所帮助。

于 2015-04-08T09:07:28.913 回答
4

作为旁注,因为我最近使用了接受的答案中提供的停止方法,根据这个链接:

https://developer.mozilla.org/en-US/docs/Web/Guide/Events/Media_events

通过手动设置 currentTime,可以在音频元素上触发“canplaythrough”事件。在链接中它提到了 Firefox,但是我在 Chrome 上手动设置 currentTime 后遇到了这个事件。因此,如果您有附加到此事件的行为,您可能最终会进入音频循环。

于 2014-08-09T01:47:06.893 回答
4

它有时在 chrome 中不起作用,

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

就这样改变,

sound.currentTime = 0;
sound.pause();
于 2018-11-08T09:31:03.850 回答
2

沙曼乔治写道:

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

这确实会发生,暂停也会触发pause事件,这两者都使得这种技术不适合用作“停止”方法。此外,src如果启用了 zaki 建议的设置,则播放器会尝试将当前页面的 URL 加载为媒体文件(并且失败) -不允许autoplay设置src为;null它将始终被视为 URL。除了破坏播放器对象之外,似乎没有提供“停止”方法的好方法,所以我建议只删除专用的停止按钮并提供暂停和后退按钮 - 停止按钮不会真正添加任何功能.

于 2014-11-23T22:59:50.957 回答
1

这种方法是“蛮力”,但假设使用 jQuery 是“允许的”,它可以工作。用 div包围你的“玩家”<audio></audio>标签(这里的 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
}
于 2015-03-19T16:03:12.820 回答
1

我正在寻找类似的东西,因为我制作了一个可以用来将声音相互分层以获得焦点的应用程序。我最终做的是 - 选择声音时,使用 Javascript 创建音频元素:

                const audio = document.createElement('audio') as HTMLAudioElement;
                audio.src = getSoundURL(clickedTrackId);
                audio.id = `${clickedTrackId}-audio`;
                console.log(audio.id);
                audio.volume = 20/100;
                audio.load();
                audio.play();

然后,将子项附加到文档以实际显示音频元素

document.body.appendChild(audio);

最后,当取消选择音频时,您可以完全停止并删除音频元素 - 这也将停止流式传输。

            const audio = document.getElementById(`${clickedTrackId}-audio`) as HTMLAudioElement;
            audio.pause();
            audio.remove();
于 2021-12-05T23:31:59.490 回答
0

我相信检查音频是否正在播放状态并重置 currentTime 属性会很好。

if (sound.currentTime !== 0 && (sound.currentTime > 0 && sound.currentTime < sound.duration) {
    sound.currentTime = 0;
}
sound.play();
于 2016-04-21T19:18:01.343 回答
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">...

希望这有帮助。

于 2017-02-02T14:00:05.580 回答
0

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

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

然后,当我想在代码中卸载它时,我会这样做:

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

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

this.song = this.songOnDeck;
于 2017-02-11T17:27:02.857 回答
0

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

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

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

注意:为了向后兼容,您可能希望将箭头函数替换为匿名函数。

于 2017-04-11T19:29:13.240 回答
0

在 IE 11 中,我使用了组合变体:

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

只有 2 次重复会阻止 IE 在 pause() 之后继续加载媒体流并由此淹没磁盘。

于 2020-08-27T10:29:14.883 回答