-
Notifications
You must be signed in to change notification settings - Fork 163
/
client.js
96 lines (74 loc) · 3.08 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
/* global Scope */
'use strict';
require('Scope/dist/Scope.js');
const createExample = require('../../lib/browser/example');
const { acquireAudioContext, releaseAudioContext } = require('../../lib/browser/webaudio/refcountedaudiocontext');
const WebAudioOscillatorNodeSineWave = require('../../lib/browser/webaudio/webaudiooscillatornodesinewave');
const description = 'This example uses node-webrtc’s RTCAudioSink to \
implement simple pitch detection server-side. The client generates a sine \
wave, and the server communicates the pitch it detects using RTCDataChannel. \
Use the number input to change the frequency of the client-generated sine \
wave.';
const frequencyInput = document.createElement('input');
frequencyInput.type = 'number';
frequencyInput.value = 440;
frequencyInput.min = 0;
frequencyInput.max = 48000 / 2;
const detectedFrequency = document.createElement('p');
detectedFrequency.innerText = 'Detected Frequency:';
function beforeAnswer(peerConnection) {
const audioContext = acquireAudioContext();
const webAudioSineWave = new WebAudioOscillatorNodeSineWave({
frequency: frequencyInput.value
});
function onChange() {
console.log(frequencyInput.value);
webAudioSineWave.setFrequency(frequencyInput.value);
}
frequencyInput.addEventListener('change', onChange);
const streamNode = audioContext.createMediaStreamDestination();
webAudioSineWave.node.connect(streamNode);
const { stream } = streamNode;
stream.getTracks().forEach(track => peerConnection.addTrack(track, stream));
const canvas = document.createElement('canvas');
const scope = new Scope(audioContext, canvas);
webAudioSineWave.node.connect(scope.input);
scope.start();
document.body.appendChild(canvas);
let dataChannel = null;
function onMessage({ data }) {
detectedFrequency.innerText = `Detected Frequency: ${data} hz`;
}
function onDataChannel({ channel }) {
if (channel.label !== 'frequency') {
return;
}
dataChannel = channel;
dataChannel.addEventListener('message', onMessage);
}
peerConnection.addEventListener('datachannel', onDataChannel);
// 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() {
frequencyInput.removeEventListener('change', onChange);
canvas.remove();
scope.stop();
webAudioSineWave.node.disconnect(scope.input);
stream.getTracks().forEach(track => track.stop());
webAudioSineWave.node.disconnect(streamNode);
webAudioSineWave.close();
releaseAudioContext();
if (dataChannel) {
dataChannel.removeEventListener('message', onMessage);
}
return close.apply(this, arguments);
};
}
createExample('pitch-detector', description, { beforeAnswer });
const frequencyLabel = document.createElement('label');
frequencyLabel.innerText = 'Frequency (hz):';
frequencyLabel.appendChild(frequencyInput);
document.body.appendChild(frequencyLabel);
document.body.appendChild(detectedFrequency);