2
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

Twilio Programmable Videoでボイスチェンジャーやバーチャル背景を実装する

Posted at

ボイスチェンジャー

こちらの記事ではブラウザ上で動作する Twilio Programmable VideoJavaScript client について説明します。オーディオデータにエフェクトをかけるのには Tone.js を利用します。他の何かを利用したい場合でも、入出力の扱い方は同じなのでまあ参考になるといいですね。

一般的にWebRTCによるビデオ通話を実装する場合、実行環境であるブラウザ側に用意されたデバイスへのインターフェース getUserMedia を通して取得した MediaStream である LocalMediaStream を相手方に送信し、相手方もまた同じ仕組みを通じてこちら側にデータを送り返すやり取りを繰り返すことになります。データの送受信は MediaStreamTrack という一種のコンテナを通じて実行されますが、そこに track と呼ばれる実際の映像や音声を追加したり外したりしてコントロールすることもできます。 音声を扱う track にはそれぞれ一つ以上の channel があります(例えばステレオの左右のチャンネルとか)が、まあ普通は track が最も低レベルのレイヤーになります。ただし、 DataChannel は違います。これは全然別のものです。

うん。訳がわかりませんよね。

 getUserMedia で↓をget!
+--------------------+        +--------------------+
|  LocalMediaStream  |        |    MediaStream     |
|  +-------------+   |        |  +-------------+   |
|  | Video Track |   |        |  | Video Track |   |
|  +-------------+   |        |  +-------------+   |
|                    |  ===>  |                    |  ===>  相手側に届く
| +----------------+ |        | +----------------+ |
| | Audio Track    | |        | | Audio Track    | |
| |                | |        | |                | |
| | "left channel" | |        | | "left channel" | |
| | "right channel"| |        | | "right channel"| |
| |                | |        | |                | |
| +----------------+ |        | +----------------+ |
+--------------------+        +--------------------+

魔法のようにわかりやすい図ですね。

さて、今回取り扱うのは、Tone.js 経由で取得した音声入力にエフェクトをかけ、改めてLocalMediaStreamにaudio trackとして追加してやる例です。省略の多いコードですがまあわかるでしょう。

import * as Video from 'twilio-video';
import * as Tone from 'tone';

const micAudio = new Tone.UserMedia(); // Tone.jsのgetUserMedia
await micAudio.open().then(() => {
  // ピッチシフターで声の高さを変えます
  const shifter = new Tone.PitchShift(7);
  const effectedDest = Tone.context.createMediaStreamDestination();
  micAudio.connect(shifter);
  shifter.connect(effectedDest);
  const effectedTrack = effectedDest.stream.getAudioTracks()[0];

  // LocalTrackを作成してRoomに接続します
  Video.createLocalTracks({
    audio: true,
    video: true,
  }).then((localTracks) => {
    localTracks.push(effectedTrack); // エフェクトがかかったtrackを追加
    Video.connect(token, {
      tracks: localTracks,
    })
  }).catch(...省略)
}).catch(...省略)

これで凶悪犯の住んでいた地域の住民がテレビで匿名でインタビューを受けるような音声になります。Tone.jsには他にもいろいろなエフェクトが用意されているので、試してみてください。

バーチャル背景

うん。

いろいろ書いたんだ。

でも

ここを読んだ方が早いよ。ちゃんと検索すればよかったよ。

2
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?