Kinect 勉強会 Vol.1 に参加してきました

RDDブログひさしぶりの小松です、

今日は、Kinect 勉強会に参加してきました

導入から丁寧に説明してもらえたので、だいぶ分かった気になりました

以下、自分のメモ。。
・最初のドライバはlibfreenect。賞金がついてオープンソースのドライバが開発された。
・今の主流はOpenNIのやつ。Macにも対応しているが、stableはwin/linux向けのもの。
・ C++/Python向けのバインディングが用意されている。
・深度画像と光学(RGB)画像が得られる。
・骨格トラッキングをすると、関節部分の座標と角度が取れる。
・primesense社のSDKというのも使えるらしい

・事例まとめ
http://www.openni.org/gallery
http://www.kinect-hacks.com/openni
・openFrameworks には、libfreenect / OpenNI のドライバが同梱されていてらくちん
・@hagino3000さんの発表スライドは、ハンドジェスチャーでページ送りしてた
・手が疲れるので途中でやめる
・画像処理はOpenCV使うとらくちん
・左右のカメラの視差で3D認識をしているんだと思っていたが、どうやら赤外線カメラで深度情報を取っているっぽい?
・@ndrugerさんの発表は、node.jpと、WebGLと、HMDを組み合わせてゲームを作る
・node.jsは、座標情報を右から左に流すだけのシンプルな物
・kinectからきた座標情報をTCPで送るコードも、OpenNIのサンプルコードに少し手を加えた程度の簡単なもの
・深度情報は、0-255の256段階、640×480の解像度
・深度は赤外線カメラで、映像はRGBカメラで撮影していて、カメラがついている位置が少し離れているためKinectに近づくと映像と、深度情報がずれる現象が起こる
・HMD楽しそうVR920 5万円ぐらいで、加速度センサ付きのHMDがかえるらしい。キネクト界隈でいろんな人が遊んでいるらしい。解像度はVGAぐらい

さて、あとは作るだけ!C++久しぶりに触ってみるのも、わくわくしますねー。

Music Boxel : Naked-eye 3D Display and Web Socket based multi user interaction

aircord社との協同プロジェクト Music Boxel のデモムービー(1分34秒)です。

Music Boxel from aircord on Vimeo.

関連記事
2011年1月17日 Music Boxel (裸眼3Dディスプレイ x WebSocketインターフェイス)
2011年2月7日 Music Boxel Prototype (Processing+PeasyCam)
2011年2月8日 Music Boxel@CreativeApplications.Net

Naked-eye 3D Display and Web Socket based multi user interaction.
Adding a voxel to make a trigger on roop timeline of virtual music box.

Display/Audio-Visual Program by aircord inc. made with : openFrameworks, SuperCollider
Server/Mobile Interface by Uniba Inc. made with : node.js, CSS3/HTML5

aircord.co.jp/​
aircord.co.jp/​labo
uniba.jp/​

Music Boxel@CreativeApplications.Net

CreativeApplications.Net 14879 February 7, 2011
Music Boxel [iPhone, iPad, openFrameworks]
http://www.creativeapplications.net/iphone/music-boxel-iphone-ipad/

取り上げていただきました!
ありがとございます!

Music Boxel Prototype (Processing+PeasyCam)

こんばんは〜

Processingでスケッチするのは、楽しいですね!的な話として今日は、Music Boxelのプロトタイプのご紹介です。

本物のMusic Boxelのリアルタイム・ヴィジュアルオーディオはaircord森氏によるopenFrameworks+SuperColliderのプログラムですが、ヴィジュアルの試作品はProcessingで書かれました。

開発中のMusic Boxelのヴィジュアル×オーディオを制作チーム内でイメージするために、「キューブ」が同心円状に4列になってぐるぐると周り、円周上の一定の角度(0度〜10度)にさしかかったときに「発光(発音)」しつつ「摩耗」する、というアイディアをProcessingでスケッチしました。

JavaApplet版はここに置いてあります。
Music Boxel Prototype (JavaApplet build with Processing)

Javaプラグインをブラウザに入れていない皆さまはこちらをどうぞ。 ↓ こんな感じです。
(動作中のJavaAppletをiPhoneでビデオ撮影したもの)

