跳到主内容

SWF 视频编码:H.263、Screen Video 与 VP6

老 SWF 也能直接塞视频:从 H.263、Screen Video 到 VP6,顺便看看它和馆内 AV1 预览有什么不同。

Flash 保存计划 · 最近整理于 2026年7月30日

本文目录 · 5 节
  1. 五种 codec ID 对照
  2. DefineVideoStream 与 VideoFrame 怎样配合
  3. 从 Player 6 到现代模拟器
  4. 与本馆 AV1 动态预览的区别
  5. 相关词条

老 Flash 作品里的运动画面,大多由时间轴、矢量和位图组成,不过 SWF 也能直接塞进压缩视频。作品页上的 h263screenvp6vp6alphascreen2,就是视频流里的 codec ID 翻成的名称。它说的是帧数据怎样解码,不是 MP4、FLV、F4V 那样的容器格式。

这套做法从 Flash Player 6 开始:先用 DefineVideoStream 建立一个视频角色,再由一连串 VideoFrame 送入压缩帧。帧就夹在 SWF 时间轴的其他标签之间,文件还没下载完,播放便可以开始。

本站顺着标签往下读。碰到 DefineVideoStream(编号 60),就把视频资源数加一,标记 media.has_video,再把其中的 CodecID 换成上面这些短名称;不认识的编号记作 unknown

media.video_codec 目前只留一个值,所以一只 SWF 若有多条视频流,页面会显示最后读到的那种。这里也不会真的解码 VideoFrame,画质、码率、关键帧和时长都要等实际播放才知道。ActionScript 临时从网上加载的 FLV / F4V,则根本没装在这只 SWF 里。

五种 codec ID 对照

本馆字段 SWF CodecID 名称 典型时期 核心特点
h263 2 Sorenson H.263 / Sorenson Spark SWF 6、Player 6 起 面向一般视频的有损运动压缩,是对 H.263v1 的 Flash 变体
screen 3 Screen Video SWF 7、Player 7 起 面向屏幕录制的分块、无损、zlib 压缩帧
vp6 4 On2 TrueMotion VP6 嵌入式 codec ID 为 SWF 8 时代;Player 8 起 同码率下通常比 Sorenson Spark 质量更好,解码成本也更高
vp6alpha 5 VP6 with alpha SWF 8、Player 8 起 一条颜色 VP6 流加一条 alpha VP6 流,可与舞台内容合成
screen2 6 Screen Video Version 2 Player 8 起 Screen Video 的扩展,支持局部更新、调色板和改进的分块压缩

这些年代说的是 codec 何时进入 Flash。今天能不能顺利播放,还要看帧本身和播放器带了哪套解码器。

