社内バ美肉しよう (3) 配信編

この投稿は [ちゅらデータアドベントカレンダー2023](https://qiita.com/advent-calendar/2023/churadata) の19日目の記事です。

---

みなさん、バ美肉（バーチャル美少女受肉）してますか？

かわいいは正義です。社内で Web 会議などするときもぜひアバターで出席して、この正義を世に広めていきましょう。

ちゅらデータの社内では、CTO が演じるロアちゃんを筆頭として、アバターを使って交流することが流行っています。バ美肉には数多くの先端技術が関わっているので、最新の技術に触れる良い機会にもなります。

今年のアドベントカレンダーでは3日に分けて、アバターを作って使うまでの色々をアバター・ボイチェン（音声変換）・配信についてご紹介しています。

https://qiita.com/k-akiyama/items/640199b19e4bea581a3d

https://qiita.com/k-akiyama/items/1e0530914537089d5d92

今回はその第3弾、配信編です。

---

# 配信編

前回まで、「新しい姿を手に入れる」「新しい声を手に入れる」ことをやってきました。今回は、手に入れた姿や声を Meet、Zoom、Huddle などの Web 会議で使う上でのノウハウをお届けします。

## 基本構成

Kalidoface Lab と VC Client (RVC) を使用することを前提に、まずはこれらのソフトウェアを実行している PC と同じ PC 上で Google Meet に参加することを考えます。

だいたいこんな感じになります。

![画像1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/116137/19298fa9-39e8-271d-43ea-8757938d29f8.png)

### 映像 (OBS Studio)

OBS Studio をインストールします。

https://obsproject.com/ja/download

設定で、映像のフォーマットをいい感じの解像度とフレームレートに設定しておきます。負荷が高い場合はこれらの数値を小さくします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/116137/0f5f5223-eaab-ff31-7795-79c80f90fe02.png)

下部にある「ソース」ドックに「ウィンドウキャプチャ」を追加し、実行中の Kalidoface のウィンドウを取ってきます。そして四隅を引っ張って見える範囲を調整します。少しオーバースキャン気味にしておくと、タイトルバーやツールバーが写り込みにくくなってよいでしょう。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/116137/1da2ff46-8219-9765-e436-b58c5e03a5f1.png)

最後に「仮想カメラ開始」ボタンを押します。あとは Google Meet などでカメラとして「OBS Virtual Camera」を選択することで、このアバターの状態でビデオ会議に参加できるようになります。

:::note info
配信中は、Kalidoface が他のウィンドウの下に完全に隠れてしまわないように気をつけましょう。Chrome は、バックグラウンドになったタブの実行を自動的に一時停止するようになっており、映像が固まってしまいます。
:::

:::note info
Mac を使用している場合、いくつかのソフトウェアから OBS Studio の仮想カメラが認識されないことがあります。たとえば Safari からは仮想カメラが認識されません。Slack の Huddle でも仮想カメラが認識されなくなる場合があります。そういった場合は、Chrome のブラウザからビデオ会議に参加するようにしましょう。Slack の Huddle もブラウザから参加することができます。
:::

### 映像（OBS Studio をインストールしたくないとき）

Google Meet 専用になりますが、Chrome の拡張機能 [Screen Capture Virtual Camera 🎥](https://chromewebstore.google.com/detail/screen-capture-virtual-ca/jcnomcmilppjoogdhhnadpcabpdlikmc) を使用して、Kalidoface のタブを仮想カメラとして使用することもできます。

https://qiita.com/noritsune/items/144fe9073a324bab8b6f

### 音声（仮想オーディオデバイス）

仮想オーディオデバイスと呼ばれるソフトウェアをインストールします。BlackHole や VB-CABLE といったものがあり、どれでも使い勝手は変わらないのでとりあえず入れます。

https://existential.audio/blackhole/

https://vb-audio.com/Cable/

例えば VB-CABLE を入れると、「CABLE Input」という録音デバイスと「CABLE Output」という再生デバイスが出現します。

VC Client は（ビルド済みバイナリの場合） `start_http.bat` または `startHttp.command` を使って立ち上げます。 input にマイク、output に CABLE Input を指定して音声変換を開始します。これによって、CABLE Input に入ってきた変換後の音声が CABLE Output という再生デバイスから出るようになります。monitor にヘッドフォンなどを指定しておくと、変換後の音声を自分でも聞くことができます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/116137/1cec3105-e5fd-a095-f00d-b249343f041d.png)

