androidでピアキャス配信するアプリを作る
Peercast for Androidの登場からはや数ヶ月、皆様いかがお過ごしでしょうか。私は思いました。ピアキャスの視聴はできる。でも配信はできない?
この疑問を解決するために試行錯誤した事柄を以下にまとめました。これからピアキャス用アプリを作る方の助けになればと思います。
1.android上でどうやってエンコードするか
2.エンコードしたデータをピアキャスに渡すには
1.android上でどうやってエンコードするか
ARなどで使われる画像認識ライブラリOpenCVをJavaから利用できるようにしたJavaCVというものがあります。その中にはカメラの入力などから動画を生成することができるFFmpegFrameRecorderが含まれていて、これを使うと動画ファイルの作成だけでなくエンコードしたデータをサーバに送信することができます。
flvでエンコードしてrtmpサーバに送信する
recorder = new FFmpegFrameRecorder(“rtmp://192.168.0.10/live/test”, 640, 480, 2);
recorder.setFormat(“flv”);
h264+AACのmp4ファイルを作成する
recorder = new FFmpegFrameRecorder(“/mnt/sdcard/test.mp4”, 640, 480, 2);
recorder.setFormat(“mp4”);
recorder.setVideoCodec(AV_CODEC_ID_H264);
recorder.setAudioCodec(AV_CODEC_ID_AAC);
rtmpのように外部にサーバを用意する場合はこれだけでもう完成したも同然です。ところがこれをピアキャスで利用しようとすると次の問題に突き当たります。ffmpegではwmv形式でエンコードすることはできても、ピアキャスにデータを送信することはできません。Windows Media Encoderがピアキャスにデータを渡せるのは、内部にサーバ機能を持っているからです。
2.エンコードしたデータをピアキャスに渡すには
通常のffmpegにはffserverというものがついていて、これがストリーミングサーバの役割をしています。もしこれを外部に用意できるなら、flvと同じようにwmv形式の動画を送信することができます。この2つを組み合わせるとwmeと同じ機能を持つことになります。もしffserverをandroidの中で起動出来れば、外部にサーバを用意しなくてもよくなります。しかし(今のところ)android用のffserverはありません。
ところでffmpegがサーバに送信するデータの中身はどのようなものでしょうか。単純なソケットサーバを作成してデータを受信してみると
POST /test.wmv HTTP/1.1 Transfer-Encoding: chunked User-Agent: Lavf/55.11.101 Accept: */* Connection: close Host: 192.168.0.10:8080 以下chunkedデータ
となっていてhttpのchunked形式のデータであることがわかります。そしてそのデータをそのまま(結合して)ファイルに保存すると、シークはできないものの再生可能なwmv形式のファイルができあがりました。
以前wmeのストリーミングをリレー・保存するソフトを作ろうと試みたとき、これと全く同じ物ができたことを思い出しました。つまりストリーミングデータとファイルの違いはストリーミングヘッダ※とindexが付いているかいないかだけの差であるということです。(実はrtmpでも同様です)
受信したデータにストリーミングヘッダをつけて、ピアキャス(やプレーヤー)に送信できればそれはストリーミングサーバを作ることと同じです。
つづく
※パケットの種類やサイズ情報を含む先頭12バイトのデータ