如何解决无法在网页上获取m4a音频文件的长度
我正在尝试创建一个nodejs网站,该网站将返回用户选择的任何音频文件的长度(以秒为单位)。到目前为止,我可以使用mp3,wav和flac文件。 但不适用于所有.m4a或.aif文件
choose audio file to get length:
<input style="cursor: pointer;" type="file" id="file" multiple="multiple" />
<script>
//when files are selected:
$("#file").change(async function (e) {
console.log('file(s) selected')
//get files
var files = e.currentTarget.files;
//get number of files
var numberOfFiles = files.length;
//for each file
for (i = 0; i < numberOfFiles; i++) {
console.log(`songs[${i}].type=`,files[i].type)
//get file length
let songLength = await getSongLength(files[i]);
console.log('songLength=',songLength)
}
});
//recieve audio file,return length
function getSongLength(song) {
return new Promise(function (resolve,reject) {
console.log('getSongLength() begin setup')
//create objectURL and audio object for ssong
objectURL = URL.createObjectURL(song);
mySound = new Audio([objectURL])
console.log('getSongLength() end setup')
//when song Metadata is loaded:
mySound.addEventListener("canplaythrough",function (e) {
console.log('getSongLength() canplaythrough')
var seconds = e.currentTarget.duration;
resolve(seconds)
});
});
}
</script>
我收集了6个不同的文件进行测试,并在上面的代码中运行它们后,发现以下结果:
- aif:不起作用
- flac:工作中
- m4a_file:不起作用
- m4a_file_from_comments_below:不起作用
- mp3:正常运行
- wav:工作
我要下载的测试文件:https://easyupload.io/m/la9xro
当我输入我的m4a文件sample_M4A_file
时,它似乎挂在getSongLength()
函数中,并且从不进入.addEventListener("canplaythrough"
函数,好像有什么办法可以使我始终如一地获取每个音频文件的持续时间(以秒为单位)?
解决方法
这是因为您的浏览器不支持Apple Lossless编解码器。如果您在Safari中尝试,它将会起作用。
如果您将error
事件附加到媒体元素,请you'll see it fires。
除了使用像mediainfo.js(2.4MB +)这样的笨重的机器(它应该支持大多数格式)之外,没有真正的通用解决方案。
const input = document.querySelector( "input" );
input.onchange = async (evt) => {
const mediainfo = await new Promise( (res) => MediaInfo(null,res) );
const file = input.files[ 0 ];
const getSize = () => file.size;
const readChunk = async (chunkSize,offset) =>
new Uint8Array( await file.slice(offset,offset + chunkSize).arrayBuffer() );
const info = await mediainfo.analyzeData(getSize,readChunk);
// assumes we are only interested in audio duration
const audio_track = info.media.track.find( (track) => track[ "@type" ] === "Audio" );
console.log( audio_track.Duration );
};
<script src="https://unpkg.com/mediainfo.js@0.1.4/dist/mediainfo.min.js"></script>
<input type="file">
Ps:使用媒体元素解决方案时,无需等待canplaythrough
,只需等待loadedmetadata
,如果得到Infinity,请尝试this hack。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。