HTML5 Funzione di arresto audio


147

Sto riproducendo una piccola clip audio al clic di ciascun collegamento nella mia navigazione

Codice 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>

Codice JS:

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

Finora funziona bene.

Il problema è quando una clip audio è già in esecuzione e faccio clic su qualsiasi collegamento non succede nulla.

Ho provato a interrompere il suono già riprodotto al clic del collegamento, ma non vi è alcun evento diretto nell'API audio di HTML5

Ho provato a seguire il codice ma non funziona

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

Qualche suggerimento per favore?

Risposte:


350

Invece di stop()te potresti provare con:

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

Questo dovrebbe avere l'effetto desiderato.


6
Questo non funziona in Chrome. L'elemento audio continua a caricare l'audio, il che non è ciò che dovrebbe accadere.
Pieter,

3
In Chrome il <audio>caricamento continua anche con l' preloadattributo forzato nonee lo <source>src eliminato.
Pioneer Skies,

6
Questo funziona, grazie. A proposito, mi piacerebbe sapere perché il w3c ha deciso di non includere un metodo stop nelle specifiche.
Reahreic,

25

per prima cosa devi impostare un ID per il tuo elemento audio

nel tuo js:

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

var oldSrc = ply.src;// solo per ricordare la vecchia fonte

ply.src = "";// per fermare il lettore devi sostituire la fonte con niente


4
Migliore soluzione per lo streaming audio
Hossein,

1
beh ... questo farà un'altra richiesta di rete per il file sorgente audio
Md. Arafat Al Mahmud

L'audio non verrà riprodotto fino al caricamento e ciò causerà ritardi indesiderati nella riproduzione dell'audio.
Abhi,

Una buona soluzione al problema quando si riproduce un flusso come la radio via Internet e Firefox ripete l'ultimo blocco quando si attiva / disattiva la pausa / riproduzione. Grazie mille.
namikiri,

14

Ecco il mio modo di fare il metodo stop ():

Da qualche parte nel codice:

audioCh1: document.createElement("audio");

e poi in stop ():

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

In questo modo non produciamo ulteriori richieste, il vecchio viene cancellato e il nostro elemento audio è pulito (testato in Chrome e FF):>


10

Ho avuto lo stesso problema. Una fermata dovrebbe fermare lo streaming e onplay andare in diretta se si tratta di una radio. Tutte le soluzioni che ho visto hanno avuto uno svantaggio :

  • player.currentTime = 0 continua a scaricare il flusso.
  • player.src = ''raccogliere erroreventi

La mia soluzione:

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

E l'HTML

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

