使用MediaStream Recording API录音如何在停止后立即显示时长和下载选项
解决方案
问题根因
该问题本质是音频元素默认不会主动加载媒体元数据,只有触发播放动作后才会加载解析时长,示例中原逻辑将时长显示、下载按钮渲染的触发时机绑定到了播放动作后,因此首次加载时不会展示对应内容。
具体修改步骤
找到录音结束后的回调逻辑(一般是MediaRecorder的onstop事件回调),对创建音频元素的逻辑做如下调整:
- 给新创建的audio元素添加
preload="metadata"属性,告知浏览器优先加载音频元数据 - 主动调用
load()方法触发元数据加载,同时监听loadedmetadata事件,元数据加载完成后立即执行时长渲染、下载按钮生成逻辑 - 可选兜底方案:录音时直接记录起止时间戳计算时长,无需依赖音频元数据加载
代码示例
修改前的核心逻辑参考:
// 录音结束后创建音频展示元素 const audio = document.createElement('audio'); audio.controls = true; audio.src = URL.createObjectURL(recordBlob); clipContainer.appendChild(audio); // 后续逻辑仅在audio的play事件触发时执行
修改后的核心逻辑:
const audio = document.createElement('audio'); audio.controls = true; audio.preload = 'metadata'; // 配置预加载元数据 audio.src = URL.createObjectURL(recordBlob); // 元数据加载完成后立即执行UI渲染 audio.addEventListener('loadedmetadata', () => { // 渲染时长逻辑 const duration = formatTime(audio.duration); durationElement.textContent = duration; // 渲染下载按钮逻辑 const downloadBtn = generateDownloadBtn(recordBlob); clipContainer.appendChild(downloadBtn); }); clipContainer.appendChild(audio); audio.load(); // 主动触发加载
兜底方案(无需依赖音频元素加载)
如果希望完全规避元数据加载的延迟,可直接在录音阶段记录时长:
// 录音开始时记录时间戳 let recordStartTime; mediaRecorder.onstart = () => { recordStartTime = Date.now(); } // 录音结束时直接计算时长 let recordDuration; mediaRecorder.onstop = () => { recordDuration = (Date.now() - recordStartTime) / 1000; // 直接用计算出的时长渲染UI,无需等待audio元素加载 const duration = formatTime(recordDuration); durationElement.textContent = duration; // 直接基于录音生成的blob创建下载按钮 const downloadBtn = generateDownloadBtn(recordBlob); clipContainer.appendChild(downloadBtn); }
内容的提问来源于stack exchange,提问作者Avery Wu。
相关产品推荐
相关产品推荐

