Rubyで動画を造ろう

2014/02/06

実験のために大量の単純な動画が必要になった。Flashなどで一つ一つ丁寧に作るという手はもちろんあった。今考えてみればそれほど時間はかからなかったかも知れないが、最近はもっぱらプログラミングに没頭する日々が多いせいかそういう単純労働をやる気になれない。やれやれ。どうしよう。多少恥ずかしい気分に襲われた。昔、僕ってMaxの名人と言われたことがなかったっけ?MaxとJitterなら出来ると言えば出来る。Maxを使いたいかというと、ふむ、まあ、特に使いたいと思わないのが本音だ。コードを書きたい。いや、コードを書くのが今の自分にとって自然なんだ。

ということで、Rubyでモーショングラッフィクス的な動画が作れないかと挑戦してみた。

この挑戦にとりあえず必要なツールは2つ。まず、描画はRCairoで行う。RCairoはCairoライブラリーのRubyバインディングだ。CairoはIllustratorなどのようにベクトル・グラフィックが描けるかなりパワフルなライブラリーだが、Rubyist Magazineにて日本語の紹介記事が読める。RCairoを使えば、静止画が簡単に書き出せるが動画は無理だから、RCairoで描いた絵をなんとか動画に変換する必要がある。いろいろ試した結果、結局短い動画ならフレームを1つ1つ画像ファイルに出力し、FFmpegでその画像たちを動画に仕上げるという戦略を選んだ。一見面倒な手法に見えるかも知れない。でも意外と楽で、画像を書き出した後、FFmpegでいろいろと圧縮設定を変えたりして動画を手軽に書き直すことができる。

では、まずFFmpegを入手する。便利なツールだからこんなプロジェクト以外にも役立つ。入手方法はいろいろあるが、OSXならHomebrewを使った方がおすすめ。

Homebrewそのもののインストール。ターミナルで以下のコマンドを実行する:

ruby -e "$(curl -fsSL https://raw.github.com/Homebrew/homebrew/go/install)"

そしてHomebrewの初期処理を行う:

brew doctor

FFmpegをインストールする:

brew install ffmpeg

最後にRCairoもインストールする:

gem install cairo

それで下準備ができた。早速コードを書こう。とりあえず簡単な絵の画像を書き出してみよう。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
require 'cairo'
 
width = 1280
height = 720
pixel_format = Cairo::FORMAT_ARGB32
 
surface = Cairo::ImageSurface.new(pixel_format, width, height)
context = Cairo::Context.new(surface)
 
context.set_source_rgb(0,0.1,0.333)
context.rectangle(0,0,width,height)
context.fill()
 
surface.write_to_png("test.png")

上記のスクリプトを実行すれば… おおおおお!こんな奇麗が画像が出来上がった。

test

すばらしい。すばらしい。でも大したことはやっていない。Cairoで描画する前にサーフェイス(面)とコンテキストが必要。絵画で例えるとサーフェイスがキャンバスでコンテキストが筆だ。基本的にコンテキストを通して描画を行う。行7でサーフェイスを作る。その際、ピクセルのフォーマットと画像の幅と高さを指定する。ここで使うピクセルフォーマットは32ビットのRGBA(各チャンネルは8ビット)。

次はいよいよ描画だ。Contextのset_source_rgbメソッドで色を指定する。アルファチャンネルを使用するならset_source_rgbaを使う。ここは奇麗なブルーにする。次の行は長方形を描くように見える。しかし、長方形が描かれるのは次の行のcontext.fill()だ。そう。Illustratorを使っている人なら基礎中の基礎だが、ベクトル絵には「塗り」と「線」がある。英語では塗りのことを「fill」といい、線は「stroke」だ。つまり、ここで長方形を塗るという指示を出している。最後にサーフェイスのwrite_to_pngメソッドでPNGファイルを出力する。

では、何かを動かそう。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
require 'cairo'
 
width = 1280
height = 720
pixel_format = Cairo::FORMAT_ARGB32
 
surface = Cairo::ImageSurface.new(pixel_format, width, height)
context = Cairo::Context.new(surface)
 
