2012年7月5日木曜日

wonderflで他のswfを呼び出す部分をまとめてみた。

ちょっとwonderflでソースコードをだだ漏れにしつつ、プログラムを組んでいました。

まぁ、つくっていたのは、httpTakStreaming用のプレーヤーとかred5でのrtmpとwebSocketによるチャットテストとかなんですが・・・

そこそこな動作になるように調整してみました。

売りはMyLoaderのところですね。
読み込みたいプロジェクトをいくつかあらかじめnew MyLoaderで予約して
MyLoader.loadAllで全部読み込んでから指定functionを動作させる。
できあがったら、あとは適当に初期化してアプリケーション動作開始・・という手はずです。

このswfロード動作、別にwonderFLにあげてなくても、crossdomainだけ解決できていれば、自分のサーバーにあるデータでも同じように読み込み→流用ということができるとおもいます。


んで余談ですが、netStream.appendBytesを利用した動画データはstreamTransportやrtmpdumpでは取得ができません。

なので

こちらにつくったtakStreamingのftmファイル生成部分をいろんな方法で暗号化して
こちらでつくったftmファイルbyteArray化の部分で複合化して視聴させるようにしつつ
しかも1時間おきとかに暗号方法を変更していったりすれば
ライブストリーミングも、動画サービスも、意図しないダウンロードからコンテンツを守れると思うんですよね、どうでしょう?みなさん。

というのが
に書いてある有償が云々のくだりなんですけど・・・

よくよくみたら、1,2はすでに実装済みですね。(*1)
3も今回のwonderflのプログラムで道筋は建ちました。

ちなみにstreamTransportでtakStreamingを視聴しているflashのデータダウンロードを実行してみたところ、header用のfthファイルがなぜか落ちてきました。(*2)
データやりとりしている部分でflvデータと解釈できたバイナリダウンロードとrtmpプロトコルの監視をしているんですかね。


ちなみにこのhttpTakStreamingみたいにnetStream.appendBytesを利用した不正ダウンロード対策が世にはびこったとして、もし僕が不正ダウンロードを実行するとしたら、flashplayerのプログラムラッパーを書いてnetStreamの動作を監視するプログラムでも書きますかね。すくなくともappendByteするタイミングでは、生のflvデータにもどっていることは確かですから。

まぁ、そんな面倒なことしなくてもデスクトップキャプチャとかで撮ってしまえば画質はわるくても一応保存できますので、そっちの方が楽ですけど。

では、本日もたわいもない記事でした。


(*1)
現行のプログラムではrtmpソースをFlashMediaServerにしてあります。
apacheプロジェクトのftpClientを利用したファイルのアップロード処理も実験済み

(*2)
現行のfthファイル先頭1パケット分の正しいflvファイルになってます。

2012年6月26日火曜日

flvにいれることが可能なmp3フォーマット

flashのflvにはsound formatの定義としてmp3を取り込むことができるようになっています。

http://osflash.org/flv
こちらのFLV Tag 0x08: AUDIOの部分には2がmp3を示してsoundRateとしては5.5kHz 11kHz 22kHz 44kHzの4段階がつかえると書いてあります。

ん?

mp3のサンプリングレートって、この4つ以外にもあったような・・・
というわけで、MP3Formatのデータも紐解いてみますと

http://mpgedit.org/mpgedit/mpeg_format/MP3Format.html
Fの項目にサンプリングレートのインデックス定義があります。
44.1kHz以外にも、48kHzとか32kHzとか

こういう場合はどうなるんだろう?ということで、ffmpegでflv出力をやってみました。

44.1kHzならコンバート可能。
それ以外の場合はCould not write header for output file とでました。
扱うことができないというわけですね。

1つ勉強になりました。

mp3をflashに読み込んでflvに直しつつnetStream.appendBytesで再生してみようかと思っていましたが、仮につくってもmp3の状態によっては、flv化できないということですか・・・
ちょっと残念。

ちなみにflashそのものでは、扱うこと事態は可能みたいですね。
http://sothis.blog.so-net.ne.jp/2006-06-18-1
こちらのブログにあがっているflashプレーヤーに48kHzのmp3をあてがってみたらきちんと動作しました。

ほぅ・・・って感じですね。

しっかし、今日はことごとくやろうと思ったことができない日だな。

2012年6月25日月曜日

wonderflで別でつくったswfの内部クラスを呼び出せないかやってみた。

wonderflはjsdo.itに似てますが別でつくったコードを読み込むといった処理はできません。
(いやあるのかもしれませんけど。)
でもswfファイルって別につくったswfが同じdomain内にあるか、crossdomainで解決しておけば読み込んで内部のクラスを使うことができたはず・・・というわけでやってみました。

