ZOOM会議をニコニコ動画風にする

この記事は[Zoom の API / SDK を使ってみよう！ by Zoom Advent Calendar 2022](https://qiita.com/advent-calendar/2022/zoom)の16日目の記事です。
もう過ぎてしまっていますが空いていたので投稿させていただきました😆


## ZOOMで盛り上がっているチャットを動画と一緒に楽しみたい！

月次ミーティングやキックオフミーティングなど、チャットが盛り上がる会議ってありますよね。「ｷﾀ――(ﾟ∀ﾟ)――!!」「88888888」「草」「wktk」など異常なボルテージを表現するのにZOOMのあのチャット欄では小さすぎる....もっと大画面で、そう、**動画の上に文字が右から左へ流れていくような、まるで文字が叫んでいるようなあの感じがほしい..!!**  

この記事ではZOOM SDKを利用して「ZOOM会議をニコニコ動画風にする」方法を紹介します。


## 完成形

https://github.com/Rasukarusan/zoom-sdk-web-nico

![demo.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/142791/7e3dfd29-74dd-8af3-3e1d-39efbbf6ce12.gif)

左側が今回作ったZOOMアプリ、右側が公式ZOOMアプリでチャットしている動画となります。
見事チャットに打ち込まれた文字が右から左に流れていきますね！

## 手順

まずはZOOM SDKを使ってZOOM会議に参加するところまでやりましょう。

1. ZOOMでアプリを作る
2. サーバー立ち上げる
3. クライアント立ち上げる


少しややこしいですが、1つずつやっていきましょう。15分もあればできます。

## 1. ZOOMでアプリを作る

基本的に[こちらの記事](https://qiita.com/yosuke-sawamura/items/de69e73e47335cd61d68)のしたがって作成すればOKです。
およそ5分ぐらいで作成できます。

https://marketplace.zoom.us/docs/api-reference/introduction/

![1_createapp.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/142791/370cf4b2-8513-4344-2675-efb2e5bac0da.png)


右上の「Create App」からアプリを作成します。ZOOMのアカウントを持っていない方はここで作成してしまいましょう。持っているならログインでOKです。

![2_meetingsdk.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/142791/a8e3dded-d269-a2d3-e398-c9a5ad060f8f.png)


次に「Meeting SDK」を選択します(私はすでに作成しているのでCreateボタンではなくなっていますが細かいことは気にしないでいきましょう)

![3_informatino.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/142791/1cb45b61-fe6f-b4d1-2119-45424b8d0b61.png)


最後に「Information」を埋めれば完了です。


## 2. サーバー立ち上げる

ZOOM SDKを使って会議に参加する際、シグネチャと呼ばれる文字列を発行する必要があります。  
クライアントアプリではこのシグネチャをキーにして会議に参加できます。  
とはいえ難しいことはなく、公式で用意されているリポジトリをcloneして環境変数セットするだけでOKです。

https://github.com/zoom/meetingsdk-sample-signature-node.js

上記のREADMEに書いてあるとおりに進めます。

```sh
# cloneする
$ git clone https://github.com/zoom/meetingsdk-sample-signature-node.js.git
# ディレクトリ移動
$ cd meetingsdk-sample-signature-node.js
# パッケージインストール(yarnでもOK)
$ npm install
# 環境変数をセットする
$ touch .env
### ZOOM_SDK_KEY=SDK_KEY_HERE
### ZOOM_SDK_SECRET=SDK_SECRET_HERE

# 起動
$ npm run start
```

環境変数の`ZOOM_SDK_KEY`と`ZOOM_SDK_SECRET`は先程作ったアプリの管理画面からコピーします

![sdk_key.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/142791/8947254a-1543-0a5f-a9e6-31f0a2226d07.png)


`npm run start`して下記のように起動したらOKです。

![run_server.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/142791/bff5df42-18ef-6e3f-ef6c-fc8ec63d0e6a.png)


## 3. クライアントアプリを立ち上げる

ラストです。いよいよZOOM会議に参加します。

https://zoom.us/meeting

まずは上記からZOOMにログインし、ミーティングを作成します。クライアントアプリからこのミーティングに参加する想定です。  

![create_meeting.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/142791/51bacccd-1451-a6be-6250-deefaed67999.png)
「ミーティングをスケジューリング」をクリックします。
![create_meeting_2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/142791/34b7db09-b022-6667-568d-5402851a027b.png)
特に変更しなくてOKです。「保存」をしてミーティングを作成します。

![create_meeting_3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/142791/bfce7ba4-95f9-4c8d-4c94-bcaa4853f828.png)
「ミーティングID」と「パスコード」を後で使うので画面はそのままにしておきます。  

次にクライアントアプリをcloneします。今回はReactで作ります。他にもVueやHTML・Javascriptのものもあるので好きなものでやればOKです。流れはすべて同じです。

https://github.com/zoom/meetingsdk-react-sample

```sh
# cloneする
$ git clone https://github.com/zoom/meetingsdk-sample-react.git
# ディレクトリ移動
$ cd meetingsdk-sample-react
# パッケージインストール(yarnでもOK)
$ npm install
# 設定を書く
$ open src/App.js
```

設定は下記のようにします。
```js
  var signatureEndpoint = 'http://localhost:4000' // 先程立ち上げたサーバー
  var sdkKey = 'a3c7gOiFNN4cEmVB6s7WazAoh3I4dK2q0d7D' // アプリのSDKKey
  var meetingNumber = '71282796218' // 先程作ったミーティングのID
  var role = 1 // 1にするとホストになります。0だと参加許可する必要があったので開発中は1にしています。
  var leaveUrl = 'http://localhost:3000'
  var userName = 'React'
  var userEmail = ''
  var passWord = 'mTs0f8' // 先程作ったミーティングのパスコード
```

これで準備はOKです。起動しましょう！
```sh
npm start
```
[http://localhost:3000/](http://localhost:3000/)にアクセス
![run1 .png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/142791/1e1b3fe5-9cd7-80f7-52c5-e004a1bf6060.png)
「Join Meeting」をクリック
![screenshot_ 2022-12-19 0.20.39.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/142791/5b5e4e05-45c7-0676-4970-665b729c28c9.png)
「Join」をクリック
![screenshot_ 2022-12-19 0.21.28.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/142791/d75a8da1-de61-966e-62e3-8a50b37c23bd.png)
このような画面になれば完了です！お疲れさまでした！

## 自作のZOOMクライアントアプリにする

無事WebでZOOMを表示できたのでここから魔改造していきます。Webの世界に持ってこれたのであとはいかようにもできますね。ここからはもはやソースコードを見てもらったほうが早いので、詳細を知りたい方は[こちらのコミット](https://github.com/Rasukarusan/zoom-sdk-web-nico/commit/f8cfd39b1ca67330e9a6d77973e87198bc976f44)をご参照ください。
要所要所のポイントだけ書いていきます。

## 1. 弾幕開始のボタンを設置

チャットメッセージを弾幕させるためのボタンを設置しました。このボタンを押すと以降チャットメッセージが画面に流れるようになります。  

![danmaku.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/142791/554d2788-c51c-f72d-5c4f-f4ad7ae31943.png)


開始ボタンを押すとsetIntervalが発動し、チャットエリアの要素の監視をスタートします。  
ZOOM SDKの機能にチャットメッセージを取得する機能がなかったので、シンプルに要素から取得するようにしました。webhookも考えたのですが、ZOOM SDKの「Event Subscriptions」にはどうもチャットメッセージの取得がなさそうでした。（もしあったら教えてほしいです〜）

## 2. 弾幕でメッセージを流す

こちらはシンプルにCSSとjsによる要素追加です。
新規のチャットメッセージが来るたびに下記のメソッドを発火します。
```js
/**
 * チャットメッセージを流す
 */
const createText = (text) => {
  const randomNum = (min, max) => Math.floor(Math.random() * (max - min + 1) + min)
  var id = "video-share-layout"
  var textbox_element = document.getElementsByClassName(id)[0];

  const height = textbox_element.style.height.replace("px", "")
  var new_element = document.createElement('p')
  new_element.textContent = text
  new_element.className = 'mytext'
  new_element.style.cssText = `top: ${randomNum(0, height)}px;`
  textbox_element.appendChild(new_element);
}
```
右から横に流すのはCSSでやっています。
```css
.mytext {
  color: white;
  left: 100%;
  font-size: 28px;
  margin:0;
  display:inline-block; 
  white-space:nowrap;
  animation-name:danmaku;
  animation-timing-function:linear;
  animation-duration:7s;
  animation-iteration-count:1;
  position:absolute;
  display: inline-block;
}
@keyframes danmaku {
  from   { left: 100%;} 
  99%,to { left: -100%;}
}
```

## 終わりに

「ZOOM会議をニコニコ動画風にする」方法を紹介しました。
はじめはZOOM SDKで何ができるのかわからなかったり`meetingNumber`ってなんぞ！？という状態でしたが、起動できると嬉しいですね。たぶんVideoSDKのほうができること多いのかなーとかAPI使ってみたいなーなど、また時間があるとき遊んでみたいと思います。  

## 参考

https://qiita.com/yosuke-sawamura/items/de69e73e47335cd61d68

https://twotone.me/web/4142/

今回ZOOM SDKを触ってみた感想はこちらの記事に書いた

https://www.rasukarusan.com/entry/2022/12/19/101116