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

Posted

技术标签:

【中文标题】无法在网页上获取 m4a 音频文件的长度【英文标题】:cant get length of m4a audio file on webpage 【发布时间】:2021-02-03 22:18:01 【问题描述】:

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

我的 html 页面的 javascript 代码如下:

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_cmets_below:不工作 mp3:工作 wav:工作

我的测试文件下载:https://easyupload.io/m/la9xro

似乎当我输入我的 m4a 文件 sample_M4A_file 时,它挂在 getSongLength() 函数中并且从不进入 .addEventListener("canplaythrough" 函数,有没有什么替代方法可以用来始终如一地获得每个音频的持续时间(以秒为单位)文件?

【问题讨论】:

可能是您正在使用的文件吗?我试过你的代码,它与m4a file 配合得很好。 能否提供您用于测试的文件?代码似乎按预期工作。 更新了我的问题,您链接的 m4a 文件确实有效,但我的 m4a 文件没有 【参考方案1】:

这是因为您的浏览器不支持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。 p>

【讨论】:

以上是关于无法在网页上获取 m4a 音频文件的长度的主要内容,如果未能解决你的问题,请参考以下文章

如何将两个 m4a 音频文件“混合/叠加”在一起

如何将m4a音频换成mp3格式

移动浏览器上的 HTML5 音频持续时间错误,在常规浏览器上运行良好(m4a 文件)

如何在 swift 5.3 中从 m4a 音频文件中获取 Track Id

iphone 5 无法播放音频文件

如何将m4a音频换成mp3格式