Processingのコードはこんな感じ。PeasyCamさえ入っていれば、手元のProcessingで動くと思います。
(PeasyCam、ありがとう!わたしのようなものぐさでも3Dでスケッチする気が起こります)

// 3Dカメラのコントロール用にpeasyを読み込んでいます。描画はOpenGL
import peasy.*;
import processing.opengl.*;

PeasyCam cam;

// キューブのサイズ初期値
float boxSize = 5;

// 4つの円周上に配置するキューブの数の初期値
int num = 4;
int num2 = 8;
int num3 = 4;
int num4 = 8;

// 4つの円の半径
float R = 5;
float R2 = 10;
float R3 = 15;
float R4 = 20;

// 4つの円の初期角度、回転スピード
float Rdiff = 0;
float Rspeed = 1;
float Rdiff2 = 0;
float Rspeed2 = 2;
float Rdiff3 = 0;
float Rspeed3 = 3;
float Rdiff4 = 0;
float Rspeed4 = 4;

void setup() {
  size(500,500,OPENGL);
  // 3Dカメラを作っています
  cam = new PeasyCam(this, 100);
  cam.setMinimumDistance(50);
  cam.setMaximumDistance(500);
}

void draw() {
  background(0);
  // 角度を加算。4つの円を回転させています
  Rdiff = Rdiff + Rspeed;
  Rdiff2 = Rdiff2 + Rspeed2;
  Rdiff3 = Rdiff3 + Rspeed3;
  Rdiff4 = Rdiff4 + Rspeed4;
  // 一番内側の円周上のキューブを描画
  for(int i=0; i<num; i=i+1) {
    // 現在の角度からキューブを配置する位置を決定しています
    pushMatrix();
    rotateZ(radians(360/num*i+Rdiff));
    translate(R,0,0);
    // "摩耗エリア(0〜10度)" にあるときに、キューブを "摩耗" させています。
    // また白い輪郭を表示しています
    if ((360/num*i+Rdiff)%360 < 10) {
      stroke(255);
      fill(255);
      boxSize = boxSize*0.9;
      box(boxSize*2);
      noFill();
      box(boxSize*3);
    } else {
      // "摩耗エリア" でないときは、通常の色で描画します
      stroke(255,0,0);
      fill(255,0,0);
    }
    // キューブを描画
    box(boxSize);
    popMatrix();
  }
  // 内側から二番目の円周上のキューブを描画
  for(int i=0; i<num2; i=i+1) {
    pushMatrix();
    rotateZ(radians(360/num2*i+Rdiff2));
    translate(R2,0,boxSize);
    if ((360/num2*i+Rdiff2)%360 < 10) {
      stroke(255);
      fill(255);
      boxSize = boxSize*0.9;
      box(boxSize*2);
      noFill();
      box(boxSize*3);
    } else {
      stroke(0,255,0);
      fill(0,255,0);
    }
    stroke(0,255,0);
    box(boxSize);
    popMatrix();
  }
  // 内側から三番目の円周上のキューブを描画
  for(int i=0; i<num3; i=i+1) {
    pushMatrix();
    rotateZ(radians(360/num3*i+Rdiff3));
    translate(R3,0,boxSize*2);
    if ((360/num3*i+Rdiff3)%360 < 10) {
      stroke(255);
      fill(255);
      boxSize = boxSize*0.9;
      box(boxSize*2);
      noFill();
      box(boxSize*3);
    } else {
      stroke(0,0,255);
      fill(0,0,255);
    }
    box(boxSize);
    popMatrix();
  }
  // 一番外側の円周上のキューブを描画
  for(int i=0; i<num4; i=i+1) {
    pushMatrix();
    rotateZ(radians(360/num4*i+Rdiff4));
    translate(R4,0,boxSize*3);
    if ((360/num4*i+Rdiff4)%360 < 10) {
      stroke(255);
      fill(255);
      boxSize = boxSize*0.9;
      box(boxSize*2);
      noFill();
      box(boxSize*3);
    } else {
      stroke(0,255,255);
      fill(0,255,255);
    }
    box(boxSize);
    popMatrix();
  }
  // キューブがある程度以上 "摩耗" したら、キューブの数、サイズをリセット
  if (boxSize < 0.1) {
    boxSize = 5;
    num = round(random(8));
    num2 = round(random(8));
    num3 = round(random(8));
    num4 = round(random(8));
  }
}