あとは Google Meet などでマイクとして「CABLE Output」を選択することで、変換後の音声を使用してビデオ会議に参加できるようになります。

#### ボイチェンを通した変換後の声を聞く

VC Client を使用している場合、 monitor にヘッドフォン等を指定することで変換後の音声を聞きながら配信することができます。しかしこれ以外の方法でも「仮想オーディオデバイスに出力している音を聞く」ことは可能なので、選択肢として知っておくと、いつかデバッグに役立つ時が来るでしょう。

**Windows の「このデバイスを聴く」機能。**[こちらの解説](http://faq3.dospara.co.jp/faq/show/6240?site_domain=default)などを参考にして、仮想オーディオデバイスの音をヘッドフォンで聴くように設定します。

**Mac の「複数出力装置」機能。**[こちらの解説](https://support.apple.com/ja-jp/guide/audio-midi-setup/ams7c093f372/mac)などを参考にして、「仮想オーディオデバイスとヘッドフォン」をまとめた複数出力装置を作ります。VC Client の output には、この複数出力装置を指定します。

#### Chrome のエコーキャンセル機能を切る

ボイチェンを通した変換後の声を聞きながら配信している場合、録音デバイスと再生デバイスで同じ音が鳴っている状態になるため、Chrome のエコーキャンセルが発動します。これが発動すると、自分の声が相手に届く際に音が潰れ、途切れ途切れになって聞こえてしまう状態になります。

Chrome のエコーキャンセル機能を切るには、アドレスバーに `chrome://flags/#chrome-wide-echo-cancellation` と入力し、 `Chrome-wide echo cancellation` を Disabled にして Chrome を再起動します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/116137/717bb66b-c033-3816-75f2-97cbecc4cdea.png)

#### 映像と音声をテストする

自分の映像や音声が相手にどのように届いているかは、ビデオ会議のプレビューからでは正確に把握することができません。Google Meet では「録画をテストする」機能が提供されているので、これを使いましょう。前述の Chrome によるエコーキャンセルが発動するかどうかも、この機能でテストすることができます。

「録画をテストする」機能は、会議に参加する前の画面でカメラを選択するメニューをクリックすると出てきます。Chrome 以外のブラウザでは表示されないかもしれません。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/116137/1cd0a407-be31-1eee-6486-71d593c84c9b.png)

## PC 2台体制で負荷分散

ボイスチェンジャー (VC Client) が結構重いので、ひとつの PC でアバターも動かしてビデオ会議に出て……とやっていると処理が追いつかなくなることがあります。そこで、バ美肉に関する処理は別途用意したバ美肉用 PC の中で行ってしまい、処理後の映像と音声をビデオ会議に参加する PC に飛ばしてくる方法を考えてみましょう。

だいたいこんな感じになります。

![画像2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/116137/710a5afd-d5a5-3284-f76c-1cc8fc8fd6fd.png)

### 映像 (OBS-NDI)

Kalidoface がバ美肉サーバー上で動いているので、この映像を Meet に参加する PC 上の OBS Studio へ飛ばしてくることを考えます。その手段の一つが OBS-NDI というプラグインです。NDI のプロトコルを使用することで、映像を低遅延でネットワーク伝送することができます。

https://github.com/obs-ndi/obs-ndi

上記の README を参照してインストールします。OBS-NDI を利用するには、送信側・受信側の両方に [OBS-NDI プラグイン](https://github.com/obs-ndi/obs-ndi?tab=readme-ov-file#install-obs-ndi)と [NDI 5 Runtime](https://github.com/obs-ndi/obs-ndi?tab=readme-ov-file#download--install-the-ndi-5-runtime) が必要です。

インストール後、送信側（バ美肉サーバー側）で OBS Studio を開くと、メニューの「ツール」に「NDI™ Output settings」という項目が増えています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/116137/a0de6e18-71c9-5e9b-57ef-eafbd3292d83.png)

