13

I have many audio elements on a single page and I want to play just one element at a time. That is if one audio element is playing and I click on play on another element, the previous audio element should pause.

I found a jQuery code from another question to do this but that uses an image as play/pause controls. I'm using the inbuilt controls='controls' attribute for the audio element instead. Is it possible to use jQuery to control the play/pause feature for the audio element in my case?

Here is my HTML code

<div>
    <p class="song"><h3><strong>#1 Intro - The Oath</strong></h3><p>
    <audio class="playback" src=http://geo-samples.beatport.com/lofi/5005876.LOFI.mp3 controls='controls' preload="none">
        <I>Your browser does not support the audio element.</I>
    </audio>
</div>

<div>
    <p class="song"><h3><strong>#2 A State Of Trance Year Mix 2013</strong></h3></p>
    <audio class="playback" src=http://geo-samples.beatport.com/lofi/5005933.LOFI.mp3 controls='controls' preload="none">
        <I>Your browser does not support the audio element.</I>
     </audio>
</div>

Here is the jQuery code

$(document).ready(function() {
    var curPlaying;

    $(function() {
        $(".playback").click(function(e) {
            e.preventDefault();
            var song = $(this).next('audio')[0];
            if(song.paused){
                song.play();
                if(curPlaying) $("audio", "#"+curPlaying)[0].pause();
            } else { song.pause(); }
            curPlaying = $(this).parent()[0].id;
        });
    });
});

The jQuery code doesn't seem to be working for me.

Unknown Coder
  • 783
  • 3
  • 12
  • 23

7 Answers7

26
$(function(){
    $("audio").on("play", function() {
        $("audio").not(this).each(function(index, audio) {
            audio.pause();
        });
    });
});

See sample at JSFiddle

LostInComputer
  • 15,188
  • 4
  • 41
  • 49
  • In my case, the JSFiddle example worked only once: #1 (ok) -> #2 (ok, stops #1) -> #1 (doesn't play, cannot stop #2). – vdi Aug 11 '21 at 08:46
12

Vanilla JS solution

Here's a solution that doesn't require jQuery.

function onlyPlayOneIn(container) {
  container.addEventListener("play", function(event) {
  audio_elements = container.getElementsByTagName("audio")
    for(i=0; i < audio_elements.length; i++) {
      audio_element = audio_elements[i];
      if (audio_element !== event.target) {
        audio_element.pause();
      }
    }
  }, true);
}

document.addEventListener("DOMContentLoaded", function() {
  onlyPlayOneIn(document.body);
});

Some things to note:

Community
  • 1
  • 1
Nathan Long
  • 122,748
  • 97
  • 336
  • 451
1

Little Modification to LostInComputer's Answer

In Your HTML Write:

<audio controls onplay="pauseOthers(this);" >
                    <source src="SourcePath">

                </audio>

In Js Write:

function pauseOthers(ele) {
                $("audio").not(ele).each(function (index, audio) {
                    audio.pause();
                });
            }
Sayyed Dawood
  • 607
  • 7
  • 15
  • 1
    For some reason the @LostInComputer answer not working for me, the play event never fired, so work in this way. – abdiel Nov 13 '20 at 22:48
0

Assuming that your syntax for stopping and pausing tracks is correct (I don't know anything about the audio element), you should be able to do something like this:

$(".playback").click(function(e) {

  // pause all other tracks
  $('.audio').each(function () {
    var song = this;
    if (!song.paused) { song.pause(); }
  });

  // play the audio associated with this element
  this.play();

});
Andy
  • 61,948
  • 13
  • 68
  • 95
0
<script>
function controlplay(e) {
  document.querySelectorAll('.playback').forEach(item => { if(item.id != e.target.id) item.pause(); });
}
</script>

<script>
document.querySelectorAll('.').forEach(item => { item.addEventListener("play", event => { controlplay(event) })});
</script>
Gova
  • 235
  • 2
  • 3
  • 12
0

Angular:

<audio (play)="audioPlay($event)" controls preload="none">
    <source [src]="url" type="audio/mpeg">
 </audio>    


audioPlay(e) {
 let eAudio = this.domService.getDocument.getElementsByTagName('audio')
 if (eAudio && eAudio.length > 0) {
  for (var i = 0; i < eAudio.length; i++) {
    if(e.target !== eAudio[i]){
      eAudio[i].pause(); 
    }
  }
}

}

kuldeep chopra
  • 652
  • 9
  • 9
0
<script>
var nowplaying = null;

// Pause and reset playing audio before starting new selection  
function pauseRunningAudio(id) {        
    if ( nowplaying != null && nowplaying != id) {
        var x = document.getElementById(nowplaying); 
        x.pause();
        x.load();   
    }
    nowplaying = id;
}
</script>

<!-- id and function value must be the same -->
<audio controls onplay="pauseRunningAudio('song1')" id="song1">
    <source src="Bohemian Rhapsody.mp3" type="audio/mpeg">
</audio>

<audio controls onplay="pauseRunningAudio('song2')" id="song2">
    <source src="November Rain.mp3" type="audio/mpeg">
</audio>

<audio controls onplay="pauseRunningAudio('song3')" id="song3">
    <source src="Smoke on the Water.mp3" type="audio/mpeg">
</audio>
  • 1
    Don't just paste a block of code, explain your answer: [How to Answer](https://stackoverflow.com/help/how-to-answer) – CascadiaJS Nov 09 '21 at 18:23