動画ツール

動画が横倒しで再生される理由と、その修正が 0.5 秒で済む理由

スマートフォンのカメラは常に横向きで録画し、プレーヤーに回転を指示する 11 バイトのメモを書き込みます。このメモが失われると動画は横倒しになります。メモの正体、それを落とすもの、修正が 1 ピクセルも触らない理由。

要点

スマートフォンのカメラセンサーは、本体に横向きで固定されています。スマートフォンを縦に持って撮影しても、センサーが記録するのは横長のフレームで、スマートフォンはファイルに「90° 回転して表示すること」というフラグを書き込むだけです。スマートフォン上のプレーヤーはどれもこのフラグに従います。一方、ほかの環境のソフトウェアの一部(古い編集ソフト、一部の Web プレーヤー、特定のアップロード処理)はこれを無視したり削除したりし、その結果、動画が横倒しで再生されます。フラグを戻すのはメタデータの編集です。ファイルサイズにかかわらず一瞬で終わり、何も再エンコードしません。

フラグの正体

MP4 や MOV のファイルは、ボックスの木構造でできています。映像トラックの表示方法を記述するボックスは tkhd(トラックヘッダー)と呼ばれ、3 × 3 の変換行列(9 個の数値、36 バイト)を含んでいます。プレーヤーは各フレームを描画する前にこの行列を適用します。回転していない動画では行列は単位行列で、スマートフォンを縦にして撮った動画では 90° の回転です。ファイル内のピクセルは横長で、行列が「回転させよ」と指示しています。Android は同じ情報を別の rotation の値として書き込み、ffmpeg はどちらもストリームのメタデータで rotate: 90 と表示します。

これは意図的な設計です。録画中に実際のピクセルを回転させると、フレームごとにエンコーダーをもう 1 回まるごと通す必要があり、それをバッテリー駆動で行うことになります。9 個の数値を書くだけなら負荷はありません。写真の EXIF の向き情報と同じ考え方で、失敗の仕方も同じです。タグを読まないソフトウェアは、元の向きのまま表示します。

フラグを落とすもの

  • 古いデスクトップの編集ソフトやプレーヤー。 スマートフォンで縦長の動画を撮る時代より前に書かれたものです。VLC と QuickTime は何年も前から行列に従っていますが、一部の企業向け動画システムや古いビルドの Windows Media Player は従いません。
  • 映像ストリームをコピーしつつコンテナを作り直す変換ツール。 「再エンコードなし、ロスレス」をうたうツールでも、単位行列の新しい tkhd を書き込むことがあります。ピクセルは残っても、指示は残りません。
  • 一部の Web アップロード。 アップロード時に再多重化するサイトはタグを失うことがあります。再エンコードするサイトは、たいてい回転を正しく焼き込みます。
  • 連結。 縦向きのクリップと横向きのクリップを 1 つのファイルにつなぐと、結合後のトラックには行列が 1 つしかありません。どちらか半分の向きが間違ったままになります。

2 つの修正方法(うち 1 つはコストなし)

行列を書き換える。 tkhd の行列(または回転のフィールド)を、動画が正しく表示される値に設定します。数 GB になりうるファイルに数十バイトを書き込むだけで、映像と音声のストリームは手を加えずにそのままコピーされます。0.5 秒、画質の劣化なし、ファイルサイズも同じです。動画回転が既定で行うのはこの処理です。端末上でファイルを読み、修正したヘッダーを書き込み、ファイルを返します。何もデコードしないので、4 GB の録画でも 4 MB のファイルと同じ速さで処理できます。

回転を焼き込んで再エンコードする。 すべてのフレームをデコードし、ピクセルを回転させ、もう一度エンコードします。必要になるのは、再生する側が行列を無視することがわかっていて、その再生側を変えられない場合だけです。デジタルサイネージのプレーヤーや古い CMS がその例です。動画の長さと同じだけの時間(ハードウェアエンコーダーがなければそれ以上)がかかり、1 世代分の画質劣化が生じます。動画回転ではこれを 2 つ目の選択肢として、ブラウザの WebCodecs エンコーダーを使って提供しており、コストの高い経路であることを画面上に表示しています。

「コストなし」の修正が効かないことがある理由

ある 1 つのプログラムでだけ横倒しになり、ほかでは正しく再生されるなら、そのプログラムが行列を無視しているので、書き換えても効果はありません。効くのは回転の焼き込みだけです。どこで再生しても横倒しなら、行列が失われているので、書き換えれば直ります。簡単な確認方法があります。最新のブラウザ(Chrome、Safari、Firefox はどれもタグに従います)でファイルを開いてください。ブラウザで横倒し → 行列が間違っているか欠けている → 書き換える。ブラウザでは正しく、ほかのプログラムで横倒し → 問題はそのプログラム → 焼き込む。

関連する落とし穴

  • サムネイル。 横倒しの動画から切り出したフレームも横倒しになります。画像は表示結果ではなくストリームから取り出されるためです。先に動画を直してから、フレームを切り出してください。
  • トリミング。 再エンコードなしのトリミングは行列を保持しますが、再多重化するツールでトリミングすると保持されないことがあります。トリミングしたクリップが横倒しで戻ってきたら、トリミングツールがタグを落としています。行列を書き換えれば元に戻ります。
  • 左右反転したフロントカメラの動画。 これは別のフラグ(同じ行列の中の水平反転)で、同じ方法で修正できます。
テキスト読み上げTextToSpeech.tools 動画圧縮FreeCompress.video 中英辞典ChineseDict.com