javascript - 如何从多个音频文件中获取总音频持续时间
问题描述
我正在尝试从一组音频路径中获取音频的总持续时间。
这是数组的样子:
var sound_paths = ["1.mp3","2.mp3",...]
我看过这篇文章,它有帮助: how to get audio.duration value by a function
但是,我不知道如何在数组上实现它。这个想法是我想遍历每个音频文件,获取其持续时间,并将其添加到“sum_duration”变量中。
我似乎无法通过 for 循环找到一种方法。我已经尝试过 Promises(我承认我是新手):(注意函数来自一个类)
getDuration(src,cb){
// takes a source audio file and a callback function
var audio = new Audio();
audio.addEventListener("loadedmetadata",()=>{
cb(audio.duration);
});
audio.src = src;
}
getAudioArrayDuration(aud_path_arr){
// takes in an array of audio paths, finds the total audio duration
// in seconds
return new Promise((resolve)=>{
var duration = 0;
for(const aud_path in aud_path_arr){
var audio = new Audio();
audio.src = aud_path;
audio.onloadedmetadata = ()=>{
console.log(audio.duration);
duration += audio.duration;
}
resolve(duration);
}
});
}
但是,这显然不起作用,只会返回 0 的持续时间值。
如何循环播放音频文件并返回每个文件的总音频持续时间?
解决方案
我认为,在这种情况下,使用 Promise 是正确的方法,是时候习惯它们了 ;) 试着记住,Promise 将在不久的将来实现你的愿望。让你的问题变得更难的是你有一个文件数组要检查,每个文件都需要分别被它自己的 Promise 覆盖,这样你的程序就可以知道它们什么时候都被完成了。
我总是称我的“承诺”吸气剂“获取......”,这样我知道它会返回一个承诺而不是直接值。
function fetchDuration(path) {
return new Promise((resolve) => {
const audio = new Audio();
audio.src = path;
audio.addEventListener(
'loadedmetadata',
() => {
// To keep a promise maintainable, only do 1
// asynchronous activity for each promise you make
resolve(audio.duration)
},
);
})
}
function fetchTotalDuration(paths) {
// Create an array of promises and wait until all have completed
return Promise.all(paths.map((path) => fetchDuration(path)))
// Reduce the results back to a single value
.then((durations) => durations.reduce(
(acc, duration) => acc + duration,
0,
))
;
}
在某些时候,你的代码将不得不处理这些异步的东西,老实说,我相信 Promises 是最简单的方法。这需要一点时间来适应,但最终还是值得的。上面可以在您的代码中使用以下内容:
window.addEventListener('DOMContentLoaded', () => {
fetchTotalDuration(["1.mp3","2.mp3",...])
.then((totalDuration) => {
document.querySelector('.player__total-duration').innerHTML = totalDuration;
})
;
});
推荐阅读
- node.js - 将多个 Nodejs 应用程序配置到 nginx conf
- ruby-on-rails - 如何将类添加到 Rails 中的 simple_form 输入包装器?
- mysql - SQL使用下一个序列值创建表格式:'for'附近的语法不正确
- javascript - 如何将数字转换为特殊格式
- hadoop - 无法阻止 Oozie 逻辑炸弹
- android - Android - 如何在以编程方式隐藏软按钮后取消隐藏它们?
- jquery - jQuery文件上传插件在上传第二张图片时再次上传第一张图片
- react-native - 如何将领域与异步获取请求一起使用?
- java - JSP 在第一次执行时执行一个 java 类来设置后端
- ssis - SQL Server 和 SSIS 包中的版本兼容性问题