-
Notifications
You must be signed in to change notification settings - Fork 1
/
main.js
100 lines (79 loc) · 3.68 KB
/
main.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
99
import { encodeTransform, decodeTransform, waitLyraReady } from './lyra-transformer';
const codecs = RTCRtpSender.getCapabilities('audio').codecs;
console.log(codecs);
const audioCodec = 'L16';
(async () => {
const sender = new RTCPeerConnection({encodedInsertableStreams: audioCodec === 'L16'});
const stream = await navigator.mediaDevices.getUserMedia({
audio: true,
});
const senderAudioTrack = stream.getAudioTracks()[0];
sender.addTrack(senderAudioTrack);
const transceiver = sender.getTransceivers()[0];
transceiver.direction = 'sendonly';
await waitLyraReady();
if (audioCodec === 'L16') {
transceiver.setCodecPreferences(codecs.filter(codec => codec.mimeType === 'audio/telephone-event' && codec.clockRate === 8000));
}
if (audioCodec === 'opus') {
transceiver.setCodecPreferences(codecs.filter(codec => codec.mimeType === 'audio/opus'));
}
const offer = await sender.createOffer();
if (audioCodec === 'L16') {
offer.sdp = offer.sdp.replace('telephone-event/8000','L16/16000').replace('a=rtpmap:126 L16/16000','a=rtpmap:126 L16/16000\r\na=ptime:20');
if ('RTCRtpScriptTransform' in window) {
const worker = new Worker('./lyra-transformer-worker.js', { type: "module" });
sender.getTransceivers()[0].sender.transform = new RTCRtpScriptTransform(worker, { name: "senderTransform" });
} else {
const senderStreams = sender.getTransceivers()[0].sender.createEncodedStreams();
const transformStream = new TransformStream({
transform: encodeTransform,
});
senderStreams.readable.pipeThrough(transformStream).pipeTo(senderStreams.writable);
}
}
console.log(offer,offer.sdp);
await sender.setLocalDescription(offer);
console.log(offer,sender.localDescription,offer.sdp === sender.localDescription.sdp);
await new Promise(resolve => {
sender.addEventListener('icegatheringstatechange', ()=>{
if (sender.iceGatheringState === 'complete') resolve();
});
if (sender.iceGatheringState === 'complete') resolve();
});
const receiver = new RTCPeerConnection({encodedInsertableStreams: audioCodec === 'L16'});
receiver.addEventListener('track',ev => {
console.log(ev);
if (audioCodec === 'L16') {
if ('RTCRtpScriptTransform' in window) {
const worker = new Worker('./lyra-transformer-worker.js', { type: "module" });
ev.receiver.transform = new RTCRtpScriptTransform(worker, { name: "receiverTransform" });
} else {
const receiverStream = ev.receiver.createEncodedStreams();
const transformStream = new TransformStream({
transform: decodeTransform,
});
receiverStream.readable.pipeThrough(transformStream).pipeTo(receiverStream.writable);
}
}
document.getElementById('audioElem').srcObject = new MediaStream([ev.track]);
});
await receiver.setRemoteDescription(sender.localDescription);
const answer = await receiver.createAnswer();
if (audioCodec === 'L16') {
answer.sdp = answer.sdp.replace('a=group:BUNDLE', 'a=group:BUNDLE 0');
answer.sdp = answer.sdp.replace('m=audio 0 UDP/TLS/RTP/SAVPF 0', 'm=audio 9 UDP/TLS/RTP/SAVPF 126');
answer.sdp += `a=rtpmap:126 L16/16000\r\na=ptime:20\r\n`;
}
console.log(answer.sdp);
await receiver.setLocalDescription(answer);
console.log(sender.localDescription, receiver.localDescription);
await new Promise(resolve => {
receiver.addEventListener('icegatheringstatechange', ()=>{
if (receiver.iceGatheringState === 'complete') resolve();
});
if (receiver.iceGatheringState === 'complete') resolve();
});
await sender.setRemoteDescription(receiver.localDescription);
console.log(sender.localDescription, receiver.localDescription);
})();