15.times do |frame_no|
	y = height * 0.5 + height * 0.4 * Math::sin(2 * Math::PI * frame_no.to_f / 15.0)
 
	context.set_source_rgb(0,0.1,0.333)
	context.rectangle(0,0,width,height)
	context.fill()
 
	context.set_source_rgb(1,1,1)
	context.arc(width * 0.5, y, 35, 0, 2 * Math::PI)
	context.fill()
 
	Dir.mkdir("cache") unless File.exists?("cache")
	surface.write_to_png("cache/img#{frame_no}.png")
end

ちょっと長くなったが、最初のプログラムと大して変わったことはやっていない。大きな違いは1枚ではなく15枚もの画像を出力していることだ。そして、下記のコードで白い正円を描いている。

context.set_source_rgb(1,1,1)
context.arc(width * 0.5, y, 35, 0, 2 * Math::PI)
context.fill()

context.arcで正円を描く場合、x座標、y座標、半径を渡してからさらに弧の開始角度と終了角度が必要。円なら、0から2πにする。y座標はサイン派に乗って上下する。

y = height * 0.5 + height * 0.4 * Math::sin(2 * Math::PI * frame_no.to_f / 15.0)

「cache」フォルダーがなければ作ってから15枚の画像をそこに保存する。

Dir.mkdir("cache") unless File.exists?("cache")
surface.write_to_png("cache/img#{frame_no}.png")

後一歩。

FFmpegを使えば、その画像から動画が簡単に作れる。一旦Rubyをやめてターミナルに戻る。

ffmpeg -r 29.97 -i cache/img%d.png -vcodec mpeg4 -b:v 2M ball.mp4

「cache」フォルダーにあるimg<フレーム番号>.pngという形式のファイル名を持つ画像を入力にする。しかし、画像にはフレームレートがないので、読み込み前に「-r 29.97」でフレームレートを指定する。出力のフォーマットを「mpeg4」にして、「-b:v 2M」でビットレートを2 Mbpsにして「ball.mp4」に動画を保存する。こんな感じになる(ブラウザーによって再生できない場合がある):

いいじゃないか。でもターミナルに戻るのはやはり面倒だ。運良く、Rubyで上記のコマンドが簡単に実行できる。おまけに、途中に生成したファイルを削除することもできる。でも冒頭に書いた通り、残すとターミナルで圧縮設定を変えて動画を書き直すことができる。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
require 'cairo'
 
width = 1280
height = 720
pixel_format = Cairo::FORMAT_ARGB32
 
surface = Cairo::ImageSurface.new(pixel_format, width, height)
context = Cairo::Context.new(surface)
 
15.times do |frame_no|
	y = height * 0.5 + height * 0.4 * Math::sin(2 * Math::PI * frame_no.to_f / 15.0)
 
	context.set_source_rgb(0,0.1,0.333)
	context.rectangle(0,0,width,height)
	context.fill()
 
	context.set_source_rgb(1,1,1)
	context.arc(width * 0.5, y, 35, 0, 2 * Math::PI)
	context.fill()
 
	Dir.mkdir("cache") unless File.exists?("cache")
	surface.write_to_png("cache/img#{frame_no}.png")
end
 
`ffmpeg -r 29.97 -i cache/img%d.png -vcodec mpeg4 -b:v 2M ball.mp4`
`rm -rf cache`

究極につまらない動画だが、同じ方法で究極に格好いいジェネレーティブ・アートも造れるので、一度試してみてください。

IAMAS DSPコースプロジェクト展「ぐらぐら」

2010/03/22

Shinobu Toma ? Ghost in the Space

Kazuomi Eshima ? Remind

Kei Shiratori ? twist suburbia

Daichi Misawa ? Skies

Leo Kikuchi ? Landscape in my Arms

Kaori Takemoto ? Hunter-gatherer Colorist

Kanna Komaki ? Utopian Babble

Jane Rigler − IAMASレクチャー

2009/11/30

フルート奏者と作曲家のJane Rigler氏が先週の金曜日にIAMASでレクチャーとパフォーマンスを行いました。彼女はソロモン諸島などの民族音楽がどういうふうに自身の作曲と演奏法に影響を及ぼしたかについて話を聞かせて下さいました。また、ライブ・パフォーマンスで使用するMaxパッチを見せて頂きました。最後に身体障害や認知障害を抱えている子供が音楽演奏を楽しめるシステム、「Music Cre8tor」を紹介しました。

