2012年2月25日土曜日

自前でhttpのstreamingをつくってみました。その2

自前でつくったhttpのstreamingをglobalにおいてみました。

globalIPしかあてていない、sakuraのvpsなのでip直うちですけど、
デモはhttp://49.212.39.17/hts/player/HttpTakStreamingPlayer.html
アクセスURLはhttp://49.212.39.17/hts?path=/default/hts/livestream
アクセスアドレスをいれて右のplayをクリックすれば、みれます。
今回はbejewed blitzというゲームをやってます。
→もうやめました。見てくださった皆さんありがとうございました。

以下、過去の記事

とりあえず、今日2/25では、23時くらいまでは流すつもりです。
でてくる映像は時計の画像です。

globalにおいて僕がみている限りでは、遅延は10秒いないみたいです。
そこそこな動作してますね。

とりあえずstreamingの名前はhttpTakStreamingと名付けておきます。
githubにそのうちプロジェクトをあげますが、まだ未定です。
アクセスするとわかりますが、動画があることを予測して、アクセスを繰り返すので404が頻発してます。
このあたりがとりあえずの修正項目かな。

ご意見等ありましたら、コメントなり、@taktodへのツイートなりお願いいたします。

やってみた感想は、h.264の放送がなぜかうまくいかなかった・・・このあたりの動作の安定化を今度はすすめないとだめっぽいですね。

2012年2月24日金曜日

自前でhttpのstreamingをつくってみました。その1

 fmsやwowza、red5等によるrtmpのストリーミングはスケーリングを実行するのが非常に面倒です。そこでapacheサーバーからデータを流すことでライブストリーミングをつくってみようと思いました。
1週間ほど、帰宅してからちまちま作っていたのですが、ついになんとか仮動作できたので報告したいと思います。


今回の動作はiMac上でManyCam -> FME -> red5 -> apache -> Flashという流れで動作させてます。
上の図の左がキャプチャ元時計、真ん中が今回つくったHttpStreamingの画像、右がRed5のデモアプリでのrtmp経由の画像となります。

遅延9秒か・・・rtmpが遅延3秒だからやっぱ5秒くらいまでには押さえたいところですがどうなんだろうか・・・

遅延の原因は
・FMEの変換効率1秒程度
・ファイルの生成キャッシュ(3秒)
・apacheサーバーへのデータ転送(0.1秒)
・生成有無の確認1秒おき(最悪で遅延が1秒になる計算)
・再生プレーヤー上のバッファタイム(2秒)

その他の要因も加味すると8秒くらいかな

バッファタイムを0にして(ファイルがそもそもバッファリングしてるみたいなものだからいらないと見た)キャッシュサイズを小さくすれば、5秒くらいに落とせるだろうか。
あまりに細切れにしすぎるとapacheが死ぬかな・・・
206レスポンスとかうまくつかえればもっとキャッシュサイズは大きめでも送信効率あがるかも。
等々いろいろ考えてます。

ではでは。

追記:netStreamのBufferTimeを0にしてみた。
ぎり5秒かな。
左から順に、オリジナル、放送用publisher、視聴用publisher(rtmp)、httpStreaming経由となっています。実際の動作では、最速で5.7秒くらいの遅延。アクセスするタイミングに左右されるので7秒くらいずれることもありました。ローカルの環境での実験なのでものすごくはやいですが、GlobalのIP経由で実験したらたぶんもっと遅延が目立つかもしれない。
今回はManyCam -> flash(flv) -> red5 -> apache -> Flashでやってみた

ではでは

2012年2月23日木曜日

videoタグでwebMのhttpストリーミングができるらしい。

今日、http streamingにいい方式ないかな・・・と思いつつgoogleをさまよっているとstream.mというwebM形式のストリーミング、しかもvideoタグで再生できるというのがあるのを知りました。
http://code.google.com/p/stream-m/

とりあえず動作させてみたいので、やってみようと思いました。
iMac上で挑戦します。

まず、ffmpegが必要なので
http://ffmpeg.org/download.html
こちらからgitでcloneしました。

