Video duration is sometimes NaN [duplicate] - 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

JavaScript html5 video

I have a sample html5 video with simple html code.
What I need to do is a customized mute button for all the videos, meaning:
if the user clicks on the mute/unmute button for one video, all the other videos get muted/unmuted as well
Is there any way of doing this?
without your html code it is pretty vague but in JS you can do it :
here is a link of the documentation im using :
https://www.w3schools.com/tags/av_prop_muted.asp
https://www.w3schools.com/tags/tryit.asp?filename=tryhtml5_av_prop_muted
<button onclick="enableMute()" type="button">Mute sound</button>
<button onclick="disableMute()" type="button">Enable sound</button>
<video id="myVideo" width="320" height="176" controls>
<source src="mov_bbb.mp4" type="video/mp4">
<source src="mov_bbb.ogg" type="video/ogg">
Your browser does not support HTML5 video.
</video>
<script>
var vid = document.getElementById("myVideo");
function enableMute() {
vid.muted = true;
}
function disableMute() {
vid.muted = false;
}
</script>
So to trigger the action on all your videos you can :
add a class preferably or id on all your video tag
make js know about them
var vid = document.getElementById("myVideo");
var vid1 = document.getElementById("myVideo1");
var vid2 = document.getElementById("myVideo2");
var vid3 = document.getElementById("myVideo3");
var vid4 = document.getElementById("myVideo4");
add an onClick action on a button that trigger an action here Mute action which will mute or unmute your videos using the mute property of your element, the action would like
function enableMute() {
vid.muted = true;
vid1.muted = true;
vid2.muted = true;
vid3.muted = true;
vid4.muted = true;
}
I think you could do it without this much duplication of code if you add the same class to all your element, and looping through all of them in the action you trigger when you click on the button and then change for each of them their property but not sure exactly how to do it

Javascript, pausing audio in function

I have created a game that acts as a showcase for my portfolio.
However I want the audio to pause when a certain function is called
var aud = document.getElementById("#music");
I created a variable that acts as the stand in for the music
function web(i){
aud.pause(); //I try to pause the variable here
keysPressed = {};
if (!jumping){$("#guy").css({"background-image":"url(img/Character-Stand.gif)"});}
window.open(pickup[i].weblink);
};
I don't know what I have done wrong, any help would be appreciated.
Your code doesn't say exactly where you initalize your var aud = document.getElementById("#music"); and also not how you define your audio-tag. But below I have a minimal working example how to pause an audio.
<html>
<body>
<script>
function pause() {
var aud = document.getElementById("myAudio");
aud.pause();
}
</script>
<audio id="myAudio" controls>
<source src="audio.mp3" type="audio/mpeg">
</audio>
<button onclick="pause()">pause</button>
</body>
</html>

Change audio file on button click

I am trying to change the audio file on a button click and am getting the error
Uncaught TypeError: audio.load is not a function
My code is below, the idea is to press the button and then the audio file will change.
Without the audio.load() line, the code will run and the src will update, but the audio does not change. What am I missing?
HTML:
<!DOCTYPE HTML>
<html>
<body>
<br>
<audio controls>
<source src = "audio_file_1.mp3"
id="audio" type="audio/mpeg">
Your browser does not support the audio element!
</audio>
<br>
<button onClick="changeAudio();">Change</button>
</body>
<script src="temp.js"></script>
</html>
Javascript:
// temp js
var a = 1;
function changeAudio() {
var audio = document.getElementById('audio');
if (a==1) {
audio.src = 'audio_file_1.mp3';
a = 2;
}
else {
audio.src = 'audio_file_2.mp3';
a = 1;
}
audio.load();
}
changeAudio();
(also, if anyone knows example sound files that I can use instead of the audio_file_1.mp3 and audio_file_2.mp3, I would be happy to update the code so anyone can run it more easily)
Edit WRT Rob M's answer:
For anyone with the same problem, the solution is to change two lines:
First, in the HTML code, the <audio control> should turn to <audio control id="audio_id">
Second, in the javascript code the audio.load() should turn to document.getElementById('audio_id').load();
There is no .load() event on a <source> tag, it is on the <audio> tag - update your code to call load() on the parent <audio> tag and it should work.
Well, I think you are trying to access to <audio> element by its id attribute, but you haven't set id attribute to audio tag.
It must be something like this
<audio id="audio" controls>
<source src = "audio_file_1.mp3"
id="track" type="audio/mpeg">
Your browser does not support the audio element!
</audio>
And changing audio file:
var a = 1;
function changeAudio() {
var audio = document.getElementById('audio');
if (a==1) {
document.getElementById('track') = 'audio_file_1.mp3';
a = 2;
}
else {
document.getElementById('track') = 'audio_file_2.mp3';
a = 1;
}
audio.load();
}
changeAudio();

