【问题标题】:how to get audio.duration value by a function如何通过函数获取 audio.duration 值
【发布时间】:2016-04-11 09:27:21
【问题描述】:

我是我的音频播放器,我需要获取我的音轨的持续时间。我需要一个函数来获取音频的 src 并返回其持续时间。这是我正在尝试做但不起作用的操作:

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;
    });
}

我尝试拆分为两个函数,但它不起作用。如果它是在工作功能上,那就太好了。

有什么想法吗?

【问题讨论】:

  • 您正试图从异步回调中返回一个值。这行不通。
  • 鉴于上述问题,是否调用了加载的元数据函数?你有任何控制台错误吗?
  • @JaromandaX 在第二个函数中很好我得到了正确的值,但不知何故它没有将它返回给第一个函数。
  • 所以您的问题与@LeeTaylor 所指出的完全一样
  • @TheGuy - 学习编写异步代码......使用回调或承诺 - 在不知道 getDuration 函数将如何使用的情况下,我只能猜测你需要做什么

标签: javascript jquery audio html5-audio


【解决方案1】:

因为您依赖于触发事件,所以您无法在 getDuration 或 getVal 中返回值

相反,您想使用回调函数,像这样(回调)

该示例假设您希望将持续时间放入这样编写的跨度中

<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;
});

任何需要“知道”长度的代码都应该在回调函数中(console.log 所在的位置)


使用承诺

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;
});

使用事件 - 注意 'myAudioDurationEvent' 显然(几乎)可以是你想要的任何东西

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);

虽然,这也可以通过回调或承诺类似地完成,方法是将目标传递给这些解决方案中的修改后的 getDuration 函数 - 我关于使用事件侦听器的观点更合适,例如,如果一个跨度被多次更新为持续时间- 这个解决方案仍然每个只跨越一次,所以可以很容易地用其他方法来实现


鉴于此答案的 cmets 中的新信息,我相信这是更好的解决方案

function getDuration(src, destination) {
    var audio = new Audio();
    $(audio).on("loadedmetadata", function(){
        destination.textContent = audio.duration;
    });
    audio.src = src;
}

然后像这样根据需要调用 getDuration

var span = createOrGetSomeSpanElement();
getDuration("./audio/2.mp3", span);

createOrGetSomeSpanElement 返回要在getDuration 函数中使用的目标元素 - 如何完成取决于您,当您在循环中创建播放列表时,我猜您创建了一些元素来接收已创建音频长度 - 有时很难回答半个问题

【讨论】:

  • 感谢您的代码。我仍然不确定它是否符合我的要求。因此,基于此,不可能有一个价值来做类似的事情:&lt;span&gt; getDuration('./music.mp3') &lt;/span&gt; 并得到像&lt;span&gt;249.2122&lt;/span&gt; 这样的响应?据我了解,我必须在回调函数中修改我的跨度。
  • 是的,因为您不能将 javascript 代码直接放在跨度内 - 让我用一个示例修改答案
  • 因为“答案”将是异步的,所以您不知道什么时候会有这个“单一最终值” - 所以任何需要这个值的代码都需要以这样的方式编写考虑到它的异步性质
  • 实际上有第三种方法可以做到这一点,使用事件 - 每次使用新的 src 调用 getDuration 时,事件更适合动态更新显示的持续时间
  • @TheGuy - 我添加了一个事件示例 - 但请阅读最后一段 - 事件不一定是您用例的更好解决方案
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-06-05
  • 2021-10-18
  • 1970-01-01
  • 1970-01-01
  • 2021-08-13
  • 1970-01-01
相关资源
最近更新 更多