Edited at

obnizOSを使ってm5stackをサブディスプレイ化してみた

m5stack.jsを出したので色々遊んでみました。

やっぱりちっちゃいディスプレイがあるので、そこで遊びたいですよね。

画像表示させたいですよね。TVとかyoutubeを流したいですよね。サブディスプレイにしたいですよね

というわけでやってみました。


つくったもの

だいたい60行ぐらいのプログラムです。 お手軽感満載です

かわりにソースコード外で色々頑張ってるところがあります。


しくみ

サブディスプレイのキャプチャを撮ってm5stackで表示しています。

色々小ネタはありますが、基本的にはそれだけです。

これを実現するのに、chrome(HTML)とobnizOSを使っています。

スクリーンショット 2019-08-24 10.36.26.png

サブディスプレイの画像取得にはchromeのgetDisplayMediaをつかっています。

最近のブラウザは便利で、ディスプレイのキャプチャまで取れてしまうんですね・・・恐ろしい時代・・・。

流れとしてはこれだけです。

1. 仮想サブディスプレイをつくる(今回未実施)

2. ディスプレイの内容をHTMLで取得する

3. 取得した画像をobnizOSをつかってM5Stackへ転送する

仮想サブディスプレイをつくる(今回未実施)のところだけ、よくわからなかったのでリアルディスプレイをつないでごまかしました。世の中には仮想ディスプレイデバイスとかあるっぽいので、それを使えばできるかと思います。(でもホントはソフトでやりたい)


作り方

まずはm5stackにobnizOSをインストールします。

こちらの記事とか、公式サイトに手順が書かれています。

obnizOSをインストールしたら、htmlアプリを作るだけです。

localhostか、もしくはSSL対応のところにHTMLをホスティングして作ります。

obnizの開発者コンソール内に作るのが楽です。

プログラムとしては、


  1. スクリーンショットを撮ってvideoタグに描画する

  2. videoの内容をcanvasに描画する

  3. canvasの内容をm5stackに描画する

だけです。


プログラムの下準備

HTML上で、canvasとvideoタグを宣言しておきます

<video controls id="v" width="480px" height="270px" autoplay></video>

<canvas id="c" width="320px" height="260px"></canvas>

JavaScript側でも使うので、変数を作っておきます

  let canvas = document.getElementById("c");

var video = document.getElementById("v");


スクリーンショットを撮ってvideoタグに描画する

まずはvideoタグにスクリーンショットが入るようにします。

  navigator.mediaDevices.getDisplayMedia({audio: false, video: true}).then(stream => {

video.srcObject = stream;
})

これを実行するとchrome上でどの画面を描画するか?のダイアログが出てきて、画面を選ぶことができます。

スクリーンショット 2019-08-24 10.35.18.png

面白いのがchromeのタブ(バックグラウンド実行も可)を選ぶこともできて、これはこれで色々できちゃうんですね。

ここで画面を選ぶと、その内容がvideoタグに入るようになります。


videoの内容をcanvasに描画する

canvasのdrawImageでそのままかけますので、canvasに描画します。

var ctx1 = canvas.getContext('2d');

ctx1.drawImage(video, 0, 0, 320, 240);

このとき、矩形抽出とかすれば特定領域だけm5stackに表示とかもできます。

2行でできてシンプルですね


canvasの内容をm5stackに描画する

ライブラリを使うので、scriptタグで読み込んでおきましょう

  <script src="https://unpkg.com/obniz@2.2.0/obniz.js"></script>

<script src="https://unpkg.com/m5stackjs/m5stack.js"></script>

obnizOSが入ったm5stacktと接続します。

OBNIZ_ID_HEREのところはm5stackにいれたobnizOSの番号を入れてください。

  let m5 = new M5Stack('OBNIZ_ID_HERE');

m5.onconnect = async function () {
await m5.m5display.onWait();
...
};

m5stackに描画するには、canvasをdrawするだけです

      m5.m5display.draw(ctx1);

これで出来上がりです!


プログラム全体

プログラムとしてはこちらです!

だいたい60行ぐらいかな。

プログラムすべてを表示


<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>youtube stack</title>
<script src="https://obniz.io/js/jquery-3.2.1.min.js"></script>
<script src="https://unpkg.com/obniz@2.2.0/obniz.js"></script>
<script src="https://unpkg.com/m5stackjs/m5stack.js"></script>
</head>
<body>

<video controls id="v" width="480px" height="270px" autoplay></video>
<canvas id="c" width="320px" height="260px"></canvas>

<script type="text/javascript">
let canvas = document.getElementById("c");
var video = document.getElementById("v");

let m5 = new M5Stack('OBNIZ_ID_HERE');

m5.onconnect = async function () {
await m5.m5display.onWait();
var ctx1 = canvas.getContext('2d');

while (1) {
ctx1.drawImage(video, 0, 0, 320, 240);
m5.m5display.draw(ctx1);

//描画サイクルが早すぎるとエラーになることがあるので調整
await new Promise(resolve => {
setTimeout(resolve, 100)
});
await m5.pingWait();
}
};

navigator.mediaDevices.getDisplayMedia({audio: false, video: true}).then(stream => {
video.srcObject = stream;
})

</script>
</body>
</html>


サブディスプレイとして活用して遊びましょう!


応用

chromeタブを描画範囲にしてyoutubeを流してみました。