読者です 読者をやめる 読者になる 読者になる

Take’s diary

Macとマイコンに関すること--ワクワクの製作日記

Raspberry Pi2 で自分の作ったプログラム 動画 をちょっと高速にWeb配信しませんか?(その2)

 前回はPi2へのOpenframeworksのインストール方法を説明しましたが、いよいよ動画配信ができるアドオンをインストールしてみます。たまたまcvl-robotさんの記事を見つけて

http://cvl-robot.hateblo.jp/entry/2014/11/05/163541

ofxHttpというアドオンを知りました。この例ではWindows環境でのOpenCVとof(以降Openframeworks)の連携みたいなので、Pi2環境でofのみで動かそうとしている初心者に近い私にはあまり理解できませんでした。

 Pi2ではofxHTTPのexampleが簡単にコンパイルできず、大変な思いをしましたが、今回改めてまとめて見ると、かなり簡単に実現できることがわかると思います。

 このアドオンを使うとOpenCV(ofxCV)を始め、ofで作ったプログラム画像がほとんどすべて画像配信可能なので、とっても面白いことができそうです。

 mjpeg-streamerやmotionをインストールすればipカメラなんかすぐできるじゃん...。みたいなことを考えている皆さん!!。違うんです。OpenframeworksやPythonライブラリのSimpleCVを使うと、画像を加工、さらにPiではセンサー類の数値を加味して画像配信できます。このことから、小さなRaspbery piでofxHTTPやSimpleCVを使うメリットは計り知れないものがありますが、今回はクラウドパイを使ってRaspbery piをipカメラ化するところまで実験して見ました。(私のPi2ではSimpleCVの画像配信はなぜかすぐ切れてしまいます)

             f:id:TAKEsan:20150826080141p:plain

ofxHTTPをダウンロード

 Openframeworksのホームページに行きaddonsのページでofxHTTPをダウンロードします。bakercp/ofxHTTP · GitHub

  私の場合インターネットから圧縮ファイルをダウンロードして解凍までをMacで行い、ForkLiftという有料ソフトでSFTP接続したPiへ解凍したファイルを移動しています。これを使うとMacでPiの中のファイルをファインダー感覚で簡単に操作できます。

f:id:TAKEsan:20150721220139p:plain

              ForkLiftの画面

 Cyberduckというほぼ同様のソフトがありますが、私の環境では接続が頻繁に切れてしまうので、有料でもかなり安定しているForkLiftを使っています。さらにPiをMac付属のターミナルでSSH接続して、前に紹介したMac上でPiのHDMI画像を表示させれば、とても楽に省スペースで開発作業ができます。

 解凍したファイルは、ofxHTTP-masterという名称になっていますが-masterを消してpi2のOpenframeworksフォルダの中にあるaddonsと名前の付いたフォルダに移動します。

   自分のofフォルダ/addons/ofxHTTP

このofxHTTPフォルダにあるREADME.mdを見ると5つのアドオンがさらに必要とのことなので、

     https://github.com/bakercp/ofxIO

     https://github.com/bakercp/ofxMediaType

     https://github.com/bakercp/ofxSSLManager

     https://github.com/bakercp/ofxTaskQueue

     https://github.com/bakercp/ofxNetworkUtils

 も同様の方法でインストールします。

 サンプルプログラムフォルダexample_basic_ip_video_serverに行き,

   自分のofフォルダ/addons/ofxHTTP/example_basic_ip_video_server

ターミナルから make run してみます。

 ofは、コンパイルするプロジェクトフォルダの位置について、厳格な規則がありますが、テストだけならこの位置からコンパイルできるので、この方法が一番簡単です。

 が......、今回のサンプルは、Pi2ではコンパイルエラーになってしまいます。

ofxHTTPのExampleがPi2ではコンパイルエラー