Sorenson H.263(h263

Codec ID 2 是 Sorenson H.263,Adobe 的产品文档也常叫它 Sorenson Spark。它从 1996 年版 ITU H.263 演变而来,但码流是 Flash 自己的变体:去掉 GOB 层和 PB 帧,加入可丢弃帧、任意画面尺寸、始终启用的 unrestricted motion vector 和去块提示,画面层与宏块层头部也另有安排。

这是 SWF 6 最早提供的内嵌视频格式,很有当年低带宽网页视频的气质。后来 VP6 已经出现,Adobe 仍把 Spark 留作兼容 Player 6 / 7 和较旧电脑的选择:更省解码力,代价是同码率下画质通常逊色一些。

顺带一提,h263 不是 H.264 的简写,两者是不同代的编码。这个小写词只是本站给 CodecID = 2 的固定名称。

Screen Video(screen

Codec ID 3 是第一代 Screen Video,出现在 SWF / Player 7。它的舞台不是摄像机实拍,而是软件演示和桌面录屏:大块像素经常不动,文字与窗口边缘又很锐利。

每帧被划成 16–256 像素见方或长方形的网格块:

  • 关键帧为每个块提供像素;
  • 后续帧可令未变化块的 DataSize 为零;
  • 有变化的块保存 B、G、R 三字节像素,并分别使用 zlib 压缩。

这是一种带分块帧间更新的无损连续位图。“无损”说的是像素不经过有损量化,可不保证文件小;拿它装实拍画面或全屏快速变化,体积照样会上去。

On2 TrueMotion VP6(vp6

Codec ID 4 是 On2 TrueMotion VP6,也是 Player 8 时代更讲究画质的选择。同码率下,它通常比 Sorenson Spark 清楚;编码更慢,观众的电脑也要多出一点力。

内嵌 VP6 属于 SWF 8 时代,不过早期 SWF 也能借脚本加载外部 VP6,只要实际运行的是 Player 8。本站写下 vp6 时,只数文件本体 DefineVideoStream 里的 codec ID 4。

普通 VP6 帧只有颜色画面。若需要逐像素透明度,SWF 使用另一个 codec ID。

VP6 with alpha(vp6alpha

Codec ID 5 是带 alpha 通道的 VP6。每帧保存两段码流:

  1. 第一条 VP6 流表示预乘 ARGB 的颜色通道;
  2. 第二条 VP6 流把 8 位 alpha 值编码进亮度分量;
  3. VP6SWFALPHAVIDEOPACKET 开头的 24 位 OffsetToAlpha 指出第二段数据从哪里开始。

解码时,两条流重新合成带透明度的像素,于是人物、烟雾、抠像素材便能叠在矢量或位图场景上。为了还能正常 seek,颜色流遇到关键帧时,alpha 流在同一点也要有关键帧。

这份 alpha 只属于视频帧,不会顺手把整个 SWF 舞台变透明。最后看到什么,还要看角色怎么摆、背景是什么,以及播放器怎样合成。

Screen Video Version 2(screen2

Codec ID 6 是 Screen Video Version 2。它保留第一代的分块屏幕录制思路,并加入几项减少块数据量的机制:

  • 块可以只更新连续的部分扫描行,而不是每次给出完整块;
  • 可利用当前或上一画面的块作为 zlib“预热”数据;
  • 除 24 位 RGB 外,还可使用 15/7 位混合色彩空间;
  • 混合色彩空间可引用 128 色调色板,码流可随时给出新调色板,否则使用规范的默认表;
  • 帧可组合 keyblock 与依赖其他画面的 interblock。

这些办法很适合颜色有限、只在局部变化的界面画面,解码自然也比第一代麻烦。Ruffle 目前的软件后端有 H.263、VP6、VP6 alpha 和 Screen Video 的分支,但 Screen Video 解码器标着“V1 only”,也找不到 ScreenVideoV2 分支。于是本站认得 screen2 这个编号,实际播放仍可能停在这里。

DefineVideoStreamVideoFrame 怎样配合

接下来看看它在文件里怎样串起来。DefineVideoStream 先把视频角色写进 SWF 字典,同时留下:

  • CharacterID:其他显示列表标签引用的视频角色 ID;
  • NumFrames:这条流声明包含多少个 VideoFrame
  • WidthHeight:视频像素尺寸;
  • 去块等级和缩放平滑开关;
  • CodecID:本页讨论的压缩格式编号。

后面的 VideoFrame(编号 61)各带一个 StreamID、流内 FrameNum 和压缩负载。StreamID 像线头一样,把这些帧牵回刚才定义的视频角色。

不过,帧数据到齐了,还得由 SWF 时间轴把画面安排上舞台:

  • 播放节奏取决于 SWF 帧率,视频负载自身的计时信息被忽略;
  • 不是每一个 SWF 帧都要配一个 VideoFrame
  • VideoFrame 只给流内帧号装入数据,不会自动出现在舞台上;
  • 要显示它,时间轴通常通过 PlaceObject2PlaceObject3Ratio 选择视频帧。

这样一来,NumFramesVideoFrame 条数、SWF 总帧数和观众真正看到的画面数自然不会总是一样。音频也另有去处:内嵌影片要出声,还得配合 SWF 声音标签或外部媒体。

从 Player 6 到现代模拟器

Player 6 带来 SWF 视频标签和 Sorenson H.263;Player 7 加上 Screen Video,也让 NetStream.play 可以直接加载 FLV;Player 8 又迎来 VP6、VP6 alpha 与 Screen Video 2。此后 FLV、F4V 和 H.264 等外部媒体路径继续生长,已经是 DefineVideoStream 那五个 ID 之外的另一段历史。

到了 Ruffle,流程还是先认出 codec ID,再把数据交给随构建启用的解码器。若帧有缺口、前置关键帧丢了、时间轴没把角色摆上舞台,或者脚本仍在等一份网络资源,页面认出了编码,画面也可能迟迟不来。

与本馆 AV1 动态预览的区别

本站页面有时还有一段 MP4 / AV1 动态预览。那是把整只 SWF 播放一遍、重新抓取画面得到的,和 media.video_codec 说的不是同一层东西:

项目 SWF 内嵌视频 codec 本馆 AV1 预览
数据来源 原始 SWF 的 DefineVideoStream.CodecIDVideoFrame 本馆在隔离渲染环境中播放整个 SWF 后抓取画面
是否属于原始文件 否,是可重建的派生展示资源
表示范围 某个内嵌视频角色 整个舞台的最终输出,包括矢量动画、位图、文字和视频
编码 H.263、Screen Video、VP6 等旧 Flash codec 使用 AV1 编码并装入页面可播放的 MP4 预览
档案身份 原始 SWF 内部事实 为浏览与缩略展示生成,不替代归档主文件

所以,“视频:无”的作品仍可能有动态预览——矢量补间、逐帧绘制、影片剪辑和脚本一样会动。反过来,原文件含 vp6 也未必能产出预览;它得先顺利播放,还得真的产生足够的画面变化。

最后解释一下名字里的“Stream”:这里说的是内嵌帧沿时间轴分布、可以渐进下载,不是 RTMP 直播。SWF 内嵌视频、RTMP 和 NetStream 加载外部 FLV,本来就是三条不同的路。

相关词条

这些资料从哪来

  1. Adobe SWF File Format Specification, Version 19
  2. Adobe Flash Professional CS6 Help:video codecs
  3. Ruffle:SWF VideoCodec type
  4. Ruffle:software video backend
  5. Ruffle:Screen Video decoder