Fonction d'arrêt audio HTML5

147

Je joue un petit clip audio en cliquant sur chaque lien dans ma navigation

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

Code JS:

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

Cela fonctionne bien jusqu'à présent.

Le problème est lorsqu'un clip audio est déjà en cours d'exécution et que je clique sur un lien, rien ne se passe.

J'ai essayé d'arrêter le son déjà lu en cliquant sur le lien, mais il n'y a pas d'événement direct pour cela dans l'API audio de HTML5

J'ai essayé de suivre le code mais cela ne fonctionne pas

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

Des suggestions s'il vous plaît?

Alok Jain
la source

Réponses:

350

Au lieu de stop()vous pouvez essayer avec:

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

Cela devrait avoir l'effet souhaité.

kr1
la source
6
Cela ne fonctionne pas dans Chrome. L'élément audio continue de charger l'audio, ce qui n'est pas ce qui devrait arriver.
Pieter
3
Dans Chrome, le <audio>chargement continue également avec l' preloadattribut forcé à noneet le <source>src supprimé.
Pioneer Skies
6
Cela fonctionne, merci. Par ailleurs, j'aimerais savoir pourquoi le w3c a décidé de ne pas inclure de méthode d'arrêt dans les spécifications.
Reahreic
25

vous devez d'abord définir un identifiant pour votre élément audio

dans votre js:

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

var oldSrc = ply.src;// juste pour se souvenir de l'ancienne source

ply.src = "";// pour arrêter le lecteur, vous devez remplacer la source par rien

zaki
la source
4
Meilleure solution pour le streaming audio
Hossein
1
bien..qui fera une autre demande réseau pour le fichier source audio
Md. Arafat Al Mahmud
L'audio ne sera pas lu tant qu'il n'est pas chargé, ce qui entraînera un retard indésirable dans la lecture audio.
Abhi
Une belle solution au problème lors de la lecture d'un flux comme la radio Internet et Firefox répète le dernier morceau lorsque la pause / lecture est basculée. Merci beaucoup.
namikiri le
14

Voici ma façon de faire la méthode stop ():

Quelque part dans le code:

audioCh1: document.createElement("audio");

puis en stop ():

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

De cette façon, nous ne produisons pas de demande supplémentaire, l'ancienne est annulée et notre élément audio est en état propre (testé dans Chrome et FF):>

MrHetii
la source
10

J'avais le même problème. Un arrêt devrait arrêter le flux et passer en direct s'il s'agit d'une radio. Toutes les solutions que j'ai vues avaient un inconvénient :

  • player.currentTime = 0 continue de télécharger le flux.
  • player.src = ''élever un errorévénement

Ma solution:

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

Et le HTML

<audio src="http://radio-stream" id="radio" class="hidden" preload="none"></audio>
Mikel
la source
Cela fonctionne dans Chrome et Firefox. Cependant, dans Firefox, cela entraîne l'erreur suivante (dans la console) [ Security Error: Content at https://localhost/url.html may not load data from blob:https://localhost/cac32534-78b0-4a62-8355-cc8f1e708d64.] Il semble n'avoir aucun effet négatif car le code continue à s'exécuter après cela (contrairement à une exception non interceptée).
BReddy le
6

Cette méthode fonctionne:

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

Mais si vous ne voulez pas avoir à écrire ces deux lignes de code chaque fois que vous arrêtez un audio, vous pouvez faire l'une des deux choses. Je pense que le second est le plus approprié et je ne sais pas pourquoi les "dieux des standards javascript" n'ont pas fait ce standard.

Première méthode: créer une fonction et passer l'audio

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

//then using it:
stopAudio(audio);

Deuxième méthode (privilégiée): étendre la classe Audio:

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

J'ai ceci dans un fichier javascript que j'ai appelé "AudioPlus.js" que j'inclus dans mon html avant tout script qui traitera de l'audio.

Ensuite, vous pouvez appeler la fonction d'arrêt sur les objets audio:

audio.stop();

ENFIN PROBLÈME CHROME AVEC "canplaythrough":

Je n'ai pas testé cela dans tous les navigateurs mais c'est un problème que j'ai rencontré dans Chrome. Si vous essayez de définir currentTime sur un audio auquel un écouteur d'événement «canplaythrough» est attaché, vous déclencherez à nouveau cet événement, ce qui peut conduire à des résultats indésirables.

Ainsi, la solution, similaire à tous les cas où vous avez attaché un écouteur d'événement dont vous voulez vraiment vous assurer qu'il ne se déclenche pas à nouveau, est de supprimer l'écouteur d'événement après le premier appel. Quelque chose comme ça:

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

PRIME:

