🎞️
Unity Library

flareStream

動画・楽曲・音声・モーション・カメラワーク・トリガー・字幕を、1 本のストリームに。
1 時間のカットシーンでも、ロード待ちもメモリ切れもなく再生できる Unity 6+ 向けライブラリ。

開発状況:音声・動画(HEVC / H.264)・モーション・カメラワーク・トリガー・テキスト・シークは実装済みで、macOS / iOS / Android の実機で再生を検証済みです。Windows はビルドまで確認済みです。

Concept

カットシーン 1 本 = ファイル 1 本

カットシーンやライブ演出を Unity で組むとき、従来は AnimationClip・AudioClip・VideoClip・Timeline がバラバラのアセットで、全部のロード完了を待ち、全データ分のメモリを展開してから再生が始まります。flareStream は動画・音声・モーション・カメラワーク・トリガー・テキストといった異種のタイムドデータを 1 本のストリームファイル (.fst) にインターリーブし、再生ヘッダを読んだ瞬間からプログレッシブに再生を開始します。

ファイル I/O は 1 ハンドル、HTTP 配信ならレンジリクエスト 1 本、暗号化も 1 本のラッパで完結。再生に必要なメモリ量は再生開始前に確定し、再生中の動的確保はありません。

Use Cases

こんな演出のために

「音楽・ダンス・カメラ・演出が、決められた時刻どおりに一斉に動く」コンテンツが対象です。

🎤

リズムゲームのライブパート

楽曲・ダンス・カメラワーク・ライティングの切り替えを 1 本にまとめて配信。曲を 1 曲追加するたびに増えるファイルは 1 個で、譜面側はトリガーと再生時刻を参照するだけです。

📱

ファンアプリの 3D ミュージックビデオ

数十分の長尺でも再生中のメモリは増えません。ダウンロードしながら再生を始められるので、「全部落ちるまで待つ」画面が要らなくなります。

🎥

モーションキャプチャ公演の再現

収録したモーション・音声・演出トリガーを丸ごと 1 本に保存。後日どの端末で再生しても、同じ演出が同じタイミングで再現されます。

🎬

RPG のカットシーン

セリフ音声・キャラクターの芝居・カメラ・字幕・エフェクト発火を 1 本に。多言語の字幕や音声は言語ごとのトラックとして同居させられます。

Promises

3 つの約束

設計の中心に置いている、変わらない 3 つの性質。

⚡

即時再生・メモリ事前確定

ファイル先頭のヘッダを読んだ瞬間に再生を開始でき、必要なメモリ量・総再生時間・トラック構成がその時点で確定します。muxer がインターリーブ窓を保証し、正確なバッファ所要量をヘッダに記録。フルデータをメモリに展開しません。

🎞️

1 コンテンツ = 1 ファイル

カットシーンやライブ演出に必要な全データが 1 本に収まります。ロード管理・配信・暗号化の対象がファイル 1 本になり、アセットの取り違えや部分欠けが構造的に起きません。

🧩

拡張できる

コンテナはトラックの中身を関知しません。ハプティクスやリップシンクなど任意のタイムドデータを SDK の API でトラックとして追加でき、未知のトラックが混ざったファイルも安全に読み飛ばして再生されます。

Tracks

トラック種別

異種のタイムドデータを、1 本のストリームの中でサンプル精度で同期。

🎧

音声 — Opus / LPCM

音声コーデック層には flareOpus を使用し、ロイヤリティフリーの Opus で同等品質の MP3 比 約 1/3〜1/4.6 まで圧縮。libopus のソフトウェアデコードなので全プラットフォームで同じ音が出ます。非圧縮 LPCM も収録でき、複数音声トラックの同時ミックス再生に対応し、全トラックがサンプル精度で同期するため、通常 BGM とアレンジ BGM を音量操作でシームレスに切り替える演出も可能。音声が再生全体のマスタークロックになります。

🎬

動画 — HEVC / H.264