$ git clone git://source.ffmpeg.org/ffmpeg.git ffmpeg
configureをしようとしたところlibvorbisとlibvpxが必要なので、そちらのデータも入手する。
libvorbisはhttp://xiph.org/downloads/
libvorbis-1.3.2.tar.gzを入手しました。
libvpxはhttp://www.webmproject.org/code/
$ git clone http://git.chromium.org/webm/libvpx.git libvpxで入手しました。

まずvpxからいってみようか、
$ ./configure --helpでめぼしいオプションを探してみました。
とりあえずこれでいってみます。
$ ./configure --enable-vp8 --enable-realtime-only
$ make
$ sudo make install
入りおわったら、きちんとはいっているか確認
ffmpegに移動して

$ ./configure --enable-libvpx
を実行
warningはでたけど、一応libvpxがはいっているのを確認しました。
WARNING: pkg-config not found, library detection may fail.

続いてvorbis
こっちは特にめぼしいオプションはなかった。
$ ./configureを実行してみたところliboggが必要とのこと・・・
よって、http://xiph.org/downloads/にいってliboggのデータ取得
libogg
$ ./configure
$ make
$ sudo make install
つづいてvorbis
libvorbis
$ ./configure
configureが通らない・・・
よくよく調べてみたところliboggがiMacをx86-64として認識してたっぽい。
$ uname -aで調べたところi386だったので、ここが間違っていたみたいです。

liboggをもっかい
$ ./configure --build=i386
$ make
$ sudo make install
つづいてvorbisもっかい
libvorbis
$ ./configure
i386として認識しているもののやっぱりoggがないっておこられる。なぜ?

config.logをみてみたところ次の記述発見
configure:12603: ./conftest
dyld: Library not loaded: /usr/local/lib/libogg.0.dylib
  Referenced from: /Users/todatakahiko/ffmpeg/libvorbis-1.3.2/./conftest
  Reason: Incompatible library version: conftest requires version 9.0.0 or later, but libogg.0.dylib provides version 6.0.0
バージョンが古いって!?
うーん、ここで手詰まり。

また気が向いたらそのうちやるか・・・

2012年2月2日木曜日

sqliteでログをとってみよう。php編その2

sqliteでログをとってみたいけど、CentOSのyumのphp53では、なぜかいれることができなかった・・・
php5.1.2に戻すという手もあるけど、json関数はつかいたい・・・
仕方ないのでもうソースからコンパイルしちまおう。

ここまでが前回のあらすじ。
とりあえず、phpinfoを吐かせて現在のphpの状態を取得しておく。

とりあえず、まず古いphpを削除する。
# yum remove php53*
これで次のものが消えます。
php53
php53-cli
php53-common
php53-devel
php53-mbstring
php-pear
削除しました。

ターゲットは最新のphp-5.3.9とします。
とりあえず解凍
# tar zxvf php-5.3.9.tar.gz
解凍をすすめる。
さて、面倒なconfigureの設定ですが・・・とりあえず先ほどのphp53の設定を元にsqliteを有効にしたものをいれてみたいとおもいます。


