ライブ配信者向けレイアウト構築システム「StreamControl」の使い方

#StreamControlの概要

##何が出来るの
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/336249/a2985a3f-88a2-d44d-b37c-ff6b2f25236b.png)
（画像は[第2回SplashGo!](https://www.youtube.com/watch?v=9MTtL1wkujM&t=2532s)より）
ゲーム大会などでよく見るこういう画面レイアウトを作れるようになります。

##強み
一般の配信ソフトでテキストを直書きすると……

- テキストを書き換えるまでに時間がかかる
- 入力ミスが起こりやすい
- 入力内容を用意した別資料を見ながら入力しなければならない

StreamControlを使えば……

- 瞬時にテキストを切り替えることが可能
    - 上記画像だと、チーム名+選手名4人という合計5要素を瞬時に切り替えることが可能です。
    - 切替可能な要素数は設定により可変です。例えば、各選手のツイッターアカウントも出したいといった要件も可能です。
- 切り替え対象のIDを選ぶだけなので入力ミスが起こりづらい
    - 上記画像だと、それぞれのチームIDを選ぶだけで切り替えが可能というイメージです。
- 入力内容は事前に用意したものを参照するので、別資料が必要ない

また、後述するようにhtml&css&javascriptによって構築されています。
従ってこれらの技術で実現可能なことなら、何でも自由にレイアウトを組むことが出来るという点も強みかと思います。

##仕組み

###配信画面はhtmlでできている
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/336249/ac3c7bb2-853e-def2-5e19-90516ec2aa90.png)
こんな感じで、配信レイアウトにしたい画面をhtmlで構成します。
最低限チーム名の部分などをdivで指定するだけでできます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/336249/8bffcedf-c22a-bd39-67b6-f411901e5912.png)
チーム名などのテキスト部分はjavascriptを動かして取得・表示します。
htmlとは別のxmlファイルに書かれている内容を取得しています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/336249/b6be730e-a629-c5c2-c634-4324cfc6b21e.png)
xmlファイルの中身はシンプルにこんな感じです。
となると、**チーム名などを切り替えるためにはxmlファイルの中身を書き換えればいい**ということになります。
ここでようやくStreamControlが登場します。

###StreamControlと連携させる

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/336249/227efcca-fa7f-1821-c3cb-759bead38e97.png)
StreamControl側の画面はこうなっています。
ここで保存ボタンをクリックすると、StreamControlに入力している内容を元に先述のxmlファイルが上書きされるという仕組みです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/336249/d2559ba2-4cec-0a4a-a118-6ad0286603e5.png)
チームIDは前方一致で候補を出してくれるので選びやすくなっています。

実際に選んでいる様子を動画で確認してみて下さい。
![StreamControl-2020-04-02-08-31-37.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/336249/3079a6a4-2149-0f21-edf1-fb315b3970ce.gif)
動画だと候補が出ている部分が映りませんでしたが、ラクに切り替え出来ているのが分かるかと思います。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/336249/fe30768e-5b0c-70b4-2013-c8df9ee66a11.png)
データソースはこのようなcsvファイルになっています。
1列目のIDを指定することで、その行に対応した各列の値をセットするイメージです。

###配信ソフトでhtmlを読み込む
ここまで出来れば、あとは各種配信ソフトでhtmlファイルを読み込むだけです。
レイアウト上の情報を更新したくなったら、StreamControlを操作して保存ボタンを押すだけです。
配信ソフト側は何もいじる必要はありません。更新されたhtmlを自動で読み込み直してくれます。

#実際に作ってみよう
##ダウンロード
配布元はこちらです。
http://farpnut.net/streamcontrol/

ですが、有志の方が公開している、既に組み上がっているレイアウトを手直しするのも良いでしょう。
各種レイアウトは[日本 StreamControl 学会](http://streamcontroljapan.blog.jp/)で公開されています。
その他、StreamControlでググることでも各種レイアウトを探すことが出来るでしょう。

2020/4/1追記
2020/4/5URL修正
レイアウト公開の許可を頂いたので、本記事で使用しているものをGitHubに公開しました。
https://github.com/anaakikutushita/64GB_Streaming_Layout

##設定
###StreamControlのレイアウト
StreamControlの画面上にテキストボックスやボタンを置いていきましょう。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/336249/eb01b02b-b261-0b04-5de6-79adb0ef82a5.png)
設定画面を開き、`Layout File`でxmlファイルを指定します。
このxmlファイルに書かれた内容の通りにテキストボックスなどが配置されます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/336249/2c017af4-6c91-6e9b-54bc-78e43fc8e00e.png)
xmlファイル側にはこのように記述します。

 - `layout`タグで全体を囲む
 - 必要な数だけ`tab`タグを作る
 - `tab`タグの中に`label`や`lineEdit`（テキストボックス）を配置する
    - `lineEdit`の`id`属性と、html側の`id`を揃えると良さげです
 - `dataSet`属性にcsvファイルを指定する
 - あとはいい感じに`dataField`属性や`master`属性を設定