読み込み対象のクラスはこちら。
http://wonderfl.net/c/diwZ

読み込む側のクラスはこちら。
http://wonderfl.net/c/kueD

loadするswfのurlがすごいことになってますが、動作しますねw。いろんなユーティリティをつくっておけば、それを組み合わせていろいろやるということができるかもしれませんね。


さて、余談ですが・・・
やれるかやれないかは別にしてやってみたいこと箇条書きにしておきます。
1:mp3をflvになおしつつ、netStream.appendBytesをつかって再生させること。
2:flashでflazr同様のプログラムを書いて、flashからファイルをrtmpにpublishさせてみる。
3:チャットまわりをつくってhttp://wonderfl.net/c/wzCpこのtakStreamingのプレーヤーにコメント機能も実装しちゃう。

このあたりやりたいですね。

それ以前にしばらくは、wonderfl上に動作ライブラリをいくつかつくるのが先決かな・・・

2012年6月22日金曜日

wonderflにHttpTakStreamingのプレーヤーつくりました。

前からおいておきたいな・・・とおもっていたwonderflにHttpTakStreamingのプレーヤーを設置しました。

http://wonderfl.net/c/9VnJ
んで、youtubeのFinalFantasy9のBGMでも流しながら実験していたのですが、どうも音がとぎれることがあった・・・
おかしいなと思って調べてみたところ、どうやら原因はリストファイルへのアクセスを頻繁に実行しすぎるためみたいでした。
もともと0.5秒に1度データを取得しにいく形だったのですが、これを1.2秒ごとに変更したところなんとかなったっぽいです。

いくつかわかったことがあるので、書いておきます。
1:Flashからダウンロード要求を発行しすぎると、詰まることがありえる。

chromeのNetWorkをみてて気づいたのですが、メディアデータをDL後にindexファイルのDLが詰まっていました。どうやら、タイマーの間隔をつめすぎていたみたいです。0.5秒は無茶だったという。
もしくは処理完了してから、indexファイルの読み込みを要求するように書き換えないとだめですね。
とりあえず。0.5秒→1.2秒にしたらなんとかなった模様です。
この設定ちょっとまずいんですけどね。

2:FlashMediaLiveEncoderの出力データのキーフレーム間隔が非常に広いみたいです。

各mediaデータの生成タイミングは、設定間隔以上で動画のキーフレームがきたら・・・という条件にしてあります。
で、出力データをしらべてみたところ、200フレーム以上はなれてkeyFrameがくるようになっていました。
14秒ごとくらいの間隔?設定間隔を1.2秒にしていたので、もっと小さなデータがながれてくることを期待していたんですが・・・
ちなみに先ほどのちょっとまずいという件は、もし、キーフレームの密度が高い放送をやってしまうと、メディアデータの間隔が、ちょうど1.2秒になります。
タイマーも1.2秒だと、下手すると、ファイルをうまく受け取れない可能性が・・・

というわけで、リアルタイム性を押し出そうとおもったら、ちょっとエンコードして、キーフレームの間隔狭めておかないとだめですね。

com.ttProject.xuggle.out.flvのパッケージのクラス準備しなきゃだめかもw。
とはいえ、変換をかませるとそれだけで遅延の原因にもなりかねないし・・・どうなんだろう。


とりあえず、やらないといけないことは・・・
1:エンコード間隔を3秒程度に変換しておく。
2:HttpTakStreamingを生データから作成ではなく、xuggle変換後の出力にする?(リアルタイムに近づけるなら。)
それか、innerFrameのところで切っても問題なく再生できるような仕組みを考える。
3:Flash側の取得動作まわりのもろもろの対策
このあたりでしょうか・・・

昨日からFlashモードになってるから、1、3やって2は天啓がおりてくるまで待機かなw
ではでは〜

2012年6月18日月曜日

jpegmp3ストリーミングについて考えてみた。

jpegmp3のストリーミングをつくって、iPhoneなのに、フルスクリーンではない再生をやってみたいと思っています。
というわけでいろいろ考えてみた。

いまのところわかっていること。
・mp3のストリームはm3u8準拠でできるみたいなので、この再生positionをベースに画像を入れ替えていこうと思う。
・画像は1枚ずつ別の画像にしてしまうと、転送データが大きくなりすぎる懸念があるので、1枚の画像に複数のシーンを書き込んだ画像を準備しようと思う。(160x120の画像を縦に10個、1秒分描くみたいな感じ。)
・mp3のストリームはtsやtakみたいに間近の2、3パケットだけ送ればよいというわけにはいかないみたい。(再生時間がはじめてからの時間になってしまい、jpegとの同期がとれないみたい。)