MusicBoxelのデモ・ムービーは、近日、もうそろそろ公開予定…

ページをゆるふわっと表示する jQuery Chaining Effects Plugin (jquery.effectchain.js)

はいこんにちは!今回はこことかここみたいなサイトのページ表示エフェクトを簡単に実現するプラグインをつくってみたのでそのご紹介です!

Internet Explorer 6+, Safari 5, Google Chrome 8, Firefox 3.6, Opera 11 で動作確認済み。不具合や動作報告などありましたらコメント欄でご連絡ドーゾ。


動作デモ

画像ではお伝えしにくいので、映像で。最初の 20 秒までがプラグインのデモになります。


特徴

簡単な記述でリッチなページ表示演出ができます。また、カスタムデータ属性を使って要素ごとにアニメーションを変えたりインターバル・ディレイを指定して表示のタイミングを制御することも可能です。(すごい!)


ダウンロード

ソースコードは GPL v2 と MIT ライセンスのデュアルライセンスです。


使い方

一般的なプラグインと同様 jQuery と一緒にプラグインファイルを script タグで読み込みます。js ファイルで完結しているので追加の CSS などはロードする必要はありません。(あんしん!)

<script type="text/javascript" src="//ajax.googleapis.com/ajax/libs/jquery/1.4.4/jquery.min.js"></script>
<script type="text/javascript" src="jquery.effectchain.js"></script>

jQuery は 1.4.3 以降を使ってください。こちらでは 1.4.3, 1.4.4, 1.5 で動作確認済みです。

一番シンプルな使い方

スクリプトをロードした状態で以下の記述を行うと、ページ内の div 要素がマークアップした順番でぱらぱらと表示されます。(かんたん!)

jQuery(function($) {
    $("body").effectChain({ target: "div" });
});

引数を指定して動作のカスタマイズ

引数を取ることもできます。(カスタマイザボー!)

jQuery(function($) {
    // アニメーション対象要素を包含する親となる要素を指定します
    // 親要素自身はアニメーション対象とはなりません
    $("#container").effectChain({
        // アニメーション対象の要素を指定します
        // jQuery Selector が使えます
        target: ".effectChain",
        // アニメーションが始まるまでの時間をミリ秒で指定します
        delay: 0,
        // アニメーション間隔をミリ秒で指定します
        interval: 50,
        // アニメーションの順序を指定します
        // true: DOM の逆順, false: DOM の正順
        reverse: false,
        // 各要素のアニメーション開始前の初期スタイルを指定します
        css: {
            opacity: 0
        },
        // animate 関数の引数を配列で指定します
        // 配列の要素がそれぞれ第一引数、第二引数に相当
        args: [{
            opacity: 1
        }, {
            duration: 500,
            easing: "swing"
        }]
    });
});

jQuery.animate() メソッドについてはこちらが詳しいです。

要素ごとのカスタマイズ

アニメーション対象の各要素にカスタムデータ属性を指定することで要素ごとのパラメータを指定することができます。カスタムデータ属性に対応するパラメータは以下のとおりです。(グレート!)

  • data-fxchain
    • effectChain メソッドの引数にパラメータを上書きします
  • data-fxchain-params
    • animate メソッドの第一引数のパラメータを上書きします
  • data-fxchain-options
    • animate メソッドの第二引数のパラメータを上書きします

カスタムデータ属性はシングルクォーテーションで囲い、データは JSON フォーマットで記述します。以下のサンプルを参考にしてみてください。

