how to get audio.duration value by a function

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("https://stackoverflow.com/questions/34647536/./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("https://stackoverflow.com/questions/34647536/./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("https://stackoverflow.com/questions/34647536/./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("https://stackoverflow.com/questions/34647536/./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

Leave a Comment