動画コーデック層には flareVideo を使用し、各 OS 標準のハードウェアデコーダ(VideoToolbox / MediaCodec / Media Foundation)で再生します。iOS / macOS では Metal ゼロコピーでテクスチャに直接届き、B フレーム入りの素材にも対応。負荷が高い端末では遅れたフレームの表示をスキップし、大きく遅れれば次のキーフレームまで読み捨てて全体の同期を守ります(表示・破棄・スキップの統計をデバッグオーバーレイで確認可能)。AV1 / VP9 はフォーマット上の識別子を予約済みで、再生対応は flareVideo の進捗に追従します。

🕺

モーション / カメラワーク — flareMotion / flareCamera

flareMotion は Humanoid ポーズ(マッスル値 95 本 + ルート + ブレンドシェイプ)を、flareCamera はカメラの位置・回転・FOV を、固定レートのサンプル列として収録する標準スキーマです。時刻ベース補間により収録レートと再生 fps は独立で、常に滑らか。全フレームがフルポーズなので任意時刻に即シークでき、遅れた場合も最新フレームだけ適用すれば破綻しません。カーブではなくサンプル列なので、AnimationClip の Keyframe Reduction や誤差許容値(Rotation / Position / Scale Error)をクリップごとに詰める調整は不要で、品質を決めるのは収録レートだけです。再生時はフレームを読んで線形補間するだけなので AnimationClip のカーブ評価より CPU が軽く、データ量は 1 キャラ 30fps・ブレンドシェイプ込みで約 140 kbps、カメラは 1 台約 12 kbps。体格非依存のため異なる体型のキャラクターにもそのまま適用できます。対応リグは Humanoid で、Generic リグは今後対応予定です。

💥

トリガー

エフェクト発火・シーン切り替え・ライト制御など、任意の瞬時イベントを時刻指定で発火。ペイロードは JSON で、C# イベントとしてメインスレッドで受信。イベント単位の失効時間も設定できます。

💬

テキスト

字幕・歌詞・キャプションを表示期間付きで時刻どおりに配信(描画はアプリ側で自由に)。多言語は言語ごとに別トラックとして格納し、再生中に API の 1 呼び出しで表示言語を切り替えられます(選んだ言語のトラックだけが配信されます)。

🧩

ユーザー定義トラック

トラックハンドラ登録と muxer のユーザー定義入力で、任意のタイムドデータを追加できます。ハプティクス、リップシンク、照明制御、独自の演出パラメータなど。たとえば「この時刻から 2 秒かけて被写界深度を X から Y へ動かす」という指示を独自トラックに収録し、受け取り側は再生時刻に合わせて補間する、といった使い方ができます。

Playback

再生機能

「再生が始まらない・メモリが読めない」をなくすための機能群。

▶️

プログレッシブ再生

ヘッダ読了後すぐに再生開始。ストレージの遅いデバイス向けに先読み量 (ReadAhead) を調整可能。必要メモリは Open 時に確定します。

⏩

シーク

任意時刻へのシークに全トラックが同期して追従。逆方向シークによるスクラブも可能です。インデックスを持つファイル(オーサリング済みの .fst)が対象で、長さ未確定のライブストリームは先頭からの再生のみになります。

⏱️

再生時刻の外部公開

CurrentTime を毎フレーム参照でき、輝度変化などトラック化していない任意の演出を再生に同期できます。

📊

統計 API とデバッグオーバーレイ

トラック別バッファ充填率・スループット・枯渇警告を実機でリアルタイム表示。「なぜ止まったか」を現場で追えます。

🧵

キャンセルと進捗報告

すべての非同期 API が CancellationToken / IProgress<float> に対応。シーン遷移でも素直に中断できます。

🔐

アセット保護

ロード API は「ファイルパス」「byte[]」「任意の Stream」の 3 系統で、StreamingAssets への平文配置に依存しません。暗号化済み配信はストリーミングのまま復号でき、標準の暗号化オプションも提供予定。

Authoring

オーサリングフロー