<div id="#container">
    <div class="effectChain"
        data-fxchain='{ "css": { "fontSize": "10px" } }'
        data-fxchain-params='{ "fontSize": "18px" }'>
        フォントが 10px から 18px にかけて大きくなる
    </div>
    <div class="effectChain"
        data-fxchain='{ "interval": 0 }'>
        次の要素のアニメーションが始まるまでの間隔を 0 にする<br />
        ↓ と同時に登場
    </div>
    <div class="effectChain"
        data-fxchain='{ "interval": 0 }'>
        ↑ と ↓ と同時に登場
    </div>
    <div class="effectChain"
        data-fxchain='{ "interval": 0 }'>
        ↑ と同時に登場
    </div>
    <div class="effectChain"
        data-fxchain='{ "delay": 500 }'
        data-fxchain-options='{ "duration": 1000 }'>
        500 ミリ秒待ってからアニメーション開始
    </div>
</div>

具体的な実装はデモサイトのソースコードを参考にしてみてください!(なげやり)


というわけでいかがでしょうか?! このプラグインを使ってふるふわ愛され上手を目指して頑張りましょう!!!(?)

Music Boxel (裸眼3Dディスプレイ x WebSocketインターフェイス)

aircord社とユニバの協同プロジェクト「Music Boxel」のご紹介です。

MusicBoxelは、aircord社が開発したN-3Dという裸眼立体視ディスプレイと、スマートフォン・携帯電話用のリアルタイム通信を組み合わせた、実験プロジェクトです。手元のモバイル端末から、ウェブページ経由でディスプレイの中を回転する「オルゴール(Music Box)」の音を増やしたり、減らしたりするリアルタイム操作を実現しています。

紹介ムービーを準備しているのですが、そちらは近日公開予定。
また、各パートを担当したスタッフから技術紹介の記事をアップしていきます。

Music Boxel
Music Boxel
Music Boxel

Music Boxel

Naked-eye 3D Display and Web Socket based multi user interaction.
Adding a voxel to make a trigger on roop timeline of virtual music box.

Display/Audio-Visual Program by aircord inc. made with : openFrameworks, SuperCollider
Server/Mobile Interface by Uniba Inc. made with : node.js, CSS3/HTML5

Node.js 用パッケージマネージャ npm と Sinatra ライク軽量フレームワークの express を使ってみた

おばんです。昨日は node.js のセットアップで終わってしまいましたが、今日は Hello, world までやってみます。


謝辞

今回エントリするにあたって以下の記事を参考にさせていただきました。ありがとうございます。


npm のセットアップ

Node.js には rpm によく似たパッケージ管理を実現する npm というものが存在します。他に同様のもので kiwi というものも存在するのですが、今後は npm を使うことが推薦されているようです。以下 kiwi の公式サイトより引用。

NOTE: kiwi is no longer supported, please use npm. This repository will remain for educational purposes only

まずは npm がないとライブラリの導入もままならないのでまっさきにインストールしてみます。セットアップに先立って、ホームディレクトリに設定ファイルを記述します。

$ vim ~/.npmrc
root = ~/.npm/libraries
binroot = ~/.npm/bin
manroot = ~/.npm/man

設定ファイルを記述したら次は環境変数を設定します。bash の場合は .bashrc に以下の内容を記述しておけばログイン時に自動的に設定されるようになります。

export NODE_PATH=~/.npm/libraries:$NODE_PATH
export PATH=~/.npm/bin:$PATH
export MANPATH=~/.npm/man:$MANPATH

source コマンドを使って今しがた設定した環境変数をロードします。(もしくは再ログインでも OK)

$ source .bashrc

設定が終わったら以下のコマンドで npm 本体をインストールします。

$ curl http://npmjs.org/install.sh | sh
% Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
Dload  Upload   Total   Spent    Left  Speed
100   661  100   661    0     0    594      0  0:00:01  0:00:01 --:--:--     0
% Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
Dload  Upload   Total   Spent    Left  Speed
100  2531  100  2531    0     0   1889      0  0:00:01  0:00:01 --:--:--  9271
% Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
Dload  Upload   Total   Spent    Left  Speed
100  576k  100  576k    0     0   188k      0  0:00:03  0:00:03 --:--:--  226k
node cli.js cache clean
npm info it worked if it ends with ok
npm info using npm@0.2.4-1
npm ok
node cli.js rm npm
npm info it worked if it ends with ok
npm info using npm@0.2.4-1
npm info not installed npm
npm ok
node cli.js install npm
npm info it worked if it ends with ok
npm info using npm@0.2.4-1
npm info fetch http://registry.npmjs.org/npm/-/npm-0.2.4-1.tgz
npm info install npm@0.2.4-1
npm info preinstall npm@0.2.4-1
npm WARN bins installing to /home/seiya/.npm/bin, outside PATH
npm WARN npm@0.2.4-1 linkMans It seems /home/seiya/.npm/man might not be visible to man
npm WARN npm@0.2.4-1 linkMans For greater justice, please add it to your man path
npm WARN npm@0.2.4-1 linkMans See: `man man`
npm info install npm@0.2.4-1
npm info postinstall npm@0.2.4-1
npm info activate npm@0.2.4-1
npm info preactivate npm@0.2.4-1
npm info activate npm@0.2.4-1
npm info postactivate npm@0.2.4-1
npm info build Success: npm@0.2.4-1
npm ok
It worked

