さくらのVPSで動画を楽しむ – ffmpeg トランスコード ストリーミング ts h.264 x264 変換

 レンタルサーバを使って動画を楽しむ話。
 さくらのVPSの処理能力の高さは各所で言われているとおりで、今回は、このパフォーマンスを動画処理に活用してみた。

 自宅の録画サーバはAMD E-350プロセッサ(2コア1.6GHz)で、PLEX PX-W3PEを挿して、地上2ch・衛星2chの同時録画が出来る静音マシンにしている。 RecTaskを使って録画しているのでファイル形式はTSだ。
 TSファイルは、基本的にMPEG2ビデオとAACオーディオ(場合によってはAC3)のタイムストリームで、地上波なら1時間7GB程度の大きなファイルだ。 スマホなどで見ようとすると32GBのmicroSDHCを使っても4時間少々しか入らず、入れ替えが面倒なので、これをコンパクトに圧縮(トランスコード)して保存活用するのがスタンダード。
 しかし、TSの直録画をしている分にはE-350でもこなせるが、トランスコードしようとなると非力すぎで、Core i7等のハイパフォーマンスPCが欲しくなってくる訳だが、この作業をさくらのVPSに任せてしまおうと画策したわけだ。

 基本的な流れ。

  • 1,録画サーバから1日1回、レンタルサーバにTSファイルをFTPで自動アップロードする(タスクスケジューラ設定でOK)
  • 2,レンタルサーバでアップロードディレクトリを監視して変換処理を行う(cronバッチシェルffmpeg
  • 3,トランスコードしたファイルをhttpディレクトリに移動する。 また、アップロードファイルを削除する。

1:
録画サーバはWindowsHomeServer2011なのでPowerShellで簡単作成。
事前に

Set-ExecutionPolicy RemoteSigned

して、シェル実行可能に設定(PowerShellの実行権限設定について参考:Paddle Log Point

PSバッチを作成(c:\shells\tsup.ps1)

echo “open ホスト名rnユーザ名rnパスワードrnbinrn" | Out-File d:\uploadcmd.txt -encoding Default
foreach($file in ls d:\ts\*.ts){
echo "put $file" | Out-File d:\uploadcmd.txt -encoding Default -append
}
echo "quit" | Out-File d:\uploadcmd.txt -encoding Default -append
ftp -s:d:\uploadcmd.txt
mv d:\ts\*.ts d:\ts_backup\

d:¥tsディレクトリ中の.tsファイルを全てアップロードするftpコマンドリストを作って、ftpコマンドに食べさせて、処理済みtsファイルをバックアップディレクトリに移動するというPSスクリプトだ。
-encoding Defaultにしないと、文字コードがUNICODEになるが、ftpコマンドのコマンドリストはローカルエンコーディングでないとエラーになるので指定している(リダイレクトもUNICODEになるからOut-File使用)
このPSを録画のない時間帯にタスクマネージャで回せばOK

2:
変換ツールを導入する

wget ftp://ftp.videolan.org/pub/x264/snapshots/last_x264.tar.bz2
bzip2 -d last_x264.tar.bz2
tar xf last_x264.tar
cd x264-snapshot-*
./configure
make
make install

wget http://sourceforge.net/projects/faac/files/faac-src/faac-1.28/faac-1.28.tar.gz/download
tar xzf faac-1.28.tar.gz
cd faac-1.28
./configure
make
make install

wget http://ffmpeg.org/releases/ffmpeg-0.9.1.tar.gz
tar xzf ffmpeg-0.9.1.tar.gz
cd ffmpeg-0.9.1
./configure --enable-libfaac --enable-pthreads --enable-libx264 --enable-gpl
make
make install

x264、faacをビルドしてから、ffmpegをビルドする(ffmpegで前2個のライブラリを使うのでffmpegは必ず最後。 他にも色々なライブラリを導入することも出来るが、今回は最低限のマルチスレッドモジュールとAACとX264エンコーダだけ追加している)

後は、必要なプリセットやパラメータを決めてcronでバッチシェルを回せばよい。
私の場合は、中間シェルを作成。

h264encode.sh

filename=$1
posi=$*
shift
expr $posi -1
ffmpeg -y -i $filename -vn -f wav -acodec pcm_s16le -shortest $filename.wav
ffmpeg -y -pre /root/high.preset -i $filename -i $filename.wav -map 0:0 -map 1:0 -f mp4 -vcodec libx264 -crf 20 -level 41 -r 30000/1001 -aspect 16:9 -s 1280x720 -acodec libfaac -ac 2 -ar 48000 -ab 128k -threads 4 -vsync 1 -async 1 -shortest -deinterlace -top -1 $* ../out/$filename.mp4
ffmpeg -y -i $filename -i $filename.wav -map 0:0 -map 1:0 -f mp4 -vcodec libx264 -vprofile baseline -level 30 -crf 22 -r 30000/1001 -aspect 16:9 -s 400x240 -acodec libfaac -ac 2 -ar 48000 -ab 128k -threads 4 -vsync 1 -async 1 -shortest -deinterlace -top -1 $* ../out/$filename-walkman.mp4
rm $filename.wav

high.preset

vprofile=high
coder=1
level=41
deblockalpha=0
deblockbeta=0

qmin=7
qmax=28
qdiff=4
qcomp=0.8
i_qfactor=0.71
keyint_min=25
sc_threshold=40

me_method=umh
refs=10
subq=6
trellis=2
bf=16
me_range=24
g=250
b_strategy=2

partitions=+parti4x4+parti8x8+partp4x4+partp8x8+partb8x8
cmp=+chroma

flags=+loop
flags2=+bpyramid+mixed_refs+wpred+dct8x8+fastpskip

directpred=3
wpredp=2
rc_lookahead=60
rc_eq='blurCplx^(1-qComp)'
bidir_refine=1

こんな感じの設定をしている。

で、メインシェル↓をcronで回している。

cd /home/transcode/up
files="/home/transcode/up/*.ts"
for filepath in ${files}
do
sh /root/h264encode.sh ${filepath}
mv ${filepath} /home/transcoder/finished_ts/
done
echo "open HTTPサーバアドレス" > /root/ftpcmd
echo "user ユーザ名 パスワード" >> /root/ftpcmd
echo "bin" >> /root/ftpcmd
files="/home/transcode/out/*.mp4"
for filepath in ${files}
do
filename=
echo ${filepath} | sed -e “s/\/.*\///g”
echo $filename
ext=
echo ${filename} | sed -e “s/^.*[\.\/]//g”
file=
echo ${filename} | sed -e “s/\.[^.]*$//g”
filename=
echo ${file} | nkf -w80MQ | sed -e “s/=$//” | tr -d ‘\n’ | tr = %`
filename=”${filename}.${ext}”
echo “put \”${filepath}\” \”${filename}\”” >> /root/ftpcmd
done
ftp -n -i < /root/ftpcmd cd /home/transcode/out for filepath in ${files} do mv ${filepath} /home/transcode/finished_mp4/ done

サーバの構成
/home/transcode/up #録画サーバからTSをアップするディレクトリ
/home/transcode/out #エンコードしたMP4が一時的に置かれるディレクトリ
/home/transcode/finished_ts #エンコード済みのTSが保管されるディレクトリ
/home/transcode/finished_mp4 #エンコード済みのMP4が保管されるディレクトリ
 これで、/home/transcode/finished_mp4以下にファイルネーム.mp4のHDファイルとファイルネーム-walkman.mp4のWalkmanA860用ファイルの2個が出来ている。
 また、別のHTTPサーバにもFTPでアップロードしている(アップロード時にファイル名をurlencodeしている)ので、レンタルサーバの動画データは定期的に消す(tmpwatchでも良い)

 最初にwavに分離してエンコードしているのは、これをしないと音ズレが発生するため(おそらく、TSファイルのストリームの時間データが狂っていて、直接TSからストリームを取り出すと時間を合わせようとして逆に狂うようで、一度wavにはき出しておくと割と音ズレを小さくできる)

 後は、Androidケータイのブラウザでファイルをタップするとプレイヤー選択が出てくるから、好きなプレイヤー(私はMeridian使用)を選べばダウンロードしないで再生できる(HTTPのRangeヘッダーを使うことでファイルの任意の場所を転送できるため、全部をダウンロードしないでも任意の位置から再生できる) PCのChromeとかでも少しバッファリングするだけで再生できる。
 ISW11Fでは、今回のHD設定ファイル(1280×720 High@4.1 3Mbps程度)でもハードウェアデコードでストリーミング再生可能。
 ただし、3Gだとすぐにパケット規制上限(3日300万パケットが規制ラインだけど、30分再生で400万パケットくらい流れる)がかかるので、実質的にはWiFi・WiMaxで繋いでいるとき限定の使い方。 また、3G回線時のスループット的には、Walkmanプロファイル(400×240 Baseline@3.0 400Kbps)の方がなめらかだろう。

 さくらのVPS 4GBはhome以下の容量が100GBだが、完成品が1時間1GB位、原料が1時間7GB位消費するのと、他の用途も兼ねていて容量を使いたくないので、完成品ファイルは配信用の別のサーバに転送している。
 配信用(と言っても認証をかけて自分専用にしている)サーバは、私の場合、WAPPYのミドルプランを利用している。
容量150GBで転送量無制限、月額700円程度で済む格安レンタルサーバ。
エンコード済みファイルなら150時間分入れておけるのでソコソコのライブラリとして使えてオススメ。
しかし、普通の共用サーバなので、プログラムなどを自由に動かしたい場合にはSaasesのOsukini ST VPSが、月額980円で100GBの容量があって良いかもしれない。

 HTTPで配信する場合、mimeタイプ設定(root権限付きサーバなら/etc/mime.typesにvideo/mp4 mp4追記、共用サーバなら.htaccessにAddType video/mp4 mp4を記述)を忘れてはいけない。

※flags2のオプションが新しいバージョンのffmpegで動かないらしい(参照:お気に入りの動画を携帯で見よう 対応パッチが置いてあるので利用させて頂く)

(1107)


カテゴリー: LAMP[Linux, Apache, MySQL, PHP]   パーマリンク

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です