audio标签默认不显示总时长,需用JavaScript监听loadedmetadata事件获取duration并格式化为MM:SS;跨域需CORS支持,iOS Safari需用户交互后才能加载元数据。

audio 标签本身不提供总时长显示功能
HTML 的 <audio> 元素默认只渲染控件(如播放/暂停、音量、进度条),但不会自动显示音频总时长(比如 “3:42”)。这是浏览器原生行为,不是你漏写了什么属性。想显示总时长,必须用 JavaScript 主动读取 duration 属性,并在加载完成后再更新 DOM。
必须等 loadedmetadata 或 canplay 事件后才能读 duration
duration 初始值是 NaN,直到浏览器解析完音频元数据。过早访问会得到无效值。常见错误是把读取逻辑写在 DOMContentLoaded 里,或直接放 script 标签末尾——此时音频可能还没加载元数据。
- 推荐监听
loadedmetadata:只要元数据就绪就触发,比canplay更早,适合只关心时长的场景 - 如果音频跨域(比如 CDN 上的 MP3),需确保服务端返回
Access-Control-Allow-Origin,否则duration始终为NaN - 某些低版本 Safari 对
duration返回Infinity(流式音频未指定长度),可加判断:if (isNaN(audio.duration) || audio.duration === Infinity)
用 JS 把 duration 转成 MM:SS 格式并插入页面
浏览器返回的 duration 是秒数(浮点型),需手动格式化。不要用 Math.round() 简单取整——它会让 60.9 秒变成 “1:01”,实际应进位到 “1:02”。正确做法是先向上取整秒数,再拆分。
const audio = document.querySelector('audio');
const timeEl = document.querySelector('#audio-duration');
audio.addEventListener('loadedmetadata', () => {
const totalSec = Math.ceil(audio.duration);
const min = Math.floor(totalSec / 60);
const sec = totalSec % 60;
timeEl.textContent = `${min}:${sec < 10 ? '0' : ''}${sec}`;
});
对应 HTML 结构示例:<audio src="song.mp3" controls></audio><span id="audio-duration">--:--</span>
将 Markdown 文章转换为微信公众号兼容的纯 HTML 格式。当用户要求"转成微信格式"、"生成公众号文章 HTML"、"排版到微信草稿箱"、"微信粘贴格式"时触发。输出带内联样式的纯 HTML,微信编辑器可直接渲染,无需额外适配。支持标题、段落、列表、粗体、行内代码、表格、引用块、代码块、配图的完整转换。
移动端 iOS Safari 的兼容性陷阱
iOS Safari 在页面未交互前禁止自动加载音频元数据(防止后台预加载耗流量),所以即使写了 loadedmetadata 监听,也可能迟迟不触发。解决方案只有两个:
立即学习“前端免费学习笔记(深入)”;
- 用户首次点击/触摸页面任意位置后,再调用
audio.load()手动触发加载 - 改用用户手势驱动的初始化,比如把
<audio>放在按钮 click 回调里创建并加载
没有纯 HTML/CSS 方案能绕过这个限制。如果你看到总时长一直显示 “--:--”,先检查是否在 iOS 上且没触发过用户交互。


