正常にインストールが出来ていれば npm コマンドが ~/.npm/bin/ 下に生成されます。

$ npm --version
0.2.4-1

ぐれーと。


express をセットアップする

Node.js には HTTP サーバを実現するライブラリがバンドルされているのですが、プリミティブなものなのでここではフレームワークを使ってみることにします。今回は Sinatra ライクに簡潔にルーティングが出来る express というフレームワークを使ってみます。早速 npm を使ってインストールしてみましょう。

$ npm install express
npm info it worked if it ends with ok
npm info using npm@0.2.4-1
npm info fetch http://registry.npmjs.org/express/-/express@1.0.0rc4.tgz
npm info fetch http://registry.npmjs.org/connect/-/connect-0.2.7.tgz
npm info install express@1.0.0rc4
npm info install connect@0.2.7
npm info preinstall express@1.0.0rc4
npm info preinstall connect@0.2.7
npm WARN bins installing to /home/seiya/.npm/bin, outside PATH
npm info install express@1.0.0rc4
npm info postinstall express@1.0.0rc4
npm info activate express@1.0.0rc4
npm info preactivate express@1.0.0rc4
npm info activate express@1.0.0rc4
npm info postactivate express@1.0.0rc4
npm info install connect@0.2.7
npm info postinstall connect@0.2.7
npm info activate connect@0.2.7
npm info preactivate connect@0.2.7
npm info activate connect@0.2.7
npm info postactivate connect@0.2.7
npm info build Success: express@1.0.0rc4
npm info build Success: connect@0.2.7
npm ok

つつがなくインストールが終わってしまいました。公式サイトのサンプルに則って適当にコードを書いてみます。ファイル名は server.js とします。

var app = require("express").createServer();

app.get("/", function(req, res) {
	res.send("Hello, world!");
	console.log([req, res]);
});

app.listen(8080);

node コマンドで実行してみます。

$ node server.js

これだけでコマンドが中断されるまで listen し続けるサーバの出来上がりです。早速ブラウザから 8080 ポートにアクセスしてみるとまばゆいばかりの Hello, world! をお目にかかることが出来ました。console.log() の内容は node の標準出力に表示されるようです。ちょっと長いですが req, res の内容を貼りつけてみました。

