【個人開発】ライブイベントで流れてる映像にハートとスタンプを送れるシステムを作った

こんにちは。はじめまして。れとるときゃりー([@retoruto_carry](https://twitter.com/retoruto_carry))と申します。

普段は趣味で個人でウェブサービスなどをたくさん作っています。

# 今回作ったもの

「ライブイベントで流れてる映像にハートとスタンプを送れるシステム」を作りました。

観客が手元のスマホで開いたサイトから、ハートとスタンプを送れます。

実際のDJイベントにて導入し、VJとして映像演出を担当しました。

## サイト

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/156690/3f69f5ca-0135-2e83-f71c-89e8fe11c764.jpeg" width="400px" />

## サイトからハートを送っているところ

![ezgif.com-gif-maker (1).gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/156690/bcc5759f-0c2f-5b23-7552-671e3c9f8903.gif)


## スタンプを送っているところ
ツイッターのハッシュタグのツイートも、リアルタイムで流れます。

![ezgif.com-gif-maker (2) (1).gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/156690/2f901338-3722-6dd9-0e4a-6d2a0f5fea0b.gif)


## 動画
https://twitter.com/retoruto_carry/status/1600514157631410178?s=20&t=by4H2Elm9Ld-hH3kpqv1NQ

# 実際のDJイベントでやりました

このシステムは、実際のDJライブイベントで導入して、お客さんに遊んでいただきました！

# DJイベント会場での様子

![ezgif.com-gif-maker (7) (1).gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/156690/e465b5d0-ff9d-5beb-312f-a90092012520.gif)


![ezgif.com-gif-maker (9) (1).gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/156690/509e63ef-8db3-1f4b-de3d-2477b62eb9f0.gif)

https://twitter.com/retoruto_carry/status/1601253974979805184?s=20&t=jaGOSjDfi99bIqs4r8FH9Q


# 作ったきっかけ

最近VJイベントによく行くのですが、そこに流れる映像に観客も参加できたら面白そうだな〜と思い作りました。

思いついてその日に動画でデモを作ったところ、翌日に知人に誘われて実際にライブに出演することが決まりました。

本番まで製作期間が２週間ほどしかなく、VJもまったくやったことがなかったため、かなりギリギリまで焦りながら、制作とVJの練習をしていまいした。

# どうやって作ったか

## ウェブサイト

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/156690/3f69f5ca-0135-2e83-f71c-89e8fe11c764.jpeg" width="400px" />

・Next.js
・Vercel
・ChakraUI

でサクッと１時間くらいで作ったやつです。

クラブは暗いので、色的にアイコンが目立って映えるかな、と思って背景を黒にしてシンプルにしました。

## スタンプのイラスト

スタンプのイラストは、友達に依頼して書いてもらいました！可愛すぎ！！！！


## スタンプを送信して表示する部分

スタンプを送信する部分は以下の図のような構成で作っています。


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/156690/9b4a46b9-6a83-00fb-9660-f7b13735a553.png)



① まず、サイトでスタンプを押すたびに、`Firebase`の`RealtimeDatabase`にデータを送信します

② ローカルで動かしている`node.js`から`RealtimeDatabase`を監視します

③ もし`RealtimeDatabase`にスタンプのデータの追加があれば、`OSC通信`で、TouchDesinger（後ほど解説します）に送信します

④ TouchDesingerでは映像をリアルタイムで生成し、`OSC通信`が送られるごとにスタンプが映像に現れるようにします

⑤ 生成された映像を、`Syphon`と呼ばれる規格の通信で、VJソフトであるResolume（後ほど解説します）に送信します


### TouchDesingerでリアルタイムにスタンプが流れる映像を作成

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/156690/63c766b7-105e-9051-dc6e-aa797a00f927.png)


ToudchDesingerはリアルタイムで映像を生成するソフトウェアです。

ノードをつなげてコードを書かずにある程度かんたんに映像を生成できます。

pythonも書けます。

[ToudchDesingerの公式サイト](https://derivative.ca/)

前から使ってみたくて、今回お試しに勉強して使ってみました。

意外ととっつきにくて難しかったです。謎のコツがあります。

以下はサイトでスタンプを押したときに、スタンプが浮き上がってくる映像がリアルタイムに生成されている様子です。


![46ed3c48d7b85518b6e5a68ce9319be3.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/156690/b884177c-a8bc-4e6a-d353-c16d342e258c.gif)

前述したように、`サイトでスタンプを押す → Firebase → node.js → OSC通信 → TouchDesinger`　という流れで、スタンプが押されたことを通知しています。

OSC通信でスタンプが押されたことが通知されるたび、TouchDesingerでスタンプを表示します。

#### OSC通信を受け取るノード

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/156690/e4e4600c-ff30-0f0e-c248-97668326dedf.png)

oscinというノードでOSC通信を受け取れます。

