Audio duration returns NaN - javascript

Accessing an HTML5 audio element (a .ogg file) with JavaScript in Chrome. The file does play properly, yet somehow it will not recognize the duration.
I just cribbed this code: https://www.w3schools.com/jsref/prop_audio_duration.asp (I know w3schools isn't great, but it seems like something else is the problem...)
var x = document.getElementById("testTone").duration;
console.log("duration:"+x); // duration:NaN
var y = document.getElementById("testTone");
y.play(); // works!
the element...
<audio controls id="testTone">
<source src="autoharp/tone0.ogg" type="audio/ogg">
</audio>

Add preload="metadata" to your tag to have it request the metadata for your audio object:
<audio controls id="testTone" preload="metadata">
<source src="autoharp/tone0.ogg" type="audio/ogg">
</audio>
In your code, attach an event handler, to set the duration when the metadata has been loaded:
var au = document.getElementById("testTone");
au.onloadedmetadata = function() {
console.log(au.duration)
};

Beside #FrankerZ's solution, you could also do the following:
<audio controls id="testTone">
<source src="https://www.w3schools.com/jsref/horse.ogg" type="audio/ogg">
<source src="https://www.w3schools.com/jsref/horse.mp3" type="audio/mpeg">
</audio>
<button onclick="myFunction()">Try it</button>
<script>
function myFunction() {
var x = document.getElementById("testTone").duration;
console.log("duration:" + x); // duration:NaN
var y = document.getElementById("testTone");
y.play(); // works!
}
</script>

you can try this..hope it will work i used this in 'timeupdate' event as i was getting same NaN error.
var x = document.getElementById("testTone").duration;
if(x){
console.log("duration:"+x);
}

Related

Multiple Alerts with Audio

Hey everyone so what I am trying to accomplish is producing this fake A.I.. I was playing around with my code and I changed something over the past while and now it's not working.
What I am trying to do is to have multiple alerts,
the first alert being- 'hello'
the second alert 'is something there'
and so on and so on.
I'm trying to attach these alerts using a particular voice in an mp3. file.
So an alert pops-up and the audio goes off.
How can I connect them?
I'm just learning code, so please forgive my lack of knowledge.
<body onload="delayedAlert();">
<script>
var timeoutID;
function delayedAlert() {
timeoutID = window.setTimeout(slowAlert, 50);
}
function slowAlert() {
var audio= document.getElementsByTagName('audio')[0];
const audio2 = document.getElementsByTagName('audio')[1];
var audio3 = document.getElementsByTagName('audio')[2];
var audio4 = document.getElementsByTagName('audio')[3];
audio.play();
var myvar1;alert('Hello?');
audio2.play();
var myvar1;alert('Is something here?');
audio3.play();
var myvar2;alert('Something is here.');
audio4.play();
const name = prompt('What is your name?')
const sentence = 'Hello,' + name +'I am Eve'+name+name+name+name+'What does a' +name +' look like?';
responsiveVoice.speak(sentence, "US English Female", {
rate: 0.4,
onend: function() {
// Redirect after sentence has been spoke
location.replace('https://www.eves.website/eve_2.html');
}
});
};
</script>
<audio>
<source src="audio/hello.wav" type="audio/wav" preload=true>
</audio>
<audio>
<source src="audio/is_something_here.wav" type="audio/wav" preload=true>
</audio>
<audio>
<source src="audio/oh_something_is_here.wav" type="audio/wav" preload=true>
</audio>
<audio>
<source src="audio/what_is_your_name.wav" type="audio/wav" preload=true>
</audio>
<video autoplay="autoplay" preload="auto" id="video" src="images/evetwo.mp4" width="1300px" height="auto" style="position:absolute; z-index:-1;" >
Video not supported.
</video>
</body>
</html>

how to make the javascript variable the current audio clip playing

