录完一段屏幕,两个现象最容易让人以为文件坏了:进度条是空的、拖动没反应;以及明明设了从第 10 秒开始,导出来却从第 4 秒就开始了。两者都不是坏文件,而是视频容器和编码结构的固有特性在浏览器环境下的表现。
现象一:WebM 没有总时长
WebM 基于 Matroska 容器,总时长写在文件头部的信息段里。问题出在录制的性质上——开始写文件那一刻,根本不知道会录多久。
传统的转码流程可以在写完之后回头把这个值补上(文件在本地,随便回写)。但 MediaRecorder 的输出设计成可以直接推流:一边编码一边往外吐数据块,不假设下游能回退修改。所以它选择了不写,结束时也不补。
后果就是播放器读到 0 或无穷大:
- 没有总时长显示
- 进度条不动或者铺满
- 拖动定位失效
文件内容是完整的,一帧都不少,只缺一个数字。
MP4 直出的浏览器没有这个问题
工具会先探测浏览器能不能直接录 MP4:
| 容器 | 编码组合 | 支持情况 | 后处理 |
|---|---|---|---|
| MP4 | H.264 + AAC | Chrome 121 以上、Safari | 不需要,录完即可用 |
| WebM | VP9/VP8 + Opus | 其余 Chromium、Firefox | 导出时补时长 |
能录 MP4 就优先录 MP4,拿到的直接是完整可用文件。只有退回 WebM 的浏览器才需要下一步。
修法:重新封装,不重新编码
补时长不需要动画面数据——把音视频数据包原样搬进一个新写好头部的容器就行。这个操作叫重新封装(remux),特征是:
- 画质完全不变:一个像素都没有重新计算
- 快:只是搬运数据,几秒级别
- 顺带:MP4 输出还会把索引挪到文件开头,便于边下边播
工具在导出 WebM 时自动做这一步,界面上会显示「修复时长元数据」。所以预览里进度条不正常是正常的,导出后就好了。
这里需要那个三十多兆的编解码核心(ffmpeg 的 WebAssembly 版)——容器层的操作浏览器原生 API 做不到。它只在真正需要处理文件时才下载,下载后会被缓存;处理全程在本机,视频不上传。这也正是要把几十兆的核心搬进浏览器的原因:不上传就只能在本地算。
现象二:快速剪辑总是多出几秒
这条更容易让人困惑,因为它看起来像 bug。根源在于视频帧的解码依赖关系。
视频里只有关键帧(I 帧)能独立解码,其余帧都记录「相对前面的帧变了什么」。不重新编码的剪切本质是「从某个位置开始把数据包原样搬过去」——这个位置必须是关键帧,否则开头的画面根本解不出来。
于是实际起点会退到你设定的时间点之前最近的那个关键帧。
为什么屏幕录制特别明显
编码器在画面剧烈变化时插入关键帧。屏幕内容大多是静态界面:鼠标动两下、菜单弹一下,编码器判断没必要插新关键帧,间隔就被拉得很长——好几秒是常态。
实拍视频画面一直在变,关键帧插得密,同一个操作偏差通常在半秒内。所以「在手机视频上剪得很准,在录屏上偏了五秒」不是工具双标,是内容性质的差别。
两端为什么不对称
| 裁切位置 | 是否需要重新编码 | 原因 |
|---|---|---|
| 只裁末尾 | 不需要 | 丢掉后面的数据包就行,前面的帧不依赖后面的帧 |
| 裁掉开头 | 要精确就需要 | 起点那一帧必须能独立解码 |
这推出一条很实用的录制习惯:开头多留几秒废镜头没关系,但尽量让正式内容从头就开始。只需要去尾的剪辑是最省事的一种——秒级完成、切点精确、完全无损。
精确模式做了什么
起点不为 0 且没勾快速剪辑时,工具走重新编码:从起点前的关键帧开始解码,丢掉起点之前的帧,然后把剩下的重新编一遍。这样起点就是你设的那一刻,误差在一帧以内。
代价有三个:
- 慢:WebAssembly 里的编码器比原生慢数倍,耗时与视频时长同量级。十分钟录像要等好几分钟,中途可以取消
- 二次编码损失:用的是视觉上接近无损的质量档,加上屏幕内容以平坦色块为主、最容易压,文字边缘基本看不出变化
- 吃内存:需要把整个文件读进受限的内存空间。超过 300MB 时工具会先弹确认框,把「改用快速剪辑」这条出口摆出来
所以判断规则是:短片段要精确 → 重新编码;长录像要剪 → 导出原始文件,拿到桌面剪辑软件里做,那边是原生速度且没有内存墙。长录场景的完整取舍见录一小时怎么不崩。
三条输出路径
把上面两件事合起来,导出时实际只有三种走法:
| 你的操作 | 处理方式 | 输出 | 耗时 |
|---|---|---|---|
| 不裁剪(MP4 源) | 原样保存 | MP4 | 瞬间 |
| 不裁剪(WebM 源) | 无损重新封装,补时长 | WebM | 几秒 |
| 只裁末尾 | 无损裁切 | 原容器 | 几秒 |
| 裁掉开头 + 快速剪辑 | 无损裁切,起点对齐关键帧 | 原容器 | 几秒 |
| 裁掉开头(默认) | 重新编码 | MP4 | 与时长同量级 |
最后一行统一输出 MP4 是有意的:既然已经在解码再编码,容器换哪个都不增加成本,而 H.264 + AAC 是兼容面最广的组合——微信、剪映、Premiere、老播放器、投屏设备都吃它,WebM 在这些地方经常打不开。顺带还把时长问题一并解决了。
反过来,无损模式必须保持原容器:那条路只搬运数据包,不能把 VP9 的数据塞进 MP4(技术上有办法,但兼容性更差,得不偿失)。
一句话总结怎么用
- 进度条不正常 → 不用管,导出就好
- 只去尾 → 直接导,无损秒完成
- 要去头且要准 → 直接导,接受重新编码的时间
- 要去头且要快 → 勾快速剪辑,接受开头多几秒
- 文件很大 → 导原始文件,去桌面软件剪
导出之后的常规下游:体积超标用视频压缩再降一档,各平台的具体要求见视频上传规格对照;只要音频用视频提取音频,流复制和重编码的区别见容器与编码的差异;要放进文档或聊天的短动图用 GIF 制作。