※2015/11/20 現在Pi2 に、Raspbian最新版、Openframeworks0.9.0 へのバージョンアップ、ofxHTTP及び上記5つのアドオンの最新版をインストールすれば、次の操作(POCOの再コンパイル)は必要ありません。(ただし今回紹介しているプログラムを動かすと、Safariの場合はすぐに画面が固まる。Chromeだとなぜか繋がる。なぜ? 現在検討中--->OSXのバグらしい。2016/4/30時点ではSafariで安定している)

 ここからが大変。ofの場合、今回の様に簡単にビルドが通らないこと(Pi2では特に)が多いので途中で投げ出したくなりますが、皆さん無償ですてきなアドオンをで公開していることを思うと、文句を言ってもしょうがありません。趣味として割り切ってしまえば、このあたりがとても面白いところではあります。

 やっと探したヒントがここにありました。

Strange ofHttpResponse response codes on Raspberry Pi 2 - openFrameworks

 このフォーラムの中間付近に書いてあるファイルを

danomatika/apothecary · GitHub ダウンロードします。

 ここからが私がかなり戸惑ったところですが、結局次の様な手順でOKでした。

 解凍したapothecary-master/scripts/apothecary つまりapothecary-masterの中にあるapothecaryフォルダをPi2の ofフォルダ/scripts の中に入れます。さらにこの中に移動して apothecary というファイルをpi付属のtext editerで開き、815行にある OS='./ostype.sh' を OS='sudo bash ./ostype.sh' に変えて保存します。

 次にターミナルから(ofフォルダ/scripts/apothecaryに移動して)sudo bash ./apothecary update poco と入力してコンパイルします。コンパイルに1時間程度かかりますがなんとかエラーなしで終了すると思います。

 要はPOCOというライブラリがPi2では正常に動かないので、再コンパイルするということの様です。

プログラムを修正する

 このexampleは、ビデオファイルを動画配信する様になっていますが、今回はUSB接続したWebカメラ画像を動画配信する内容に変えたいので、ソースファイルを次のように変更します。

 example_basic_ip_video_server/src/ofApp.h の変更

------------------------------------------------------------------------------------

#pragma once

#include "ofMain.h"

#include "ofxHTTP.h"

class ofApp: public ofBaseApp

{

public:

    void setup();

    void update();

    void draw();

 

    ofx::HTTP::BasicIPVideoServer::SharedPtr server;

 

    ofVideoPlayer player;

    ofVideoGrabber cam;

};

------------------------------------------------------------------------------------

つまりofApp.hの最後に、ofVideoGrabber cam; を追加。

さらにexample_basic_ip_video_server/src/ofApp.cppの中身を修正します

------------------------------------------------------------------------------------

 

#include "ofApp.h" 

 

void ofApp::setup()

{

    ofSetFrameRate(60);

 

    // Set up our video to broadcast.

    //player.loadMovie("fingers.mp4");

    //player.play();

    //player.setLoopState(OF_LOOP_NORMAL);

    cam.initGrabber(640,480);

    ofx::HTTP::BasicIPVideoServerSettings settings;

 

    // Many other settings are available.

    settings.setPort(8080);

 

    // The default maximum number of client connections is 5.

     //settings.setMaxClientConnections(2);

 

    // Apply the settings.

    server = ofx::HTTP::BasicIPVideoServer::makeShared(settings);

 

    // Start the server.

    server->start();

 

#if !defined(TARGET_LINUX_ARM)

    // Launch a browser with the address of the server.

    ofLaunchBrowser(server->getURL());

#endif

 

}

void ofApp::update()

{

    // Update the video player.

    //player.update();

     cam.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(cam.getPixelsRef());

    //}

}

void ofApp::draw()

{

    // Draw the video on the server screen.

    cam.draw(0,0);

 

    // Display the number of connected clients for reference.

    std::stringstream ss;

 

    ss << "Num clients connected: ";

    ss << server->getNumConnections();

 

    ofDrawBitmapStringHighlight(ss.str(), 20, 20);

}

 

------------------------------------------------------------

 

 これだけでカメラを使ったネイティブアプリが作れるのですから驚きですよね。コメントを抜くと、ほんのメモ程度のプログラムでjpeg配信できるんです。画像の大きさなどは

  フレームレイト           :ofSetFrameRate(60);

   配信する画像の大きさ:cam.initGrabber(640,480);

  配信するPi2のポート   :settings.setPort(8080);