This script works: but does anyone know how I can alter the javascript so the 'var aud' on //line1 is the current audio playing -> ( i.e whichever of my 7 audio clips happens to be playing at that point), something about 'this'? Thanks
<script>
var aud = document.getElementById("myAudio"); //line1
aud.onplay = function() {
var aud1 = document.getElementById("myAudio1");
aud1.currentTime = 0;
aud1.pause();
};
</script>
var audios = document.getElementsByTagName('audio');
console.log(audios)
for(var i in audios)
if(audios.hasOwnProperty(i)){
var t = audios[i];
t.onplay = function(){
alert(t.innerHTML)
}
}
<audio controls="">
<source src="https://www.w3schools.com/tags/horse.ogg" type="audio/ogg">
<source src="https://www.w3schools.com/tags/horse.mp3" type="audio/mpeg">
Your browser does not support the audio element.
</audio><audio controls="">
<source src="https://www.w3schools.com/tags/horse.ogg" type="audio/ogg">
<source src="https://www.w3schools.com/tags/horse.mp3" type="audio/mpeg">
Your browser does not support the audio element.
</audio><audio controls="">
<source src="https://www.w3schools.com/tags/horse.ogg" type="audio/ogg">
<source src="https://www.w3schools.com/tags/horse.mp3" type="audio/mpeg">
Your browser does not support the audio element.
</audio>
Add an event listener for all your audio elements, and then with this code it should console.log whichever one triggered the event. If that works then do whatever you want to do with the audio element which triggered the event.
var aud = document.getElementsByTagName("audio");
aud.onplaying = function() {
console.log(this);
var playingAudio = this;
playingAudio.pause();
}
<script type="text/javascript">
var aud = document.getElementById("myAudio"); //line1
var audio = []
for (var i = 1; i <= 7; i++){
aud.onplay = function() {
var audio[i] = document.getElementById("myAudio"+i);
audio[i].currentTime = 0;
audio[i].pause();
};
}
</script>
This should work. share comment if not!

Sequential playback of audio files overlap using .addEventListener ended

The following code is intended to play a series of short audio files in a sequence, as held in a javascript array named audio_sequence.
an .addEventListener('ended',function()) is used to trigger playback of each audio clip in the sequence.
This works as expected for the first 5 items in the array, playing each in turn, but then the audio elements start to play simultaneously and the sequence becomes jumbled.
I have tried several different approaches all yielding similar results.
Would very much appreciate any insights.
And example of the code running can be found here:
Play Sequence
Here's the javascript:
<script type="text/javascript">
var game_sounds = ["rooms", "bars", "food", "inveraray", "arse"];
var game_sequence = [0,1,2,3,4,0,1,2,3,4,0,1,2,3,4];
var sequence_position = 0;
function play_next(){
if (sequence_position < game_sequence.length){
var audioElement = document.getElementById(game_sounds[game_sequence[sequence_position]]);
audioElement.addEventListener('ended', function(){
sequence_position++;
play_next();
}, true);
audioElement.play();
}
}
function playSequence(){
sequence_position = 0;
var audioElement = document.getElementById(game_sounds[game_sequence[sequence_position]]);
// alert(game_sounds[game_sequence[sequence_position]]);
audioElement.addEventListener('ended', function(){
sequence_position++;
play_next();
},true);
audioElement.play();
}
</script>
& the html is as follows:
<a onClick="javascript:playSequence();" href="#"><h2>Play Sequence</h2></a>
<audio hidden id="rooms" preload="auto">
<source src="/audio/rooms.mp3">
</audio>
<audio hidden id="food" preload="auto">
<source src="/audio/food.mp3" >
</audio>
<audio hidden id="bars" preload="auto">
<source src="/audio/bars.mp3">
</audio>
<audio hidden id="inveraray" preload="auto">
<source src="/audio/inveraray.mp3">
</audio>
<audio hidden id="arse" preload="auto">
<source src="/audio/arse.mp3">
</audio>
What is causing the problem is that you are attaching the same event listener several times to each element, as they are in a loop. In a non particularly elegant but effective workaround, you could remove the listener before attaching it again:
var game_sounds = ["rooms", "bars", "food", "inveraray", "arse"];
var game_sequence = [0,1,2,3,4,0,1,2,3,4,0,1,2,3,4];
var sequence_position = 0;
function play_next(){
if (sequence_position < game_sequence.length){
playSequence();
}
}
function playSequence(){
var audioElement = document.getElementById(game_sounds[game_sequence[sequence_position]]);
// alert(game_sounds[game_sequence[sequence_position]]);
audioElement.removeEventListener('ended', prepareNextAudio);
audioElement.addEventListener('ended', prepareNextAudio, true);
audioElement.play();
}
function prepareNextAudio() {
sequence_position++;
play_next();
}
This code works and stops the playlist when each audio has been played for three times, which I guess is what you needed.