Jane and I, providing the Japanese translation
リグラー氏と通訳中の私

DSC_0015-small

写真撮影:河村陽介

動画の可聴化@慶應義塾大学Open Research Forum 2009

2009/11/25

「PictureSynth」以外にも、今年のORFで私が所属している研究室「サイバーサウンドプロジェクト」のブースで、動画の可聴化についての展示もさせて頂きました。この研究について既に紹介ページを作りましたので、興味がある方はこちらをご覧になってください。

PictureSynth@慶應義塾大学SFC Open Research Forum 2009

2009年11月23・24日に六本木ヒルズのアカデミーヒルズ40で開催された「慶應義塾大学SFC Open Research Forum 2009」が無事に閉幕しました。

私は、湘南藤沢学会のコーナーで、最新のプロジェクトの「PictureSynth」を披露しました。「PictureSynth」とは、写真と音楽を融合した作品です。最近、Brian Enoの「Bloom」や「Trope」で話題になっているジェネレーティブ・ミュージックのiPhoneアプリと似ているプロジェクトですが、「PictureSynth」では、タッチなどによるユーザー・インタラクションではなく、体験者が写真を撮る事によって音楽が変わる仕組みになっています。例えば、リズミカルな雰囲気にしたい時に、整列された模様を写します。

PhotoSynthKeyboard

ぼやけた写真を撮れば、音楽がそれに合わせてよりアンビエントな曲に変身します。ベーズになる曲は予め作曲家(私)に用意されていますので、写真ごとに全く新しい曲が生まれるというよりも、既存の曲の一つのバリエーションが生成されます。ジャズの様に、作曲家が曲の骨組みを決めて、演奏家が即興で無数の異なるバージョンを実現させるに近い訳です。

写真で音楽を作る事はいうまでも無く非常に恣意的な行為ですが、その方法を応用した理由がちゃんとあります。曲の決められていない部分を偶然に委ねるより、自然ならではの秩序された複雑さに委ねた方が豊富な種類のバリエーションを生み出します。そして、操作する人間が音楽の特徴と写真の特徴の関連性を認識する事ができますから、面白い音楽が出たら、また同じような写真を撮ってその体験を再現しようという楽しみもあります。

今回のデモで、時にブルースっぽい、時にインドっぽい曲を用意しました。以下のトラックは23日の夕方に特に気に入ったパターンが出た時に録音しました。

[soundcloud]http://soundcloud.com/jmpelletier/photosynth-orf2009[/soundcloud]

Landschaft 1.0

2009/08/18

Landschaft1_0

この作品は梅雨明けのニセ音風景だが、使用した音の全ては職場付近の小川の動画から生成された。

[audio: Landschaft1_0.mp3]

IAMASオープンハウス 2009

2009/08/01

International Computer Music Conference 2009

2009/07/24

2009年8月16-21日 マギル大学、モントリオール(カナダ)

「Perceptually Motivated Sonification of Moving Images」という論文を発表する予定。動画の可聴化についての論文ですので音と動画のサンプルも体験できる。

ICMC 2009の公式サイト

OpenCV and Computer Vision in Art Workshop

2009年4月28日 ソンシル大学、ソウル(韓国)

4時間程のワークショップで、画像解析が芸術に於いてどういう風に利用されてきたか、歴史的な観点を紹介した後にOpenCVライブラリーの基礎的な使い方に移った。

Soongsil2009

このワークショップは、IAMASのDSPコースとソンシル大学のBK21 Media Divisionが共催となったHome Partyというイベントの催しだった。

Les Journ?es de l’Infomatique Musicale 2009 (JIM ’09)

2009年4月1-3日 Phelma、グルノーブル(フランス)

JIMはフランス・コンピュータ・音楽協会(AFIM)が毎年指揮する会議で、2009年にグルノーブルにある研究所、ACROEによって開催された。 動画の可聴化についての論文発表と口頭発表を行った。

JIM2009-Minatec

会議の公式サイト