仕様はドキュメントで確認できます。
http://farpnut.net/streamcontrol/layout-documentation/

いい感じに出来たらcsvを作って動作確認してみてください。
出力するxmlファイルは`streamcontrol.xml`となります。

###javascriptの設定
html及びcssはいい感じに作ってください。

xmlから要素を取得してhtml内に反映させるところを解説します。
基本的な構造は次のようになります。

 - `init()`の中にやりたいことを全部書く
    - xmlファイルの変更を検知するため、setIntervalで定期的に読みに行く
 - `body`タグの`onload`属性に`init()`を指定する

全部載せると煩雑になるので、主要な部分を載せます。

```js
var xmlDoc;
var xhr = new XMLHttpRequest();
var doUpdate = false;

function init() {

    xhr.overrideMimeType('text/xml');

    var timeout = this.window.setInterval(function() {
        pollHandler();
    }, 250);

    $('#round').html('');
    ...
    //その他初期化

    $.play();
}

function pollHandler()
{
    loadData();
    // htmlの中身を更新すべきかどうか、loadDataしたときのtimestampを使って判断します
    if (timestamp != timestampOld) {
        doUpdate = true;
    }
    if (doUpdate) {
        updateBoard();
    }
}

function loadData() {
    xhr.open('GET', 'streamcontrol.xml');
    xhr.send();
    xhr.onreadystatechange = function(){
        xmlDoc = xhr.responseXML;

        round = getValueFromTag(xmlDoc,'round')
        // その他、タグを指定してxmlから値を取得

        timestampOld = timestamp;
        timestamp = getValueFromTag(xmlDoc,'timestamp');
    }
}

function getValueFromTag (xmlDoc,tag) {
    if (xmlDoc.getElementsByTagName(tag).length != 0 ) {
        if (xmlDoc.getElementsByTagName(tag)[0].childNodes.length == 0) {
                return '';
            } else {
                return xmlDoc.getElementsByTagName(tag)[0].childNodes[0].nodeValue;
        }
    } else {
        return '';
    }
}

function updateBoard() {
    // xmlから取得した値でhtmlの各要素を上書き
    $('#round').html(round)
    ...

    $.play();

    doUpdate = false;
}
```

```html
<body onload="init()">
  ...
</body>
```

javascriptが動けば、StreamControlが出力するxmlと連携してレイアウトの更新が出来るようになると思います。
フロントエンドメッチャデキル人が何かスゴいレイアウトを作ってくれたらいいと思います。

#まとめ
##システム模式図
![IMG_20200402_095304_waifu2x_art_noise2_tta_1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/336249/268eacf7-44da-1262-73d0-93b8e732dc51.png)
StreamControlのシステム全体を模式図にするとこんな感じになるかと思います。
用意するものが少し多くて大変ですが、使いこなせれば配信する上で非常に便利です。
お読み頂きありがとうございました。

分からないところなどあればコメント頂けると幸いです。この記事は随時更新してより良いものに仕上げていきたく思います。

##参考にしたのとか
先駆者の方々のお力添えによって少しでもStreamControlを使えるようになりました。ありがとうございます。

StreamControl テンプレート 2019年版 配布
http://shigaming.com/2018/11/30/streamcontroltemplate2019/

OBSでのStream Control テンプレートの使い方（SHIG 仕様2019版）
https://pick-up-space.com/streamcontrol01/

ソフトの存在および基本的な使い方はがまのあぶらさんに教わりました。
https://twitter.com/gamanoabura_nsb

ちなみに：上記SHIGのレイアウトでは国旗を表示させることも出来ます。
こちらはhtmlに表示したいテキストをxmlに出力したのと同様に、表示したい国旗画像ファイルのファイル名をxmlに出力してあげてjavascript側でimgタグのsrc属性を書き換えてあげればできます。
国旗画像のアセットはネット上を検索すれば見つけられます。