Unable to play an array of videos using javascript

I have an array of video links and i need to play it in a loop back to back.I tried the below link but it did not work for me.
how to display multiple videos one by one dynamically in loop using HTML5 and javascript
My array is
player1=["videoplayback (1).mp4","videoplayback (2).mp4","videoplayback (3).mp4"];
My code is:
function playit()
{
var t=['videoplayback.mp4','videoplayback (1).mp4','videoplayback (3).mp4'];
var myNodelist = document.getElementsByTagName("source");
var i;
for (i = 0; i < myNodelist.length; i++) {
myNodelist[i].src = t[i];
}
}
And this is my html code for video player:
<body onload="playit()">
<video id="video" width="420" autoplay="" loop="" controls="" style="margin-top: 30px;margin-left:40px" >
<source src="" type="video/mp4" id="video1">
<source src="" type="video/mp4" id="video2">
<source src="" type="video/mp4" id="video3">
Your browser does not support HTML5 video.
</video>
</body>
You can do something like include the source files in array and add an event listener, so that each time a video finishes playing it switches to the new source file. The first time you would have to do an onload so that the js function myNewSrc() is called the first time for loading first video. To do that it would look like this:
HTML:
<body onload="myNewSrc()">
<div id="section-title" >
<video preload="auto" onended="myAddListener()" autoplay controls width="480" height="360" title="" poster="https://placehold.it/350x150">
<source src="" type="video/mp4">
</video>
</div>
</body>
JS:
//array of video source files you will be looping through
var videoSources = ["http://www.quirksmode.org/html5/videos/big_buck_bunny.mp4", "http://www.html5videoplayer.net/videos/toystory.mp4", "http://www.quirksmode.org/html5/videos/big_buck_bunny.mp4", "http://www.quirksmode.org/html5/videos/big_buck_bunny.mp4", "http://www.quirksmode.org/html5/videos/big_buck_bunny.mp4"];
var currentIndex = 0;
// listener function changes src
function myNewSrc() {
var myVideo = document.getElementsByTagName('video')[0];
myVideo.src = videoSources[currentIndex];
myVideo.load();
}
// add a listener function to the ended event
function myAddListener(){
var myVideo = document.getElementsByTagName('video')[0];
currentIndex = (currentIndex+1) % videoSources.length;
myVideo.src = videoSources[currentIndex];
myVideo.addEventListener('ended', myNewSrc, false);
}
You can see a working sample here: https://jsfiddle.net/l33tstealth/pnjchwyf/1/

Audio duration returns NaN need some modification to run the player

Whenever I run the script it returns NaN for audio duration.
Script
var mytrack = document.getElementById('mytrack');
var duration1 = document.getElementById('fullDuration');
duration1.innerHTML = parseInt(mytrack.duration);
HTML
<audio id="mytrack" controls autoplay>
<source src="kalimba.mp3" type="audio/mp3" />
</audio>
<span id="fullDuration">0:00</span>
It is always advised to use the event of loadedmetadata and then calling them will always work. Using Event Listeners are best in this case.
var a = document.getElementById('mytrack');
a.addEventListener("loadedmetadata", function() {
var duration1 = document.getElementById('fullDuration');
duration1.innerHTML = parseInt(a.duration);
}, true);
This waits till the media is loaded and then it sets the contents of the <span> tag. For best results, please put this code either in the end of the document, before </body> tag or use window's load event:
document.addEventListener('DOMContentLoaded', function () {
var a = document.getElementById('mytrack');
a.addEventListener("loadedmetadata", function() {
var duration1 = document.getElementById('fullDuration');
duration1.innerHTML = a.duration;
}, true);
}, false);
As said in comments, there's also another way to do it using preload attribute:
This enumerated attribute is intended to provide a hint to the browser about what the author thinks will lead to the best user experience.
But since you already haveautoplay attribute, I guess preload won't be necessary.
The autoplay attribute has precedence over preload. If autoplay is specified, the browser would obviously need to start downloading the audio for playback.
You can use oncanplaythrough event. parseInt() is not necessary.
var mytrack = document.getElementById("mytrack");
var duration1 = document.getElementById("fullDuration");
mytrack.oncanplaythrough = function() {
duration1.innerHTML = this.duration
}
<audio id="mytrack" controls autoplay>
<source src="https://upload.wikimedia.org/wikipedia/commons/6/6e/Micronesia_National_Anthem.ogg" type="audio/ogg">
</audio>
<span id="fullDuration">0:00</span>

Categories

Resources