IndexedDB 不适合存储音视频二进制流,因其写入大文件易阻塞主线程、版本升级卡顿、单条记录大小受限且不支持流式写入和零拷贝;应专注缓存轻量结构化元数据。

IndexedDB 在低延迟音视频剪辑场景中,适合缓存时间轴元数据、片段引用、滤镜参数、关键帧信息等结构化但非媒体本体的数据,而非直接存储原始音视频文件。
为什么不用 IndexedDB 存音视频二进制流?
虽然 IndexedDB 支持 ArrayBuffer 和 Blob,但实际用于缓存音视频文件会带来明显瓶颈:
- 写入大文件(如 >10MB)易触发主线程阻塞,影响时间轴拖拽、实时预览等交互响应
- 数据库增长过快时,版本升级或清理操作可能卡顿,破坏剪辑流程的连续性
- 浏览器对单条记录大小有限制(Chrome 约 1GB,但实际建议控制在几十 MB 内),且无流式写入支持
- 无法像
Cache API或File System Access API那样与 MediaRecorder、WebCodecs 直接协同做零拷贝处理
推荐的缓存分工模式
将不同数据分层交由更合适的机制管理,IndexedDB 聚焦“轻量、高频、需索引”的剪辑状态数据:
- 用 IndexedDB 缓存:轨道结构、片段起止时间戳、缩略图 URL(非图像本身)、音频波形采样点数组(压缩后 ≤2MB)、LUT 参数、转场类型 ID、用户标记(如“待审核”“主镜头”)
- 用 Cache API 或 Service Worker 缓存:已导出的预览片段(MP4/WebM)、远程加载的素材代理文件(proxy clips)
- 用 File System Access API(配合 WritableStream):本地导入的大素材文件、导出中的临时分片(支持后台写入、进度监听)
-
内存中保留:当前编辑帧的解码图像(
VideoFrame)、实时音频分析结果(FFT 数据),避免反复读库
优化 IndexedDB 读写性能的关键实践
针对剪辑应用高频率更新时间轴的需求,可采取以下具体措施:
- 使用
transaction('store', 'readwrite').objectStore('store').put()替代批量add(),减少版本变更开销;对同一轨道多次修改,合并为一次事务 - 为常用查询字段(如
trackId、startTime)建立多字段索引:createIndex('byTrackAndTime', ['trackId', 'startTime']) - 启用
webkitIndexedDB或标准 IndexedDB 的durability: 'relaxed'(若浏览器支持),降低写入确认等待时间 - 对波形数据等长数组,先用
Uint16Array压缩采样精度,再转为ArrayBuffer存储,体积可减少 50% 以上
一个典型剪辑元数据缓存示例
假设缓存一段 10 秒视频片段的编辑状态,结构精简如下:
{
id: "clip_abc123",
trackId: "video_track_01",
startTime: 12450, // 毫秒,精确到毫秒级定位
duration: 3200,
filters: ["brightness(1.2)", "saturation(0.8)"],
waveform: new Uint16Array([12, 45, 88, ..., 2047]), // 2KB 左右
markers: [{time: 1500, label: "cut_in"}, {time: 2800, label: "voice_start"}]
}
该对象序列化后约 4–6KB,IndexedDB 单次写入耗时稳定在 1–3ms(SSD+现代浏览器),完全满足子帧级编辑反馈需求。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











