すべての形式のページ ↓
グラフィックとメディア

Bink — TA: Kingdomsのカットシーン動画

出典:coreprime/kbot @ 0ab97bf · GitHubで編集

Total Annihilation: Kingdomsは、初代のムービーに使われていたSmacker(.zrb)に代えて、RAD Game Toolsの新しいBinkコーデックを採用し、.bikとして格納しています。ミッションのイントロ、勢力ごとのブリーフィング、エンディングはすべて、movies/以下にBink 1ファイルとして収録されています。

拡張子 使用箇所 備考
.bik TA: Kingdomsのmovies/*.bik RAD Bink 1。シグネチャはBIKとリビジョンバイト1つ(TA:KではBIKf)。

BinkはSmackerではありません。独自のDCTベースの映像ビットストリームと独自の音声(Bink Audio、DCTまたはRDFT)を持つ、別の後発コーデックです。kbotはコンテナのヘッダーを自前で解析しますが、ピクセルのデコードはFFmpegに任せます。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")

TA: Kingdomsのインストール先にあるもの

$ 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)が1本付いています。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はfloatとして保持します。

音声フラグ(16ビットのFlagsワード)

ビット 意味
0x4000 16ビットサンプル(そうでなければ8ビット)
0x2000 ステレオ(そうでなければモノラル)
0x1000 DCTコーデック(そうでなければRDFT)

Note

SampleRateは格納されている値そのものです。TA:Kのファイルは切りのよい22050ではなく22254 Hzになっています。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エンコーダーは存在せず、.bikファイルを作れるのはRADの独自ツールだけです。実際にはSmackerも同じで、標準のFFmpegにはSmackerのエンコーダーもマルチプレクサーもありません(Smacker/ZRBを参照)。

Warning

幅や高さが奇数のクリップ。movies/gui/*.bikのクリップのいくつかは、幅や高さが2で割り切れません(例:124 × 101)。yuv420pのH.264では幅と高さが偶数でなければならないため、コンバーターは拡大縮小せず、padフィルターで次の偶数サイズまで広げます。ピクセルが再サンプリングされることはなく、代わりに黒い行や列が端に加わります。


注意点

  • BinkはSmackerではありません。.bikにkbot zrbを使ったり、.zrbにkbot bikを使ったりしないでください。シグネチャもコーデックもまったく異なります。
  • Bink 2(KB2)には対応していません。TA:KはBink 2より前の製品なので、収録されているファイルはすべてBink 1(BIK*)です。kbotはKB2*を、内容のはっきりしたエラーで拒否します。
  • 暗号化されたBoneyardsの短いクリップ。boneyards/metagame/*.bik以下のいくつかのファイル(例:ftuimovie2.bik)は、拡張子こそ.bikですがBinkコンテナではありません。オンラインのメタゲームUI用に、スクランブルまたは難読化されたペイロードです。kbotは中身を推測せず、不正なファイルとして拒否します。

関連項目

  • Smacker / ZRB — Binkが置き換えた、初代TAのカットシーン形式。
  • HPI — これらのファイルを収録しているラッパーアーカイブ。