繁体   English   中英

无法在网页上获取 m4a 音频文件的长度

[英]cant get length of m4a audio file on webpage

我正在尝试制作一个 nodejs 网站,该网站将返回用户选择的任何音频文件的长度(以秒为单位)。 到目前为止,我可以使用 mp3、wav 和 flac 文件。 但它不适用于所有 .m4a 或 .aif 文件

我的带有 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>

我收集了 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事件附加到您的媒体元素,您将看到它 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,试试这个hack

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM