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?

Réponses:


350

Au lieu de stop()vous pouvez essayer avec:

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

Cela devrait avoir l'effet souhaité.


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


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


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>

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

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.


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.


3

Cela ne fonctionne pas parfois dans Chrome,

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

change juste comme ça,

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

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é .


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
}

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

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.


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;

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.

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.