forked from node-webrtc/node-webrtc-examples
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathclient.js
98 lines (75 loc) · 3.05 KB
/
client.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
/* global Scope */
'use strict';
require('Scope/dist/Scope.js');
const createExample = require('../../lib/browser/example');
const { acquireAudioContext, releaseAudioContext } = require('../../lib/browser/webaudio/refcountedaudiocontext');
const description = 'This example uses node-webrtc’s RTCAudioSource to \
generate a stereo sine wave server-side. Use the number input to change the \
panning of the server-generated sine wave. Panning changes are sent to the \
server using RTCDataChannel.';
const panningInput = document.createElement('input');
panningInput.type = 'number';
panningInput.value = 50;
panningInput.min = 0;
panningInput.max = 100;
const canvases = document.createElement('div');
canvases.className = 'grid';
async function beforeAnswer(peerConnection) {
const audioContext = acquireAudioContext();
const remoteStream = new MediaStream(peerConnection.getReceivers().map(receiver => receiver.track));
const remoteAudio = document.createElement('audio');
remoteAudio.srcObject = remoteStream;
remoteAudio.play();
document.body.appendChild(remoteAudio);
const source = audioContext.createMediaStreamSource(remoteStream);
const splitter = audioContext.createChannelSplitter(2);
source.connect(splitter);
const leftCanvas = document.createElement('canvas');
const rightCanvas = document.createElement('canvas');
const leftScope = new Scope(audioContext, leftCanvas);
const rightScope = new Scope(audioContext, rightCanvas);
splitter.connect(leftScope.input, 0, 0);
splitter.connect(rightScope.input, 1, 0);
leftScope.start();
rightScope.start();
canvases.appendChild(leftCanvas);
canvases.appendChild(rightCanvas);
let dataChannel = null;
function onDataChannel({ channel }) {
if (channel.label === 'panning') {
dataChannel = channel;
}
}
peerConnection.addEventListener('datachannel', onDataChannel);
function onChange() {
if (dataChannel.readyState === 'open') {
dataChannel.send(panningInput.value);
}
}
panningInput.addEventListener('change', onChange);
// NOTE(mroberts): This is a hack so that we can get a callback when the
// RTCPeerConnection is closed. In the future, we can subscribe to
// "connectionstatechange" events.
const { close } = peerConnection;
peerConnection.close = function() {
panningInput.removeEventListener('change', onChange);
peerConnection.removeEventListener('datachannel', onDataChannel);
remoteAudio.remove();
remoteAudio.srcObject = null;
leftCanvas.remove();
rightCanvas.remove();
leftScope.stop();
rightScope.stop();
splitter.disconnect(leftScope.input, 0);
splitter.disconnect(rightScope.input, 1);
source.disconnect(splitter);
releaseAudioContext();
return close.apply(this, arguments);
};
}
createExample('sine-wave-stereo', description, { beforeAnswer, stereo: true });
const panningLabel = document.createElement('label');
panningLabel.innerText = 'Panning (0–100):';
panningLabel.appendChild(panningInput);
document.body.appendChild(panningLabel);
document.body.appendChild(canvases);