HTML5 Audio Stop Funktion

147

Ich spiele einen kleinen Audioclip ab, indem ich auf jeden Link in meiner Navigation klicke

HTML Quelltext:

<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-Code:

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

Bisher funktioniert es gut.

Problem ist, wenn ein Soundclip bereits läuft und ich auf einen Link klicke, passiert nichts.

Ich habe versucht, den bereits wiedergegebenen Sound beim Klicken auf den Link zu stoppen, aber es gibt kein direktes Ereignis dafür in der Audio-API von HTML5

Ich habe versucht, folgenden Code zu verwenden, aber es funktioniert nicht

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

Irgendwelche Vorschläge bitte?

Alok Jain
quelle

Antworten:

350

Stattdessen stop()könnten Sie versuchen mit:

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

Dies sollte den gewünschten Effekt haben.

kr1
quelle
6
Dies funktioniert in Chrome nicht. Das Audioelement lädt weiterhin Audio, was nicht passieren sollte.
Pieter
3
In Chrome wird das weiterhin <audio>geladen, wobei das preloadAttribut erzwungen noneund der <source>src entfernt wird.
Pioneer Skies
6
Das funktioniert, danke. Nebenbei möchte ich gerne wissen, warum das w3c beschlossen hat, keine Stop-Methode in die Spezifikation aufzunehmen.
Reahreic
25

Zuerst müssen Sie eine ID für Ihr Audioelement festlegen

in deinem js:

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

var oldSrc = ply.src;// nur um sich an die alte Quelle zu erinnern

ply.src = "";// Um ​​den Player zu stoppen, müssen Sie die Quelle durch nichts ersetzen

Zaki
quelle
4
Beste Lösung für Audio-Streaming
Hossein
1
Nun ... das wird eine weitere Netzwerkanfrage für die Audio-Quelldatei stellen
Md. Arafat Al Mahmud
Audio wird erst abgespielt, wenn es geladen ist. Dies führt zu unerwünschten Verzögerungen bei der Audiowiedergabe.
Abhi
Eine gute Lösung des Problems beim Abspielen eines Streams wie Internetradio und Firefox wiederholt den letzten Block, wenn Pause / Wiedergabe umgeschaltet wird. Vielen Dank.
Namikiri
14

Hier ist meine Art, die stop () -Methode auszuführen:

Irgendwo im Code:

audioCh1: document.createElement("audio");

und dann in stop ():

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

Auf diese Weise erzeugen wir keine zusätzliche Anfrage, die alte wird abgebrochen und unser Audioelement befindet sich in einem sauberen Zustand (getestet in Chrome und FF):>

MrHetii
quelle
9

Ich hatte das gleiche Problem. Ein Stopp sollte den Stream stoppen und das Onplay wird live geschaltet, wenn es sich um ein Radio handelt. Alle Lösungen, die ich sah, hatten einen Nachteil :

  • player.currentTime = 0 lädt den Stream weiter herunter.
  • player.src = ''errorEreignis auslösen

Meine Lösung:

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

Und der HTML

<audio src="http://radio-stream" id="radio" class="hidden" preload="none"></audio>
Mikel
quelle
Dies funktioniert in Chrome und Firefox. In Firefox führt dies jedoch zu folgendem Fehler (in der Konsole). [ Security Error: Content at https://localhost/url.html may not load data from blob:https://localhost/cac32534-78b0-4a62-8355-cc8f1e708d64.] Es scheint keine negativen Auswirkungen zu haben, da der Code danach weiter ausgeführt wird (im Gegensatz zu einer nicht erfassten Ausnahme).
BReddy
6

Diese Methode funktioniert:

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

Wenn Sie diese beiden Codezeilen jedoch nicht jedes Mal schreiben müssen, wenn Sie ein Audio stoppen, können Sie eines von zwei Dingen tun. Das zweite ist meiner Meinung nach das passendere und ich bin mir nicht sicher, warum die "Götter der Javascript-Standards" diesen Standard nicht gemacht haben.

Erste Methode: Erstellen Sie eine Funktion und übergeben Sie das Audio

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

//then using it:
stopAudio(audio);

Zweite Methode (bevorzugt): Erweitern Sie die Audio-Klasse:

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

Ich habe dies in einer Javascript-Datei namens "AudioPlus.js", die ich in mein HTML vor jedem Skript einbinde, das sich mit Audio befasst.

Dann können Sie die Stoppfunktion für Audioobjekte aufrufen:

audio.stop();

ENDLICH CHROM AUSGABE MIT "canplaythrough":

Ich habe dies nicht in allen Browsern getestet, aber dies ist ein Problem, auf das ich in Chrome gestoßen bin. Wenn Sie versuchen, currentTime für ein Audio festzulegen, an das ein Ereignis-Listener "Durchspielen" angehängt ist, lösen Sie dieses Ereignis erneut aus, was zu unerwünschten Ergebnissen führen kann.

Ähnlich wie in allen Fällen, in denen Sie einen Ereignis-Listener angehängt haben, um sicherzustellen, dass er nicht erneut ausgelöst wird, besteht die Lösung darin, den Ereignis-Listener nach dem ersten Aufruf zu entfernen. Etwas wie das:

//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 ...
});

BONUS:

Beachten Sie, dass Sie der Audio-Klasse (oder einer beliebigen nativen Javascript-Klasse) noch mehr benutzerdefinierte Methoden hinzufügen können.

Wenn Sie beispielsweise eine "Neustart" -Methode wünschen, mit der das Audio neu gestartet wird, könnte dies folgendermaßen aussehen:

