1

Im having trouble firing up the audio (playback+pause) on the same page.

My standard HTML5 audio player works perfect and has standard controlls like this:

<play title="Play spoken audio for the visually impaired">&#9654;</play>
<pause title="Pause audio, and press again to resume play">&#10074;&#10074;</pause>

Now imagine you would like to have a simplified alternative play/pause controls elsewhere on the same page. Good idea right? Now my problem is, that if I add a separate more minimalistic play / pause control elsewhere on the page, then the first play/pause buttons dissappear entirely!

<play>&#9654;</play>
<pause>&#10074;&#10074;</pause>

All that I want is to duplicate the functionality of the first play/pause and place them elsewhere on the page, allowing users on mobile to have the play/pause on another location of the page for ease of use.


So in summary, I would like to allow the user to controll the playback from two different places simultaneously. The main one has fancier layout, while the alternative one in location 2 has only play and pause toggle. Both should toggle if either one is pressed. (when play is pressed it shows as a pause button and when pause is pressed it becomes a play button).

What must I change in html and or javascript to achieve this? Thanks in advance!


The javascript looks like this:

window.onload = function(){

var myAudio = document.getElementsByTagName('audio')[0];
var play = document.getElementsByTagName('play')[0];
var pause = document.getElementsByTagName('pause')[0];

function displayControls() {
    play.style.display = "block";
}

// check that the media is ready before displaying the controls
if (myAudio.paused) {
    displayControls();
} else {
    // not ready yet - wait for canplay event
    myAudio.addEventListener('canplay', function() {
    displayControls();
    });
} 

play.addEventListener('click', function() {
    myAudio.play();
    play.style.display = "none";
    pause.style.display = "block";
});

pause.addEventListener('click', function() {
    myAudio.pause();
    pause.style.display = "none";
    play.style.display = "block";
});

}

DEMO

Sam
  • 15,254
  • 25
  • 90
  • 145
  • document.getElementsByTagName('play')[0] is only binding the first play button. Instead, add an onclick handler to each button. Add an event listener to document.getElementsByTagName('play')[1]. – Kento Nishi Jul 12 '18 at 17:24
  • Thanks @Kento Nishi I dont understand mate. Please incorporate your suggestions into an answer. Add/change/borrow what you mean and adopt and adapt the current code pieces sothat its clear how the new situation should look like. That way I can test the new situation and Accept your answer once it has solved the quesion. Thanks! – Sam Jul 12 '18 at 18:36
  • 1
    Ok, I'll try... – Kento Nishi Jul 12 '18 at 18:42
  • Thank you! PS I dont mind the two variants having their own html elements like `` for the default and `` for the alternative controlls. Doest that make it easier? Otherwise leave both `` I am targeting both with selectors in CSS with no problems for layout so if they can stay the way are now I am also happy with that. – Sam Jul 12 '18 at 18:43
  • Just used a button, because I was lazy. – Kento Nishi Jul 12 '18 at 19:01
  • That's also not recommended, as custom tags are purely bad practice. Use classes, ids, names, or any other element property. – Kento Nishi Jul 12 '18 at 19:08
  • Hey, can you accept the answer? That would help! – Kento Nishi Jul 12 '18 at 19:11
  • Added a demo of the problem https://jsfiddle.net/nav158cs/ (feel free to change the demo with your version!) and I see now that you have posted an answer will check it in an hour after dinner excited :) – Sam Jul 12 '18 at 19:18
  • My answer does exactly what you want, check it out! – Kento Nishi Jul 12 '18 at 20:41
  • NEVER USE CUSTOM TAGS! You can use them, but it's not good practice. – Kento Nishi Jul 12 '18 at 20:41
  • Ask a new question! And also, I checked your code briefly, but I see that "play" is not defined in play.addEventListener("keyup", function(event) and others. Fix obvious errors first! – Kento Nishi Jul 13 '18 at 04:58
  • Your answer is exactly what I asked. Thanks! – Sam Jul 13 '18 at 09:27
  • @KentoNishi, wanted to bring your attention to this new question (worth 200 bounties for whoever provides the best or most elegant answer) https://stackoverflow.com/questions/51324942 – Sam Jul 15 '18 at 12:47
  • 1
    Thanks for the notice, I might look into the new issue later! – Kento Nishi Jul 16 '18 at 15:00

1 Answers1

1

So you have the following code...

var myAudio = document.getElementsByTagName('audio')[0];
var play = document.getElementsByTagName('play')[0];
var pause = document.getElementsByTagName('pause')[0];

Step-by-step breakdown...

document.getElementsByTagName('audio')[0]

Get the 0th (1st) element in the document that has the tag name audio.

document.getElementsByTagName('play')[0]

Get the 0th (1st) element in the document that has the tag name play.
  • Problem #1. You only register the first play button for the code. You must add code for the second play button.

document.getElementsByTagName('pause')[0]

Get the 0th (1st) element in the document that has the tag name pause.
  • Problem #2. Same problem as #1.

So the solution is:

var audio;
window.onload=function(){
  audio=document.getElementsByTagName("audio")[0];
  //YOU MUST REGISTER AN EVENT LISTENER FOR EVERY PLAY AND PAUSE BUTTON.
  document.getElementsByClassName("playpause")[0].addEventListener("click",playpause);
  document.getElementsByClassName("playpause")[1].addEventListener("click",playpause);
}
function playpause(){
  var state;
  if(audio.paused){
    audio.play();
    state="Pause";
  }else{
    audio.pause();
    state="Play";
  }
  for(var i=0;i<document.getElementsByClassName("playpause").length;i++){
    document.getElementsByClassName("playpause")[i].innerHTML=state;
  }
}
<audio>
  <source src="http://www.kozco.com/tech/32.mp3" type="audio/mpeg">
</audio>
<button class="playpause">Play</button>
<button class="playpause">Play</button>
Kento Nishi
  • 578
  • 1
  • 9
  • 24