12
9

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

SkyWayAdvent Calendar 2018

Day 2

Raspberry Pi + Node.jsでSkyWayを動かしてみる

Posted at

Raspberry PiでSkyWayが動作するskyway-webrtc-gatewayというSDK(?)をNode.jsで使ってみます。

ハンズオンでRubyでやった内容

先日、ハンズオンが行われたのですが、 ラズパイにつないだLEDをWebから制御しつつ、その様子を接続したカメラでWebから監視する仕組みを作りました。

リモートLチカ監視ですね。

こんな感じです。

当日はRubyで実装を試したのですが、個人的にはNode.jsでやりたいのでNode.jsで動かしてみました。

Raspberry Piの準備

Raspberry PiのOSのインストールなどは各自やっておきましょう。
ちなみにハードウェアはRaspberry Pi 3 B+を使います。zeroだと動きませんでした。

また、 Node.jsのインストールもしておきましょう。
今回はNode.js v11.0を使っています。

関連ソフトウェアの準備

skyway-webrtc-gatewayを利用するにあたりラズパイに関連ソフトウェアをインストールしておきましょう。

$ sudo apt install autoconf automake libtool
$ sudo apt install gstreamer1.0-tools gstreamer1.0-plugins-good gstreamer1.0-plugins-ugly libgstreamer1.0-dev libgstreamer-plugins-base1.0-dev
$ git clone git@github.com:thaytan/gst-rpicamsrc.git
$ cd gst-rpicamsrc
$ ./autogen.sh --prefix=/usr --libdir=/usr/lib/arm-linux-gnueabihf/
$ make
$ sudo make install

npmパッケージのskyway-gatewayを使ってみます。

$ npm i skyway-gateway

ハローワールド

Raspberry Pi側

  • app.jsを作成
app.js
'use strict';
const SkyWay = require('skyway-gateway');
 
const options = {
    apikey: `My SkyWay API Key`,
    peerid: process.argv[2]
}
 
const skyway = new SkyWay(options);
(async () => {
    await skyway.init()
    await skyway.start()
})();
  • 実行
$ node app.js hogehoge

peeridというコネクションを識別するためのIDを指定して実行します。このサンプルコードと実行例だとhogehogeがpeeridになります。

接続を確認する母艦側

今回は母艦はMacになります。

Macのブラウザで↓のWebサイトを開いて、Raspberry Piのカメラ映像を受け取ります。

<!DOCTYPE html>
<html>
    <head lang="ja">
        <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
        <title>SkyWay JS SDK Tutorial</title>
    </head>
 
    <body>
        <input type="text" id="target_id_box" />
        <button id="call_button">call</button>
        <br />
        <input type="text" id="chat_box" />
        <button id="chat_button">send message</button>
        <br />
        <video id="remote_video" muted="true" autoplay playsinline="true"></video>
 
        <script src="https://cdn.webrtc.ecl.ntt.com/skyway-latest.js"></script> 
        <script>
            'use strict';
            // Get Parametersを取得するやつ
            function getQueryParams() {
                if (1 < document.location.search.length) {
                    const query = document.location.search.substring(1);
                    const params = query.split('&');
 
                    const result = {};
                    for(var param of params) {
                        const element = param.split('=');
                        const key = decodeURIComponent(element[0]);
                        const value = decodeURIComponent(element[1]);
                        result[key] = value;
                    }
                    return result;
                }
                return null;
            }
 
            window.onload = ()=> {
                const query = getQueryParams();
                // api keyはGet Parameterから取る
                // これは演習で簡単に設定するための雑な処理で推奨ではない
                const key = query["key"];
                //peer idもGet Parameterから取る
                const peer_id = query["peer_id"]
                const peer = new Peer(peer_id, {
                    key: key,
                    debug: 3
                });
 
                peer.on('open', function (a) {
                    console.log(a);
                    // SkyWay Serverに自分のapi keyで繋いでいるユーザ一覧を取得
                    let peers = peer.listAllPeers(peers => {
                        //JavaScript側で入れたやつとRuby側で入れたやつが出てくればよい
                        console.log(peers);
                    });
                });
                peer.on('error', (err) => alert(err.message));
 
                document.getElementById("call_button").onclick = ()=>{
                    const target_id = document.getElementById("target_id_box").value;
 
                    const call = peer.call(target_id, null, {videoReceiveEnabled: true });
                    call.on('stream', (stream) => {
                        document.getElementById("remote_video").srcObject = stream;
                        console.log(call)
                        setTimeout(() => {
 
                        },1000 * 10);
                    });
 
                    const connection = peer.connect(target_id, {serialization: "none"});
                    connection.on('data', (data) => console.log(data));
 
                    document.getElementById("chat_button").onclick = ()=> {
                        const message = document.getElementById("chat_box").value;
                        console.log(message);
                        connection.send(message);
                    };
                };
            };
        </script> 
    </body>
</html>
  • ローカルサーバーを起動
$ python -m SimpleHTTPServer 8080

GPIOを利用

GPIO利用の場合はonoffというモジュールを使うのが個人的にはオススメです。
他のモジュールはsudo実行が必要だったりと権限周りでこけました苦笑

$ npm i onoff
'use strict';
const SkyWay = require('skyway-gateway');
 
const options = {
    apikey: `My SkyWay API Key`,
    peerid: process.argv[2]
}
 
const skyway = new SkyWay(options);
(async () => {
    await skyway.init()
    await skyway.start()
})();
 
const Gpio = require('onoff').Gpio;
const led = new Gpio(21, 'out');
 
skyway.dataListen((msg, rinfo) => {
  const mes = msg.toString('ascii', 0, rinfo.size);
  console.log(`data len: ${rinfo.size} data: ${mes}`);
 
  if(mes === 'on'){
    led.writeSync(1)
  }else{
    led.writeSync(0)
  }
});
  • 配線

以下のように21番ピンに配線します。

参考: [SkyWay WebRTC Gatewayハンズオン Chapter0](https://qiita.com/nakakura/items/9d5fb1ff43c40c97c244)

これで実行することで、最初のGIFのようにフォームからonって送るとLEDがついて、offって送るとLEDが消えます。

所感

ちょっとまだ挙動が不安定な気がするけどとりあえずは動きました。
不安定なところ解消しつつNode.jsプロセスの永続化なども試して知見公開していきたいです。

npmページのREADMEもご確認ください〜

https://www.npmjs.com/package/skyway-gateway

12
9
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
12
9

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?