コールバックでpythonのコードを実行できるので、それぞれのスタンプの種類ごとに分岐させてボタンを発火させています。

#### スタンプを生成するノードたち

![3514ba59087b97f8285230211e1db3c8.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/156690/dd84f490-4c23-d0fb-8897-fb0560eaae83.gif)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/156690/6828c893-ce74-ac38-171e-cfcdfb55b7bb.png)


「スタンプのイラストのパーティクルを一つ生成するボタン」を作り、前述のoscinのコールバックのpythonから発火させています。


## ハッシュタグのツイートをニコ動みたいに表示する部分

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/156690/cab5ee87-fc1b-5219-ab1f-5102e004aa42.png)

ツイッターのハッシュタグのツイートをリアルタイムに表示しています。

以下の図のような構成で作っています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/156690/7ef38360-8307-65eb-baae-1c0b08f88081.png)

① まず、ローカルで動かしている`node.js`で、ツイッターのハッシュタグのツイートをリアルタイムに取得します

② もし新しいツイートがあれば、`Firebase`の`RealtimeDatase`に投稿します

③ Chromeブラウザ開いたウェブページで、`Firebase`の`RealtimeDatabase`のツイートの投稿を監視し、もし新しいツイートの投稿があれば、グリーンバックの上にコメントを左に向かって流します。

④ Chromeブラウザごと`NDI Scan Converter`を用いてキャプチャします

⑤ `NDI`という通信規格でResolume（VJソフト）に映像ソースを送信します

#### グリーンバックの上にツイートが流れる映像はどうやって作っているか

JavaScriptのアニメーションライブラリの[GSAP](https://greensock.com/gsap/)で実装しています。ニコ動みたいに左に流れるやつです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/156690/db3da34e-07ea-e746-0b35-961b8cc6f3e7.png)

#### 裏話

このツイートが流れる部分ですが、最初はTouchDesingerでも実装を進めていました。

しかし微妙なバグが直せず、当日の朝に諦めて仕方なくWebサイト上にGSAPでサクッと実装してしまいました。

Chromeも使うことでマシンのスペックが逼迫してしまったので、TouchDesingerだけで実装したほうがパフォーマンスは良さそうです。

## 実際にスクリーンに表示する映像をVJソフト（Resolume）で作る

ResolumeはVJソフトです。

VJとは、ビデオジョッキーの略称で、クラブでスクリーンに流れる映像を演出する人です。雰囲気に合わせ、即興で映像演出を行ったりします。

Resolumeでは、映像をレイヤーごとに重ねて、リアルタイムで各レイヤーを切り替えたりエフェクトを掛けることができます。

![19e37ab2f6c66da25c5337a8e988bbb9.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/156690/4dc72035-1112-b4d5-d430-5acd5ab5d9f2.gif)


これを使って、実際の現場のスクリーンに出力する映像を操作します。

これも今回初めて購入して勉強して使いました。


### Resolumeで映像ソースを重ねてスクリーンに投影する

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/156690/e2ed8d81-9d47-ed9d-0eb8-fcc2948fd78e.png)


いままで解説してきた`スタンプを送信して表示する映像（スタンプレイヤー）`と`ハッシュタグのツイートをニコ動みたいに表示する映像（コメントレイヤー）`をここに送り、背景動画の上に重ねています。

さらに、リアルタイムで背景レイヤーの映像を切り替えたり、エフェクトをかけたりすることで、リアルタイムでの映像の演出を可能にしています。

レイヤーやエフェクトの切り替えには、実機のMIDIコントローラーを割り当てて使っています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/156690/d791e2a9-ab2d-5d23-712d-717a0d4bdc32.png)


### 背景素材の用意

Boothで背景に流す映像を買ったり、フリー映像をインターネットで探してきてダウンロードして、背景映像を200動画くらい用意しました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/156690/6d4fa3bf-2abf-41f9-427f-fdb480ba212e.png)

下の画像はResolumeに動画素材を登録して並べている様子です。

![999809a79740cb63e3b9bc1b92a14259.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/156690/428cf2fa-6675-aa5e-2eec-e419705b9422.gif)

また、イベントのロゴの画像を作ったり、ロゴが動いている映像をAftterEffectのテンプレートから作成しました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/156690/05839b3b-ccac-a8d3-da05-2049d8fdbacd.png)


### VJソフトの使い方の理解と練習

VJ自体が初めてだったので、その方法を調べるところからはじめました。

この方の動画が特にとても参考になりました。感謝 :pray:

https://www.youtube.com/watch?v=3gQGWjL0KBA&t=593s&ab_channel=%E3%82%B4%E3%83%BC%E3%82%B0%E3%83%AB%E9%83%A8%E3%81%A1%E3%82%83%E3%82%93%E3%81%AD%E3%82%8B

あとは、流れている音楽に合わせて、即興で映像レイヤーを切り替えたりエフェクトを掛けたりする練習を家でしました。
　
### マイクから音楽のBPMを自動で取得

