この記事はIoTLT Advent Calendar 2020の12月12日の記事です。
カメラ切替器ATEM Miniをobnizで操作してみたので概要を記載します。
カメラ切替器ATEM Mini
コロナの影響で遠隔授業やオンラインイベントが増え、動画を撮影する人が増えました。動画を撮影する際、自分の姿、プレゼン資料、机上に用意した道具などの映像を随時切り替えて撮影したくなります。それを実現してくれるのがカメラ切替器ATEM Miniです。ATEM Miniは4系統のHDMI入力をボタン操作で簡単に切り替えられるハードウェアです。
ATEM Miniには、カメラの切り替えだけではなく複数の映像を組み合わせたりテロップを追加したりする機能があります。
ATEM Miniの性能を引き出すにはソフトを使う
カメラの切り替えやPicture In Pictureといった基本的な機能は、ATEM Miniに装備されているボタンを押すことで実行できます。しかし、Picture In Pictureのサイズや表示位置を変えるとか、表示するテロップの中身を変更するといった複雑な操作は装備されているボタンでは行えません。
複雑な操作はPC上で起動するATEM Software Controlで行います。
細かな設定を柔軟におこなえるようにATEM Software Controlにはボタン、プルダウンメニュー、パラメータ入力欄などが所狭しと並んでいます。細かな設定ができるのはいいのですが、動画撮影時に使おうとすると操作する部分を見つけるのに時間がかかったり、間違えて他の部分を操作してしまうことがよくあります。
よく使う機能を物理ボタンとして用意できれば、押し間違いがなく便利です。
秘密兵器 Elgato STREAM DECK ・・・ でも・・・
ATEM Software Controlで扱う機能を物理ボタンに割り当てることができる製品があります。ElgatoのSTREAM DECKがその製品です。
STREAM DECKをATEM Miniを組合わせて使う方法は、鈴木康之さんのyoutube動画 「配信だけじゃない録画でも便利 Elgato STREAM DECK」で詳しく説明されています。
STREAM DECKはとてもすばらしい製品なんですが17,000円ぐらいします。私には買えません。そこで物理ボタンを自作してみることにしました。
ATEM Miniを操作するライブラリを探す
ATEM Miniを発売しているBlack Magic Design社がSDKを公開しています。ガチでプログラムを書きたい人はこのSDKを使えばいいのですが、なるべく楽をしたい私には難易度が高すぎます。
簡単に使えるライブラリがあるんじゃないかとおもって検索してみたら、北崎恵凡さんが書いたQiita記事「Node-REDからATEM miniを操作してみた。」が見つかりました。
記事を読んでみると、
- blackmagic-atem-noderedというNode-REDモジュールが公開されている
- 使い方は簡単
ということがわかりました。
このNode-REDモジュールを使ってみることにしました。
物理ボタンの実現方法・・・obnizの利用
ATEM Miniとの接続部分はblackmagic-atem-noderedモジュールを使えばできることはわかりました。次に必要なのは物理ボタンのクリックを検知する部分の実装です。制約条件として「Node-REDでプログラムをかける」ことが必要です。
検索してみたところ、木戸康平さんのQiita記事「Node-REDのobnizノードがバージョンアップした!」が見つかりました。
2種類のモジュール「obniz function」、「obniz repeat」が用意されていて、obnizのプログラムがNode-RED上で簡単に書けることがわかりました。
実装
物理ボタンとobnizの配線
大き目のタクトスイッチを3個obnizにつなぎました。IO0をGNDにし3つのボタンで共有しています。IO1,2,3は各々のボタンに配線しています。
Node-REDフローの全体像
作成したNode-REDのフローはこちらです。
緑色のノードはデバッグ情報表示用なので、このプログラムの動作に必要なのは
- obniz repeatノード「obniz1Y」
- Functionノード「Macro呼び出し」
- ATEM Miniノード「ATEM mini」
の3ノードだけです。
obniz1Yノードのプログラム
obnizのプログラムは2つの部分から構成されます。
- obnizIDの指定と初期化処理
- 繰り返し呼び出されるプログラム
①には3個のボタンに対応するobniz Buttonパーツの初期化処理を記述しました。
IO0のGNDは3個のボタンで共有するのでbutton1とbutton2にはgnd:の指定を省略しています。
②には、3個のボタンの状態を取得し、押されているボタンがあればその番号をmsg.payloadに入れて送信するプログラムを記述しました。
繰り返し間隔であるInterval(ms)には100を設定しました。実際の運用ではもう少し小さな値にした方がボタンのレスポンスを良くできると思います。
Macro呼び出しノード
このノードは、obniz1Yノードからボタン番号を受信し、それを使ってMacro呼び出しのJSONデータを作成します。実際にATEM Miniにjsonデータを送る動作はATEM miniノードが行います。
ATEM miniノード
使用するATEM MiniのIPアドレスを指定します。
プログラムの動作
3つのボタンに次のようなマクロを割り当てました。
- button0: Picture In Pictureを画面左半分に表示
- button1: Picture In Pictureを画面右半分に表示
- button2: Picture In Pictureを消去
button0, 1, 2と順に押した場合の画面の変化を動画にしました。最初はPicture In Pictureが無い状態から始まり、button0を押すと左半分にPicture In Pictureが表示されます。button1を押すとPicture In Pictureが右半分に表示されます。button2を押すとPicture In Pictureが消えます。
今後の課題
obnizでボタンの状態を取得する部分のプログラムは、obniz repeatノードを使ってポーリングするプログラムになっています。これでは無駄にCPUを消費してしまうし、消費を抑えようとしてポーリング間隔を長くするとボタンのレスポンスが悪くなってしまいます。
obnizにはボタンが押された時にコールバック関数を呼び出す仕組みがあります。これを使えば上記の問題は解決するのですが、obnizのNode-REDノードでコールバックを使う方法がわかりませんでした。この部分の書き方をobnizの中の人に聞いてプログラムをバージョンアップしようと考えています。
追記:コールバック関数を使うようにプロラムを変更
コールバックの使い方の詳しい解説を木戸康平さんが書いてくれました。
node-REDのobnizノードでコールバック形式に対応してみる