一聚教程网:一个值得你收藏的教程网站

最新下载

热门教程

HTML怎么实现录音功能_html MediaRecorder录音实现教程【建议收藏】

时间:2026-07-20 10:39:55 编辑:袖梨 来源:一聚教程网

HTML录音必须依赖MediaRecorder API和用户麦克风授权,非安全上下文(如file://)直接报错;需检查权限状态而非仅try/catch;指定兼容MIME类型并合理设置timeslice,否则blob可能为空或无法播放。

HTML 本身不能录音,必须靠 JavaScript 调用 MediaRecorder API,且依赖用户授权麦克风权限 —— 没有后端配合、没处理权限拒绝、没兼容旧浏览器,点一下就报错或静音。

为什么 MediaRecorder 在本地文件里直接双击打不开就失败?

因为 MediaRecorder 要求页面运行在安全上下文(https://localhost),非 HTTPS 的 http://127.0.0.1:8080 可以,但直接打开 file:///xxx/index.html 会触发 NotAllowedError: Permission denied

  • 开发时用 python3 -m http.server 8000 或 VS Code Live Server 插件起本地服务
  • Chrome 对 file:// 协议彻底禁用 navigator.mediaDevices.getUserMedia
  • 即使加了 --unsafely-treat-insecure-origin-as-secure 启动参数,也不能保证 MediaRecorder 正常工作

调用 getUserMedia 前必须检查权限状态

直接 await navigator.mediaDevices.getUserMedia({ audio: true }) 会卡死或抛异常,尤其在用户之前点过“拒绝”后,再调用会立刻 reject,且不弹新提示。

  • 先查状态:const permission = await navigator.permissions.query({ name: 'microphone' })
  • permission.state 可能是 'granted''denied''prompt'
  • 如果是 deniedgetUserMedia 必定失败,得引导用户去系统设置手动开启
  • 别用 try/catch 代替状态检查 —— denied 状态下 catch 到的错误无法恢复

MediaRecorder 录音后生成的 Blob 为什么播放没声音?

常见原因是 MIME 类型不匹配或编码不被支持。Chrome 默认用 audio/webm(含 Opus),Firefox 也支持,但 Safari 直到 iOS 16.4 / macOS 13.3 才支持 MediaRecorder,且只认 audio/mp4(需后端转码)。

立即学习“前端免费学习笔记(深入)”;

  • 创建时显式指定类型:new MediaRecorder(stream, { mimeType: 'audio/webm;codecs=opus' })
  • 别依赖 MediaRecorder.isTypeSupported('audio/mp4') 返回 true 就以为能录 —— Safari 支持查询但不支持录制 mp4
  • 录完用 URL.createObjectURL(blob) 播放前,确认 blob.type 是浏览器能解码的格式
  • 移动端某些安卓 WebView(比如微信内置)完全不支持 MediaRecorder,得降级用 Web Audio API + ScriptProcessorNode(已废弃)或 AudioWorklet

停止录音后,ondataavailable 拿到的 event.data 为空 Blob 怎么办?

这是最常踩的坑:没在 start() 后主动触发数据收集,或 stop() 调得太快,导致还没来得及产出第一个 chunk。

  • 确保 mediaRecorder.start(1000) 设置了 timeslice(毫秒),否则只在 stop() 时吐一次 data
  • 监听 dataavailable 事件,把每个 event.data 推进数组:chunks.push(event.data)
  • 别在 stop() 后立刻合并:new Blob(chunks, { type: chunks[0]?.type }),要等 onstop 事件触发后再处理
  • 如果用 timeslice: 0,必须靠 requestData() 主动拉取,否则可能漏数据

真正难的不是写那十几行代码,而是判断当前环境是否支持、用户是否给过权限、录出来的 blob 能不能被目标设备播放 —— 这些没法靠一个 if 解决,得逐层 fallback 和提示。

热门栏目