MediaRecorder本身不支持断点续传式录制,需叠加前端分片管理、文件指纹和服务端协同三层逻辑:先录制暂停导出完整Blob,再按字节切片并携带uploadId、chunkIndex、totalChunks和MD5上传,服务端须支持切片状态查询、幂等接收、校验及合并。

MediaRecorder 本身不提供“分段切片上传”或“断点续传式录制”功能,它只负责把录音流按时间切片(如每200–500ms生成一个 Blob),但这些片段是纯音频数据,没有文件级唯一标识、无序号、无校验,也不能直接用于断点续传上传。真正实现断点续传式录制,必须在 MediaRecorder 基础上叠加**前端分片管理 + 文件指纹 + 服务端协同**三层逻辑。
先明确:MediaRecorder 的“分片”不是断点续传所需的分片
MediaRecorder 触发 dataavailable 事件时产生的 Blob 是时间维度的音频帧片段,比如:
- 第1次回调:200ms 的
audio/webm数据 - 第2次回调:又一个200ms 的
audio/webm数据 - ……它们彼此独立,无索引、无顺序标记、不能单独合并成完整文件
这类片段无法直接用于断点续传——因为断点续传依赖的是**文件字节级分块(如每2MB一个切片)+ 全局MD5 + 切片索引号**,而 MediaRecorder 不产生字节切片,也不暴露原始 ArrayBuffer。
实现断点续传式录制的正确路径
核心思路是:用 MediaRecorder 录制 → 暂停后导出当前完整 Blob → 对该 Blob 手动按字节切片 → 每片带 uploadId、chunkIndex、totalChunks 和文件 MD5 → 单独上传 → 服务端按序落盘并支持状态查询。
将 Markdown 文章转换为微信公众号兼容的纯 HTML 格式。当用户要求"转成微信格式"、"生成公众号文章 HTML"、"排版到微信草稿箱"、"微信粘贴格式"时触发。输出带内联样式的纯 HTML,微信编辑器可直接渲染,无需额外适配。支持标题、段落、列表、粗体、行内代码、表格、引用块、代码块、配图的完整转换。
立即学习“前端免费学习笔记(深入)”;
- 暂停录制时,调用
mediaRecorder.stop(),触发onstop,此时new Blob(audioChunks)得到的是当前已录全部音频(注意:不是单个分片) - 拿到完整 Blob 后,用
file.slice(start, end)按固定大小(如2MB)切片,末尾一片的end必须设为blob.size,避免丢数据 - 用 SparkMD5 或 Web Crypto API 计算整个 Blob 的 MD5,作为文件唯一标识
fileId - 每片 FormData 中必须携带:
uploadId(前端生成,如crypto.randomUUID())、chunkIndex(从 0 开始)、totalChunks、fileId、fileName - 上传失败的切片可重试,服务端需幂等接收(相同
uploadId+chunkIndex不重复写)
关键细节:如何让“暂停/继续”真正支持断点
用户点击暂停,不只是停止 MediaRecorder,还要保存两个状态:
- 已录制的音频总时长(或已生成的
audioChunks数量),用于 UI 进度展示 - 已成功上传的切片索引列表(存在
localStorage或indexedDB),刷新页面后能查出哪些片已落盘
继续录制时,不是恢复 MediaRecorder,而是新建一个 Recorder 继续录新内容;最终合并时,把“前一段 Blob”和“后一段 Blob”拼成新 Blob,再重新切片上传——这样才真正复用已传切片。
服务端必须配合的四件事
前端再严谨,没有服务端支持就不是断点续传:
- 提供接口查询某
fileId已上传的chunkIndex列表 - 接收任意顺序的切片,按
uploadId+chunkIndex写入临时存储(如 Redis 或磁盘临时目录) - 每个切片上传后返回校验结果(如服务端计算该片 MD5 并比对)
- 所有切片收齐后,按
chunkIndex升序合并为完整文件,并触发清理临时数据


















