如何基于MediaRecorder实现N秒滚动窗口的屏幕录制
基于MediaRecorder实现固定时长滚动窗口录屏方案
原生MediaRecorder没有内置滚动缓冲区能力,不需要依赖第三方封装库,用分片循环录制的方案就可以低成本实现,内存占用完全可控,不会出现长时录制的内存溢出问题。
核心实现逻辑
- 初始化录制实例时配置时间片输出
创建MediaRecorder实例时,调用start(timeslice)方法传入分片间隔参数,建议设为1000(即每1秒返回一个独立的录制分片)。监听实例的ondataavailable事件,每次拿到分片Blob时,将分片和对应的录制起始时间戳一起存入一个先进先出的队列。 - 维护固定时长的窗口队列
每新增一个分片入队,就计算队列内所有分片的累计总时长,当总时长超过你预设的窗口值(比如30秒)时,直接弹出队头最早存入的分片,始终保证队列内分片总时长维持在预设窗口值附近。因为时间片切分存在毫秒级误差,判断时可以预留0.5-1秒的冗余,避免最终导出的片段时长不足。 - 触发导出时合并分片
当用户触发剪辑生成操作时,直接把队列中现存的所有Blob分片作为参数传入Blob构造函数,合并为完整的媒体文件,即可生成可下载、可分享的录屏片段。
实现注意事项
几个容易踩的坑需要提前规避:
- 不要尝试直接截断单个长录制文件的二进制数据:主流编码格式的媒体头信息存储在文件起始位置,直接截断二进制会导致文件损坏无法播放,分片存储的方案从根源上规避了这个问题。
- 内存占用控制:30秒1080P屏幕录制的分片总体积通常在10-30MB区间,远低于浏览器内存阈值;如果需要进一步降低内存占用,可以把时间片间隔调整到2-3秒,减少队列元素数量即可。
- 精度优化:如果需要严格控制窗口时长,可以在每个分片入队时记录
performance.now()高精度时间戳,导出时校验首尾分片的时间差,精准剔除超出时长的最早分片,最终误差可以控制在1秒以内,完全满足普通分享场景的需求。
如果需要帧级的精准裁剪,可以搭配MediaSource接口做缓冲区细粒度控制,但实现复杂度会提升数倍,绝大多数场景下上述分片方案代码量不足百行,稳定性足够。
内容的提问来源于stack exchange,提问作者Matthew Herbst
相关产品推荐
相关产品推荐