./configure --build=x86_64-redhat-linux-gnu --host=x86_64-redhat-linux-gnu --target=x86_64-redhat-linux-gnu --program-prefix= --prefix=/usr --exec-prefix=/usr --bindir=/usr/bin --sbindir=/usr/sbin --sysconfdir=/etc --datadir=/usr/share --includedir=/usr/include --libdir=/usr/lib64 --libexecdir=/usr/libexec --localstatedir=/var --sharedstatedir=/usr/com --mandir=/usr/share/man --infodir=/usr/share/info --cache-file=../config.cache --with-libdir=lib64 --with-config-file-path=/etc --with-config-file-scan-dir=/etc/php.d --disable-debug --with-pic --disable-rpath --with-pear= --with-bz2 --with-exec-dir=/usr/bin --with-freetype-dir=/usr --with-png-dir=/usr --with-xpm-dir=/usr --enable-gd-native-ttf --without-gdbm --with-gettext --with-gmp --with-iconv --with-jpeg-dir=/usr --with-openssl --with-pcre-regex=/usr --with-zlib --with-layout=GNU --enable-exif --enable-ftp --enable-sockets --enable-sysvsem --enable-sysvshm --enable-sysvmsg --with-kerberos --enable-ucd-snmp-hack --enable-shmop --enable-calendar --with-libxml-dir=/usr --enable-xml --with-system-tzdata --with-apxs2=/usr/sbin/apxs --without-mysql --without-gd --disable-dom --disable-dba --without-unixODBC --disable-pdo --disable-xmlreader --disable-xmlwriter --disable-phar --disable-fileinfo --without-pspell --disable-wddx --disable-posix --disable-sysvmsg --disable-sysvshm --disable-sysvsem
こんな感じ→ですが、configureとおらなかった・・・
apxsがだめらしい。
yum で httpd-develをインストールします。
# yum install httpd-devel

さて、もう一度configureを・・・
今度はlibxml2か・・・
# yum install libxml2

次はどうだ・・・
configure実行・・・
あれ、同じところがエラーになったなぜ?
# yum install libxml*
こっちで再度トライ

Could not find pcre.h・・・peclねぇ・・・
yumでいくか・・・これも・・・
# yum install pcre*
さくっといれて再度挑戦

BZip2を入れ直せ・・・とでた。
# yum install bzip2*
yum超便利、yum万歳
入れ直せなのに、そのまま追加インストールしただけでconfigure再挑戦

今後はgmp.hか・・・
# yum install gmp*

configureを再開、成功したけど
--with-system-tzdata
このオプションが存在しないよ?っていわれた。たしかに--helpでみても対象オプションはないっぽい。
とりあえず外します。

最終的にはこうなりました。
./configure --build=x86_64-redhat-linux-gnu --host=x86_64-redhat-linux-gnu --target=x86_64-redhat-linux-gnu --program-prefix= --prefix=/usr --exec-prefix=/usr --bindir=/usr/bin --sbindir=/usr/sbin --sysconfdir=/etc --datadir=/usr/share --includedir=/usr/include --libdir=/usr/lib64 --libexecdir=/usr/libexec --localstatedir=/var --sharedstatedir=/usr/com --mandir=/usr/share/man --infodir=/usr/share/info --cache-file=../config.cache --with-libdir=lib64 --with-config-file-path=/etc --with-config-file-scan-dir=/etc/php.d --disable-debug --with-pic --disable-rpath --with-pear= --with-bz2 --with-exec-dir=/usr/bin --with-freetype-dir=/usr --with-png-dir=/usr --with-xpm-dir=/usr --enable-gd-native-ttf --without-gdbm --with-gettext --with-gmp --with-iconv --with-jpeg-dir=/usr --with-openssl --with-pcre-regex=/usr --with-zlib --with-layout=GNU --enable-exif --enable-ftp --enable-sockets --enable-sysvsem --enable-sysvshm --enable-sysvmsg --with-kerberos --enable-ucd-snmp-hack --enable-shmop --enable-calendar --with-libxml-dir=/usr --enable-xml --with-apxs2=/usr/sbin/apxs --without-mysql --without-gd --disable-dom --disable-dba --without-unixODBC --disable-pdo --disable-xmlreader --disable-xmlwriter --disable-phar --disable-fileinfo --without-pspell --disable-wddx --disable-posix --disable-sysvmsg --disable-sysvshm --disable-sysvsem

make開始
# make
おわったらテスト開始
# make test
テスト項目に
SQLite3::open error test [ext/sqlite3/tests/sqlite3_15_open_error.phpt]
というのがあったので、非常にいやな予感がしますが、とりあえずphpをつかえるようにしたいので、インストールする。
# make install

# php -r
で動作することを確認して、httpd.confを書き直す。

こちらを参考にして、php.confを作成しました。

あとは、noteAppでつかったcssの読み込み直しjsonデータ応答PHPをキックしたり、phpinfoをキックしたりしてみて動作を確認。
これで問題なしということになりました。