NDI™ Output settings を開いて、一番上の Main Output のチェックボックスにチェックを入れておきます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/116137/23045faf-9bb5-e650-f7e7-aa17b0cc354f.png)

次に受信側（Meet に参加する PC 側）で OBS Studio を開き、新しいシーンを追加して、ソースに「NDI™ Source」を追加します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/116137/502b23b8-6c98-84e7-5068-956b69b238eb.png)

Source name のドロップダウンから送信側のコンピュータ名を選択すると、映像が表示されます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/116137/a2b523e5-4b91-5333-0224-770ac97ce42c.png)

この画面で映像の伝送方法を指定できます。

- **Bandwith**: Highest/Lowest で解像度が変わり、使用するネットワーク帯域に影響します。Lowest にすると解像度が半分になります。
- **Latency Mode**: Normal/Low/Lowest でバッファサイズが変わり、遅延と安定性に影響します。Lowest にすると非常に早いです。

Meet に参加する PC 側の OBS Studio でアバターの映像を受信できるようになったので、あとは仮想カメラを開始するだけです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/116137/8783b71a-b6d6-f1e3-7d0c-30de4fab2223.png)

### 映像 (FFmpeg, UDP)

OBS-NDI を使う方法は低遅延でおすすめなのですが、OBS Studio 標準の機能だけで実現できる方法もご紹介します。

送信側（バ美肉サーバー側）の OBS Studio で設定を開き、「出力」画面で「出力モード」を「詳細」に設定します。続いて表示される「録画」タブで次のように設定します。

- **種別**: カスタム出力 (FFmpeg)
- **FFmpeg出力の種類**: URLに出力
- **ファイルパスまたは URL**: `udp://192.168.1.3:2222?pkt_size=1316`
    - 受信側（Meet に参加する PC 側）の IP アドレスと、任意のポート番号を指定します。
- **コンテナフォーマット**: mpegts
- **映像エンコーダ**: mpeg2video - MPEG-2 video
- **音声エンコーダ**: エンコーダを無効にする

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/116137/2ce5ae98-2f7b-d5cd-c0d2-28c48b89a3c7.png)

設定が終わったら、「録画開始」ボタンをクリックすることで送信が始まります。録画という表現にはなっていますが、ファイルに保存されるのではなく、エンコードしつつ UDP で受信側へ一方的に投げつけている状態になります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/116137/53d65550-f02e-b88c-1dad-53a533a0d299.png)

:::note info
受信側（Meet に参加する PC 側）のファイアウォールで UDP 2222番（または任意に設定した番号）のポート開放が必要になる場合があります。
:::

次に受信側（Meet に参加する PC 側）で OBS Studio を開き、新しいシーンを追加して、ソースに「メディアソース」を追加します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/116137/0798d26c-ff42-1f32-678b-d4adaf8d1113.png)

「ローカルファイル」のチェックを外し、「入力」に先ほど設定したものと同じ URL を入力します。遅延を小さくするため、ネットワークバッファリングの数値はなるべく小さくしておくと良いでしょう。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/116137/e320dc69-8af7-e8cb-ccc1-28024545bf6e.png)

Meet に参加する PC 側の OBS Studio でアバターの映像を受信できるようになったので、あとは仮想カメラを開始するだけです。

### 音声

バ美肉サーバー側で VC Client を `start_https.bat` または `startHttps.command` を使って立ち上げておきます。Meet に参加する PC 側からブラウザで `https://192.168.1.2:18888/` などにアクセスすれば、マイクからの音声がサーバーに送信され、重いボイスチェンジャーの処理がサーバー側で行われるようになっています。

:::note info
バ美肉サーバー側のファイアウォールで TCP 18888番のポート開放が必要になる場合があります。
:::

:::note warn
「この接続ではプライバシーが保護されません」という画面になる場合があります。「詳細設定」ボタンをクリックすると「192.168.x.x にアクセスする（安全ではありません）」というリンクが出現するので、そこから続行することができます。推奨される操作ではないため、Web 上のサイトを閲覧する際には行わないでください。
:::

---

新たな姿と声で、同僚とわいわいできましたか？

少し複雑になってしまいますが、自分なりの構成をしっかり固めておいて、必要になった際はいつでもバ美肉ができるようにしておきましょう。