使用 ffmpeg 进行视频编码
在输出为 MP4 或 WebM 等视频格式时,console2svg 使用与静态图片完全相同的终端仿真器与 SVG 渲染器。 系统按照指定的采样间隔将终端状态生成为静态 SVG,将其栅格化为 PNG,然后依次通过管道推送到 ffmpeg(开源音视频处理工具)的标准输入中。 全流程在内存中完成而不产生任何中间文件,从而彻底消除了磁盘 I/O 开销。
终端仿真器的单向推进回放
Section titled “终端仿真器的单向推进回放”在以固定帧率(FPS)采样视频帧时,系统绝不会针对每一帧都从录制开头(时间 0)重新执行仿真。 而是仅保留一个仿真器实例,随着采样时间的推移,仅向前应用尚未处理的新到达事件。
事件的检索索引同样保持单向向前递增。 这避免了在生成后续帧时反复遍历过去全部事件的无谓开销,使总处理时间随录制时长呈线性增长。
利用签名抑制 SVG 重复生成
Section titled “利用签名抑制 SVG 重复生成”仿真器推进到当前采样时间后,系统会立即获取整屏的视觉签名(由单元格内容和光标状态计算得出的哈希值)。 以该签名作为键,系统最多缓存 128 条最近生成的 SVG 字符串。
由于命令行应用程序在等待按键或命令执行期间通常会有较长时间的静止,许多采样点指向完全相同的画面。
当签名匹配时,系统将跳过 XML 的构建过程,直接返回缓存中的同一 string 实例。
保持时序的并行栅格化
Section titled “保持时序的并行栅格化”将 SVG 栅格化为 PNG 是计算密集型的 CPU-bound 操作。 因此,系统会根据可用的 CPU 核心数,最多使用 8 个线程并行执行栅格化。
与此同时,传递给视频编码器的图像帧必须严格保证时序先后顺序。 为此,系统通过一个具有容量限制的 FIFO 队列来管理异步栅格化任务,并由单一写入器按照队首任务完成的顺序依次写入 ffmpeg 的标准输入。 这种控制机制在充分发挥多核并行性能的同时,避免了将整部视频的所有未压缩帧一次性堆积在内存中的风险。
基于对象同一性的两级缓存
Section titled “基于对象同一性的两级缓存”由于生成的 PNG 图像比 SVG 字符串占用大得多的内存,因此 PNG 缓存的容量被严格限制在 16 项。
该缓存的键使用的是对象引用(同一性)而非字符串内容比较。
这是因为前一级的 SVG 缓存对于相同画面会返回完全相同的 string 实例。
由此构成的 两级缓存 能够在无需对庞大的 XML 字符串进行哈希计算或全文比对的前提下,同时避免 SVG 的重复生成与 PNG 的重复栅格化。
基于 image2pipe 的单进程传输
Section titled “基于 image2pipe 的单进程传输”在生成整个视频的过程中,系统仅启动一个 ffmpeg 进程。
所有图像帧均通过 image2pipe(通过标准输入或管道批量接收连续图像流的 ffmpeg 输入格式)传入。
指定的启动参数为 -f image2pipe -vcodec png -i pipe:0。
子进程的标准输出和标准错误输出在进程启动后便立即通过异步循环读取并丢弃(drain)。 这既防止了管道缓冲区溢出导致 ffmpeg 阻塞挂起,又能在编码失败时从标准错误中提取错误信息作为诊断日志。 当发生操作取消时,系统会向整个进程树发送终止信号以释放资源。
事先探测确认 SVG 解码器能力
Section titled “事先探测确认 SVG 解码器能力”不同构建版本的 ffmpeg 所包含的内置库存在很大差异。 即使格式列表中列出了 SVG,某些运行环境中也可能缺少内部的 SVG 解码器(如 libxml2 或 librsvg)。
因此,console2svg 在启动时会实际执行一次最小 SVG 到 PNG 的转换探测,判断其是否具备 SVG 解码能力并缓存结果。
在内存视频管道中,由于无法通过管道安全地切分多个连续的 SVG 文档,管道会优先调度内置的 resvg 或 rsvg-convert 进行栅格化,从而让 ffmpeg 专职负责视频编码流程。
MP4 编解码器选择与偶数尺寸补齐
Section titled “MP4 编解码器选择与偶数尺寸补齐”当输出到 MP4 容器时,如果系统中存在 libx264 则优先选用,否则回退到 mpeg4。
若输出为 WebM 或 GIF,则交由容器的默认编解码器处理。
MP4 的像素格式指定为在各类播放环境中兼容性极佳的 yuv420p(基于亮度信号 Y 和两路色度信号 U/V,且在水平和垂直方向上每 2×2 像素进行一次色度抽样压缩的格式)。 由于 yuv420p 规范要求图像的宽度和高度必须为偶数,系统会应用以下 ffmpeg 滤镜:
pad=ceil(iw/2)*2:ceil(ih/2)*2:0:0该滤镜将奇数像素的宽或高向上取整,在右侧或底部补齐最多 1 像素的填充。 这样可以在不偏移左上角基准坐标系的前提下,生成完全符合编码器规范的合法视频。