さて、肝心のsqliteですが・・・
PHP Warning:  PHP Startup: Unable to load dynamic library '/usr/lib64/20090626/sqlite.so' - /usr/lib64/20090626/sqlite.so: cannot open shared object file: No such file or directory in Unknown on line 0
こうなりました。正直20090626というディレクトリが謎です。

phpのsqlite用のライブラリをコンパイルしないとだめなんで
php-5.3.9/ext/sqliteでphpizeを実行
# phpize
# ./configure
# make
# make test
まできました。すると動作がほぼすべてエラーになった・・・なんだこれ。

気にせずインストールしちゃえってことでインストール
# make install

さて、cliで
<?php
$link = sqlite_open("3.db", 0666, $sqliteerror);
if(!$link) {
        die("error for connect" . $sqliteerror);
}
echo "connect ok\n";
sqlite_close($link);
echo "disconnect\n";
このコードを実行してみたところ・・・

$ php test.php 
connect ok
disconnect

やっとキター
テストでエラーになったのは、たぶんライブラリがうまく見れないとかそんなところだろう。

次は実際にphpでsqliteをいじってみよう。

追記:
よくよく調べてみたところsqlite_openってsqlite3じゃないみたいですね。
SQLite3クラスをつかって処理しないといけないみたいです。なんだったんだ。sqliteの手間は・・・

まぁあっても特に不都合はないのでこのまま放置しますけど。

2012年2月1日水曜日

sqliteでログをとってみよう。php編

sqlite3でログをとってみたら有用ではないのか?とおもったので、いろいろやってみます。
今回はphpでの動作。

ログを保存するのは、当然としてphpでデータを解析してページで確認とかしそうなので、その動作についていろいろ調べてみます。

とりあえず、UbuntuのVMでテストしたところ、問題なく動作しましたが、サクラのVPSでつかっているCentOSではsqlite_open等の関数が利用できませんでしたので、準備を進めます。

早速yumでせめて見ますが、僕の環境では、json_encodeがつかいたくてphp53(version 5.3)をインストールしていました。なのでphp_develをインストールするわけにはいかないみたいです。

# yum install php53-devel
を実行、とりあえずdevelをいれた
# yum install php-*
を実行、準備されているphp53シリーズを確認→動作自体はキャンセル
# yum install php-pear
peclをつかいたいのでpearをいれる。
入ったのでさっそくpeclの力を借りる
# pecl install SQLite
→makeに失敗。
ソースからいかなきゃいかんのね・・・

# pecl download SQLite
# tar zxvf SQLite-1.0.3.tgz
# cd SQLite-1.0.3
# ./configure
# make
ここでこけた。
とりあえずこちらを参考に・・・
CentOS5.1でphp-sqliteを利用するときのメモ
該当箇所をコメントアウトしていく・・・

うぅ〜だめだ。書いてあるとおりに変更しても通らない・・・peclはあきらめてphp-5.3のソースからいってみようとおもいます。
http://php.net/downloads.php
ここからソースを取得
5.3.9だけどまぁいいでしょう。
# tar zxvf php-5.3.9.tar.gz
解凍して・・・
# cd php-5.3.9/ext/sqlite
# phpize
やってみたところwarningがでた。が、まいいや。
# ./configure
# make
すんなり終わる。
# make test

FAIL sqlite, session storage test [tests/sqlite_session_001.phpt]
FAIL sqlite, session destroy test [tests/sqlite_session_002.phpt]
エラーでた・・・

とりあえずレポートを投げることにする。
エラーでてるけど、とりあえずmake installやっちゃう。
/usr/lib64/php/modulesと/usr/include/phpにデータがはいった。
起動時にうまく動作しなかった・・・orz

仕方ないので、古いphpをつかってみることにします。
というわけでphp.5.3.4をゲット
# phpize
# ./configure
# make
# make test
今度はどうだ!?
だめだ同じところでエラーになる。このエラーがなんなのかやってみないとだめっぽいな・・・

