如何获得 html5 音频持续时间

Posted

技术标签:

【中文标题】如何获得 html5 音频持续时间【英文标题】:How can I get the html5 audio's duration time 【发布时间】:2012-06-27 13:27:30 【问题描述】:

我在页面中有一个 html5 <audio> 标签,但我怎么知道它的持续时间?

<audio controls="">
    <source src="p4.2.mp3">
</audio>

【问题讨论】:

【参考方案1】:

2020 年解决方案:

当尚未加载音频元数据时,您将收到 undefinedNaN(不是数字)。因此有人建议使用onloadedmetadata 来确保首先获取音频文件的元数据。此外,大多数人没有提到的是,您必须使用[0] 来定位音频 DOM 元素的第一个索引,如下所示:

-- 原版 javascript

var audio = document.getElementById('audio-1');
audio.onloadedmetadata = function() 
  alert(audio.duration);
;

如果这不起作用,试试这个,但不太可靠并且依赖于用户连接:

setTimeout(function () 
    var audio = document.getElementById('audio-1');
    console.log("audio", audio.duration);
, 100);

-- jQuery:

$(document).ready(function() 
   var audio = $("#audio-1")[0];
   $("#audio-1").on("loadedmetadata", function() 
       alert(audio.duration);
   ); 
);

【讨论】:

从什么时候开始"$("#audio-1")[0];"香草Javascript?您的两个示例都是 jQuery 示例-不确定您是否理解其中的区别。原版将是“document.getElementById('audio-1');”而是在这里。 @RichardEdwards 感谢您指出这一点。在我完全切换到 Vanilla JS 之前,我在写这个答案时主要使用 JQuery,并没有注意到这个错字。【参考方案2】:
var au = document.createElement('audio');
au.addEventListener('loadedmetadata',function()
    au.setAttribute('data-time',au.duration);
,false);

【讨论】:

【参考方案3】:

在上面的评论中,提到解决方案是将事件句柄绑定到事件加载元数据。我就是这样做的——

audio.onloadedmetadata = function() 
  alert(audio.duration);
;

【讨论】:

【参考方案4】:

我一直在努力在 React 组件中加载持续时间,因此遵循 @AlexioVay 的解决方案,如果您使用的是 React,这里是一个答案:

这假设您将 ref 用于您的音频组件类,您需要将 audio 元素作为播放/暂停处理程序的目标。

&lt;audio /&gt; 元素:

<audio ref=audio =>  this.audio = audio  src=this.props.src preload="auto" />

然后在您的componentDidMount() 中:

componentDidMount() 

    const audio = this.audio

    audio.onloadedmetadata = () => 
        console.log(audio.duration)
        this.setState(
           duration: this.formatTime(audio.duration.toFixed(0))
        )
    

最后是formatTime() 函数:

formatTime(seconds) 
    const h = Math.floor(seconds / 3600)
    const m = Math.floor((seconds % 3600) / 60)
    const s = seconds % 60
    return [h, m > 9 ? m : h ? '0' + m : m || '0', s > 9 ? s : '0' + s]
        .filter(a => a)
        .join(':')

这样,h:mm:ss 格式的持续时间将在音频 src 数据加载后立即显示。甜蜜。

【讨论】:

感谢您提及我。你能提供你的 React hooks 解决方案吗?【参考方案5】:

我使用“canplaythrough”事件来获取曲目时长。我有一个案例,我有两个玩家,我想在第一个玩家完成前 2 秒停止第二个玩家。

$('#' + _currentPlayerID).on("canplaythrough", function (e)    
    var seconds = e.currentTarget.duration;    
    var trackmills = seconds * 1000;
    var subTimeout = trackmills - 2000; //2 seconds before end

    //console.log('seconds ' + seconds);
    //console.log('trackmills ' + trackmills);
    //console.log('subTimeout ' + subTimeout);

    //Stop playing before the end of thet track
    //clear this event in the Pause Event
    _player2TimeoutEvent = setTimeout(function ()  pausePlayer2(); , subTimeout);

);

【讨论】:

【参考方案6】:

只需使用audioElement.duration

【讨论】:

不行,不行,我试过了:var audio = $('#audio')[0]; console.log('audio', audio.duration);,结果是NaN 这给出了正确的持续时间(在 Firefox 中测试),但只有在加载元数据事件发生之后。 当您使用 setTimeout(function () ... , 10); 而不是立即执行它时似乎可以工作。 @AlexioVay 关于超时是正确的,文件需要有时间加载才能测试【参考方案7】:

要获得阅读的结束,有必要在事件“onended”的情况下使用“loop = false”。如果 loop = true,onended 不起作用;)

要制作播放列表,您必须设置 loop = false 以使用 'onended' 事件来播放下一首歌曲。

如果您的脚本正确完成,您可以在任何地方恢复持续时间。如果 'duration' 的值为 NaN,则浏览器找不到该文件。如果值为'Infinity' 'INF' 它是一个流,在这种情况下,与读取时间'currentime'相比增加了1 mn。 对于* I.E,这是废话。当前时间可能大于持续时间,在这种情况下,您可以: var 持续时间 = (this.currentime> this.duration)? this.currenttime: this.duration;

那是(O_°)

【讨论】:

【参考方案8】:

最好这样使用事件...

ObjectAudio.onprogress  =function()
    if(this.buffered.length)
    var itimeend = (this.buffered.length>1)? this.buffered.end(this.buffered.length-1):this.buffered.end(0);
    ....
        Your code here.......
    

【讨论】:

以上是关于如何获得 html5 音频持续时间的主要内容,如果未能解决你的问题,请参考以下文章

如何在录制过程中获得录制音频的确切持续时间?

HTML5 音频持续时间返回“未定义”(jQuery)

如何获得 Soundpool 的持续时间

Internet Explorer 11 HTML5 音频持续时间 = 无限问题

HTML5 音频标签在 Chrome 中显示错误的 MP3 持续时间

将 mp3 从服务器流式传输到 html5 音频时传递持续时间