JSFiddle - React, Tailwind, and code Playground
HTML
<button onclick="start()">start</button>
<br>
<video id="video1" autoplay playsInline controls></video>
<video id="video2" autoplay playsInline controls></video>
<br>
<div id="log"></div>
JavaScript
async function exchange(useRemote, stream)
{
if (!stream) {
const context = new AudioContext();
const oscillator = context.createOscillator();
const streamDestination = context.createMediaStreamDestination();
oscillator.connect(streamDestination);
oscillator.start();
stream = streamDestination.stream;
}
if (!useRemote) {
video2.srcObject = stream;
await video2.play();
return;
}
const localPC = new RTCPeerConnection();
const remotePC = new RTCPeerConnection();
remotePC.onicecandidate = event => event.candidate && localPC.addIceCandidate(event.candidate);
localPC.onicecandidate = event => event.candidate && remotePC.addIceCandidate(event.candidate);
const result = new Promise(resolve => {
remotePC.ontrack = event => {
console.log('got track:', event.track);
resolve({
remoteTrack: event.track,
remoteStream: new MediaStream([event.track]),
localPC,
remotePC
});
};
});
localPC.addTrack(stream.getAudioTracks()[0], stream);
const offer = await localPC.createOffer();
await localPC.setLocalDescription(offer);
await remotePC.setRemoteDescription(offer);
const answer = await remotePC.createAnswer();
await remotePC.setLocalDescription(answer);
await localPC.setRemoteDescription(answer);
const res = await result;
video2.srcObject = res.remoteStream;
await video2.play();
return localPC.getSenders()[0];
}
async function start()
{
const defaultAudioConstraints = {
sampleRate: 48000,
sampleSize: 16,
channelCount: 1,
echoCancellation: true,
noiseSuppression: true
};
const musicModeAudioConstraints = {
sampleRate: 48000,
sampleSize: 16,
channelCount: 2,
echoCancellation: false,
noiseSuppression: false
};
const stream1 = await navigator.mediaDevices.getUserMedia({ audio: defaultAudioConstraints});
video1.srcObject = stream1;
const sender = await exchange(true,...