Notez que vous pouvez ajouter encore plus de méthodes personnalisées à la classe Audio (ou à toute classe JavaScript native d'ailleurs).

Par exemple, si vous vouliez une méthode de "redémarrage" qui redémarrait l'audio, cela pourrait ressembler à quelque chose comme:

Audio.prototype.restart= function() {
    this.pause();
    this.currentTime = 0;
    this.play();
};
Zuks
la source
function stopAudio(audio) { audio.pause(); this.audioStream.src = ""; } Cela a fini par fonctionner pour moi et j'ai supprimé l'icône du haut-parleur dans le navigateur Chrome qui apparaît lors de la lecture audio sur la page. testé sur Chrome Version 59.0.3071.109
lasec0203
En général, je ne recommanderais pas d'étendre des prototypes comme celui-ci. Une application audio-lourde peut avoir différentes fonctions d'arrêt pour différents cas et jouer avec des prototypes est susceptible de conduire à des bugs à long terme à mon humble avis
milesaron
5

De ma propre fonction javascript pour basculer Play / Pause - puisque je gère un flux radio, je voulais qu'il efface le tampon afin que l'auditeur ne finisse pas par se désynchroniser avec la station de 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;
        }
}

Il s'avère que le simple fait d'effacer le currentTime ne le coupe pas sous Chrome, il faut également effacer la source et la recharger. J'espère que cela vous aidera.

James Groves
la source
4

En remarque et parce que j'utilisais récemment la méthode d'arrêt fournie dans la réponse acceptée, selon ce lien:

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

en définissant currentTime manuellement, on peut déclencher l'événement «canplaythrough» sur l'élément audio. Dans le lien, il mentionne Firefox, mais j'ai rencontré cet événement se déclenchant après avoir défini currentTime manuellement sur Chrome. Donc, si vous avez un comportement associé à cet événement, vous risquez de vous retrouver dans une boucle audio.

Shamangeorge
la source
3

Cela ne fonctionne pas parfois dans Chrome,

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

change juste comme ça,

sound.currentTime = 0;
sound.pause();
gogog
la source
2

shamangeorge a écrit:

en définissant currentTime manuellement, on peut déclencher l'événement «canplaythrough» sur l'élément audio.

C'est en effet ce qui va se passer, et une pause déclenchera également l' pauseévénement, ce qui rendra cette technique impropre à une utilisation comme méthode "d'arrêt". De plus, en définissant srccomme suggéré par zaki, le lecteur essaiera de charger l'URL de la page actuelle en tant que fichier multimédia (et échouera) si autoplayest activé - le réglage srcsur nulln'est pas autorisé; il sera toujours traité comme une URL. À moins de détruire l'objet joueur, il ne semble pas y avoir de bon moyen de fournir une méthode "d'arrêt", donc je suggérerais simplement de laisser tomber le bouton d'arrêt dédié et de fournir des boutons de pause et de retour arrière à la place - un bouton d'arrêt n'ajouterait pas vraiment de fonctionnalité .

Ola Tuvesson
la source
1

Cette approche est «force brute», mais elle fonctionne en supposant que l'utilisation de jQuery est «autorisée». Entourez vos <audio></audio>balises "player" avec un div (ici avec un id de "plHolder").

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

Ensuite, ce javascript devrait fonctionner:

function stopAudio() {
    var savePlayer = $('#plHolder').html(); // Save player code
    $('#player').remove(); // Remove player from DOM
    $('#FlHolder').html(savePlayer); // Restore it
}
utilisateur3062615
la source
La même chose est expliquée par zaki dans sa réponse ci-dessus, sans utilisation de jquery.
Alok Jain
Je ne l'ai pas expérimenté, mais je n'étais pas sûr que sa méthode fonctionnerait s'il y avait plusieurs balises <source>.
user3062615
#FlHoldersemble une faute de frappe pour#plHolder
Pioneer Skies
1
En réponse au commentaire de @ alok-jain: je pense que cette réponse est complètement différente de celle de @zaki. Ici, nous re-restituons un élément dans le DOM, dans l'autre réponse, il "efface" simplement l' srcattribut du joueur.
Pioneer Skies
0

Je pense qu'il serait bon de vérifier si l'audio est en cours de lecture et de réinitialiser la propriété currentTime.

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

pour moi, ce code fonctionne bien. (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">...

J'espère que cette aide.

Ricardo G Saraiva
la source
0

Ce que j'aime faire, c'est supprimer complètement le contrôle en utilisant Angular2, puis il est rechargé lorsque la chanson suivante a un chemin audio:

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

Ensuite, lorsque je veux le décharger dans le code, je fais ceci:

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

Lorsque le morceau suivant est attribué, le contrôle est complètement recréé à partir de zéro:

this.song = this.songOnDeck;
Helzgate
la source
0

Le moyen simple de contourner cette erreur est de détecter l'erreur.

audioElement.play () renvoie une promesse, donc le code suivant avec un .catch () devrait suffire à gérer ce problème:

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

Remarque: vous souhaiterez peut-être remplacer la fonction flèche par une fonction anonyme pour des raisons de compatibilité descendante.

James Marks
la source