ofxHttpを使って、WindowsでMJpegの動画ストリーミングサーバーを作る
画像配信のノウハウは奥が深くて、理屈は分かっても自分で実装するのはなかなか大変です。Linuxで動画のストリーミング配信を行うのは、ffmpegのffserverなどを使えばいいのでとっても簡単です。しかし、Windows上でストリーミング配信をするアプリケーションは数多くありますが、それを自分で実装したい時に参考にできそうなコードは多くありません。
いい方法がないかなーと探していたところ、openFrameworksのaddonでbakercpさんが開発されたofxHTTPにIPVideoServerなる機能があることが分かりましたので、これを使ってみます。*1
1.ofxHTTPのインストール
[1]のサイトから、ofxHTTP-master.zipをダウンロードしてきて解凍し、フォルダ名をofxHTTPに整形して、openframeworksのaddonフォルダの中に放り込みます。
依存ライブラリである下記も同様にaddonの下に放り込みます。
- https://github.com/bakercp/ofxIO
- https://github.com/bakercp/ofxMediaType
- https://github.com/bakercp/ofxSSLManager
- https://github.com/bakercp/ofxTaskQueue
つぎに、openframeworksのprojectGeneratorを開き、addonにofxHTTP, ofxIO, ofxMediaType, ofxSSLManager, ofxTaskQueue、ofxJSONのチェックを入れて、空のプロジェクトを作ります。
ofxHTTPのフォルダの中にある、
example_basic_ip_video_server
のソースコードとテストデータであるbinフォルダとsrcフォルダを空のプロジェクトの物に上書き保存して、置き換えます。
2.動画配信アドレスの修正
IPVideoRouteSettings.cppの中で、画像配信URLが指定されています。
const std::string IPVideoRouteSettings::DEFAULT_VIDEO_ROUTE = "/ipvideo";
openCVでは、拡張子が無いと正しく画像形式を読み取ることが出来ないようですので、これを次のように書き換えます。
const std::string IPVideoRouteSettings::DEFAULT_VIDEO_ROUTE = "/ipvideo.mjpg";
実際の画像送信は次のように1枚1枚渡していますので、ここを動画ではなく自前のカメラ画像など好きな物に置き換えれば、なんでも送れます。
void ofApp::update()
{
// Update the video player.
player.update();// If the frame is new, then send it to the server to be broadcast.
if(player.isFrameNew())
{
// This can be any kind of pixels.
server->send(player.getPixelsRef());
}
}
3.openCVでの受信プログラム
OpenCVで受信するプログラムは次の通り。
https://gist.github.com/3a5250b438da055626c8.git
できたー。
生のTCPやOSCを使って画像送信プログラムを書くよりもずっと簡単かも。
最初からこうしておけばよかったな。。。
[2] c++ - IP camera and OPENCV - Stack Overflow
*1:ちなみにopenFrameworksなので、さまざまな動作環境で動きます。armなどでも行けるようなので、自作IPカメラも出来そうですね。 でも悪用は駄目よ。