【问题标题】:understanding javascript jquery function to get file duration? [closed]了解 javascript jquery 函数以获取文件持续时间? [关闭]
【发布时间】:2018-07-10 06:33:08
【问题描述】:

我有一个 javascript 函数可以正确获取一个上传文件的文件持续时间,我正在尝试重新使用工作函数,以便我可以在其他地方获取文件持续时间,但我遇到了问题,我的 html5 代码看起来像这样:

<link rel="stylesheet" type="text/css" href="style.css">
<p>Select a .mp3 file</p>
<input type="file" id="file" multiple="multiple"/>

<audio id="audio"></audio>

<p>
  <label>Song Duration:</label>
  <span id="duration"></span>
</p>

<p>
  <label>Tracklist:</label>
  <span id="tracklist"></span>
</p>

我的 javascript 函数会在第一个文件上传后立即获取持续时间,如下所示:

$("#audio").on("canplaythrough", function(e){
    console.log("calculating duration");
    var seconds = e.currentTarget.duration;
    var duration = moment.duration(seconds, "seconds");

    var time = "";
    var hours = duration.hours();
    if (hours > 0) { time = hours + ":" ; }

    time = time + duration.minutes() + ":" + duration.seconds();
    $("#duration").text(time);

    URL.revokeObjectURL(objectUrl);
});

我基本上是在尝试复制此功能,因为我知道它可以工作,并在上传的多个文件的数组中获取每首歌曲的持续时间(以秒为单位)。但是如果我只是尝试歌曲[i].duration,那总是会产生一个“未定义”的值,这是一个带有我完整代码的 jsfiddle:

https://jsfiddle.net/gt4wro11/

tldr;我有一个用户上传的多个文件的数组,我试图打印出数组中每个文件的持续时间。这 $("#audio").on("canplaythrough", function(e){ 函数成功获取了一个文件的持续时间,我正在尝试重新调整它的用途以满足我的需求,但不知道如何让它工作。

感谢您处理这么长的问题!

【问题讨论】:

  • 数组中的任何内容,很可能是看起来像的字符串,没有名为 duration 的属性,您没有提供足够的代码来实际帮助您
  • @JarrodRoberson 检查 jsfiddle,它包含我的所有代码,应该让它更清晰。如果我打印我的歌曲 [] 数组,在控制台中我可以看到它是一个文件列表。我感到困惑的是函数(e)如何获取其文件数据,该函数的前两行获取 var seconds 和 var duration 令人困惑,我试图将它们重新用于我可以用 var seconds = song[i ].duration.
  • 在尝试提出更多问题之前,请阅读How do I ask a good question?所有相关代码都必须在问题中。外部网站过时了。

标签: javascript jquery html file duration


【解决方案1】:

songs[i]File 的一个实例,你需要一个HTMLAudioElement 的实例。

每当触发文件选择的change 事件时,您应该读取选定的文件,为每个文件创建一个对象URL,并通过创建不可见的&lt;audio&gt; 元素来加载它们。等到所有音频元素的canplaythough 已触发,然后读取它们的持续时间。

您的代码可能看起来像这样:(您可能需要编辑某些部分以跟踪每个音频的文件名/大小/等)

function loadAudio(url) {
    return new Promise((resolve, reject) => {
    var audio = new Audio();
    audio.oncanplaythrough = () => resolve(audio);
    audio.onerror = reject;
    audio.src = url;
  });
}

$("#file").change(function(e){
    var files = e.currentTarget.files;
    var length = songs.length;

    Promise.all(Array.from(files).map(file => loadAudio(URL.createObjectURL(file))))
    .then(audios => {
        console.log("Audio elements: ", audios)
    });
});

【讨论】:

  • 谢谢你,这给了我一些很好的信息。我目前有一个从 i = 0 开始的 for 循环; to i = song[].length, 现在在那个 for 循环中,我让它创建一个对象 URL; “objectURL = URL.createObjectURL(songs[i]);”。不过,我对下一步有点迷茫,我应该如何确保 canplaythrough 已经触发?
  • 你必须异步工作,这是肯定的。我建议您学习如何使用 Promises,因为它们简化了许多异步任务并被广泛接受。对于每个音频元素,创建一个在其 canplaythrough 触发时解析的 Promise,然后使用 Promise.all() 等待所有 Promise 都已解析。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-04-03
  • 1970-01-01
  • 1970-01-01
  • 2012-08-16
  • 1970-01-01
  • 2013-03-01
  • 2018-01-23
相关资源
最近更新 更多