Im my audio player I need to get the duration of my audio track. I need a function that gets src of the audio and returns its duration. Here is what I am trying to do but does not work:
function getDuration(src){
var audio = new Audio();
audio.src = "./audio/2.mp3";
var due;
return getVal(audio);
}
function getVal(audio){
$(audio).on("loadedmetadata", function(){
var val = audio.duration;
console.log(">>>" + val);
return val;
});
}
I tried to split into two functions but it does not work. It would be great if it was as on working function.
Any idea?
because you're relying on an event to fire, you can't return a value in getDuration or getVal
instead, you want to use a callback function, like this (callbacks)
The example assume you want to put the duration into a span written like this
<span id="duration"></span>
function getDuration(src, cb) {
var audio = new Audio();
$(audio).on("loadedmetadata", function(){
cb(audio.duration);
});
audio.src = src;
}
getDuration("./audio/2.mp3", function(length) {
console.log('I got length ' + length);
document.getElementById("duration").textContent = length;
});
Any code that needs to "know" the length should be inside the callback function (where console.log is)
using Promises
function getDuration(src) {
return new Promise(function(resolve) {
var audio = new Audio();
$(audio).on("loadedmetadata", function(){
resolve(audio.duration);
});
audio.src = src;
});
}
getDuration("./audio/2.mp3")
.then(function(length) {
console.log('I got length ' + length);
document.getElementById("duration").textContent = length;
});
using Events - note 'myAudioDurationEvent'
can obviously be (almost) anything you want
function getDuration(src, obj) {
return new Promise(function(resolve) {
var audio = new Audio();
$(audio).on("loadedmetadata", function(){
var event = new CustomEvent("myAudioDurationEvent", {
detail: {
duration: audio.duration,
}
});
obj.dispatchEvent(event);
});
audio.src = src;
});
}
var span = document.getElementById('xyz'); // you'll need to provide better logic here
span.addEventListener('myAudioDurationEvent', function(e) {
span.textContent = e.detail.duration;
});
getDuration("./audio/2.mp3", span);
although, this can be done similarly with callback or promise by passing in a destination to a modified getDuration function in those solutions as well - my point about using event listeners was more appropriate if one span for example was updated with duration multiple times - this solution still only does each span only once, so can be achieved with the other methods just as easily
given the new information in the comments for this answer, I believe this to be the better solution
function getDuration(src, destination) {
var audio = new Audio();
$(audio).on("loadedmetadata", function(){
destination.textContent = audio.duration;
});
audio.src = src;
}
and then invoke getDuration as needed like this
var span = createOrGetSomeSpanElement();
getDuration("./audio/2.mp3", span);
createOrGetSomeSpanElement
returns the destination element to use in the getDuration
function - how this is done is up to you, seeing as you create a playlist in a loop, I'm guessing you have some element created to receive the audio length already created - it's hard to answer a half asked question sometimes