Audio.prototype.restart= function() {
    this.pause();
    this.currentTime = 0;
    this.play();
};
Zuks
quelle
function stopAudio(audio) { audio.pause(); this.audioStream.src = ""; } Dies funktionierte für mich und entfernte das Lautsprechersymbol im Chrome Browser, das angezeigt wird, wenn Audio auf der Seite abgespielt wird. getestet auf Chrome Version 59.0.3071.109
lasec0203
Im Allgemeinen würde ich nicht empfehlen, solche Prototypen zu erweitern. Eine audio-schwere Anwendung kann für verschiedene Fälle unterschiedliche Stoppfunktionen haben, und das Durcheinander mit Prototypen kann langfristig zu Fehlern führen. Imho
Milesaron
5

Von meiner eigenen Javascript-Funktion zum Umschalten von Wiedergabe / Pause - da ich einen Radiostream verarbeite, wollte ich, dass dieser den Puffer löscht, damit der Hörer nicht nicht mehr mit dem Radiosender synchronisiert ist.

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

Es stellt sich heraus, dass nur das Löschen der currentTime nicht unter Chrome abgeschnitten wird. Sie müssen auch die Quelle löschen und wieder laden. Ich hoffe, dies hilft.

James Groves
quelle
4

Als Randnotiz und weil ich kürzlich die in der akzeptierten Antwort angegebene Stoppmethode verwendet habe, laut diesem Link:

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

Durch manuelles Einstellen von currentTime kann das Ereignis 'canplaythrough' auf dem Audioelement ausgelöst werden. In dem Link wird Firefox erwähnt, aber dieses Ereignis wurde ausgelöst, nachdem currentTime manuell in Chrome eingestellt wurde. Wenn Sie also ein Verhalten mit diesem Ereignis verknüpft haben, könnten Sie in einer Audio-Schleife enden.

Shamangeorge
quelle
3

Es funktioniert manchmal nicht in Chrom,

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

ändere dich einfach so,

sound.currentTime = 0;
sound.pause();
Gogog
quelle
2

Shamangeorge schrieb:

Durch manuelles Einstellen von currentTime kann das Ereignis 'canplaythrough' auf dem Audioelement ausgelöst werden.

Dies ist in der Tat der Fall, und eine Pause löst auch das pauseEreignis aus. Beides macht diese Technik für die Verwendung als "Stopp" -Methode ungeeignet. srcWenn Sie die von zaki vorgeschlagene Einstellung festlegen, versucht der Player außerdem, die URL der aktuellen Seite als Mediendatei zu laden (und schlägt fehl), wenn diese autoplayOption aktiviert ist. Die Einstellung srcauf nullist nicht zulässig. Es wird immer als URL behandelt. Ohne das Player-Objekt zu zerstören, scheint es keine gute Möglichkeit zu geben, eine "Stopp" -Methode bereitzustellen. Daher würde ich vorschlagen, einfach die dedizierte Stopp-Taste fallen zu lassen und stattdessen Pausen- und Rücksprung-Tasten bereitzustellen - eine Stopp-Taste würde keine wirklichen Funktionen hinzufügen .

Ola Tuvesson
quelle
1

Dieser Ansatz ist "Brute Force", funktioniert jedoch unter der Annahme, dass die Verwendung von jQuery "zulässig" ist. Umgeben Sie Ihre "Player" <audio></audio>-Tags mit einem Div (hier mit der ID "plHolder").

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

Dann sollte dieses Javascript funktionieren:

function stopAudio() {
    var savePlayer = $('#plHolder').html(); // Save player code
    $('#player').remove(); // Remove player from DOM
    $('#FlHolder').html(savePlayer); // Restore it
}
user3062615
quelle
Dasselbe erklärt Zaki in seiner obigen Antwort ohne Verwendung von JQuery.
Alok Jain
Ich habe nicht damit experimentiert, aber ich war mir nicht sicher, ob seine Methode funktionieren würde, wenn es mehrere <source> -Tags gäbe.
user3062615
#FlHolderscheint ein Tippfehler für#plHolder
Pioneer Skies
1
Antwort auf @ alok-jain Kommentar: Ich denke, diese Antwort ist völlig anders als die von @zaki. Hier rendern wir ein Element im DOM neu, in der anderen Antwort "löscht" er nur das srcAttribut des Spielers.
Pioneer Skies
0

Ich glaube, es wäre gut zu überprüfen, ob das Audio wiedergegeben wird, und die Eigenschaft currentTime zurückzusetzen.

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

Für mich funktioniert dieser Code einwandfrei. (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">...

Ich hoffe das hilft.

Ricardo G Saraiva
quelle
0

Was ich gerne mache, ist das Steuerelement mit Angular2 vollständig zu entfernen und es dann neu zu laden, wenn der nächste Song einen Audiopfad hat:

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

Wenn ich es dann im Code entladen möchte, mache ich Folgendes:

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

Wenn das nächste Lied zugewiesen wird, wird das Steuerelement von Grund auf neu erstellt:

this.song = this.songOnDeck;
Helzgate
quelle
0

Der einfache Weg, um diesen Fehler zu umgehen, besteht darin, den Fehler abzufangen.

audioElement.play () gibt ein Versprechen zurück, daher sollte der folgende Code mit .catch () ausreichen, um dieses Problem zu beheben:

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

Hinweis: Möglicherweise möchten Sie die Pfeilfunktion aus Gründen der Abwärtskompatibilität durch eine anonyme Funktion ersetzen.

James Marks
quelle