$ node server.js
[ { socket:
     { fd: 7
     , type: 'tcp4'
     , secure: false
     , _readWatcher: [Object]
     , readable: true
     , _writeQueue: []
     , _writeQueueEncoding: []
     , _writeQueueFD: []
     , _writeWatcher: [Object]
     , writable: true
     , _writeImpl: [Function]
     , _readImpl: [Function]
     , _shutdownImpl: [Function]
     , remoteAddress: '110.4.189.82'
     , remotePort: 55368
     , server: [Object]
     , _outgoing: []
     , __destroyOnDrain: false
     , ondrain: [Function]
     , _idleTimeout: 120000
     , _idleNext: [Object]
     , _idlePrev: [Circular]
     , _idleStart: Sat, 23 Oct 2010 16:38:26 GMT
     , _events: [Object]
     , ondata: [Function]
     , onend: [Function]
     , _onOutgoingSent: [Function]
     }
  , connection: [Circular]
  , httpVersion: '1.1'
  , headers:
     { host: 'rd-sandbox-2.aws.uniba.jp:8080'
     , connection: 'keep-alive'
     , 'cache-control': 'max-age=0'
     , accept: 'application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5'
     , 'user-agent': 'Mozilla/5.0 (X11; U; Linux x86_64; en-US) AppleWebKit/534.7 (KHTML, like Gecko) Chrome/7.0.517.41 Safari/534.7'
     , 'accept-encoding': 'gzip,deflate,sdch'
     , 'accept-language': 'ja,en-US;q=0.8,en;q=0.6'
     , 'accept-charset': 'Shift_JIS,utf-8;q=0.7,*;q=0.3'
     , cookie: '__utmz=258608462.1286871711.6.2.utmcsr=rd.uniba.jp|utmccn=(referral)|utmcmd=referral|utmcct=/blog/; __utma=258608462.1333207560.1282819752.1287049453.1287724320.9'
     }
  , url: '/'
  , method: 'GET'
  , statusCode: null
  , client: [Circular]
  , httpVersionMajor: 1
  , httpVersionMinor: 1
  , upgrade: false
  , originalUrl: '/'
  , query: {}
  , app: [Circular]
  , res:
     { socket: [Circular]
     , connection: [Circular]
     , output: []
     , outputEncodings: []
     , _last: false
     , chunkedEncoding: false
     , shouldKeepAlive: true
     , useChunkedEncodingByDefault: true
     , _hasBody: true
     , finished: true
     , writeHead: [Function]
     , headers: [Object]
     , app: [Circular]
     , req: [Circular]
     , _header: 'HTTP/1.1 200 OK\r\nContent-Type: text/html; charset=utf-8\r\nContent-Length: 13\r\nDate: Sat, 23 Oct 2010 16:38:26 GMT\r\nX-Response-Time: 0ms\r\nX-Powered-By: Connect 0.2.7\r\nServer: Node v0.2.3\r\nConnection: keep-alive\r\n\r\n'
     , _headerSent: true
     }
  , next: [Function: next]
  , params: []
  }
, [Circular]
]

うーん素晴らしい!あとは O/R Mapper があれば簡単な Web アプリケーションが作れそうですね。今回はチュートリアルみたいな感じになってしまいましたが、どんどん高度なことにチャレンジしていきたいですね。それではまた!

Fedora 8 上で node.js を RPM からインストールする

おばんです。最近では JavaScript に夢中になっていて、サーバサイドも JavaScript で書きたくなってきた今日この頃みなさまいかがお過ごしでしょうか。

今回はサーバサイドで JavaScript を実行することが出来る node.js (執筆時点で最新版の v0.2.3) を Amazon AWS の Fedora 8 上で RPM を作ってインストールしてみたので記録として残しておきます。未確認ですが他の RedHat 系のディストリビューションでも通用するかと思います。


前もってソースコードのビルドに必要そうなものを入れておく

# yum groupinstall "Development Tools"

コンパイラや基本的なライブラリをまとめてセットアップしてしまいます。


必要なファイルを集める

# cd /usr/src/redhat/SOURCES
# wget http://nodejs.org/dist/node-v0.2.3.tar.gz

公式サイトからソースコードを入手します。

# cd /usr/src/redhat/SPECS
# wget http://gist.github.com/raw/635036/79e971db1dac505201525d9f13218f734b37ff17/nodejs.spec

すでに node.js の spec ファイルを書いている人がいたので、ありがたく利用させていただきました。(いまや spec ファイルも gist で公開されるような時代なのか……。)


RPM の作成・インストール

rpmbuild コマンドを使ってビルドします。

# rpmbuild -bb nodejs.spec
実行中(%prep): /bin/sh -e /var/tmp/rpm-tmp.86351
+ umask 022
+ cd /usr/src/redhat/BUILD
+ LANG=C
+ export LANG
+ unset DISPLAY

... snip ...

/usr/src/redhat/BUILD/node-v0.2.3/wscript:188: error: Could not autodetect OpenSSL support. Make sure OpenSSL development packages are installed. Use configure --without-ssl to disable this message.
エラー: /var/tmp/rpm-tmp.86351 の不正な終了ステータス (%build)

RPM ビルドエラー:
    /var/tmp/rpm-tmp.86351 の不正な終了ステータス (%build)

