ライブ配信レイアウトを作るNode.jsのフレームワーク
ライブ配信レイアウトを作るNode.jsのフレームワーク:
こんにちは。普段フロントエンド(とか)エンジニアをしていますが、趣味でRTAをやっている繋がりでオンラインやオフラインのゲームイベントの運営もやってたりします。
この記事、別の話をしようと思っていましたが、悩んだ結果、運営をやっている繋がりでNodeCGというフレームワークを使ったりmaintainerをしたりしている話をしようと思います。
https://nodecg.com
https://github.com/nodecg/nodecg
一言で言うと「ライブ配信のレイアウトをWeb技術で作るフレームワーク」です。
ちょっと何言っているのかわからないですね。
噛み砕くと
まだどんなものかよくわからないので、サンプルを動かしてみましょう。下のはGamesDoneQuick1というRTAイベントで使われた、NodeCGで作られたレイアウトです。(https://github.com/gamesdonequick/sgdq18-layouts)
ついでなので、実際のイベントで動いているところを見てみましょう
https://youtu.be/tsUvZ9yiN_U?t=1433
バックエンドにexpressが使われ、HTML+CSS+JSでブラウザにレイアウトを表示します。
NodeCGでレイアウトを構築するときにつくる、フロントエンドとバックエンドがセットになったものをbundleと呼んでいます。1つまたは複数のbundleを組み合わせて1つのNodeCGアプリを作るイメージです。
1つのbundleは
dashboardで操作すると、NodeCGのサーバーサイドを通してgraphicsに反映され、追加でサーバーサイドのロジックを書きたい場合extensionを定義する、といったものです。
せっかくなので何か作ってみましょう。必要なものはNode 8以上です。
なかなかセットアップが原始的ですが、許してください。2018年ですが本当に
これでNodeCGが起動するので、
右上の
...他に何も書いていないので数字しかいません。実際にレイアウトを作る際は、HTML、CSS、SVGなどを駆使して上の動画みたいなレイアウトを作ります。
さておき、dashboardのボタンを押してみましょう。
いい感じでリアルタイムに動いています。
今までブラウザでレイアウトを表示してきましたが、実施の配信で使うときはブラウザに写しません。何を使うかというと配信ソフトについているブラウザソースの機能です。
例えばOBS Studioは、内蔵のChromiumを使って配信に直接表示することができ、ブラウザに写してそれをキャプチャ、といった煩わしい手順がいらないです。こういった理由で、このような動的なレイアウトはNodeCGでなくてもHTML+CSS+JSが使われることが多いです。
全機能紹介するとキリがないので、抜粋しつつ
dashboardとgraphicsの中のJSでは、
これはNodeCGの中にある簡易的なデータベースのためのAPIで、代入された値を保存して同時に変更をlistenerに伝える仕組みです。dashboardで数を増やしたら、その瞬間サーバーを通してgraphicsに
Replicantは実際にファイルに保存されるため、何かの不具合でサーバーが落ちたとしても値が保存されます。(やり直しがないライブ配信ではかなり大事な機能です)
他にもいろいろ機能があります
基本的に薄く、unopinionatedに作られているため、例のようにplainなHTMLで作ったり、Reactで書いたりVueで書いたりなんでもできます。 (フレームワークの部分はPolymer 2でできていますが、中身を作る際は関係ありません)
Replicantの代入、変更、mutateに対してJSのProxyを挟むことで、変更を検知して各場所にWebSocketを通じて通知することで、すべての場所で同じデータを見ているような仕組みになっています。。
Proxyは興味深く、IE11で使用できずPolyfillも不可能なためまだ流行っていませんが、IE11を最初からサポートしていないNodeCGではこのような使い方ができています。(将来VueがリアクティビティをProxyで作り直すことも発表されています。)
(dashboardで値の変更)→(proxyがサーバーに通知)→(サーバーがgraphicsに通知)→(graphicsの表示が変更)
フロントエンドのリアクティブなフレームワークがHTMLとJSの間でリアクティビティを実現しているのと同じような関係を、クライアントとサーバーの壁を超えて実現しているあたり面白い仕組みだと思っています。
個人的な話をすると、1年半くらい前、このフレームワークを使って関わっているイベントのレイアウトを作るのが、本格的にプログラミングを始めるきっかけでした。
その後、TypeScriptの型定義をつけたり、テストのリファクタリングしたりしていたら、maintainerにならないかと誘われました。それまでは作者のLangeが1人でメンテナンスしてきたこともあり、まだまだ発展途上なフレームワークなので、できるだけ貢献していきたいです。
あと、海外では幅広いイベントで使われているのですが、日本で使っているのが自分ともう1人しか知らないので、もっと流行ってほしいですね!
こんにちは。普段フロントエンド(とか)エンジニアをしていますが、趣味でRTAをやっている繋がりでオンラインやオフラインのゲームイベントの運営もやってたりします。
この記事、別の話をしようと思っていましたが、悩んだ結果、運営をやっている繋がりでNodeCGというフレームワークを使ったりmaintainerをしたりしている話をしようと思います。
NodeCG
https://nodecg.comhttps://github.com/nodecg/nodecg
一言で言うと「ライブ配信のレイアウトをWeb技術で作るフレームワーク」です。
ちょっと何言っているのかわからないですね。
噛み砕くと
- Twitch、YouTube Live、ニコニコ生放送などのライブ配信で
- 動的でリッチな見た目の画面表示を作るための
- 大枠の仕組みを提供するフルスタックフレームワーク
まだどんなものかよくわからないので、サンプルを動かしてみましょう。下のはGamesDoneQuick1というRTAイベントで使われた、NodeCGで作られたレイアウトです。(https://github.com/gamesdonequick/sgdq18-layouts)
ついでなので、実際のイベントで動いているところを見てみましょう
https://youtu.be/tsUvZ9yiN_U?t=1433
おおざっぱな説明
バックエンドにexpressが使われ、HTML+CSS+JSでブラウザにレイアウトを表示します。NodeCGでレイアウトを構築するときにつくる、フロントエンドとバックエンドがセットになったものをbundleと呼んでいます。1つまたは複数のbundleを組み合わせて1つのNodeCGアプリを作るイメージです。
1つのbundleは
-
dashboard: レイアウトを操作するページ -
graphics: 表示するレイアウトのページ -
extension: サーバーサイド (今回は省略)
dashboardで操作すると、NodeCGのサーバーサイドを通してgraphicsに反映され、追加でサーバーサイドのロジックを書きたい場合extensionを定義する、といったものです。
つくってみる
せっかくなので何か作ってみましょう。必要なものはNode 8以上です。
NodeCGをcloneして準備する
なかなかセットアップが原始的ですが、許してください。2018年ですが本当にbower
という文字が見えています。許してください。(ここでしか使う必要はないです。)$ npm i -g nodecg-cli bower $ nodecg setup $ mkdir bundles/hoge-layout $ cd $_ $ npm init -y
bundleの設定を書く
bundles/hoge-layout
のほうのpackage.jsonに設定を書いていきます。https://nodecg.com/tutorial-5_manifest.htmlpackage.json
{ "nodecg": { "compatibleRange": "^1.0.0", "dashboardPanels": [ { "name": "sample-panel", "title": "Sample Panel", "file": "sample-panel.html" } ], "graphics": [ { "file": "index.html", "width": 1280, "height": 720 } ] } }
dashboardを書く
dashboard
ディレクトリを作り、dashboardに数字をカウントアップするボタンを付けてみます。dashboard/sample-panel.html
<!DOCTYPE html> <html> <body> <button id="increment">+1</button> <script> const incrementEl = document.getElementById('increment') const countReplicant = nodecg.Replicant('count') incrementEl.addEventListener('click', () => { countReplicant.value += 1 }) </script> </body> </html>
graphicsを書く
graphics
ディレクトリを作り、数字を表示するレイアウトを作ってみます。graphics/index.html
<!DOCTYPE html> <html> <body> <div id="count"></div> <script> const countEl = document.getElementById('count') const countReplicant = nodecg.Replicant('count', {defaultValue: 0}) countReplicant.on('change', newValue => { countEl.innerText = newValue }) </script> </body> </html>
動かす
$ cd ../.. $ node .
localhost:9090
でdashboardを出してみます。右上の
GRAPHICS
から、配信レイアウトを出せます...他に何も書いていないので数字しかいません。実際にレイアウトを作る際は、HTML、CSS、SVGなどを駆使して上の動画みたいなレイアウトを作ります。
さておき、dashboardのボタンを押してみましょう。
いい感じでリアルタイムに動いています。
実際の配信での使い方
今までブラウザでレイアウトを表示してきましたが、実施の配信で使うときはブラウザに写しません。何を使うかというと配信ソフトについているブラウザソースの機能です。例えばOBS Studioは、内蔵のChromiumを使って配信に直接表示することができ、ブラウザに写してそれをキャプチャ、といった煩わしい手順がいらないです。こういった理由で、このような動的なレイアウトはNodeCGでなくてもHTML+CSS+JSが使われることが多いです。
すこし詳しく説明
全機能紹介するとキリがないので、抜粋しつつ
機能
dashboardとgraphicsの中のJSでは、window.nodecg
が定義されていて、いろいろなプロパティがいますが、例で使ったのはnodecg.Replicant
です。これはNodeCGの中にある簡易的なデータベースのためのAPIで、代入された値を保存して同時に変更をlistenerに伝える仕組みです。dashboardで数を増やしたら、その瞬間サーバーを通してgraphicsに
'changed'
イベントが伝えられ、新しい値が伝わります。Replicantは実際にファイルに保存されるため、何かの不具合でサーバーが落ちたとしても値が保存されます。(やり直しがないライブ配信ではかなり大事な機能です)
他にもいろいろ機能があります
-
message: データのやり取りでなく、イベントを直接やり取りできる機能 -
sound: 音声ファイルをアップロードしておき、キューを送ることでレイアウトで音を再生できる機能 -
asset: 画像や動画ファイルをアップロードして、レイアウトやダッシュボードから参照できる機能
基本的に薄く、unopinionatedに作られているため、例のようにplainなHTMLで作ったり、Reactで書いたりVueで書いたりなんでもできます。 (フレームワークの部分はPolymer 2でできていますが、中身を作る際は関係ありません)
中身の技術
Replicantの代入、変更、mutateに対してJSのProxyを挟むことで、変更を検知して各場所にWebSocketを通じて通知することで、すべての場所で同じデータを見ているような仕組みになっています。。Proxyは興味深く、IE11で使用できずPolyfillも不可能なためまだ流行っていませんが、IE11を最初からサポートしていないNodeCGではこのような使い方ができています。(将来VueがリアクティビティをProxyで作り直すことも発表されています。)
(dashboardで値の変更)→(proxyがサーバーに通知)→(サーバーがgraphicsに通知)→(graphicsの表示が変更)
フロントエンドのリアクティブなフレームワークがHTMLとJSの間でリアクティビティを実現しているのと同じような関係を、クライアントとサーバーの壁を超えて実現しているあたり面白い仕組みだと思っています。
Maintainerとして
個人的な話をすると、1年半くらい前、このフレームワークを使って関わっているイベントのレイアウトを作るのが、本格的にプログラミングを始めるきっかけでした。その後、TypeScriptの型定義をつけたり、テストのリファクタリングしたりしていたら、maintainerにならないかと誘われました。それまでは作者のLangeが1人でメンテナンスしてきたこともあり、まだまだ発展途上なフレームワークなので、できるだけ貢献していきたいです。
あと、海外では幅広いイベントで使われているのですが、日本で使っているのが自分ともう1人しか知らないので、もっと流行ってほしいですね!
-
同時視聴10万人以上、1週間で2億円以上寄付金を集めるマンモスチャリティイベント。RTAを披露して視聴者から寄付金を募る。 ↩
コメント
コメントを投稿