2011年10月29日土曜日

rtmfpで高画質配信をやってみたい。その3

rtmfpで高画質配信をしてみたいので、最近がんばってます。
その3回目。
とりあえず、flvパケットに変換するサーバーはできあがりました。(まだ動作に不備があるとは思うけどね。)

Red5用のアプリのソース:https://github.com/taktod/packetTest
Flexのアプリのソース:https://github.com/taktod/packetTestSwf
仮においてみたRed5サーバー:rtmp://49.212.39.17/test/hoge
Flash:http://poepoemix.appspot.com/hqtest/HighQualityMovieTest.swf

ルームのhogeの部分を適当な文字に変更してそこに向かって放送を実行。
Flashで同じルームに接続するとflvの断片がサーバーから送られてきて放送が開始されます。


自分の方で動作確認してみたところ、結構なクオリティーの映像が流れました。
あとは、rtmfpにパケットデータをどんどん流して共有するプログラムをかけば、高画質なライブをP2Pで実装できると思う。

flvファイルの解析がかなりできたので、ローカルのファイルをそのままP2Pに流すプログラム(VODの記事みたいに最初から再生じゃなくて、同時進行系の動作)も、書けそう。
Xugglerつかってリアルタイムエンコードして、放送をコンパクトにしたり・・・とかもやってみたいですね。

では、次はいよいよrtmfpに着手だ。

2011年10月28日金曜日

rtmfpで高画質配信をやってみたい。その2

rtmfpで高画質配信をやってみたいので、こんなものをつくってみました。

https://github.com/taktod/packetTest
Red5のサーバーアプリケーションのソースコードです。

  1. このサーバーアプリにむけて何らかの方法で放送を開始する。(接続はデフォルト)
  2. このサーバーアプリの適当なルーム宛にFlashアプリで接続する
すると対象Flashアプリは次の命令を受け取ります。
flvHeader(data:*):void
flvMetaData(data:*):void
flvData(data:*):void
dataはすべてArray(byte[])で送られてきます。
このバイトデータを整形して、NetStream.appendBytesに送ってやると
高画質な再生ができるという寸法です。

H.264、AACの対応が難しくもあり、パズルをとくみたいで楽しかったです。
手持ちの環境では、H.264 VP6 FLV1、音声はmp3、AACで検証確認してあります。

今後実行することは
  1. Flex側のソースコードの公開。
  2. rtmfp経由の動作の実験。
  3. rtmfpをつかったライブチャットサービスの作成と公開
  4. その他rtmfpをつかったアプリの構築
といったところですね。

2011年10月27日木曜日

rtmfpで高画質配信をやってみたい。

rtmfpのサーバーがオープンソースできてしまった上に、放送の実装ができてしまったので、せっかくなので高画質配信をやってみたいと思います。
NetStreamには任意のFLVのデータをappendBytesで追加していってやると動画に変換して放送するという超便利な動作があるので、これを利用してやってみようと思います。
概念的にはこんな感じ。

flvデータをrtmfpで共有してどうこうするというのは、こちらの記事にあります。
オブジェクトデータにして、byteArrayのデータをNetGroupで共有する。
そんな感じの動作です。

FMEやXSplitによる配信データをflvのデータにリアルタイムで変換するというのは、探しても記事がなかったので独自に作成しました。
とりあえずRed5でプログラムをごりごりと書きました。ソースコードは後日githubにあげる予定。
動作概念としては
■サーバー側
1:放送のストリームにstreamListenerをくっつけてパケット情報を監視する。
2:メタデータを受け取った場合はそれを保持しておく。
3:一番はじめのビデオデータ(フレームデータ)を保持しておく。(H.264キーフレーム対策)
4:再生させたい端末(クライアント)がアクセスしてきたら
FLVヘッダ(固定)、メタデータ、フレームデータを送信する。
5:その後は送られてきたパケットデータをクライアントに随時送信する。
で、OK
注意点としては、配信ソフトにはパケットデータを返さないこと(処理量が増えて重くなる。)

■クライアント側
1:NetStream.appendBytesを実行するための準備をおこなっておく。
NetStreamAppendBytesAction.ResetBeginも先に実行してOK。
2:FLVヘッダ、メタデータ、フレームデータ(始めのフレーム)は即netStreamに流してOK
3:しかるべきタイミングでパケットデータをnetStreamに流していく。
H.264の場合、キーフレームを1番はじめにしないとだめ。
H.263やVP6の場合、そのまま流してOK

複数のrtmfpのネットワークに所属するノードがいれば、別のネットワークに又投げしたりできるので、かなり大人数の配信が可能になると思われる。(実質無制限?)

うぉーなんかわくわくしてきましたw。

2011年10月25日火曜日

オープンソースのrtmfp?

今日、同僚に教えてもらったのですがオープンソースでのrtmfp実装がとうとうでてきたそうです。
https://github.com/OpenRtmfp

wireshark等で解析をしようといろいろ情報あつめてたことがあるので、ちょっと興味津々。

node実装とC++実装の2つがあるみたいですね。
とりあえず、低レベルと思われるC++実装の方を選択してみようと思います。
可能なら、Java実装をつくったりrtmfpClientをつくったりしてみたいところです。(後者はFlashの動作を調査しないとわからないかもしれないですね。)

