自習室

こもります

マイク入力を WebAudio で加工して、ビデオと合流させた後 WebRTC で使う

はじめに

前の2記事ほど、ウェブカメラの映像を openFrameworks で加工してビデオデバイスに再度流し込むことで、WebRTC などで扱えるようにする方法について調査してきました。

音声も同様に加工して WebRTCで扱えるようにしたいなーと思いました。

完成品

f:id:AMANE:20150118110301p:plain

こちらで動かしています -> http://www.izmiz.me/mediaStreamMerging/

簡単に使い方
  • ウェブカムとマイクを持っている二台のPCで上記サイトにアクセスします
  • カメラとマイクの利用の許諾を問われるので、許可してください。
  • どちらかのPCで、相手の画面に表示されているIDを打ち込んで call すると、ウェブチャットが開始されます
  • Filter on にチェックして、 Frequency や Q値 を動かすと、相手側に伝える音声に ローパスがかかります
  • ハウリング注意。

検討した2手法

仮想サウンドドライバを使ってOSに流し込む方法 (不採用)

ycapture と同じ考え方で、作り上げた音声をOSの音声デバイスに再度流し込む手法を初めは検討しました。ドライバ相当のものを自力で書くのは面倒なので、有り物の組み合わせで何とか行きたいです。

と思って調べていたところ、ニコニコとかで実況をする方々が、自分の音声と音楽やら動画やらの音声を混ぜるのにOSのソフトウェアミキサー(Windowsのステレオミキサー)を使っていることを知りました。さらにその流れで、NETDUETTO というソフトに同梱されている仮想サウンドドライバを使うことで、コンピュータで再生している音声を音声デバイスとして再入力出来ることが分かりました。

となれば、oF なり Pure data なりで音声を加工してこの仕組みで音声デバイスに戻せば、WebRTCでも使えそうです。

f:id:AMANE:20150118104431p:plain

WebAudio と WebRTC を組み合わせる方法 (採用☆)

一方で、WebAudio API を使えば、jsの簡単なコードで音声にエフェクトを掛けられることも分かりました。ブラウザ内で完結するのもgoodです。

  • WebAudio APIの入力をマイクにする
  • WebAudio APIの出力を、mediaStream のビデオに合流させる

この2つが出来れば、目的は果たせます。そのためにちょいと調査をしました

こちらの記事様の時点では、AudioDestinationNode から mediaStream を引っこ抜くのは実装が不完全そう、という結果になっていました。しかし希望を持ったのでもう少し調べて見たところ、w3c の公式で「まさに」な内容が紹介されていました

The following examples illustrate WebRTC integration with the Web Audio API.

とのことです。このページの Example5 が、まさに今回の内容と同じになっています。図示すると下のような感じになります。これでいけそうです。

f:id:AMANE:20150118104440p:plain

今回は

ウェブカム映像へのエフェクトについては、パフォーマンスの観点から別アプリとの連携という形にしましたが、ちょっとWebAudio API を使ってみたところ、シンプルなフィルタリング等ならパフォーマンスに問題はなさそうでした。

システム構成もシンプルに出来るので、音声に関しては後者、ブラウザ内ですべてやる方式でトライしてみます。

音質

NETDUETTO の仮想デバイスをまたいで入ってきた音の音質が悪い印象もありました。これはもしかしたら私の設定の問題かもしれないのでここでは断言はしませんが、今のところ音質良くできている Web Audio API を利用する方向で行きます。

実装

映像のストリームも加える

最終的に「映像・音声共にエフェクトの掛けられるウェブチャットシステム」としたいので、上のExample 5に加えて、カメラ映像もmediaStreamに合流させる必要があります。

試行錯誤した結果、映像・音声で別々の mediaStream を作ったあと、片方をもう片方にマージ出来ることが分かりました。

// videoStream 映像のMediaStream
// audioDestNode WebAudio API の AudioDestinationNode

videoStream.addTrack(audioDestNode.stream.getAudioTracks()[0]);

// できあがったstream を、peerjs で使う

先の構成図にこの処理を加えて、最終的にはこんな感じになります

f:id:AMANE:20150118175140p:plain

完成品

今回は、下記二つのコードを合体させています

これに、上で述べた映像のストリームを追加する方法を加えて、音声加工可能なビデオチャットシステムとしています。

初めにも書きましたが、完成品はこちらで動いています。http://www.izmiz.me/mediaStreamMerging/

SkyWay サービス利用の注意点

上がっているコードには、SkyWayのAPI key が直打ちされています。この API key は私のドメイン(www.izmiz.me)からしか使えない物になっているので、ご自身で試される場合は、ご自身でSkyWayのアカウントを作成し、ご自身のドメインを適用して API key を取得してください。

さいごに

今回はWebRTC との組み合わせにフォーカスしてまとめました。

次はWebAudio API にフォーカスして、エフェクトの作り込みにトライしてみたいです。