エンコードは ffmpeg やベイクエクスポータなど既存のツールで自由にチューニングし、専用ツール fstmux がタイムスタンプ整列・インターリーブ・メモリ保証の算出を行って .fst 1 本にまとめる 2 段構成です。動画は ffmpeg で作った MP4 から fstmux extract-mp4 で H.264 / HEVC のエレメンタリストリームを取り出して収録し、モーションとカメラは Unity エディタで AnimationClip や Timeline を再生した結果をベイクして flareMotion / flareCamera として書き出します。生成した .fst は ffprobe 相当の fstprobe でトラック構成・コーデックパラメータ・インターリーブ品質・バッファ宣言値を検証でき、fstmux demux / extract-wav / extract-opus / extract-lrc で個別素材に戻せます。Unity エディタ内での .fst 生成(素材ドロップ)にも対応予定。

やらないことも決めています——動画・音声のエンコード機能は持たず、mp4 / mkv / HLS 等の既存コンテナは直接再生せず、字幕の描画や DRM の鍵管理は扱いません。コンテナと同期再生に集中する設計です。

fstprobe — 中身を見て、検証する

.fst はブラックボックスではありません。付属の CLI fstprobe は、ヘッダに書かれた宣言値(平均レート・最大チャンク・バッファ量)と全チャンクを走査した実測値を並べて表示し、タイムスタンプの順序・インターリーブ窓の制約・宣言値と実測値の一致・Index の整合性を検証します。問題があれば「症状 + 対処」を 1 行で示し、終了コードで結果を返します。下はベンチマークと同じ Candy Rock Star の .fst に掛けた実際の出力(抜粋)。ベンチマークの「再生時メモリ 19.2 KiB」は、ここに出ている min buffer の値そのものです。

$ fstprobe crs.fst
Format
  container:         flareStream .fst v0.1
  file size:         8,900,620 bytes (header 7,333 / body 8,420,781 / index 472,490 / footer 16)
  duration:          240.667 s
  bitrate:           295,865 bit/s
  interleave window: 500.0 ms
  index:             26,249 entries
  tracks:            5
  min buffer:        19,692 bytes (Σ buffer_size_hint)

Track #0 audi/opus MustPlay
  codec:             48000 Hz 2 ch, pre_skip=312, input 48000 Hz
  declared:          avg 15,226 B/s, max_chunk 636 bytes, buffer_size_hint 9,956 bytes
  measured:          avg 15,226 B/s, max_chunk 636 bytes, buffer peak 9,956 bytes
  chunks:            11,752 (RAP 11,752 / discontinuity 0 / EOS 0), payload 3,664,271 bytes
  time:              0.000 s .. 235.020 s, avg interval 20.0 ms

Track #1 motn/fmo0 LatestWins
  codec:             flareMotion v0 "unitychan" 30 fps, 7221 frames, 95 muscles, 31 blend shapes
  declared:          avg 16,803 B/s, max_chunk 560 bytes, buffer_size_hint 8,960 bytes
  measured:          avg 16,803 B/s, max_chunk 560 bytes, buffer peak 8,960 bytes
  chunks:            7,221 (RAP 7,221 / discontinuity 0 / EOS 0), payload 4,043,760 bytes
  time:              0.000 s .. 240.667 s, avg interval 33.3 ms

Track #2 motn/fcam, #3 trig/trgj, #4 text/txtj ... (略)

Problems
  問題は見つかりませんでした。

--json でビルドパイプラインから読める形に、--strict で警告も終了コード 2 に格上げして CI の品質ゲートに、--header-only で巨大ファイルのヘッダだけを素早く確認、--chunks / --index でチャンクや Index の一覧に降りられます。macOS(Apple Silicon / Intel)と Windows 向けの単体バイナリで、.NET ランタイムのインストールは不要です。

Benchmarks

性能は、実測値で示します

従来構成(モーションと音声を個別アセットとして読み込む組み方)と flareStream を、同一コンテンツで実測比較しました。題材は Unity-chan「Candy Rock Star」の約 4 分のライブ演出(楽曲 235.0 秒 / ダンス 240.7 秒)です。

