[英]cant get length of m4a audio file on webpage
I am trying to make a nodejs website that will return the length in seconds of any audio file a user chooses.我正在尝试制作一个 nodejs 网站,该网站将返回用户选择的任何音频文件的长度(以秒为单位)。 So far I have it working with mp3, wav, and flac files.
到目前为止,我可以使用 mp3、wav 和 flac 文件。 But it doesn't work for all .m4a or .aif files
但它不适用于所有 .m4a 或 .aif 文件
The code for my HTML page with javascript is below:我的带有 javascript 的 HTML 页面的代码如下:
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>
I gathered 6 different files for testing, and after running them on my above code have found out the following results:我收集了 6 个不同的文件进行测试,在我上面的代码上运行它们后,发现了以下结果:
my test files for download: https://easyupload.io/m/la9xro我的测试文件下载: https : //easyupload.io/m/la9xro
It seems like when I input my m4a file sample_M4A_file
that it hangs inside the getSongLength()
function and never enters the .addEventListener("canplaythrough"
function, is there any alternative I can use to consistently get the duration in seconds for every audio file?似乎当我输入我的 m4a 文件
sample_M4A_file
,它挂在getSongLength()
函数内并且从不进入.addEventListener("canplaythrough"
函数,是否有任何替代方法可以用来始终如一地获取每个音频文件的持续时间(以秒为单位)?
It's because your browser doesn't support Apple Lossless codecs.这是因为您的浏览器不支持Apple Lossless编解码器。 If you try in Safari, it will work.
如果您在 Safari 中尝试,它将起作用。
If you attach an error
event to your media element, you'll see it fires .如果您将
error
事件附加到您的媒体元素,您将看到它 fires 。
There is no real universal solution, apart from using an heavy machinery like mediainfo.js (2.4MB+) which should support most formats.除了使用像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: when using the media element solution, there is no need to wait for canplaythrough
, just wait for loadedmetadata
, and if you get Infinity, try this hack . Ps:使用媒体元素方案时,无需等待
canplaythrough
,只需等待loadedmetadata
,如果你得到Infinity,试试这个hack 。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.