
右の「このデバイスではこの動画は再生できません」状態を、たった一バイト変更するだけで直します。
以下のPerl Scriptで、こうするだけです
# デフォルトではlevel 4.1 に変更 % ch264level leveltoohigh.mp4 # level 3.1 に変更 % ch264level -l31 leveltoohigh.mp4
ch264level.pl
#!/usr/bin/env perl # # $Id: ch264level.pl,v 0.1 2012/08/31 18:13:16 dankogai Exp dankogai $ # use strict; use warnings; use Getopt::Std; getopts 'l:' => \my %opt; my $level = $opt{l} || 41; die <<"EOF" unless @ARGV; $0 [-l] foo.mp4 bar.mp4 default is 41 for H.264 level 4.1 -l40 set H.264 level to 4 -l31 sets H.264 level to 3.1 see http://en.wikipedia.org/wiki/H.264/MPEG-4_AVC#Levels EOF chlevel( $_, $level ) for @ARGV; sub chlevel { my ( $path, $level ) = @_; open my $fh, '+<', $path or die "$path: $!"; scan: while ( !eof($fh) ) { read $fh, my $header, 8; my $len = unpack( "N", $header ); my $name = substr( $header, 4 ); #warn "$name:$len"; if ( $name eq 'moov' ) { read $fh, my $moov, $len - 8; if ( $moov =~ s{( trak.+ mdia.+ minf.+ stbl.+ stsd.+ avc1.+ avcC \01..)(.) }{ $1 . chr $level }emsx ) { last scan if ord $2 == $level; warn sprintf "%s : %d -> %d\n", $path, ord $2, $level; seek $fh, -$len + 8, 1; # rewind syswrite $fh, $moov; # rewrite last scan; } } seek $fh, $len - 8, 1; } close $fh; }
たった一バイトしか書き換えないので、何GBもあるフルHD動画も安心です。
解説
webMがドM専用フォーマットであることがほぼ確実になった今や動画のデファクトスタンダードになった感がある、H.264。しかし「スタンダード」という割には、あっちの環境で難なく再生できてたのにこっちで出来なかったりという状況は未だに珍しくありません。
その理由のかなりの部分が、レベルの過剰申告にあることに今さらながら気づきました。
H.264 - WikipediaMPEG-2などと同様、目的用途別に定義された機能の集合を表すプロファイルと、処理の負荷や使用メモリ量(これらは画面解像度やフレームレートに影響する)を表すレベルが定義がされる。H.264に準拠する機器(又はビットストリームそのもの)はこのプロファイルとレベルによって性能(又はビットストリームをデコードするのに必要な性能)を表示することが多い。
つまり再生機器は、このプロファイルとレベルを確認して、自分がそれを再生できるかを判断しているわけです。当然なるべく低いプロファイル、なるべく低いレベルの方が対応機器は増えます。例えばiPhone 4Sは ハイプロファイルレベル4.1 まで再生できますが、iPhone 4だとこれがメインプロファイルレベル3.1に下がり、iPhone 3GSに至ってはベースラインプロファイルまで下がってしまいます。
ところがiPhone 4でも余裕で再生できそうな、縮小しなくてもRetina Displayに収まってしまう動画がiPhone 4Sや新iPadで再生できなかったりするのです。そういう動画を調べてみると、レベル5.1とかになってたりするのです。
こんなメイジャーなやつまで。
% mp4info sm8628149.mp4 mp4info version 1.9.1 sm8628149.mp4: Track Type Info 1 video H264 High@5.1, 219.000 secs, 507 kbps, 512x384 @ 30.000000 fps 2 audio MPEG-4 AAC LC, 219.080 secs, 100 kbps, 44100 Hz
ニコ動のHTML5ページやiOSアプリだと何の問題もなく視聴できるのですが、ダウンロードしたファイルをWeb共有などで直見すると再生できませんでした。
どうみてもそんな過剰スペックは必要ありません。
% ffprobe sm8628149.mp4 .... Input #0, mov,mp4,m4a,3gp,3g2,mj2, from 'sm8628149.mp4': Metadata: major_brand : isom minor_version : 1 compatible_brands: isom creation_time : 2009-10-25 18:07:02 copyright : copyright-eng : Duration: 00:03:39.08, start: 0.000000, bitrate: 610 kb/s Stream #0.0(und): Video: h264 (High), yuv420p, 512x384, 506 kb/s, 30 fps, 30 tbr, 30030 tbn, 60 tbc Metadata: creation_time : 2009-10-25 07:46:14 Stream #0.1(und): Audio: aac, 44100 Hz, stereo, s16, 100 kb/s Metadata: creation_time : 2009-10-25 18:07:02
実際レベルを書き換えただけで何の問題もなく再生されるようになりました。

実際 Handbrake のAppleTV 3用のプリセットを使ってエンコードしなおしたら、レベル3になりました。にも関わらずファイルサイズは小さくなりました。画質の劣化は肉眼では判別不能だと思います。
% mp4info sm8628149-appletv3.mp4 mp4info version 1.9.1 sm8628149-appletv3.mp4: Track Type Info 1 video H264 High@3, 219.100 secs, 317 kbps, 512x384 @ 29.981743 fps 2 audio MPEG-4 AAC LC, 219.103 secs, 163 kbps, 44100 Hz Encoded with: HandBrake 0.9.8 2012071800
1080p@30FPSでも4.1で充分なはずなのに、なぜレベル5.1な動画がこんなに巷に溢れているのか。
ここからは憶測ですが、最高画質を目指すあまり、あまりに多くの人が手でレベルを設定してしまっているのではないでしょうか。そこはエンコーダーに任せるべきです。まともなエンコーダーであれば、無指定であればレベルを逆算して設定してくれるはずです。
まとめ
- Mac/PCでは再生できるのにスマフォやタブレットで再生できなかったら、レベルを調べてみよう
- 過剰レベルだとしたら、上のスクリプトなどでレベルを書き換えて試してみよう
- 本来フルHD(1080p)でもHigh@4.1、HD(720p)でもMain@3.1でも充分なはず。5.1って4K2K用ですよ?
- 再エンコードは最後の武器
- 視聴者にそうさせないためにも、エンコーダー諸氏は適切なレベルの設定を!
- 必要な発電所が減ったりして。
Dan the HD Blogger
このブログにコメントするにはログインが必要です。
さんログアウト
この記事には許可ユーザしかコメントができません。