計測環境は Unity 6000.3.23f1 / macOS (Apple Silicon)、メモリは Profiler.GetRuntimeMemorySizeLong() によるアセット実体のランタイムサイズ。キャラクターモデル(メッシュ・テクスチャ)はどちらの方式でも同じだけ必要なため、比較対象から除いています。

測り方と数値の詳細
指標 測り方 従来構成 flareStream
再生時メモリ(時系列データ)
モーション + 音声の常駐量
従来は AnimationClip 45.27 MiB + AudioClip 39.55 MiB の全展開。flareStream はコンテナが宣言するバッファ量の合計 84.8 MiB 19.2 KiB
再生開始までの時間
再生を始められる状態になるまで
従来は音声の LoadAudioData だけで 493 ms(モーションの展開は別途)。flareStream はヘッダ読了までの時間 493 ms + 32 ms
データサイズ
時系列データの合計
従来は FBX 7.01 MiB + mp3 7.25 MiB。flareStream はカメラワークと字幕も含んだ .fst 1 本 14.26 MiB 8.49 MiB
ファイル数・I/O ハンドル数
1 コンテンツあたり
従来は FBX / 音声 / 演出スクリプト / シーンに分散。HTTP 配信ならリクエスト本数も同数 4 種以上 1 個
モーション適用コスト
1 フレームあたり
95 マッスル + ブレンドシェイプ 31 件の適用(flareStream 実測) — 0.02 ms

従来構成の音声を Streaming 設定にすれば、音声分のメモリは削減できます。ただし AnimationClip にストリーミング再生の仕組みは存在しないため、モーションの 45 MiB は展開されたままです。この点が構造的な差になります。

Why

この差を生んでいるもの

数値の背景にある設計判断と、それが開くこと。

コンテンツの長さと再生時メモリの関係 横軸はコンテンツの長さ(0〜60 分)、縦軸は再生時メモリ。従来構成は 4 分の実測 84.8 MiB から線形に伸び、1 時間では約 1.2 GiB に達する試算。flareStream は 19.2 KiB のまま長さに依存しない。 0 256 MiB 512 MiB 768 MiB 1 GiB 0 10 20 30 40 50 60 分 コンテンツの長さ → 再生時メモリ → 実測 84.8 MiB(4 分) 従来構成:1 時間で 約 1.2 GiB(線形換算) flareStream:19.2 KiB のまま(長さに依存しない) ↓ 低いほど優秀
4 分の実測値(従来構成 84.8 MiB、flareStream 19.2 KiB)から、コンテンツの長さを伸ばしたときの再生時メモリを描いたもの。従来構成の 4 分以降は線形換算の試算です。音声を Streaming 設定にしても、AnimationClip はストリーミングできないためモーション分(4 分で 45 MiB、1 時間で約 680 MiB)は残ります。flareStream のバッファ量はインターリーブ窓の時間幅で決まるため、長さが変わっても増えません。
📐

メモリがコンテンツ長に依存しない

バッファ量は「インターリーブ窓」という時間幅で決まるため、4 分でも 1 時間でも再生時メモリは変わりません。muxer が各トラックの最大バッファ占有量をファイルに記録し、再生側はヘッダを読んだ時点で所要量を確定できます。

🕺

モーションをストリーミング再生できる

Unity の AnimationClip にはストリーミング再生の仕組みがありません。flareStream はモーションをタイムスタンプ付きチャンク列として持つため、音声と同じように「必要な区間だけ読む」再生ができます。

🎚️

収録レートと再生 fps が独立

モーションは「任意時刻のポーズを返すもの」として扱い、描画フレームごとに時刻ベースで補間します。30fps で収録したモーションを 60fps でも 120fps でも可変フレームレートでも滑らかに再生でき、24fps 動画と 60fps モーションの混在も問題になりません。

🧍

体格非依存のモーション

Humanoid のマッスル値は体格で正規化された値なので、収録元と異なる体型のキャラクターにそのまま適用できます。リターゲット処理は不要です。

🎯

手続き的な演出も焼き込める