Changing video src via javascript

I have multiple videos on my website that has multiple codecs for multiple browsers.
<video id="video2" width="480" height="270">
<source src="movies/vid2.ogv" type="video/ogg">
<source src="movies/vid2.webm" type="video/webm">
<source src="movies/vid2.mp4" type="video/mp4">
Your browser does not support HTML5 video.
</video>
I only need to show one video at a time. so i have
onClick="changevid(A)
the onClick is working fine, changing the vids. but how do i change all 3 of them?
vid1.ogv
vid1.webm
vid1.mp4
i can only change 1 by doing
var A = 'movies/vid1.mp4';
function changevid(q){
document.getElementById('video2').setAttribute('src', q);
}
Thanks
Maybe this helps:
var doc = document, bod = doc.body;
function E(e){
return doc.getElementById(e);
}
function changevid(q){
E('video2').src = q;
}

Play multiple audio files sequentially or randomly in background using HTML5 and javascript

I am trying to play 3 audio files (with the possibility of more later) that run in the background. At this point I am simply trying to play them sequentially and have it loop back to the first audio file when the last is played. I believe I have tried almost every solution or combination of functions and I just can't get it to work. I run into one of two problems:
If I try using repetition with each audio stored in the array, the page will successfully play the first then tries to play the next two simultaneously, rather than sequentially. And it certainly does not go back to the first. Furthermore, if you notice in my html, I have a seperate ID for each player. Would it be better to put them all in the sample player ID?
jQuery(document).ready(function (){
var audioArray = document.getElementsByClassName('playsong');
var i = 0;
var nowPlaying = audioArray[i];
nowPlaying.load();
nowPlaying.play();
while(true){
$('#player').on('ended', function(){
if(i>=2){
i=0;
}
else{
i++;
}
nowPlaying = audioArray[i];
nowPlaying.load();
nowPlaying.play();
});
}
});
On the other hand, I can play each sequentially but each play needs to be hardcoded for and I cannot loop back to the first
jQuery(document).ready(function (){
var audioArray = document.getElementsByClassName('playsong');
var i = 0;
var nowPlaying = audioArray[i];
nowPlaying.load();
nowPlaying.play();
$('#player').on('ended', function(){
// done playing
//alert("Player stopped");
nowPlaying = audioArray[1];
nowPlaying.load();
nowPlaying.play();
$('#player2').on('ended', function(){
nowPlaying = audioArray[2];
nowPlaying.load();
nowPlaying.play();
});
});
});
Here is my html
<audio id="player" class = "playsong">
<source src="1.mp3" />
</audio>
<audio id="player2" class = "playsong">
<source src="2.mp3" />
</audio>
<audio id="player3" class = "playsong">
<source src="3.mp3" />
</audio>
I am not terribly familiar with javascript, I am wondering if there is another event trigger function built into JS that I am not using? Some help is greatly appreciated.
HTML
<audio id="song-1" preload class="songs">
<source src="1.mp3" type="audio/mpeg" />
</audio>
<audio id="song-2" preload class="songs">
<source src="2.mp3" type="audio/mpeg" />
</audio>
<audio id="song-3" preload class="songs">
<source src="3.mp3" type="audio/mpeg" />
</audio>
<audio id="song-4" preload class="songs">
<source src="4.mp3" type="audio/mpeg" />
</audio>
JS
jQuery(document).ready(function (){
var audioArray = document.getElementsByClassName('songs');
var i = 0;
audioArray[i].play();
for (i = 0; i < audioArray.length - 1; ++i) {
audioArray[i].addEventListener('ended', function(e){
var currentSong = e.target;
var next = $(currentSong).nextAll('audio');
if (next.length) $(next[0]).trigger('play');
});
}
});

Categories