OpenSSL の devel パッケージがはいっていないのでビルド出来ずエラーしてしまいました。yum でサクっと入れてしまいます。

# yum install openssl-devel

気をとりなおしてもう一度!

# rpmbuild -bb nodejs.spec
実行中(%prep): /bin/sh -e /var/tmp/rpm-tmp.4886
... snip ...

メガバイト級のソースコードなのでビルドに結構時間がかかります。そろそろ終わりそうなところにさしかかってまたエラーしてしまいました。

... snip ...
ファイルの処理中: nodejs-debuginfo-0.2.3-1.fc8
Requires(rpmlib): rpmlib(CompressedFileNames) <= 3.0.4-1 rpmlib(PayloadFilesHavePrefix) <= 4.0-1
伸張ファイルの検査中: /usr/lib/rpm/check-files /var/tmp/nodejs-0.2.3-1.fc8-tV2607
エラー: インストール済み(ただし未伸張)ファイルが見つかりました:
   /usr/lib/node/wafadmin/Build.pyc
   /usr/lib/node/wafadmin/Build.pyo
   /usr/lib/node/wafadmin/Configure.pyc
   /usr/lib/node/wafadmin/Configure.pyo
   /usr/lib/node/wafadmin/Constants.pyc
   /usr/lib/node/wafadmin/Constants.pyo
... snip ...

エラーメッセージを Google で調べてみると spec ファイル内の定義と実際の BUILDS ディレクトリのファイルに差異があると発生するようです。

上記サイトによると以下のオプションをつけて rpmbuild するとエラーしなくなるということがわかりました。(感謝!)

# rpmbuild -bb --define="__check_files %{nil}" nodejs.spec
実行中(%prep): /bin/sh -e /var/tmp/rpm-tmp.26330
... snip ...

またビルドが始まります。前回のビルド時にオブジェクトファイルが生成されているためか程々の時間でビルドが終了しました。

... snip ...
Requires(rpmlib): rpmlib(CompressedFileNames) <= 3.0.4-1 rpmlib(PayloadFilesHavePrefix) <= 4.0-1
書き込み完了: /usr/src/redhat/RPMS/x86_64/nodejs-0.2.3-1.fc8.x86_64.rpm
書き込み完了: /usr/src/redhat/RPMS/x86_64/nodejs-debuginfo-0.2.3-1.fc8.x86_64.rpm
実行中(%clean): /bin/sh -e /var/tmp/rpm-tmp.60752
+ umask 022
+ cd /usr/src/redhat/BUILD
+ cd node-v0.2.3
+ rm -rf /var/tmp/nodejs-0.2.3-1.fc8-Pw6173
+ exit 0

これで /usr/src/redhat/RPMS/ 下に RPM をビルドすることに成功しました。あとはいつものとおり rpm コマンドでインストールすれば OK です。

# cd ../RPMS/x86_64
# rpm -ivh nodejs-0.2.3-1.fc8.x86_64.rpm
準備中...                ########################################### [100%]
   1:nodejs                 ########################################### [100%]

コマンドを叩いてみます。

# node --version
v0.2.3

大丈夫そうですね。


途中躓きながらでしたが無事 RPM からインストール出来ました。手始めに PHP では実装の難しいソケットサーバにチャレンジしてみようかなと思います。それではまた!

ファイル数が無尽蔵に増え続けそうな Linux サーバでは updatedb を無効にしておいたほうが良さげ

何気に Unix 系のネタは初めてです。お手柔らかに!

弊社では社内サーバのストレージを pdumpfs を使ってバックアップ専用のサーバに毎日バックアップを取得しているのですが、バックアップサーバのパフォーマンスが著しく劣化 (iowait が常時 50%) しているので調査してみました。

本当は調査の過程を詳細に書ければよかったのですが、とりあえず当てずっぽうに (top コマンドで updatedb がちらついていたのが気になったので) updatedb の仕業じゃないかなーと思って止めてみたらビンゴ。以下のように改善しました。

CPU 使用率 (年単位)

Week 41 の中盤頃に updatedb を停止したところ一気に負荷が下がりました。

CPU 使用率 (年単位)

