c/fe

http://d.hatena.ne.jp/uzulla から移行しました。

mencoder+PHPで動画を回転する

ffmpegばっかり使ってるんだけど、ffmpegだと回転がサポートできないので。
エンコードオプションはかなり適当、しかしmencoderはオプション指定が謎すぎる。

<?
require_once 'rotateMedia.php';
class RotateMovie extends RotateMedia
{

    private $MENCODER_PATH = '/usr/local/bin/mencoder';
    private $TMP_DIR = '/tmp';
    private $MENCODER_OPT_ENC = ' -of lavf -oac mp3lame -lameopts abr:br=64 -ovc lavc -lavcopts vcodec=flv:vbitrate=512:mbd=2:mv0:trell:v4mv:cbp:last_pred=3 -fps 29.97 -srate 22050';

    private $MENCODER_OPT_ROT_90 = '-vf-add rotate -vf rotate=2';
    private $MENCODER_OPT_ROT_180 = '-vf-add flip,mirror';
    private $MENCODER_OPT_ROT_270 = '-vf-add rotate -vf rotate=1';

	public function __construct(){
	}

	public function rotate($fromPath, $toPath, $degree){
        if($degree != 0 && $degree < 360){

            $tmpPath = tempnam  ( $this->TMP_DIR  , 'rot'  ).".flv";

            $exec = $this->MENCODER_PATH." $fromPath -o $tmpPath ";

            if($degree == 90){
                $exec .= $this->MENCODER_OPT_ROT_90;

            }else if($degree == 180){
                $exec .= $this->MENCODER_OPT_ROT_180;

            }else if($degree == 270){
                $exec .= $this->MENCODER_OPT_ROT_270;

            }else{
                // mencoder can't rotate other than 90 180 270.
                return false;
            }


            $exec .= $this->MENCODER_OPT_ENC;
            //echo $exec;
            
            exec($exec, $last_line, $retval);

            if($retval != 0){
                // どうも返値は信用できない?
                @unlink($tmpPath);
                return false;
            }

            if(file_exists($tmpPath) && filesize($tmpPath)>0){
                // 失敗すると、大抵ファイルサイズが0になるか、そもそもファイルができない。
                @unlink($toPath);
                rename($tmpPath, $toPath );
                return true;
            }else{
                //maybe fail
                return false;
            }

        }else{
            return false;
        }
	}

}
?>

※親クラスのRotateMediaは角度を人語で指定できるInterfaceだけなので省略。

private $MENCODER_OPT_ROT_270 = '-vf-add rotate -vf rotate=1';
private $MENCODER_OPT_ROT_90 = '-vf-add rotate -vf rotate=2';

rotate に指定する数値は
http://www.wikihouse.com/htumenc/index.php?Man%2FVIDEO%20FILTERS%2Frotate
の通り。


180度回す、だけはちょっとややこしくて(本当はすっきりしたのがあるのかもしれないが)
private $MENCODER_OPT_ROT_180 = '-vf-add flip,mirror';
上下反転した上で、左右反転している。


…なんでrotate一発で180度回せない設計なのか、よくわからない。
っつか、なんで1=右90度、2=右180度, 3=右270度とかじゃなく、
0=右90度+左右反転、1=右90度、2=左90度、3=左90度+左右反転、なんて謎オプションなのか、悩む。



mencoderは多機能で色々できるので、ffmpegよりも今後はmencoderを使おうかなー。ffmpegはビルドがめんどくさすぎるし。