というわけで現時点での案は次のような感じ。
・mp3の18375000パケットごとにセグメントをループさせる。(ちょうど1分の長さ)
要は1分20秒の画像と3分20秒の画像のindexは同じになる。
・jpeg用のインデックス定義ファイルはjplという拡張子にしておく。jpegListファイル内容は次のとおり。
#JPL-X-MEDIA-SEQUENCE:xx
冒頭の情報が何番目のセグメントであるか定義する。
#JPLINF:1111001111:[jpegファイルへのURL]という形で各要素は定義しておく。
1はフレームが存在する。0はフレームが存在しない(jpegの形式だと黒になる。)
1フレームがちょうど0.1秒分になるので、あとはjavascriptで画像をいれかえていけばOK

例としてはこんな感じ
index.jplの内容例
#JPL-X-MEDIA-SEQUENCE:120
#JPLINF:1110110111:http://49.212.39.17/stest/jpeg/test/120.jpg
#JPLINF:1111111101:http://49.212.39.17/stest/jpeg/test/121.jpg
#JPLINF:1111111111:http://49.212.39.17/stest/jpeg/test/122.jpg
#JPLINF:1011111111:http://49.212.39.17/stest/jpeg/test/123.jpg
#JPLINF:1111100111:http://49.212.39.17/stest/jpeg/test/124.jpg
#JPLINF:0111110111:http://49.212.39.17/stest/jpeg/test/125.jpg

こんなもんで構築できるかな

実際にプログラムをつくったら利用するファイルは以下
m3u8(mp3のストリーム定義)
mp3(mp3のデータ本体)
jpl(jpegのストリーム定義)
jpg(jpegのデータ本体)

mp3のストリームの再生位置を取得しつつjpegデータをcanvasにjavascriptで描きまくるみたいな動作になる予定

また帰宅後にぼちぼちプログラムをしていこうと思う。


おまけ、HttpTakStreamingの今回つくったファイル、ftl fth ftmファイルについて
■ftlファイル(FlvTakListファイル)
#FTH:[fthファイルのアドレス]

ヘッダファイルの定義


#FTM-X-MEDIA-SEQUENCE:xx
開始場所が何番目のシーケンスかの定義
xxは数値この数値と内容リストから、ファイルの結合順を導きだす。

#FTMINF:[ftmファイルのアドレス]
メディアファイルのデータ

■fthファイル(FlvTakHeaderファイル)
バイナリファイルで内容はflvの冒頭定義 + 映像の先頭パケット(AVCのみ) + 音声の先頭パケット(AACのみ)で構築されたファイル

■ftmファイル(FlvTakMediaファイル)
バイナリファイルで内容はflvの各メディアパケット(ただしタイムスタンプに細工あり)

ぶっちゃけると、先頭からファイルを入手すればcat結合でFLVファイルに復元することが可能。

$ cat index.fth > data.flv

$ cat 0.ftm >> data.flv
$ cat 1.ftm >> data.flv
$ cat 2.ftm >> data.flv
$ cat 3.ftm >> data.flv
$ cat 4.ftm >> data.flv
$ cat 5.ftm >> data.flv
$ cat 6.ftm >> data.flv
...
でdata.flvがちゃんとしたflvファイルになる。
これをnetStream.appendByteにむかってやってるのが、HttpTakStreamingになります。

ちなみに転送媒体をファイルではなくrtmfpのノード間通信にしたのが過去の記事のやつです。(p2pで高画質配信したいというやつ。)netGroupでは無理でしたが、netStreamでの転送なら動作可能です。

では、本日の由なしごとでした。

2012年6月17日日曜日

mediastreamingのデモができました。

最近いろいろやっていたmediastreamingのデモができました。

いまのところ次のような状況です。

■構成:
rtmpの配信クライアント→FlashMediaServer4→Flazrベースのjavaクライアント→セグメント用ファイル→クライアント


■対応セグメント:
HttpTakStreaming(Flash用)のftl、fth、ftm
HttpLiveStreaming(apple用)のts、m3u8
Mp3Streaming(apple用)のmp3、m3u8
(jpegMp3Streaming:将来つくる予定)

■デモ概要:
49.212.39.17のsakuraのvps上にFlashMediaServer 4.5をインストールし、Flazrのプログラムでストリームを監視しています。
適当な配信プログラムで次の放送を実施します。
rtmpアドレス:rtmp://49.212.39.17/test
ストリーム名:test

しばらくすると必要なコンバートがはじまるので、各セグメントにアクセスしてデータを視聴します。
Flashで見る場合
http://49.212.39.17/stest/player/HttpTakStreamingPlayer.htmlにアクセスします。
playボタンを押せば視聴がはじまります。

iOSデバイスで見る場合(HttpLiveStreaming)
MobileSafariで
http://49.212.39.17/stest/ts/test/index.m3u8
にアクセスすればOK