アニメーションデータとして存在しない演出、たとえば実行時にコードで生成されるカメラワークも、同じロジックを決定的に回して時系列サンプルとして収録できます。ベンチマークに使ったサンプルのカメラワークが実際にそれで、毎回まったく同じ演出を再現できるようになります。配信・収録コンテンツで効いてくる性質です。

🧩

足りないデータは自分で足せる

コンテナはトラックの中身を関知しないので、被写界深度の遷移・ハプティクス・照明制御といった独自の時系列データを、独自トラックとして同じストリームに同居させられます。受け取り側はハンドラを 1 つ登録するだけで、提示時刻どおりに届きます。

On Device

実機で動いています

同じ .fst・同じサンプルシーンを、各プラットフォームの実機で再生して確認しています。題材はベンチマークと同じ Unity-chan「Candy Rock Star」約 4 分(楽曲 + ダンス + カメラワーク + 演出トリガー + 歌詞字幕を 1 本の .fst に収録)です。

プラットフォーム 検証機 フレームレート モーション適用 結果
macOS
Standalone / Apple Silicon
Apple Silicon Mac 60 fps — 音声の途切れなし。Unity 合計メモリ 80.1 MB
iOS
IL2CPP / arm64
iPhone 17 / iOS 26.6.1 — — 5 トラック 235 秒を通しで再生。モーション・カメラ・トリガー・字幕すべて同期、例外なし(フレームレートは未計測)
Android
IL2CPP / arm64-v8a
Pixel 5a / Android 11 30 fps 0.11 ms 音声の途切れなし。Unity 合計メモリ 80.9 MB
Windows
Standalone x64
— — — ビルドまで確認済み(実機での再生確認は準備中)

実機でのバッファ実測(Android)は音声 195 KB・モーション 16.4 KB・カメラ 1.2 KB(macOS は 195 KB / 18.6 KB / 1.3 KB)。コンテンツの長さに関係なく一定で、再生が進んでも増えません。動画込みのデモ(720p H.264 + Opus)も macOS / iOS / Android の実機で再生を確認しており、iOS / macOS は Metal ゼロコピー、Android は Unity 合計メモリ 67 MB で動作します。実機の .fst はアプリ専用領域に配置して読み込んでおり、StreamingAssets への平文配置に依存しません。

Quality

壊れていないことを、数値で示します

「軽い・速い」だけでなく、データが劣化していないことを検証で担保しています。すべて自動テストとして常設し、変更のたびに実行しています。

検証項目 内容 結果
音声(Opus 往復)
WAV → Opus 96 kbps → .fst → デコードの往復で SNR を測定 42.31 dB
音声(非圧縮 往復)
WAV → .fst → デコードでバイト列を比較 完全一致
モーション往復
ベイク → .fst → 適用で 95 マッスルと重心 TRS を比較 誤差 < 0.005
コンテナ往復
エレメンタリストリーム → mux → demux でバイト列を比較 完全一致

muxer は決定的です(同一入力から常にバイト一致の .fst を生成)。付属の fstmux demux で .fst を個別トラックに戻せ、fstprobe で宣言値と実測値の一致やインターリーブ窓の制約を検証できるため、往復検証はご自身の環境でも再現できます。上記に加え、コンテナ層と muxer の自動テスト 316 件、Unity エディタ上の自動テスト 49 件を常設し、変更のたびに実行しています。

Availability

提供はお問い合わせから

音声コーデック層には flareOpus、動画コーデック層には flareVideo を使用します。コンテナ・モーション・カメラ・トリガー・テキストは C# のみで実装されているため Unity が動く環境ならそのまま動作し、音声 Opus のネイティブプラグインは iOS / Android / macOS / Windows に対応済みです。動画トラックは flareVideo のネイティブプラグインを使い、macOS / iOS / Android で再生を確認済み、Windows は flareVideo の対応に追従します。コンソール対応はアドオンとして検討中です。

有償ライセンスでの提供を予定しています。フォーマットのコア仕様と実装は一般には公開していませんが、採用いただくプロジェクトには仕様書とソースコードを開示する予定です。ご相談・ユースケースのご連絡は [email protected] までお寄せください。