web-dev-qa-db-fra.com

Fonction d'arrêt audio HTML5

Je joue un petit clip audio au clic de 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 survient 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à joué 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 ça ne marche pas

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

Des suggestions s'il vous plaît?

120
Alok Jain

au lieu de stop(), vous pouvez essayer avec:

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

cela devrait avoir l'effet désiré

280
kr1

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 rappeler l'ancienne source

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

23
zaki

Voici ma façon de faire de 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 manière, nous ne produisons pas de requête supplémentaire, l'ancienne est annulée et notre élément audio est en état de propreté (testé sous Chrome et FF):

11
MrHetii

De ma propre fonction javascript pour basculer entre Play/Pause - puisque je gère un flux radio, je voulais qu’elle efface la mémoire tampon afin que l’auditeur ne soit pas désynchronisé 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;
        }
}

En fait, effacer simplement le temps actuel ne le coupe pas sous Chrome, il faut aussi effacer la source et la recharger. J'espère que cela vous aidera.

5
James Groves

Cette méthode fonctionne:

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

Mais si vous ne voulez pas écrire ces deux lignes de code chaque fois que vous arrêtez un fichier audio, vous pouvez faire l'une des deux choses suivantes. La seconde, à mon avis, est la plus appropriée et je ne sais pas pourquoi les «dieux des normes javascript» n’ont pas créé cette norme.

Première méthode: créer une fonction et transmettre 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 cela dans un fichier javascript que j'ai appelé "AudioPlus.js" que j'inclus dans mon code html avant tout script traitant de l'audio.

Ensuite, vous pouvez appeler la fonction stop sur les objets audio:

audio.stop();

FINALEMENT CHROME ISSUE 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 fichier audio auquel est associé un écouteur d'événement "canplaythrough", vous déclencherez à nouveau cet événement, ce qui peut entraîner des résultats indésirables.

Ainsi, la solution, comme dans tous les cas où vous avez attaché un écouteur d'événement et que vous voulez vraiment vous assurer qu'il ne soit plus déclenché, consiste à 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 à n'importe quelle classe javascript native pour cette question).

Par exemple, si vous vouliez une méthode de "redémarrage" pour redémarrer l'audio, elle pourrait ressembler à ceci:

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

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

  • player.currentTime = 0 continue de télécharger le flux.
  • player.src = '' augmenter 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>
3
Mikel

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 manuellement currentTime, on peut déclencher l'événement 'canplaythrough' sur l'élément audio. Dans le lien, il est fait mention de Firefox, mais j'ai rencontré cet événement qui se déclenche après avoir défini manuellement currentTime sur Chrome. Donc, si vous avez un comportement lié à cet événement, vous pourriez vous retrouver dans une boucle audio.

3
shamangeorge

shamangeorge a écrit: 

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

C’est effectivement ce qui se produira et la pause déclenchera également l’événement pause, qui rendra cette technique impropre à une utilisation en tant que méthode "stop". De plus, si vous définissez la variable src proposée par zaki, le lecteur essaiera de charger l'URL de la page actuelle en tant que fichier multimédia (et échouera) si autoplay est activé - la définition de src à null n'est pas autorisée. il sera toujours traité comme une URL. À moins de détruire l’objet du joueur, il ne semble pas y avoir de bon moyen de fournir une méthode «stop». Je suggère donc d’abandonner le bouton d’arrêt dédié et de prévoir des boutons de pause et de retour rapide: un bouton d’arrêt n’ajouterait aucune fonctionnalité. .

2
Ola Tuvesson

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

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

Alors ce javascript devrait fonctionner:

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

Ça ne marche pas parfois en chrome,

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

il suffit de changer comme ça,

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

Le moyen le plus simple de contourner cette erreur est d’attraper l’erreur.

audioElement.play () retourne une promesse, le code suivant avec .catch () devrait donc 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 de flèche par une fonction anonyme pour assurer la compatibilité avec les versions antérieures.

0
James Marks

Je crois 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
NoviceLearner

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

Alors quand je veux le décharger en code je fais ceci:

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

Quand la chanson suivante est assignée, le contrôle est complètement recréé à partir de zéro:

this.song = this.songOnDeck;
0
Helzgate

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
Ricardo G Saraiva