の数値変更でカスタマイズできます。画像の大きさについては、あらかじめ設定された大きさ以外の数値は受け付けないので、注意が必要です。デイバイスIDはUSB接続したWEBカメラは0になりますが、プログラムで何も指定しない場合は、自動的に0を認識します。

 フレームレイトはとりあえず最大の60にしておきます。最大にしても、実行環境によってスピードが遅くなりますが、それでもけっこう高速です。少なくともmjpeg-streamerよりは配信スピードがUPします。ポート番号は8080以外でもOK。ポート番号に関して、いろいろ約束事があるようですが、セオリーに違反しない程度に変更して構わないと思います。

動画配信してみる

 今変更したファイルを保存し、make run (ただしsrcフォルダから1つ上に移動して)。無事にビルドできれば、あとは他のコンピュータのブラウザからPiを呼び出すだけです。

ちなみにサファリでは今回の場合 IPアドレス:ポート名--->xxxx.local:8080

で動画が確認できます。カメラは前の記事でも説明したように、画像が安定しているロジクール

これと同じ様なことがintel Edisonでできるとかなり面白くなると思いますが、これも大分時間がかかりましたが実現できています。今後に乞うご期待。

クラウドパイをつかってみる

 クラウドパイって知ってますか?。これを使うと遠隔地から簡単にpiサーバーに接続できます。インストール方法はスイッチサイエンスさんが詳しく説明しておられますので、そちらを参考にしてください。iPhone環境だとブラウザが特定されますが、特に問題なく動いています。このソフトに関してあまりにも情報が少ない(メーカーやる気あるのかな?)ので、私なりに「ofxHTTPも使える」ことを提案したいと思います。

 参考にexample_basic_ip_video_serverを実行してPiでjpeg配信を実行、iMac(有線)とMacbook(Wifi)のサファリとiPhone(クラウドパイ4G回線)から同時に画像を取り込んでいる様子を動画にしましたので、確認してみてください。なんかワクワクしませんか?

 

                            

  画面中央:HDMI接続されたPi画面(ofxHTTPのサンプルを実行している)

  画面左 :Macbookのサファリ画面(Wifi接続)

  画面右 :iMac上のサファリ画面(有線)

  画面右下:iPhoneクラウドパイ専用ブラウザ(4G回線)

  見難いがカメラはiMac上部に取り付けている

  

今回はこれまで。openframeworksではPiのioを使うアドオンもあるのですが、今後の応用はあと回しとします。

今後の予定

 いろいろなマイコンボードを手に入れたけど,もう一歩踏み込んで面白そうなことをやってみたいと思っている皆さん。日本のWeb上ではそんな記事が意外に少ないと思いませんか?。海外の皆さんは、惜しげもなく自分の知識を公開しています。すぐにマネーにすることを考えないで、批判も恐れずにどんどん自分のやってることを公開すれば、とってもHappyになれて、日本でもっとこの分野が活性化できるんじゃないかな。

 あまり知識のない者でも、目標があれば今の時代なんとかなるという実証も兼ねて今まで実現できたことを次回以降にメモしたいと思います。(ググりまくった情報の合成が80%くらいですけど)乞うご期待!!

 

  Pi2でofxFaceTrackerを実現させる

  スイッチサイエンス版Eagletを使ってMEMS非接触温度センサーを動かす

  EdisonでμOled(4dsystems)を動かす。(かっこいいスイッチのシュミレーション)

  Openframeworks初心者が、iOS環境でアプリを作る

  iOSofxFaceTrackerを実現させる

  EdisonとiPhoneWifiで連携させる(MEMS非接触温度センサー応用編)

  いろいろなEdisonのEagletをためす。

  Edison+Henry基盤でSimpleCVを使って動画配信する

  MicroPython(Pyboad)を使ってカラーディスプレイ(μOled128)を動かす

  udooで面白いことをやってみる