Modern WebRTC Detect drop
by jib1
HTML
<video id="v1" height="120" width="160" autoplay muted></video>
<video id="v2" height="120" width="160" autoplay></video><br>
<button onclick="start()">Start!</button>
<button onclick="drop()">Drop!</button>
<div id="div"></div><div id="div2"></div>
<script src="https://webrtc.github.io/adapter/adapter-latest.js"></script>
JavaScript
var pc1 = new RTCPeerConnection(), pc2 = new RTCPeerConnection();
var start = () =>
navigator.mediaDevices.getUserMedia({ video: true, audio: true })
.then(stream => pc1.addStream(v1.srcObject = stream))
.catch(log);
var drop = () => pc1.close();
var add = (pc, can) => can && pc.addIceCandidate(can).catch(log);
pc1.onicecandidate = e => add(pc2, e.candidate);
pc2.onicecandidate = e => add(pc1, e.candidate);
pc2.onaddstream = e => v2.srcObject = e.stream;
pc1.oniceconnectionstatechange = e => log(pc1.iceConnectionState);
pc1.onnegotiationneeded = e =>
pc1.createOffer().then(d => pc1.setLocalDescription(d))
.then(() => pc2.setRemoteDescription(pc1.localDescription))
.then(() => pc2.createAnswer()).then(d => pc2.setLocalDescription(d))
.then(() => pc1.setRemoteDescription(pc2.localDescription))
.catch(log);
var findStat = (m, type) => [...m.values()].find(s => s.type == type && !s.isRemote);
var hasConnected = new Promise(resolve => pc2.oniceconnectionstatechange =
e => pc2.iceConnectionState == "connected" && resolve());
var hasDropped = hasConnected.then(() => new Promise(resolve => {
var lastPackets = countdown = 0, timeout = 3; // seconds
var iv = setInterval(() => pc2.getStats().then(stats => {
var packets = findStat(stats, "inbound-rtp").packetsReceived;
update(packets +" packets");
countdown = (packets - lastPackets)? timeout : countdown - 1;
if (!countdown) resolve(clearInterval(iv));
lastPackets = packets;
}), 1000);
}));
hasDropped.then(() => (v2.srcObject = null, log("dropped"))).catch(log);
var update = msg => div.innerHTML = msg;
var log = msg => div2.innerHTML += "<br>" + msg;