1. tomoyukilabs

    No comment

    tomoyukilabs
Changes in body
Source | HTML | Preview
@@ -1,112 +1,112 @@
ちょっとお遊びで、WebRTCの音声通話で、音声の途中で都合の悪い言葉を隠すのに「ピー」という音を入れることができるようになる方法を試してみます(笑)。
*Chrome for Androidでは残念ながら動作しないようです。
(参考: http://caniuse.com/#search=web%20audio )*
# まずはマイクの音声をキャプチャ
お約束の`navigator.getUserMedia()`です。
```js:音声キャプチャを開始
var mic;
navigator.getUserMedia =
navigator.getUserMedia ||
navigator.webkitGetUserMedia ||
navigator.mozGetUserMedia;
navigator.getUserMedia(
- {audio: true;},
+ { audio: true },
function(s) { mic = s; },
function(e) { console.log(e); }
);
```
# 「ピー」を作る
「ピー」という音を、今回はWeb Audio APIを使って作ってみます。正弦波のオシレータを使えば、十分それっぽい雰囲気が出るのではと思います。
```js:「ピー」の音をオシレータで再現
var context = window.AudioContext || window.webkitAudioContext;
var ctx = new context();
var osc = context.createOscillator();
osc.frequency.value = 880 * Math.pow(2,2/12); // シの音階(ラの音階より全音上)
```
# マイクと「ピー」をミキシング
まず、WebRTC Advent Calendar 9日目の[getUserMedia使ってJSで動くチューナー作った。](http://qiita.com/ymmtmdk/items/0d8a3d6d613ff61e65be)の記事と同様に、マイクの入力ノードを`createMediaStreamSource()`で取り出します。
その後、マイクと「ピー」のそれぞれの音量をコントロールするゲインノードを作って接続し、それらを`createMediaStreamDestination()`で生成した出力ノードに接続してミキシング、という順序になります。
```js:マイクと「ピー」をミキシング
var micNode = context.createMediaStreamSource(mic);
var micGain, oscGain;
if(context.createGain) {
micGain = context.createGain();
oscGain = context.createGain();
}
else {
// 多分不要だと思われますが、念のため古いWeb Audio APIへの対処
micGain = context.createGainNode();
oscGain = context.createGainNode();
}
micNode.connect(micGain);
osc.connect(oscGain);
// まずはマイクを鳴らして「ピー」をミュート
micGain.gain.value = 1;
oscGain.gain.value = 0;
// ミキシング
var output = context.createMediaStreamDestination();
micGain.connect(output);
oscGain.connect(output);
if(osc.start)
osc.start(0);
else
// 多分不要だと思われますが、念のため古いWeb Audio APIへの対処
osc.noteOn(0);
```
# いよいよWebRTC
さて、いよいよWebRTCの初期化です。ここでは詳細は省かせていただいて、要点に絞って説明します。
`RTCPeerConnection`の初期化やoffer/answerのやりとり等は通常の手順と同様で、`RTCPeerConnection.addStream()`で渡すストリームだけ変えればよい、ということになります。
ひとまず、通常と同じようにRTCPeerConnectionインスタンスを生成し、必要な初期化を行います。
そして、`addStream()`で、先ほど生成したミキシングの出力ノードのストリームをここに渡せばよい、ということになります。`output`自体ではなく、`output.stream`を渡す点に注意が必要です。
```js:RTCPeerConnection初期化
var PC =
window.RTCPeerConnection ||
window.webkitRTCPeerConnection ||
window.mozRTCPeerConnection;
var peer = new PC({ iceServers: [ { ... } ] });
peer.onicecandidate = function(ice) { ... };
// ミキシングの出力ノードのストリームをRTCPeerConnectionに追加
peer.addStream(output.stream);
```
あとは、引き続きoffer/answerを経てセッションを確立させれば、いつもどおりWebRTCで通話ができるようになるわけですが、ここでもう少々細工をして、好きなタイミングでマイクの音声の代わりに「ピー」が相手に聞こえるようにしてみます。ここでは「P」キーを押している間はマイクがミュートされて「ピー」が相手に聞こえる、というようにしています。
```js:「ピー」の切替
function startCensor(evt) {
if(evt.keyCode == 'P'.charCodeAt(0)) {
micGain.gain.value = 0;
oscGain.gain.value = 1;
}
}
function stopCensor(evt) {
if(evt.keyCode == 'P'.charCodeAt(0)) {
micGain.gain.value = 1;
oscGain.gain.value = 0;
}
}
document.addEventListener('keydown', startCensor, false);
document.addEventListener('keyup', stopCensor, false);
```
...というわけで、WebRTC音声チャットで「ピー」、という非常にくだらない使い道を例として(笑)、WebRTCにWeb Audio APIを組み合わせる方法、でした。
この他にも、Web Audio APIをWebRTCに組み合わせて、例えば、音楽ファイルがあれば保留音を相手に聞こえるようにする、等の使い方ができます。色々とお試しあれ。