iOSでバイスで聴く場合(Mp3Streaming)
MobileSafariで
http://49.212.39.17/stest/mp3/test/index.m3u8
にアクセスすればOK

■いまのところわかっているバグ_
h264WebStreamerのデモで配信すると動作が芳しくない。
・FlashMediaLiveEncoderのAACを使うとhttpLiveStreamingで音飛びが発生する?
・たまにmpegtsのデータがおかしくなる。(音声の同期がくずれる?)

■今後やりたいこと
・とりあえず、安定化。
・適当な放送プレーヤーと視聴プレーヤーをwonderflあたりに作りたい。
・jpegmp3ストリーミングの構築
・iphone用の適当な視聴プレーヤーをjsdo.itあたりに作りたい。
・無料webスペースにセグメントファイルを配布する実験。
・amazonS3あたりにsegmentを配置して大規模配信のテストやってみたい。

とりあえず、早急には地に足がついた感じの安定感がほしいですね。
まだまだネタレベル。

以下追記

いまのところキーフレームベースで切り分けするようにしているので、時間ベースで均等にわけるようにすれば、もっと安定するかな・・・開始動作が安定しそうにないけどw。

□デモを試してみたい方おりましたら
red5のpublisherか、FlashMediaLiveEncoderあたりで、rtmp://49.212.39.17/test向けにtestという配信やってみてください。
ただし一般的に問題のある配信(アダルトとか違法なものとか)はご遠慮ください。

なんか問題があったり飽きたりした場合は撤去しますので、あしからず。

□ソースコード他
Flazrまわりの変換動作のソースコード
https://github.com/taktod/streaming/tree/mediastreaming
HttpTakStreamingのソースコード(主にFlash)
https://github.com/taktod/HttpTakStreaming
HttpLiveStreamingのmp3化はこのブログをひっくり返してもらえばでてくると思います。
HttpLiveStreamingそのものはgoogle.comあたりで検索してもらえればいろいろ情報がでてくるかと思います。

2012年6月15日金曜日

FlashMediaServerのメモ

SakuraのvpsにFlashMediaServerをいれました。
いれたといってもDevelop版ですけどね。

今回いろいろなsegmentをつくるプログラムを書いてるわけですが、元になるサーバーをFlashMediaServerにしたいと思います。

理由はこんな感じ
1:小規模solutionに展開していいらしい。
え?小規模ソリューションの展開にご使用していいの?

2:Flazr経由でのFlashMediaServerのデータのダウンロードができる件。
Red5のRtmpClientでは無理だったんですが、Flazrなら接続もデータのダウンロードも可能です。もちろんxuggleのffmpegのつなぐことも可能でした。まぁ、ちょっと謎解きが必要ですけど。なお、H.263のDisposable InnerFrameの件もRed5じゃなければ問題なく扱えるみたいです。

3:堂々とFlashMediaLiveEncoderが使える件。
Adobeが提供している無料で高画質配信できるアレです。
ライセンスにたしか、FlashMediaServerにしか流しちゃだめよというのがあったかと思います。
これですね。Flash Media Serverには流してよし、このソフトをつかってサーバーや実行ファイルをつくったり、他のプログラム(ストリームをやりとりする系)に流すのはだめって書いてあります。

まぁ、FlashMediaServerのライセンスにFlash以外の3rdパーティーのクライアントでつないじゃダメといった条項はなさそうだし、今回やりたいことはオッケーであろうと判断しました。

まぁ、単なる言い訳ですね。


さて、サーバーに導入するにあたってRed5のときと同じく、特定のアプリだけにしかアクセスできなくしたいと思います。

[fms]/applicationsの中にある邪魔なプログラムをすべて撤去します。(liveとかvodとか)
で、アプリ用のディレクトリを作ります。
今回はtestというディレクトリにしました。(あとで多分変更する。)
[fms]/applications/test/
これだけでアプリケーションとして有効になるので
rtmp://[ドメイン]/test
でアクセスできるようになるわけですが、これだけだと、任意のRoomアクセスできるし、ストリームも流し放題になります。

そこで次のようにやりました。
[fms]/applications/test/main.ascを準備して以下のコードを書きました。

application.onPublish = function(client, stream) {
        if(stream.name != "test") {
                this.disconnect(client);
        }
}
if(application.name != "test/_definst_") {
        application.shutdown();
}

test/_definst_以外のアプリケーションは生成させない。(room)を禁止する。
testという名前以外で放送開始したら、クライアントを切断させる。

ついでに[fms]/applications/test/streams/のディレクトリの所有者をrootに変えました。
これでrecordで放送されてもファイルはできません。

以上で特定のアプリのみRoom禁止、放送もできるけど放送可能なストリーム名は固定され、かつ録画もできない

という状況をつくりました。