Help us understand the problem. What is going on with this article?

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

More than 1 year has passed since last update.

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

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

所感

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

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

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

Why do not you register as a user and use Qiita more conveniently?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away