年単位で見るといい感じに特徴的なカーブを描いています。

ちなみに updatedb は locate コマンド用にインデックスを作成する処理のようです。locate コマンドは使わないし find コマンドで代用できるのでオフにしても問題ないという判断で今回はオフにしてみました。

updatedb は cron によって起動されているので、cron のスクリプト (弊社の使っている CentOS 5 では /etc/cron.daily/mlocate.cron) をコメントアウトして停止しています。

#!/bin/sh
#nodevs=$(< /proc/filesystems awk '$1 == "nodev" { print $2 }') #renice +19 -p $$ >/dev/null 2>&1
#/usr/bin/updatedb -f "$nodevs"

というわけで今回は、ファイル数が無尽蔵に増え続けるようなサーバでは updatedb を停止したほうがよいかもというお話でした。それではまた!

jQuery の animate() メソッドをアニメーション以外に応用する方法

前回と同じようなネタですが、今度は逆転の発想で jQuery.animate() をアニメーション以外にも応用する方法をご紹介します。時間の経過が伴う処理の場合は今回の方法を使ったほうが直感的です。

謝辞

今回のサンプルは Steven Wittens 氏の canvas 要素に対して jQuery.animate() 関数を利用する方法を参考にさせていただきました。

http://acko.net/blog/abusing-jquery-animate-for-fun-and-profit-and-bacon

上記ページのデモの空中をベーコンが飛び交うさまは一見の価値ありです。(笑)


jQuery.animate() で音声のフェードイン・フェードアウトを実装する

Live Demo (requires Google Chrome, Firefox 3.5 or higher, Safari 3 or higher)

HTML5 から audio 要素と JavaScript を使ってネイティヴで音声を再生・制御する仕組みが用意されました。この機能を使ってオーディオのフェードイン・フェードアウトを jQuery.animate() メソッドを応用して実装してみます。

HTML

<body>
	<div>
		<button id="fadeIn">Fade In</button>
		<button id="fadeOut">Fade Out</button>
	</div>
	<audio>
		<!-- for Safari, Chrome -->
		<source src="sallsamma_ting.mp4" />
		<!-- for Firefox, Opera -->
		<source src="sallsamma_ting.ogg" />
	</audio>
</body>

制御用のボタンと、オーディオタグを記述しておきます。ブラウザによってサポートする音声形式が異なるので MP4 と Vorbis を指定しておきます。

JavaScript

// プロパティ保持用のダミーの div 要素を作成する
// jQuery.exntend() メソッドを使って volume というプロパティを初期値 0 で追加する
var vars = jQuery.extend($('<div>')[0], { volume: 0 });

jQuery(function($) {
	var audio = $("audio:first")[0];	// 要素の参照を取得する
	audio.volume = 0;	// 初期設定 (0 = 無音, 1 = 最大音量)

	// イベントの割り当て
	$("button#fadeIn").live("click", fadeIn);
	$("button#fadeOut").live("click", fadeOut);

	/**
	 * フェードインしながら再生開始
	 */
	function fadeIn(e) {
		if (!audio.paused) {
			return;
		}
		audio.play();
		$(vars).stop().animate({ volume: 1 }, {
			easing: "linear",
			duration: 2000,
			step: function() {
				audio.volume = this.volume;	// this == vars
			}
		});
	}

	/**
	 * フェードアウトしながら再生停止
	 */
	function fadeOut(e) {
		if (audio.paused) {
			return;
		}
		$(vars).stop().animate({ volume: 0 }, {
			easing: "linear",
			duration: 2000,
			step: function() {
				audio.volume = this.volume;	// this == vars
			},
			complete: function() {
				audio.pause();
			}
		});
	}
});

3 行目がキモです。vars というダミーの要素を生成して volume というプロパティを追加します。fadeIn(), fadeOut()varsvolume プロパティを jQuery.animate() で操作することにより、フェードイン・フェードアウトを実現しています。もちろんイージングを取り替えたり duration を変更してフェードの効果を変更することも可能です。

いかがでしたでしょうか。今回は音声のフェードイン・フェードアウトを実装してみましたが、他にも色々応用できると思います。ぜひチャレンジしてみてください!それでは!

preload preload preload