blob: c6a6ed79fdd02be8bbb6e46104fc9d2537ef7220 [file] [edit]
/*
* Copyright (c) 2015 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree.
*/
'use strict';
/* global WebAudioExtended, webkitRTCPeerConnection */
var audioElement = document.querySelector('audio');
var statusDiv = document.querySelector('div#status');
var startButton = document.querySelector('button#start');
var stopButton = document.querySelector('button#stop');
startButton.onclick = start;
stopButton.onclick = stop;
var renderLocallyCheckbox = document.querySelector('input#renderLocally');
renderLocallyCheckbox.onclick = toggleRenderLocally;
document.addEventListener('keydown', handleKeyDown, false);
var localStream;
var pc1;
var pc2;
var webAudio = new WebAudioExtended();
webAudio.loadSound('audio/Shamisen-C4.wav');
function trace(txt) {
statusDiv.innerHTML += '<p>' + txt + '</p>';
}
function start() {
webAudio.start();
var constraints = {
audio: true,
video: false
};
navigator.mediaDevices.getUserMedia(constraints).
then(handleSuccess).catch(handleFailure);
startButton.disabled = true;
stopButton.disabled = false;
}
function stop() {
webAudio.stop();
pc1.close();
pc2.close();
pc1 = null;
pc2 = null;
startButton.enabled = true;
stopButton.enabled = false;
renderLocallyCheckbox.disabled = true;
localStream.getTracks().forEach(function(track) {
track.stop();
});
}
function handleSuccess(stream) {
renderLocallyCheckbox.disabled = false;
var audioTracks = stream.getAudioTracks();
if (audioTracks.length === 1) {
console.log('Got one audio track:', audioTracks);
var filteredStream = webAudio.applyFilter(stream);
var servers = null;
pc1 = new webkitRTCPeerConnection(servers); // eslint-disable-line new-cap
console.log('Created local peer connection object pc1');
pc1.onicecandidate = iceCallback1;
pc2 = new webkitRTCPeerConnection(servers); // eslint-disable-line new-cap
console.log('Created remote peer connection object pc2');
pc2.onicecandidate = iceCallback2;
pc2.onaddstream = gotRemoteStream;
pc1.addStream(filteredStream);
pc1.createOffer().
then(gotDescription1).
catch(function(error) {
console.log('createOffer failed: ' + error);
});
stream.oninactive = function() {
console.log('Stream inactive:', stream);
startButton.disabled = false;
stopButton.disabled = true;
};
localStream = stream;
} else {
alert('The media stream contains an invalid number of audio tracks.');
stream.getTracks().forEach(function(track) {
track.stop();
});
}
}
function handleFailure(error) {
startButton.disabled = false;
stopButton.disabled = true;
alert('Failed to get access to local media. Error: ' +
error.name);
}
function forceOpus(sdp) {
// Remove all other codecs (not the video codecs though).
sdp = sdp.replace(/m=audio (\d+) RTP\/SAVPF.*\r\n/g,
'm=audio $1 RTP/SAVPF 111\r\n');
sdp = sdp.replace(/a=rtpmap:(?!111)\d{1,3} (?!VP8|red|ulpfec).*\r\n/g, '');
return sdp;
}
function gotDescription1(desc) {
console.log('Offer from pc1 \n' + desc.sdp);
var modifiedOffer = new RTCSessionDescription({
type: 'offer',
sdp: forceOpus(desc.sdp)
});
pc1.setLocalDescription(modifiedOffer);
console.log('Offer from pc1 \n' + modifiedOffer.sdp);
pc2.setRemoteDescription(modifiedOffer);
pc2.createAnswer()
.then(gotDescription2)
.catch(function(error) {
console.log('createAnswer failed: ' + error);
});
}
function gotDescription2(desc) {
pc2.setLocalDescription(desc);
console.log('Answer from pc2 \n' + desc.sdp);
pc1.setRemoteDescription(desc);
}
function gotRemoteStream(e) {
audioElement.srcObject = e.stream;
}
function iceCallback1(event) {
if (event.candidate) {
pc2.addIceCandidate(
new RTCIceCandidate(event.candidate)
).then(
onAddIceCandidateSuccess,
onAddIceCandidateError
);
console.log('Local ICE candidate: \n' + event.candidate.candidate);
}
}
function iceCallback2(event) {
if (event.candidate) {
pc1.addIceCandidate(
new RTCIceCandidate(event.candidate)
).then(
onAddIceCandidateSuccess,
onAddIceCandidateError
);
console.log('Remote ICE candidate: \n ' + event.candidate.candidate);
}
}
function onAddIceCandidateSuccess() {
trace('AddIceCandidate success.');
}
function onAddIceCandidateError(error) {
trace('Failed to add Ice Candidate: ' + error.toString());
}
function handleKeyDown() {
webAudio.addEffect();
}
function toggleRenderLocally() {
console.log('Render locally: ', renderLocallyCheckbox.checked);
webAudio.renderLocally(renderLocallyCheckbox.checked);
}