Bink——横扫千军:王国的过场视频
《横扫千军:王国》把初代游戏的 Smacker(
.zrb)过场动画换成了 RAD Game Tools 更新的 Bink 编解码器,以.bik存储。任务开场、阵营简报和结尾动画都以 Bink 1 文件的形式发布在movies/下。
扩展名 使用者 说明 .bik横扫千军:王国的 movies/*.bikRAD Bink 1。签名是 BIK加一个修订版本字节(TA:K 中为BIKf)。Bink 不是 Smacker——它是一种独立的、更晚出现的编解码器,有自己基于 DCT 的视频比特流和自己的音频(Bink Audio,DCT 或 RDFT)。kbot 原生解析容器的文件头,但把像素解码交给 FFmpeg,后者自带 Bink 1 解码器(
binkvideo、binkaudio_dct/binkaudio_rdft)。
Tip
自己试试。
kbot bik info movies/takmission14_ph.bik # header summary
kbot bik to-mp4 movies/takmission14_ph.bik out.mp4 # decode to MP4 (requires ffmpeg)
在 Go 中调用。 使用 formats/bik:
import "github.com/coreprime/kbot/formats/bik"
r, _ := bik.OpenReader("movies/takmission14_ph.bik")
defer r.Close()
fmt.Println(r.Width(), r.Height(), r.FrameCount(), r.FrameRate())
_ = bik.ConvertToMP4("movies/takmission14_ph.bik", "out.mp4")
横扫千军:王国安装目录中有什么
$ ls $(kbot ctx path)/movies/*.bik
takmission01_ph.bik takmission14_ph.bik takx21_dh.bik …
$ ls $(kbot ctx path)/movies/gui/*.bik
snort4.bik snort6.bik … # tiny UI stingers, often a few KB
典型的任务过场动画是 640 × 350、15 fps,带一条 16 位立体声音轨(约 22 kHz)。movies/gui/ 中的片段要小得多,有时尺寸是奇数(例如 124 × 101)——见下面的坑点。
文件头布局(Bink 1)
所有字段都是小端序。kbot 读到音轨表为止(含音轨表);逐帧索引和压缩的比特流留给 FFmpeg 处理。
typedef struct {
char Signature[4]; // 'B','I','K', revision (revision 'f' in TA:K)
uint32 FileSize; // total file size minus 8
uint32 Frames; // video frame count
uint32 LargestFrame; // size in bytes of the biggest frame
uint32 FramesCopy; // duplicate frame count (ignored)
uint32 Width;
uint32 Height;
uint32 FPSNum; // frame rate numerator
uint32 FPSDen; // frame rate denominator
uint32 VideoFlags; // bit 0x00100000 = alpha plane, 0x00020000 = grayscale
uint32 NumAudioTracks;
// if NumAudioTracks > 0:
uint32 AudioMaxSize[NumAudioTracks]; // per-track max packet (ignored)
struct { uint16 SampleRate; uint16 Flags; } AudioInfo[NumAudioTracks];
uint32 AudioTrackID[NumAudioTracks];
// followed by:
uint32 FrameOffsets[Frames + 1]; // LSB of each offset is the keyframe flag
} BinkHeader;
帧率
fps = FPSNum / FPSDen。TA:K 的过场动画使用 15 / 1。由于它是一对有理数,值可能带小数,所以 kbot 把它保存为浮点数。
音频标志(16 位的 Flags 字)
| 位 | 含义 |
|---|---|
0x4000 |
16 位采样(否则为 8 位) |
0x2000 |
立体声(否则为单声道) |
0x1000 |
DCT 编解码器(否则为 RDFT) |
Note
SampleRate 就是存储的原值——TA:K 发布的是 22254 Hz,而不是整齐的 22050。kbot 原样报告。
转换只能单向解码
kbot bik to-mp4 会调用 FFmpeg:
ffmpeg -i in.bik \
-vf "pad=ceil(iw/2)*2:ceil(ih/2)*2" \
-c:v libx264 -preset fast -crf 18 \
-c:a aac -b:a 192k \
-y out.mp4
没有 from-mp4:不存在任何开源的 Bink 编码器,只有 RAD 的专有工具能生成 .bik 文件。Smacker 实际上也是如此——原版 FFmpeg 同样没有 Smacker 编码器或封装器(见 Smacker/ZRB)。
Warning
奇数尺寸。 有几个 movies/gui/*.bik 片段的尺寸不能被 2 整除(例如 124 × 101)。采用 yuv420p 的 H.264 要求宽和高都是偶数,因此转换器用 pad 滤镜把尺寸补到下一个偶数,而不是重新缩放——不会重采样任何像素,只是加上一行/一列黑边。
坑点
- Bink 不是 Smacker。 不要用
kbot zrb处理.bik(也不要用kbot bik处理.zrb);两者的签名和编解码器完全不同。 - 不支持 Bink 2(
KB2)。 TA:K 早于 Bink 2,因此每个发行文件都是 Bink 1(BIK*)。kbot 会以明确的错误拒绝KB2*。 - 加密的 Boneyards 短片。
boneyards/metagame/*.bik下有少数几个文件(例如ftuimovie2.bik)带着.bik扩展名,但不是 Bink 容器——它们是在线元游戏界面所用的、经过扰乱/混淆的载荷。kbot 会把它们作为无效文件拒绝,而不是去猜测。
另见
- Smacker / ZRB——Bink 所取代的初代 TA 过场视频格式。
- HPI——发布这些文件的外层压缩包。