Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why using a source tag inside an audio tag prevents the loadeddata event from firing?

For better accessibility we needed a second alternative set of play/pause controls and (with the help of user Kento Nishi) we successfully moved from DEMO A (with only 1 audio playback control) to DEMO B (with duplicated audio playback controls).

PROBLEM1 The time duration (far right number) is broken in DEMO B.

PROBLEM2 Every webpage has its own folder. Some pages have a spoken audio file ready made, *.mp3 but some pages dont. Would it be possible to hide all audio controls html if the spoken.mp3 (same file name for all pages) is absent in the page's own filder? So in summary: if the *.mp3 file exists on the server in the current web page folder <source src="*.mp3" type="audio/mpeg"> then display the html for the audio controls. Otherwise hide the audio html controls via CSS.

The old DEMO A, with only 1 set of controls:

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

The new DEMO B, with multiple set of controls:

document.getElementsByTagName("playpause")[0].addEventListener("click", playpause);
document.getElementsByTagName("playpause")[1].addEventListener("click", playpause);

Here JS Lint shows errors: unexpected for and unexpected var, but I doubt wether these the reason behind the broken audio time duration.

BEAUTY The good part about both demos A & B are that the audio file is loaded not until (and only after) a user clicks play. That way not wasting any bandwith untill user clicks play! This functionality is important and should remain intact, as well as the duplicated set of controls layout-wise and the html parts should remain as much as possible intact.

BOUNTY:200 The new demo works except the duration/audio length is broken and when audio file is not existing the controlls are shown. The bounty is a little token of appreciation for a solution to either problems (or both) in a working jsfiddle demo. Thanks for any and all help.

like image 236
Sam Avatar asked Jul 13 '18 12:07

Sam


2 Answers

This is a new answer based on the changing requirements and due to a bug that I missed causing the audio to auto load on page load.

https://jsfiddle.net/3aof2jnL/

This fiddle I have rebuilt from the ground up for your requirements.

This uses one time only functions as event binding that are then unbound once the system is set up.

it also does not have the <audio> tags in the HTML to prevent preloading before it's needed. and create the audio when the play button is triggered.

To understand it all the code in this fiddle has been commented so for more details on how I did it please read the comments in the fiddle.

As for problem 2 you are better off using server-side code E.G use PHP

<?php
$page_name = $_SERVER['REQUEST_URI'];
str_replace($page_name, ".php", ".mp3");
if(file_exists("audio/{$pageName}")){
 // page has an mp3 audio
}
?>

Oh and one last thing before I go you need to get all your audio's and converted them to OGG and have both an OGG Vorbis format and an MP3 format, not all browser support mp3 and the ones that don't do support OGG. then with my javascript, you will see

audioSources["audio/mpeg"] = "http://www.hochmuth.com/mp3/Bloch_Prayer.mp3";

you should add an OGG path for example.

audioSources["audio/ogg"] = "http://www.hochmuth.com/ogg/Bloch_Prayer.ogg";

------ old answer fixed the original problem only -----

Here you go working, https://jsfiddle.net/y61bjk5e/1/

The reason for this is your we're binding events after they had fired because they were inside the playpause function

Also, your play variable was not set so that is now set to a collection that it loops through.

like image 177
Barkermn01 Avatar answered Nov 06 '22 05:11

Barkermn01


If I understand correctly, you use JSLint to lint your code. The reason why it says the for is unexpected is because of the configuration of JSLint which by default doesn't accept a for-loop. On the JSLint website, you can take a look at the bottom of the page to change that:

enter image description here

Basically, some consider that every loop should be done in functional programming style (with a .forEach for instance). To know why, I suggest you take a look online to get multiple opinions but you can have one here.

As for your "bonus question", I can conclude that the problem lies with using the source tag to specify your audio source. Try using the src attribute of the audio tag and it should work. I could not find why, so we'll have to wait for someone else to answer that.

like image 2
Jeahel Avatar answered Nov 06 '22 05:11

Jeahel