ArchLinuxでVapourSynth

VapourSynthについての説明は省略
http://www.vapoursynth.com/

python3系で動く事を想定しているのならLinux環境でも動かせるのではないか?

というわけで自宅PCに入ってるArchLinuxで試してみた

  • 注意事項

 この記事はArchLinuxでの利用を想定してます
 Arch以外のディストリだと細かい部分で作法が違う為動かない可能性もあります
 本記事は2013/2/2の時点での情報です
 VapourSynthはまだまだ開発途上の為この記事が古く使用出来なくなる可能性があります


まずはVapourSynthのインストールから
あっさりとAURで発見 https://aur.archlinux.org/packages/vapoursynth

インストール後にVersionを確かめてみる
pythonを対話型で起動して次のように入力

>>> import vapoursynth as vs;core = vs.Core();print(core.version())
VapourSynth Video Processing Library
Copyright (c) 2012 Fredrik Mellbin
Core r17
API r3

こんな感じで表示されればインストール成功してると思います

で、ここからが本番

公式ページのサンプルをみてみる
http://www.vapoursynth.com/doc/gettingstarted.html
ffms2を利用して映像を読み込んでいるようだ

VapourSynthの開発者Fredric Mellbin氏はffms2の開発者でもあり
ffms2にはVapourSynthで利用するためのコードがすでにマージされています

サンプル通り試しにffms2を使用して映像を取り込んでみる事に
おなじみAURにあったのでインストール
https://aur.archlinux.org/packages/ffmpegsource2-svn/

注意事項として、現在(2013/2/2時点)公式で提供されているffms-2.17だと
まだVapourSynth用のコードがマージされていない古いverのため
最新のコードをsvnから取得してインストールするようにしましょう

ffms2をインストールしたら
正常にインストールされているかどうかを確認

#!/usr/bin/env python
# -*- coding: utf-8 -*-

import vapoursynth as vs
core = vs.Core()
core.std.LoadPlugin(path='/usr/lib/libffms2.so') #ここのPATHは人によって違うかも
print(core.list_functions())

利用可能な関数一覧を表示してくれるコード書いて保存して実行(名前適当)

$ python vs_functions.py
FFmpegSource 2 for VapourSynth
	namespace:	ffms2
	identifier:	com.vapoursynth.ffms2
		GetLogLevel()
		Index(source:data; cachefile:data:opt; indexmask:int:opt; dumpmask:int:opt; audiofile:data:opt; errorhandling:int:opt; overwrite:int:opt; demuxer:data:opt;)
		SetLogLevel(level:int;)
		Source(source:data; track:int:opt; cache:int:opt; cachefile:data:opt; fpsnum:int:opt; fpsden:int:opt; threads:int:opt; timecodes:data:opt; seekmode:int:opt; width:int:opt; height:int:opt; resizer:data:opt; format:int:opt;)
		Version()
VapourSynth Resize
	namespace:	resize
	identifier:	com.vapoursynth.resize
		Bicubic(clip:clip; width:int:opt; height:int:opt; format:int:opt; yuvrange:int:opt;)
		Bilinear(clip:clip; width:int:opt; height:int:opt; format:int:opt; yuvrange:int:opt;)
		Gauss(clip:clip; width:int:opt; height:int:opt; format:int:opt; yuvrange:int:opt;)
		Lanczos(clip:clip; width:int:opt; height:int:opt; format:int:opt; yuvrange:int:opt;)
		Point(clip:clip; width:int:opt; height:int:opt; format:int:opt; yuvrange:int:opt;)
		Sinc(clip:clip; width:int:opt; height:int:opt; format:int:opt; yuvrange:int:opt;)
		Spline(clip:clip; width:int:opt; height:int:opt; format:int:opt; yuvrange:int:opt;)