以下の記事を参考にして、会場に流れている音楽のBPMをリアルタイムで解析して、TouchDesingerとResolume(VJソフト)に送信するようにしました。

これにより、BPMに同期した映像表現がかんたんに行えるようになりました。

https://ino2408m-pinv.hatenadiary.jp/entry/2021/05/30/143018


## 会場に貼るポスター

お客さんにシステムの存在を知ってもらい、実際にサイトを開いてスタンプを押してもらうために、説明とQRコードを載せたポスターを会場にたくさん貼りました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/156690/5589a617-d6a9-ec06-68c5-f0e46f79366b.png)


<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/156690/59ea5fcc-3bca-e1f1-8942-8f00475da72f.png" width="400px">

### スマホの電波が入らない人向け対策

イベント会場は地下でした。事前の下見でドコモや楽天の電波がめちゃくちゃ弱いことがわかっていたので、レンタルWifiを借りて、Wifiを使ってもらうためのポスターも用意しました

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/156690/a15932d3-810d-39e3-6dd1-208db3c6b3a7.png" width="400px">

### ポスターの作りかた

ポスターは、サクッとiPadにラフを書いて、それをCanvaというデザインツールでデータに落とし込んでつくりました。

前日夜に１時間ほどで作りました。Canva、めちゃくちゃ便利ですね。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/156690/55295cdd-b6bb-202c-5d3a-446aee4b84a3.png" width="400px">

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/156690/def4fdae-a756-8f86-e6a3-7a54dfff0bc0.png)


# 当日の現場でのオペレーション
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/156690/1274b08a-73c3-b313-4d43-a4d11a9b34be.png)



私の他に、もうひとりVJさんがいらっしゃり、そちらの方にサポート頂きつつ交代でVJを行いました。

もうひとりのVJさんがVJをする場合、HDMIキャプチャボードを使い、私のパソコンから彼のパソコンにグリーンバックでスタンプレイヤーとコメントレイヤーの映像を送るようにしました。

## 本番中にノートパソコンがクラッシュした

今回構築したシステム全体の負荷があまりにも高く、一度本番中に私のノートパソコン（macbook pro）がクラッシュしてしまいました。

パソコンを再起動してる間、もうひとりのVJさんにVJをしてもらい事なきを得ましたが、本当に助かりました。

こういう複雑なことをリアルタイムにする場合、トラブルが起きた時にワンオペだと厳しいかもな〜と思いました。

もしも次の機会があれば、可能なら高スペックのデスクトップパソコンを持っていきたいです。

# イベントの振り返り

![ezgif.com-gif-maker (7) (1).gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/156690/e465b5d0-ff9d-5beb-312f-a90092012520.gif)


![ezgif.com-gif-maker (9) (1).gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/156690/509e63ef-8db3-1f4b-de3d-2477b62eb9f0.gif)

実際にイベントでは、参加者の方がかなりスタンプを押してくれていて、楽しんでいただけたようでした。

ツイッターのハッシュタグのコメントが画面に流れるのも、かなりリアルタイム性があって、盛り上がっていました。

参加者の方や出演者の方から、「面白い！」「他のイベントでもやって欲しい！」とたくさん言っていただけて、とても嬉しかったです。

また、VJとして映像も「かっこ良かった」と言っていただけてホッとしました。練習して良かったです。

# 作ってみた感想

思いついてから本番までの準備期間が２週間と短く、ほとんど全く知らない分野だったので、締切に追われて必死に調査・作成していました。

前日から徹夜して、現場に向かう直前まで作業していました。めちゃくちゃヒヤヒヤしましたが、ギリギリ間に合ってなんとか形にできて良かったです。

また、TouchDesingerやResolumeという今まで馴染みがなかった技術やツールに触れられて面白かったです。

なんとなく雰囲気が分かったので、これからもっと面白いものを作ってみたいです。

# 今後の展望

今回は準備期間が本当に短く、もっとやりたかったけどできなかった事がたくさんありました。

また次にイベントでVJをさせていただける機会があれば（多分ありそう...！）、もっと面白いことができないか探ってみたいです。

特に、TouchDesingerを使って、BPMに同期させた映像表現を模索したり、ほかのインタラクティブなコンテンツを作ってみたいです。

# まとめ

 「ライブイベントで流れてる映像にハートとスタンプを送れるシステム」を作った話でした。

# ここまで読んでくれた方へ
ここまで読んでくださりありがとうございます。

いいねやコメント、SNSでの共有等をしてくださると、今後の励みになります。よろしくお願いします。

ツイッター([@retoruto_carry](https://twitter.com/retoruto_carry))もフォローしていただけると嬉しいです。

また、先日こんな記事を書いたので、良かったらこちらも読んでいってください。

https://zenn.dev/retoruto_carry/articles/eaef7a95125586