最近は動画を使ったアプリケーションを仕事で作っているのですが、その途中で iPhone を使って縦向きに撮影した動画が、アップロードして video タグで再生した場合に横向きになってしまう現象に遭遇しました。
具体的には以下のような感じです。
これは Chrome に mp4 をドロップして再生させた状態ですが、HTML5 の video タグを使った場合も同様に横向きになってしまいました。
ちなみに FFmpeg を使って動画のサムネイルを作成した場合にも、同様に横向きの画像となってしまいます。
ffmpeg.exe -ss 3 -i daruyanagi.mp4 -vframes 1 -f image2 daruyanagi.jpg
実際に作成したサムネイルは以下のような感じ。
これが全てのブラウザやプレイヤーで再現してくれれば iPhone の撮影時に問題があったことになるのですが、Internet Explorer や Windows Media Player では正しく縦向きの動画として再生されます。
正直良く分からなかったので困っていたのですが、ふとファイルのプロパティを確認してみると実は横長の画像であることがわかりました。
なので、FFmpeg を使ってもっと詳細なファイル情報を出力してみることにしました。
ffmpeg.exe -i daruyanagi.mp4
パラメータとして -i だけを指定するとビットレートなどの基本的な情報から、動画に埋め込まれているメタデータなど様々な情報を得ることが出来ます。
実行した結果を長いですが載せておきます。
ffmpeg version N-64477-g5864069 Copyright (c) 2000-2014 the FFmpeg developers built on Jul 6 2014 22:02:08 with gcc 4.8.3 (GCC) configuration: --enable-gpl --enable-version3 --disable-w32threads --enable-avisynth --enable-bzlib --enable-fontconfig --enable-frei0r --enable-gnutls --enable-iconv --enable-libass --enable-libbluray --enable-libcaca --enable-libfreetype --enable-libgme --enable-libgsm --enable-libilbc --enable-libmodplug --enable-libmp3lame --enable-libopencore-amrnb --enable-libopencore-amrwb --enable-libopenjpeg --enable-libopus --enable-librtmp --enable-libschroedinger --enable-libsoxr --enable-libspeex --enable-libtheora --enable-libtwolame --enable-libvidstab --enable-libvo-aacenc --enable-libvo-amrwbenc --enable-libvorbis --enable-libvpx --enable-libwavpack --enable-libwebp --enable-libx264 --enable-libx265 --enable-libxavs --enable-libxvid --enable-decklink --enable-zlib libavutil 52. 90.101 / 52. 90.101 libavcodec 55. 68.101 / 55. 68.101 libavformat 55. 45.100 / 55. 45.100 libavdevice 55. 13.101 / 55. 13.101 libavfilter 4. 10.100 / 4. 10.100 libswscale 2. 6.100 / 2. 6.100 libswresample 0. 19.100 / 0. 19.100 libpostproc 52. 3.100 / 52. 3.100 Input #0, mov,mp4,m4a,3gp,3g2,mj2, from 'daruyanagi.mp4': Metadata: major_brand : qt minor_version : 0 compatible_brands: qt creation_time : 2014-06-14 10:58:39 encoder : 7.1.1 encoder-jpn : 7.1.1 date : 2014-06-14T19:58:39+0900 date-jpn : 2014-06-14T19:58:39+0900 location : +33.8390+132.7707+041.785/ location-jpn : +33.8390+132.7707+041.785/ model : iPhone 5s model-jpn : iPhone 5s make : Apple make-jpn : Apple Duration: 00:00:13.03, start: 0.000000, bitrate: 17084 kb/s Stream #0:0(und): Video: h264 (High) (avc1 / 0x31637661), yuv420p(tv, bt709), 1920x1080, 16991 kb/s, 29.98 fps, 29.97 tbr, 600 tbn, 1200 tbc (default) Metadata: rotate : 90 creation_time : 2014-06-14 10:58:39 handler_name : Core Media Data Handler encoder : H.264 Side data: displaymatrix: rotation of -90.00 degrees Stream #0:1(und): Audio: aac (mp4a / 0x6134706D), 44100 Hz, mono, fltp, 62 kb/s (default) Metadata: creation_time : 2014-06-14 10:58:39 handler_name : Core Media Data Handler At least one output file must be specified
注目すべきは Metadata にある rotate: 90 という表示ですね。結局は System.Drawing が画像の方向を無視するので対応した話 - しばやん雑記 と同じように回転情報だけを持っていて、プレイヤー側で対応しろということなのでした。
ちなみにもう少し仕様を調べたところ、mp4 というか mov は Exif のような単純な仕様とは異なり、メタデータとして変換行列を持っているらしいですね。
QuickTime File Format Specification: Basic Data Types
そして、結局 Chrome でも正しい向きで再生するためには、メタデータの変換情報を削除して再エンコードするしかないみたいです。そして FFmpeg を使ってサムネイルを作成する場合には回転のフィルタだけ掛けてあげれば良さそうですね。