VapourSynth Core Functions
	namespace:	std
	identifier:	com.vapoursynth.std
		AddBorders(clip:clip; left:int:opt; right:int:opt; top:int:opt; bottom:int:opt; color:float[]:opt;)
		AssumeFPS(clip:clip; src:clip:opt; fpsnum:int:opt; fpsden:int:opt;)
		BlankClip(clip:clip:opt; width:int:opt; height:int:opt; format:int:opt; length:int:opt; fpsnum:int:opt; fpsden:int:opt; color:float[]:opt;)
		Cache(clip:clip; size:int:opt; fixed:int:opt;)
		ClipToProp(clip:clip; mclip:clip; prop:data:opt;)
		CropAbs(clip:clip; width:int; height:int; x:int:opt:link; y:int:opt:link;)
		CropRel(clip:clip; left:int:opt; right:int:opt; top:int:opt; bottom:int:opt;)
		DoubleWeave(clip:clip; tff:int;)
		Expr(clips:clip[]; expr:data[]; format:int:opt;)
		FlipHorizontal(clip:clip;)
		FlipVertical(clip:clip;)
		Interleave(clips:clip[]; extend:int:opt; mismatch:int:opt;)
		LoadPlugin(path:data; forcens:data:opt;)
		Loop(clip:clip; times:int:opt;)
		Lut(clip:clip; lut:int[]; planes:int[];)
		Lut2(clips:clip[]; lut:int[]; planes:int[];)
		MaskedMerge(clips:clip[]; mask:clip; planes:int[]:opt; first_plane:int:opt;)
		Merge(clips:clip[]; weight:float[]:opt;)
		ModifyFrame(clips:clip[]; selector:func;)
		PEMVerifier(clip:clip; upper:int[]:opt; lower:int[]:opt;)
		PlaneAverage(clip:clip; plane:int; prop:data:opt;)
		PlaneDifference(clips:clip[]; plane:int; prop:data:opt;)
		PropToClip(clip:clip; prop:data:opt;)
		Reverse(clip:clip;)
		SelectClip(clips:clip[]; src:clip[]; selector:func;)
		SelectEvery(clip:clip; cycle:int; offsets:int[];)
		SeparateFields(clip:clip; tff:int;)
		ShufflePlanes(clips:clip[]; planes:int[]; format:int;)
		Splice(clips:clip[]; mismatch:int:opt;)
		StackHorizontal(clips:clip[];)
		StackVertical(clips:clip[];)
		Transpose(clip:clip;)
		Trim(clip:clip; first:int:opt; last:int:opt; length:int:opt;)
		Turn180(clip:clip;)

上記のようにFFmpegSource 2 for VapourSynth〜の部分が表示されていれば正常にimportされています
されなかった場合はimportに失敗しているので、ライブラリのPATHが間違っている or ffms2自体が正常にインストールされていない等の可能性があります

では実際に映像を読み込んでみます

#!/usr/bin/env python
# -*- coding: utf-8 -*-

import vapoursynth as vs
import sys

core = vs.Core()
core.std.LoadPlugin(path='/usr/lib/libffms2.so')
ret = core.ffms2.Source(source='hoge.mp4')
ret.output(sys.stdout, y4m=True)

サンプルと同じようにコードを書いて保存
後はこれをx264に渡せば完了ダァ!


と思っていた時期もありました


そのまま渡すとArchがパッケージで提供しているx264ではGPAC(mp4 output)が有効になっていないためエラーになります
rawとかなら出力できるかもしれません(未確認)

せっかくなのでmp4で出力出来るようにGPAC(MP4Box)をインストールします
ArchではGPACパッケージが提供されているのでそこから
https://www.archlinux.org/packages/community/x86_64/gpac

インストールしたらx264をビルドしなおします

自分でソースコードgitから引っ張ってきてやってもいいですが
せっかくのArchなのでx264のPKGBUILDからインストール
パッケージで入れた方が管理も楽ですしね

PKGBUILDをそのままmakepkgしてインストールすればGPACが有効になってると思います

GPACが有効になっている事を確認

$ x264 --help
Outfile type is selected by filename:
 .264 -> Raw bytestream
 .mkv -> Matroska
 .flv -> Flash Video
 .mp4 -> MP4 if compiled with GPAC support (yes)

上記のようにmp4の部分が(yes)になってれば有効になっています

もし有効になっていなければ、手動でMP4Boxをインストールする必要があります
やり方については検索すれば山ほど詳しく出てくるので割愛します

ここまでこれば後はイカのように

$ python vs_encode.py | x264 --demuxer y4m -o sample.mp4 -

実行してみてsample.mp4ファイルが出来ていれば完成です

ここではmp4をサンプルとして読み込みましたが
ffmpegsourceが対応してる動画形式なら大抵読み込めると思います
(mpg,mkv,wmv…etc)

現時点でVapourSynth自身に音声処理はまだ未実装のようなので
今までの手順でやっても映像しか出力されません

音声は今のところ(ffmpeg|avconv)とかで抜き取って後でmuxさせるしかないのかな?

この先VapourSynthのnativeプラグインも増えていくと予想してますし
今後も期待してます