やりたかったこと
音声通話をするときに、マイクの音量を変更したい。
そのときにストリームの音量を変更して、通信相手にも変更した音量で音声が聞こえるようにしたい。
MediaStreamの音量を変更する方法
-
getUserMediaでMediaStreamを取得する
-
AudioContextを作成する。
AudioContextはユーザーの操作(クリックなど)があったときに生成しないとエラーやWarningがでたりする。audioContext = new (window.AudioContext || window.webkitAudioContext)();
-
1で取得したMediaStreamを指定して、MediaStreamAudioSourceNodeを生成する。
MediaStreamAudioSourceNodeオブジェクトからの音声は再生や編集が可能になる。source = audioContext.createMediaStreamSource(stream);
-
AudioContextからMediaStreamAudioDestinationNodeを生成する。
MediaStreamAudioDestinationNodeのstreamプロパティはMediaStreamと同じような使い方ができる。
このstreamをRTCPeerConnectionで送信することができる。audioDestination = audioContext.createMediaStreamDestination();
-
AudioContextからGainNodeを生成する。
GainNodeで音声のボリュームを操作できる。gainNode = audioContext.createGain();
-
3〜5で生成したNodeをconnectで接続する
audioDestination(MediaStreamAudioDestinationNode)のstreamで音量が変更されたstreamにアクセスすることができる。source.connect(gainNode); gainNode.connect(audioDestination);
↓ Sample(スライダーで音量変更するだけ)
See the Pen gainNode-test by mossan245 (@mossan245) on CodePen.
WebRTCで通信相手に音量変更したStreamを送信する
送信しているMediaStreamの音声のトラックをMediaStreamAudioDestinationNodeのstreamのAudioTrackで置き換えることで実現できる。
Trackの置き換えにはRTCRtpSender.replaceTrack()を利用する。
しかし、FFやSafariだとうまく音量が変更されたStramの送信がうまいくが、Chromeから送信すると受信側で音声が再生されなくなってしまう。
どうやらChromeにバグがあるらしく現状のバージョンだとうまく動かない。
そのため、Chromeの場合は別途音量変更を通知する仕組みを用意して、通信相手側で直接音量を変更する必要がある。