ニコニコ動画の H.264 ビデオをなるべく高品質で iPod で見たい
「ゆーすけべー日記: Plaggerでニコニコ動画を一括ダウンロード&変換 Podcast を生成して iPod touch で見る」を前提として。
方針
- なるべく高品質で再変換する。
環境の違い
書いたもの
yaml(の一部):
- module: Filter::FLVInfo rule: - expression: $args->{entry}->enclosure->type eq 'video/x-flv' - expression: "not -e File::Spec->catfile('/path/to/output', $args->{entry}->enclosure->filename . '.mp4')" - module: Filter::FFmpeg rule: expression: $args->{entry}->enclosure->type eq 'video/mp4' config: command: /opt/local/bin/ffmpeg ext: mp4 dir: /path/to/output encoding: utf8 noresize: 1 extra_options: -coder 0 -level 13 -flags loop -deblockalpha 2 -qmin 21 -sameq -r 29.97 options: video_codec: libx264 audio_codec: copy
「noresize: 1」は私が勝手につけました。yaml からではサイズの指定を無効にできない(指定しないとデフォルトのサイズが設定される)ので、Filter::FFmpeg にちょっと手を加えます(sオプションを削除しているだけ)。
*************** *** 72,77 **** --- 72,90 ---- $ff->output_options($output_options); } + # noresize feature. + if ($self->conf->{noresize}) { + $context->log( info => 'no resize option detected.' ); + my @opt = @{ $ff->options }; + for ( my $i = 0; $i < @opt; $i++ ) { + if ( $opt[$i] eq "-s" ) { + splice @opt, $i, 2; + $ff->options(@opt); + last; + } + } + } + unless( -e $output_file ){ $context->log( info => 'Converting ' . $enclosure->filename . ' ...' ); my $result = $ff->exec();
extra_options の「-coder 0 -level 13」は iPod に転送するのに必要だそうです。
調べたところ、iPodビデオはベースラインプロファイルとかいう形式でないとだめらしく、その形式にするオプションが下記の2つらしい。
http://d.hatena.ne.jp/shimibow/20060914/1158237089
-coder 0 Baselineプロファイルに切り替え(-coder 0:cabac不使用 -coder 1:cabac使用) -vlevel 13 Baselineプロファイル中のサポートレベル
「-flags loop -deblockalpha 2」はブロックノイズを減らせるっぽいです。
-deblockalpha
最新ffmpeg/高度なオプション - MobileHackerz Knowledgebase Wiki
x264 の in-loop デブロックフィルタの強度パラメータ [-6〜6] の範囲で指定。
-flags loop でデブロックフィルタを ON にした場合のみ意味がある。-6:デブロック弱 <-> +6:デブロック強。 細部がつぶれすぎていると思ったら値を下げ、低ビットレート時のブロックノイズが気になるなら値を上げる。 十分にビットレートを割り当ててる場合は、そもそも -flags loop を指定せずでブロックフィルタを切ってしまうのも手。
「-qmin 21」ですが、これが無いと
[libx264 @ 0x1416710]OVERFLOW levelcode=4377
が大量に出て、動画の一部がグレーになる現象が起こりました(かなりハマった)。
qmin は以下を参考にしました。
-qmin
最新ffmpeg/高度なオプション - MobileHackerz Knowledgebase Wiki
q値の最小値 (デフォルト=2)
x264 ではデフォルトの qmin=2 は小さ過ぎる。少なくとも 10 以上にした方がよい。 qminが小さすぎるとソースによっては黒いバックなどの動きが少ないシーンでグレーの 靄がかかったようなフレーム ("Gray Fogged Frame") が出来てしまうことがある。
「-sameq」は元のビデオと同じクオリティで変換するオプションです。が、やはり劣化するので、ファイルサイズを気にしなければ、ビットレートで大きい値を設定する方が良いかもしれません。
-sameq
最新ffmpeg/ビデオオプション - MobileHackerz Knowledgebase Wiki
ソースと同じクオリティで変換する。
-b, -bt, -qmax, -qmin, -qcomp, -qdiff, -maxrate, -bufsize 等のビットレート指定/品質コントロール系オプションは無視される
音に関しては「audio_codec: copy」としているので劣化は無いと思われます*1。
あとダウンロード済みのビデオに対して毎回スリープが発生していたので、FetchNicoVideo.pm に手を入れて回避しました。かなり手抜き。
*************** *** 52,57 **** --- 52,102 ---- #get video_id my ($video_id) = $entry->link =~ m!www.nicovideo.jp/watch/(.*)!; + #set local path + my $filename = $self->conf->{id_as_filename} ? $video_id : $entry->title; + utf8::encode($filename); + if ( $self->conf->{filename_encode} ) { + Encode::from_to( $filename, "utf-8", $self->conf->{filename_encode} ); + } + + # ignore when the local file exists. + if ( -e File::Spec->catfile($self->conf->{dir}, $filename . ".mp4")) { + $context->log(info => "Exist File: $video_id"); + my $path = File::Spec->catfile($self->conf->{dir}, $filename . ".mp4"); + my $enclosure = Plagger::Enclosure->new; + $enclosure->filename($filename); + $enclosure->local_path($path); # set to be used in later plugins + $enclosure->length(-s $path); + $enclosure->media_type("video/mp4"); + $enclosure->type(Plagger::Util::mime_type_of($path)); + $entry->add_enclosure($enclosure); + return; + } + if ( -e File::Spec->catfile($self->conf->{dir}, $filename . ".swf")) { + $context->log(info => "Exist File: $video_id"); + my $path = File::Spec->catfile($self->conf->{dir}, $filename . ".swf"); + my $enclosure = Plagger::Enclosure->new; + $enclosure->filename($filename); + $enclosure->local_path($path); # set to be used in later plugins + $enclosure->length(-s $path); + $enclosure->media_type("application/x-shockwave-flash"); + $enclosure->type(Plagger::Util::mime_type_of($path)); + $entry->add_enclosure($enclosure); + return; + } + if ( -e File::Spec->catfile($self->conf->{dir}, $filename . ".flv")) { + $context->log(info => "Exist File: $video_id"); + my $path = File::Spec->catfile($self->conf->{dir}, $filename . ".flv"); + my $enclosure = Plagger::Enclosure->new; + $enclosure->filename($filename); + $enclosure->local_path($path); # set to be used in later plugins + $enclosure->length(-s $path); + $enclosure->media_type("video/x-flv"); + $enclosure->type(Plagger::Util::mime_type_of($path)); + $entry->add_enclosure($enclosure); + return; + } + #get flv url my $res = $ua->get("http://www.nicovideo.jp/api/getflv?v=$video_id"); my $q = CGI->new( $res->content ); *************** *** 67,79 **** $enclosure->url( URI->new($flv_url) ); $enclosure->media_type("video/x-flv"); - #set local path - my $filename = $self->conf->{id_as_filename} ? $video_id : $entry->title; - utf8::encode($filename); - if ( $self->conf->{filename_encode} ) { - Encode::from_to( $filename, "utf-8", $self->conf->{filename_encode} ); - } - $enclosure->url =~ m!^http://[^/]+(?:smilevideo|nicovideo)\.jp/smile\?(\w)=(?:[^.]+)\.\d+(?:low)?!; my %video_type_of = ( v => 'flv', --- 112,117 ----
extra_options に「-r 29.97」を追加。
http://www.nicovideo.jp/watch/sm2990910 が変換できてなかったので。
timebase not supported by mpeg 4 standard
Version: media-video/ffmpeg-0.4.9_p20060530 USE="aac imlib sdl truetype vorbis zlib -a52 -amr -debug -doc -dts -encode -ieee1394 -network -ogg -oss -test -theora -threads -v4l -x264 -xvid" 0 kB
Command: fmpeg -i 1.avi -f psp -r 29.970030 -b 768 -ar 24000 -ab 64 -s 320x240 M4V00001.MP4
Error: [mpeg4 @ 0x2ba7e3a0be70]timebase not supported by mpeg 4 standard Error while opening codec for output stream #0.0 - maybe incorrect parameters such as bit_rate, rate, width or height
Solution: I had to change -r 29.970030 to -r 29.97
Did you try -r 30000/1001? That should work.
Site Unavailable
追記
「-flags loop -deblockalpha 2」なんですが、なんか画面が白っぽくなっちゃいますね。外した方が良いかも。
お願い
よりよい方法があれば教えてください。
お願い2
port で ffmpeg のバージョンの下げる方法があれば教えてください。
*1:じゃあ「video_codec: copy」ではどうかというと、再生は開始されましたがやけに重たくてまともに再生されませんでした