仕方ないので、次回やるときには、yumではなくphpをソースから入れようと思いました。
とりあえず今日はここまで・・・

sqliteでログをとってみよう。

ふと思ったんですが、各サーバーの動作ログを一元管理したいときに、テキスト形式のログファイルを吐いたり、syslogのサーバーに集めたり、はたまたmysqlに保存したりとしますが、個人的に以下のような欠点があります。

テキスト形式のログ:動作は簡単、お手軽、検索等は文字列の検索になるので、苦手。1カ所に集めるのが面倒。
syslogのログ:動作は簡単、お手軽といえばお手軽、検索等はやりにくい。1カ所にまとめるのも簡単。UDPで通信してるので、遮断されたらだめかも。
mysqlのログ:動作はやや面倒。手軽というほどでもない。検索はやりやすい。1カ所にまとめるのもやりやすい。TCPで接続してやり取りしなければいけない。あとサービスでつかいまくってると、重いクエリを走らせたりしちゃうと、サービスに影響がでる。

といった感じです。

そこでsqliteをつかってみようと思いました。
sqliteのログ:動作はやや面倒。手軽ではある。検索はやりやすい。1カ所にまとめるのは面倒、通信しないのでサーバーが死なない限り動作できる。なんかあったら手元にダウンロードして解析とかもできる。なんといっても複数サーバーのログをまとめて、あつかったりできる。
という感じ。
あたらしい手段としては、なかなか優れてる気がします。

というわけで、さっそくいろいろ調べていきます。
まず、基本的な情報
iMacにいれてあるのはsqlite 3.6.12
CentOS(サクラVPS)にいれてあるのはsqlite 3.3.6
基本的なコマンドは次のとおり。
$ sqlite3 (dbファイル名)
テーブル作成
sqlite> create table [テーブル名] (カラム,カラム....);
データ取得
sqlite> select * from [テーブル名];
データ追加
sqlite> insert into [テーブル名] (データ, データ....);
sqliteをやめる。
sqlite> .quit;

sqliteでデータをいれたものを合成して結果を出す方法。
unionで結合すればOK

ざっとこんな感じ。
testlogというテーブルにdate(文字列) task(文字列) result(文字列)という構成があるとします。


sqlite> attach database "1.db" as a;
sqlite> attach database "2.db" as b;
sqlite> select * from a.testlog;                                                

date|task|result
2012-02-01 20:30:50|test|ok
2012-02-01 20:30:53|test2|ok?
2012-02-01 19:40:50|test3|ng
sqlite> select * from b.testlog;
date|task|result
2012-02-01 20:40:50|test3|ng
2012-02-01 20:40:30|test4|ng?
2012-02-01 19:30:30|test5|ok
中身はこんな感じです。


さてこのログを時系列で並べるならこんな感じ

sqlite> select * from a.testlog union select * from b.testlog order by date asc;
date|task|result
2012-02-01 19:30:30|test5|ok
2012-02-01 19:40:50|test3|ng
2012-02-01 20:30:50|test|ok
2012-02-01 20:30:53|test2|ok?
2012-02-01 20:40:30|test4|ng?
2012-02-01 20:40:50|test3|ng
ちゃんと時間順に並んでます。
order byは全体にかかるみたいです。

時間を制限するとすれば、
sqlite> select * from b.testlog where date > "2012-02-01 20:00:00" union select * from a.testlog where date > "2012-02-01 20:00:00" order by date asc;
date|task|result
2012-02-01 20:30:50|test|ok
2012-02-01 20:30:53|test2|ok?
2012-02-01 20:40:30|test4|ng?
2012-02-01 20:40:50|test3|ng
こんな感じになります。where文は両方に設定しないとだめみたいです。

とりあえずここまでの調査で、sqlite3のファイルを日付順にでも並べておいて、どこかのサーバーにまとめてしまえば特定のサーバーの特定の日付の範囲のログとか出せそうです。

あとは、phpやjava、そのほかの言語での動作の確認をチェックしてやれば・・・いろいろできるはず。

以上個人メモでした。