とりあえず、Cumulusの導入してみて、rtmfpの動作確認までいきたいですね。
初回はCumulusのインストールと起動までを・・・

いれた場所はsakuraのvpsです。

1:Cumulusをダウンロードします。
$ git clone git://github.com/OpenRTMFP/Cumulus.git

2:opensslとpocoが必要なので、準備する。
# yum install openssl
でopensslをインストール
pocoはソースをダウンロードしてきてからコンパイルしました。

$ wget http://jaist.dl.sourceforge.net/project/poco/sources/poco-1.4.2/poco-1.4.2p1.tar.gz
$ tar zxvf poco-1.4.2p1.tar.gz

$ cd poco-1.4.2p1
$ make
# make install
で完了。
3:ライブラリパスを通しておく。
$ export LD_LIBRARY_PATH=/usr/local/lib
4:CumulusLibをコンパイル
$ make→パーミッションエラー後
# makeで完了(makeのみでインストールされるらしい。)
5:CumulusServiceをコンパイル
$ makeで完了
6:起動する。
$ ./CumulusService

INFO  Handshake[43] Id of this cumulus server : bb6c0ad01bd6b0dd4290141b34adb8eaca21584744b3d1c6fd513af32e49f947
NOTE  RTMFPServer[101] RTMFP server starts on 1935 port
こんな感じで起動します。

$ netstat -na | grep 1935
udp        0      0 0.0.0.0:1935                0.0.0.0:*       
無事プログラムが起動し、1935ポートのlistenが開始されました。

以上

2011年10月18日火曜日

red5の音声動作にバグあり?

Flazrのライブラリをつかうと、flvをrtmpに変換して流すことができます。

これをちょっと改造して、ネット上にあるflvをrtmpに変換して任意のサーバーに流す・・・そんなプログラムを書いていたのですが、H.264、AACのflvを流しているときに気づいてしまいました。

放送開始まえから、視聴側でplayを実行、再生中にpauseを実行して再度playを実行しても、音声がずっと聞けましたが・・・
放送開始後に、視聴側のstream.playを実行すると映像は見れるのに、音声が流れない・・・
どうやら、途中からplayを開始するとFlash側に音声エンコード情報が届いていないようです。

たしか昔、ClientBroadcastStreamのクラスをいじっていたとき、音声コーデックの情報保持はしていなかったような気がするので、このあたりをもてあそんでやればなんとかなりそうですが、果たして・・・

FlashMediaLiveEncoderのプラグインにAACサポートするのがあって、これを利用すればAACコーデックで音声を流すテストができますので、誰か素敵な紳士・淑女が、Red5の開発陣にバグあるよってレポートしてくれないかなぁ。

ちなみに音声コーデックがmp3なら問題ないみたいです。

ではでは〜

2011年10月4日火曜日

HashMapで文字列キーに対応するデータがとれない・・・あるはずなのに・・・

HashMapのキーの文字列をいれているときに、キー側のデータをStringBuilderで作成したり、通信した後にbyte[]から起こしたりすると、あらたなHashの文字列ができてしまって、参照がおかしくなるときがあります。

こんなときの救世主がinternメソッド。
文字列プール上に展開されている文字列で一致するものを返してくれる。

これをつかえば、確実にキーのhash値が一致するようになるので、データの取得がうまくいくようになります。

これ今日のプログラム変更で非常にやくにたった。
Flexとの通信なんかやってると型変換が内部で大量に発生するので、取得できないデータがぽろぽろとでてきました。

MapをつかうときにはStringのintern()メソッド。
思い出してやってください。

2011年10月2日日曜日

Airで外部プロセスを起動するときのメモ

AdobeのAirで外部プロセスを起動させ、SayKotoeriに発言させてみたくなったので、ちょっとプログラムを書いてみた。

ポイントは2点
・プロセスを呼び出すこと
・suppertedProfilesの記述をapp.xmlの方につけておくこと
です。

とりあえず呼び出すプログラムから・・・
 app.xml側の記述はこんな感じ
これで実行すると「あいうえお」って発言されました。
app.xmlの記述が忘れやすいっていうかわかりにくかったです。

2011年10月1日土曜日

Jmeterのプラグインを書く、その3、データ設定をおこなう。

ひさしぶりにJmeterのプラグインを作成する側の記事を書きたいと思います。

今回はSamplerに設定項目を追加する方法です。

やり方は簡単でBeanのように、設定項目用の変数を準備。
SetterとGetterを配置してやればOKです。

というわけで、TestPluginForJmeterのリポジトリのプログラムにdata1とdata2という変数を追加してみました。

やったことは、変数を追加して、JmeterのGUI上で入力をしておくと、返答結果に入力文字が追加されるというもの。
追加項目が2つでています。2つ目の方は未定義にしてみました。
 実行すると、実行結果の部分に入力したtest1というデータがはいっています。

このJmeterの入力パラメーターですが、どうやら普通の変数ではないようです。
詳細はTableをつかえるようにするときに公表すると思いますが、この動作のおかげでTableEditorをつかった複数項目入力動作の実装がかなりややこしくなっています。
そして今もその設定の仕方について悩んでいたりします。

次に記事を書くとしたら、細かい設定の項目分け方法等ですかね。
では〜