Funziona con Chrome e Firefox. Tuttavia, in Firefox provoca il seguente errore (nella console) [ Security Error: Content at https://localhost/url.html may not load data from blob:https://localhost/cac32534-78b0-4a62-8355-cc8f1e708d64.] Sembra non avere alcun effetto negativo poiché il codice continua a essere eseguito successivamente (diversamente da un'eccezione non rilevata).
BReddy

6

Questo metodo funziona:

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

Ma se non vuoi scrivere queste due righe di codice ogni volta che interrompi un audio, potresti fare una delle due cose. Il secondo credo sia il più appropriato e non sono sicuro del motivo per cui gli "dei degli standard javascript" non hanno creato questo standard.

Primo metodo: creare una funzione e passare l'audio

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

//then using it:
stopAudio(audio);

Secondo metodo (preferito): estendi la classe Audio:

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

Ho questo in un file javascript che ho chiamato "AudioPlus.js" che includo nel mio html prima di qualsiasi script che si occuperà di audio.

Quindi è possibile chiamare la funzione di arresto su oggetti audio:

audio.stop();

FINALMENTE CROMATO CON "canplaythrough":

Non l'ho provato in tutti i browser, ma questo è un problema che ho riscontrato in Chrome. Se si tenta di impostare currentTime su un audio a cui è associato un listener di eventi "canplaythrough", si attiverà nuovamente quell'evento che può portare a risultati indesiderati.

Quindi, la soluzione, simile a tutti i casi in cui è stato collegato un listener di eventi che si desidera veramente assicurarsi che non venga nuovamente attivato, è rimuovere il listener di eventi dopo la prima chiamata. Qualcosa come questo:

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

Nota che puoi aggiungere ancora più metodi personalizzati alla classe Audio (o qualsiasi classe javascript nativa per quella materia).

Ad esempio, se si desidera un metodo di "riavvio" che riavvii l'audio, potrebbe essere simile a:

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

function stopAudio(audio) { audio.pause(); this.audioStream.src = ""; } Questo ha funzionato per me e ha rimosso l'icona dell'altoparlante nel browser Chrome che appare quando l'audio è in riproduzione sulla pagina. testato su Chrome Versione 59.0.3071.109
lasec0203,

In generale, non consiglierei di estendere prototipi come questo. Un'applicazione audio pesante può avere diverse funzioni di arresto per casi diversi e la pasticciata con i prototipi può portare a bug
nell'immo

5

Dalla mia funzione javascript per attivare Play / Pausa: poiché sto gestendo un flusso radio, volevo che cancellasse il buffer in modo che l'ascoltatore non finisse per sincronizzarsi con la stazione radio.

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

Si scopre che solo cancellare il currentTime non lo taglia in Chrome, necessario anche per cancellare il sorgente e ricaricarlo. Spero che questo aiuti.


4

Come nota a margine e poiché di recente stavo usando il metodo stop fornito nella risposta accettata, secondo questo link:

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

impostando manualmente CurrentTime si può attivare l'evento 'canplaythrough' sull'elemento audio. Nel link menziona Firefox, ma ho riscontrato questo evento che si attiva dopo aver impostato currentTime manualmente su Chrome. Quindi, se hai un comportamento associato a questo evento, potresti finire in un loop audio.


3

A volte non funziona in Chrome,

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

cambia così,

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

2

shamangeorge ha scritto:

impostando manualmente CurrentTime si può attivare l'evento 'canplaythrough' sull'elemento audio.

Questo è effettivamente ciò che accadrà e la sospensione attiverà anche l' pauseevento, entrambi i quali rendono questa tecnica inadatta all'uso come metodo di "arresto". Inoltre, l'impostazione srccome suggerito da zaki farà tentare al lettore di caricare l'URL della pagina corrente come file multimediale (e fallire) se autoplayè abilitato - l'impostazione srcsu nullnon è consentita; sarà sempre trattato come un URL. A parte distruggere l'oggetto giocatore non sembra esserci un buon modo per fornire un metodo di "arresto", quindi suggerirei semplicemente di rilasciare il pulsante di arresto dedicato e fornire invece i pulsanti Pausa e Salta indietro: un pulsante di arresto non aggiungerebbe davvero alcuna funzionalità .


1

Questo approccio è "forza bruta", ma funziona supponendo che l'uso di jQuery sia "consentito". Circonda i tuoi <audio></audio>tag "player" con un div (qui con un id di "plHolder").

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

Quindi questo javascript dovrebbe funzionare:

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

La stessa cosa è spiegata da zaki nella sua risposta sopra, senza l'uso di jquery.
Alok Jain,

Non l'ho provato, ma non ero sicuro che il suo metodo avrebbe funzionato se ci fossero più tag <source>.
user3062615

#FlHoldersembra un refuso per#plHolder
Pioneer Skies il

1
In risposta al commento di @ alok-jain: penso che questa risposta sia completamente diversa da quella di @zaki. Qui stiamo ridistribuendo un elemento nel DOM, nell'altra risposta sta semplicemente "cancellando" l' srcattributo del giocatore.
Pioneer Skies,

0

Credo che sarebbe bene controllare se l'audio è in riproduzione e ripristinare la proprietà currentTime.

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

0

per me quel codice funziona benissimo. (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">...

Spero che questo aiuto.


0

Quello che mi piace fare è rimuovere completamente il controllo usando Angular2, quindi viene ricaricato quando il brano successivo ha un percorso audio:

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

Quindi, quando voglio scaricarlo nel codice, faccio questo:

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

Quando viene assegnato il brano successivo, il controllo viene completamente ricreato da zero:

this.song = this.songOnDeck;

0

Il modo semplice per aggirare questo errore è quello di catturare l'errore.

audioElement.play () restituisce una promessa, quindi il seguente codice con un .catch () dovrebbe bastare a gestire questo problema:

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

Nota: è possibile sostituire la funzione freccia con una funzione anonima per la compatibilità con le versioni precedenti.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.