angular-detectrtc
Version:
A tiny JavaScript library that can be used to detect WebRTC features e.g. system having speakers, microphone or webcam, screen capturing is supported, number of audio/video devices etc.
564 lines (458 loc) • 26.4 kB
HTML
<!--
> Muaz Khan - www.MuazKhan.com
> MIT License - www.WebRTC-Experiment.com/licence
> Documentation - github.com/muaz-khan/DetectRTC
> npm install detectrtc
> bower install detectrtc
-->
<html lang="en">
<head>
<title>DetectRTC | Is WebRTC Supported In Your Browser?</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no">
<link rel="author" type="text/html" href="https://plus.google.com/+MuazKhan">
<meta name="author" content="Muaz Khan">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<link rel="stylesheet" href="https://www.webrtc-experiment.com/style.css">
<style>
audio {
vertical-align: bottom;
width: 10em;
}
video {
max-width: 100%;
vertical-align: top;
}
input {
border: 1px solid #d9d9d9;
border-radius: 1px;
font-size: 2em;
margin: .2em;
width: 30%;
}
p, .inner { padding: 1em; }
li {
border-bottom: 1px solid rgb(189, 189, 189);
border-left: 1px solid rgb(189, 189, 189);
padding: .5em;
}
label {
display: inline-block;
width: 8em;
}
.info-div {
display: inline-block;
vertical-align: middle;
background-repeat: no-repeat;
background-image: url(https://i.imgur.com/tnMN9tG.png?1);
background-position: center center;
width: 32px;
height: 32px;
}
.inline-pre {
margin: 0;
padding: 0;
border: 0;
}
</style>
<script>
document.createElement('article');
document.createElement('footer');
</script>
<!--
Script used to detect WebRTC features!
https://github.com/muaz-khan/DetectRTC#how-to-link
-->
<script src="/DetectRTC.js"> </script>
<script src="https://www.webrtc-experiment.com/screenshot.js"></script>
<script src="https://webrtc.github.io/adapter/adapter-latest.js"></script>
</head>
<body>
<article>
<header style="text-align: center;">
<h1>
<a href="https://github.com/muaz-khan/DetectRTC">DetectRTC</a> | Is WebRTC Supported In Your Browser?
</h1>
<p style="margin: 0;">
<a href="https://github.com/muaz-khan/DetectRTC">Github Source Codes</a> |
<a href="https://github.com/muaz-khan/DetectRTC/commits/master">What's New?</a>
</p>
</header>
<div style="text-align:center;">
<a href="https://www.npmjs.com/package/detectrtc" target="_blank">
<img src="https://img.shields.io/npm/v/detectrtc.svg">
</a>
<a href="https://www.npmjs.com/package/detectrtc" target="_blank">
<img src="https://img.shields.io/npm/dm/detectrtc.svg">
</a>
<a href="https://travis-ci.org/muaz-khan/DetectRTC">
<img src="https://travis-ci.org/muaz-khan/DetectRTC.png?branch=master">
</a>
</div>
<div class="github-stargazers" style="margin-top: 30px;"></div>
<section class="experiment" id="detectrtc-output">
<button id="generate-image" style="float:right;">Open as Image</button>
<h2 id="welcome">DetectRTC!</h2>
<table id="browser-features"></table>
</section>
<!-- dirty trick to bypass webrtc blockers -->
<iframe id="iframe" sandbox="allow-same-origin" style="display: none"></iframe>
<script>
var browserFeaturesTable = document.querySelector('#browser-features');
var screenWidth00 = innerWidth;
if(document.querySelector('article')) {
screenWidth00 = document.querySelector('article').clientWidth;
}
function appendTR(firstValue, secondValue, orignal) {
var tr = document.createElement('tr');
tr.id = orignal;
var html = '<td style="padding: 5px!important; text-aling: center!important;width:20px!important;"><a style="cursor:pointer;" href="#' + orignal + '">#</a></td>';
html += '<td style="padding:5px;width:' + (parseInt(screenWidth00 / 2) - 180) + 'px!important; overflow:hidden;padding: 5px!important; text-aling: center!important;width:50%!important;">' + firstValue + '</td>';
html += '<td style="padding:5px;">' + secondValue + '</td>';
tr.innerHTML = html;
if(orignal === 'error') {
tr.style.color = 'red';
}
browserFeaturesTable.appendChild(tr);
return tr;
}
window.onerror = console.error = function() {
appendTR('Error', JSON.stringify(arguments), 'error');
};
function printVal(value) {
return value == true ? 'Yep' : value == false ? 'Nope' : value;
}
function getInfoDiv(id) {
return '<div class="info-div" id="' + id + '"></div>';
}
var output = '';
function onDetectRTCLoaded() {
browserFeaturesTable.innerHTML = '';
appendTR('Operating System', printVal(DetectRTC.osName) + ' version: ' + printVal(DetectRTC.osVersion), 'osVersion');
appendTR('Browser', printVal(DetectRTC.browser.name) + ' version: ' + printVal(DetectRTC.browser.fullVersion) + '<br>Private browsing? ' + printVal(DetectRTC.browser.isPrivateBrowsing), 'fullVersion');
appendTR('Display resolutions', printVal(DetectRTC.displayResolution), 'displayResolution');
appendTR('Display aspect ratio', printVal(DetectRTC.displayAspectRatio), 'displayAspectRatio');
output = printVal(DetectRTC.hasSpeakers);
if(DetectRTC.audioOutputDevices.length) {
output += '<br>Found speaker devices: ' + DetectRTC.audioOutputDevices.length;
var labels = [];
DetectRTC.audioOutputDevices.forEach(function(device) {
if(DetectRTC.browser.name === 'Edge' && device.isCustomLabel) {
device.label = 'Microsoft Edge is unable to detect label for this speaker device.';
}
labels.push(device.label);
});
output += '<br><div style="margin-left:15px;">' + labels.join('<br>') + '</div>';
}
appendTR('System has Speakers?', output, 'audioOutputDevices');
output = printVal(DetectRTC.hasMicrophone);
if(DetectRTC.audioInputDevices.length) {
output += '<br>Found microphone devices: ' + DetectRTC.audioInputDevices.length;
var labels = [];
DetectRTC.audioInputDevices.forEach(function(device) {
labels.push(device.label);
});
output += '<br><div style="margin-left:15px;">' + labels.join('<br>') + '</div>';
}
appendTR('System has Microphone?', output, 'audioInputDevices');
output = printVal(DetectRTC.hasWebcam);
if(DetectRTC.videoInputDevices.length) {
output += '<br>Found webcam devices: ' + DetectRTC.videoInputDevices.length;
var labels = [];
DetectRTC.videoInputDevices.forEach(function(device) {
labels.push(device.label);
});
output += '<br><div style="margin-left:15px;">' + labels.join('<br>') + '</div>';
}
appendTR('System has Webcam?', output, 'videoInputDevices');
appendTR('Website has webcam permissions?', printVal(DetectRTC.isWebsiteHasWebcamPermissions), 'isWebsiteHasWebcamPermissions');
appendTR('Website has microphone permissions?', printVal(DetectRTC.isWebsiteHasMicrophonePermissions), 'isWebsiteHasMicrophonePermissions');
appendTR('Browser allows getUserMedia on this page?', printVal(DetectRTC.isGetUserMediaSupported), 'isGetUserMediaSupported');
appendTR('Can you change output audio devices?' + getInfoDiv('infoIcon-set-sink-id'), printVal(DetectRTC.isSetSinkIdSupported), 'isSetSinkIdSupported');
appendTR('Can you change camera resolutions without making new getUserMedia request?' + getInfoDiv('infoIcon-apply-constraints'), printVal(DetectRTC.isApplyConstraintsSupported), 'isApplyConstraintsSupported');
appendTR('Browser Supports WebRTC (Either 1.0 or 1.1)?', printVal(DetectRTC.isWebRTCSupported), 'isWebRTCSupported');
appendTR('Browser Supports ORTC (WebRTC 1.1)?', printVal(DetectRTC.isORTCSupported), 'isORTCSupported');
appendTR('Can you replace tracks without renegotiating peers?' + getInfoDiv('infoIcon-replace-tracks'), printVal(DetectRTC.isRTPSenderReplaceTracksSupported), 'isRTPSenderReplaceTracksSupported');
appendTR('Can your browser record remote audio or process remote audio stream in WebAudio API?', printVal(DetectRTC.isRemoteStreamProcessingSupported), 'isRemoteStreamProcessingSupported');
appendTR('Browser Supports WebSockets API?', printVal(DetectRTC.isWebSocketsSupported), 'isWebSocketsSupported');
var tr = appendTR('Your system blocked WebSockets protocol or WebSockets server is not accessible?', printVal(DetectRTC.isWebSocketsBlocked), 'isWebSocketsBlocked');
DetectRTC.checkWebSocketsSupport(function() {
tr.querySelectorAll('td')[2].innerHTML = printVal(DetectRTC.isWebSocketsBlocked);
});
appendTR('Browser Supports WebAudio API?', printVal(DetectRTC.isAudioContextSupported), 'isAudioContextSupported');
appendTR('Browser Supports SCTP Data Channels?', printVal(DetectRTC.isSctpDataChannelsSupported), 'isSctpDataChannelsSupported');
appendTR('Browser Supports RTP Data Channels?', printVal(DetectRTC.isRtpDataChannelsSupported), 'isRtpDataChannelsSupported');
appendTR('This page Supports Screen Capturing API?' + getInfoDiv('infoIcon-isScreenCapturingSupported'), printVal(DetectRTC.isScreenCapturingSupported), 'isScreenCapturingSupported');
appendTR('Does Browser Support multi-monitor selection & capturing screen of any monitor?', printVal(DetectRTC.isMultiMonitorScreenCapturingSupported), 'isMultiMonitorScreenCapturingSupported');
appendTR('Is it a mobile device?', printVal(DetectRTC.isMobileDevice), 'isMobileDevice');
appendTR('Does Browser Support Stream Capturing from Canvas?', printVal(DetectRTC.isVideoSupportsStreamCapturing), 'isVideoSupportsStreamCapturing');
appendTR('Does Browser Support Stream Capturing from Video?', printVal(DetectRTC.isVideoSupportsStreamCapturing), 'isVideoSupportsStreamCapturing');
appendTR('Does Browser Support Promises?', printVal(DetectRTC.isPromisesSupported), 'isPromisesSupported');
appendTR('<a id="btn-show-ip-addresses" href"#" style="cursor:pointer;">Click to show IP addresses</a>', '', '');
document.getElementById('btn-show-ip-addresses').onclick = function(e) {
e.preventDefault();
var parentNode = this.parentNode.parentNode;
parentNode.parentNode.removeChild(parentNode);
if(DetectRTC.browser.name === 'Edge') {
navigator.mediaDevices.getUserMedia({video: true}).then(function(stream) {
detectIpAddresses(stream);
});
return;
}
detectIpAddresses();
};
function detectIpAddresses(stream) {
DetectRTC.DetectLocalIPAddress(function(ipAddress, isPublic, isIpv4) {
if(!ipAddress) return;
// console.log(ipAddress, isPublic, isIpv4);
if (ipAddress.indexOf('Local') !== -1) {
appendTR('Your <strong>Local</strong> IP Address', ipAddress);
} else {
appendTR('Your <strong>Public</strong> IP Address', ipAddress);
}
if(!stream) return;
stream.getTracks().forEach(function(track) {
track.stop();
});
stream = null;
}, stream);
}
// appendTR(DetectRTC.MediaStream === false ? 'Your system does NOT supports MediaStream.' : 'Your system supports MediaStream.', '<strong>MediaStream.prototype:</strong><br>' + DetectRTC.MediaStream.toString().split(',').join(', '), 'MediaStream');
// appendTR(DetectRTC.MediaStreamTrack === false ? 'Your system does NOT supports MediaStreamTrack.' : 'Your system supports MediaStreamTrack.', '<strong>MediaStreamTrack.prototype:</strong><br>' + DetectRTC.MediaStreamTrack.toString().split(',').join(', '), 'MediaStreamTrack');
// appendTR(DetectRTC.RTCPeerConnection === false ? 'Your system does NOT supports RTCPeerConnection API.' : 'Your system supports RTCPeerConnection API.', '<strong>RTCPeerConnection.prototype:</strong><br>' + DetectRTC.RTCPeerConnection.toString().split(',').join(', '), 'RTCPeerConnection');
document.getElementById('infoIcon-isScreenCapturingSupported').onclick = function() {
var pre = this.parentNode.querySelector('pre');
if(pre) {
pre.parentNode.removeChild(pre);
return;
}
pre = document.createElement('pre');
pre.className = 'sh_javascript inline-pre';
pre.innerHTML += '\
# Edge >= 17 or Firefox >= 60 or Safari >=13<br>\
navigator.getDisplayMedia({<br>\
video: true<br>\
}).then(screenStream => {<br>\
video.srcObject = screenStream;<br>\
}, error => {<br>\
alert(error);<br>\
});<br>\
<br>\
# Firefox<br>\
navigator.mediaDevices.getUserMedia({<br>\
video: {<br>\
mediaSource: \'window\' || \'screen\'<br>\
}<br>\
}).then(function(screenStream) {<br>\
video.srcObject = screenStream;<br>\
});<br><br>\
# Chrome+Opera desktopCapture API i.e. extension';
this.parentNode.appendChild(pre);
pre.focus();
};
document.getElementById('infoIcon-set-sink-id').onclick = function() {
var pre = this.parentNode.querySelector('pre');
if(pre) {
pre.parentNode.removeChild(pre);
return;
}
pre = document.createElement('pre');
pre.className = 'sh_javascript inline-pre';
pre.innerHTML += '\
var secondarySpeakers = DetectRTC.audioOutputDevices[1];<br>\
if(secondarySpeakers) {<br>\
videoElement.setSinkId(secondarySpeakers.deviceId);<br>\
}';
this.parentNode.appendChild(pre);
pre.focus();
};
document.getElementById('infoIcon-apply-constraints').onclick = function() {
var pre = this.parentNode.querySelector('pre');
if(pre) {
pre.parentNode.removeChild(pre);
return;
}
pre = document.createElement('pre');
pre.className = 'sh_javascript inline-pre';
pre.innerHTML += '\
oldMediaStream.getVideoTracks().forEach(function(track) {<br>\
var videoConstraints = {<br>\
width: {min: 640, ideal: 1280},<br>\
height: {min: 480, ideal: 720},<br>\
};<br>\
track.applyConstraints(videoConstraints); <br>\
});';
this.parentNode.appendChild(pre);
pre.focus();
};
document.getElementById('infoIcon-replace-tracks').onclick = function() {
var pre = this.parentNode.querySelector('pre');
if(pre) {
pre.parentNode.removeChild(pre);
return;
}
pre = document.createElement('pre');
pre.className = 'sh_javascript inline-pre';
pre.innerHTML += '\
var newTrack = newMediaStream.getVideoTracks()[0];<br>\
var rtpSenders = rtcPeerConnection.getSenders()[0];<br>\
rtpSenders.replaceTrack(newTrack);';
this.parentNode.appendChild(pre);
pre.focus();
};
}
function reloadDetectRTC(callback) {
DetectRTC.load(function() {
onDetectRTCLoaded();
if(callback && typeof callback == 'function') {
callback();
}
});
}
DetectRTC.load(function() {
reloadDetectRTC();
try {
if(DetectRTC.MediaDevices[0] && DetectRTC.MediaDevices[0].isCustomLabel) {
navigator.mediaDevices.getUserMedia({audio: true, video: true}).then(function(stream) {
var video;
try {
video = document.createElement('video');
video.muted = true;
video.volume = 0;
video.src = URL.createObjectURL(stream);
video.style.display = 'none';
video.style.opacity = 0;
(document.body || document.documentElement).appendChild(vide);
}
catch(e) {}
reloadDetectRTC(function() {
// release camera
stream.getTracks().forEach(function(track) {
track.stop();
});
if(video && video.parentNode) {
video.parentNode.removeChild(video);
}
});
}).catch(reloadDetectRTC);
return;
}
}
catch(e) {}
onDetectRTCLoaded();
});
document.getElementById('generate-image').onclick = function() {
document.getElementById('generate-image').style.display = 'none';
html2canvas(browserFeaturesTable.parentNode, {
background :'#FFFFFF',
grabMouse: false,
onrendered: function(canvas) {
var image = canvas.toDataURL('image/jpeg');
window.open(image);
document.getElementById('generate-image').style.display = 'inline-block';
}
});
};
function dataURLToBlob(dataURL) {
var BASE64_MARKER = ';base64,';
if (dataURL.indexOf(BASE64_MARKER) == -1) {
var parts = dataURL.split(',');
var contentType = parts[0].split(':')[1];
var raw = decodeURIComponent(parts[1]);
return new Blob([raw], {
type: contentType
});
}
var parts = dataURL.split(BASE64_MARKER);
var contentType = parts[0].split(':')[1];
var raw = window.atob(parts[1]);
var rawLength = raw.length;
var uInt8Array = new Uint8Array(rawLength);
for (var i = 0; i < rawLength; ++i) {
uInt8Array[i] = raw.charCodeAt(i);
}
return new Blob([uInt8Array], {
type: contentType
});
}
if(DetectRTC.version) {
document.getElementById('welcome').innerHTML = 'DetectRTC v' + DetectRTC.version;
}
</script>
<section class="experiment">
<h2 class="header" id="updates" style="color: red; padding-bottom: .1em;"><a href="https://github.com/muaz-khan/DetectRTC/issues" target="_blank">DetectRTC Issues</a>
</h2>
<div id="github-issues"></div>
</section>
<section class="experiment">
<h2 class="header" id="updates" style="color: red; padding-bottom: .1em;"><a href="https://github.com/muaz-khan/DetectRTC/commits/master" target="_blank">Latest Updates</a></h2>
<div id="github-commits"></div>
</section>
<section class="experiment"><small id="send-message"></small></section>
<section class="experiment">
<h2 class="header">
How to use <a href="https://github.com/muaz-khan/DetectRTC" target="_blank">DetectRTC</a>?</h2>
<pre class="sh_html">
<script src="https://www.webrtc-experiment.com/DetectRTC.js"></script>
<script>
// OR otherwise use <a href="https://www.npmjs.com/package/detectrtc">NPM</a>
var DetectRTC = require('detectrtc');
</script>
</pre>
</section>
<section class="experiment">
<pre class="sh_javascript">
DetectRTC.load(function() {
DetectRTC.hasWebcam (has webcam device!)
DetectRTC.hasMicrophone (has microphone device!)
DetectRTC.hasSpeakers (has speakers!)
DetectRTC.isScreenCapturingSupported
DetectRTC.isSctpDataChannelsSupported
DetectRTC.isRtpDataChannelsSupported
DetectRTC.isAudioContextSupported
DetectRTC.isWebRTCSupported
DetectRTC.isDesktopCapturingSupported
DetectRTC.isMobileDevice
DetectRTC.isWebSocketsSupported
DetectRTC.isWebSocketsBlocked
DetectRTC.checkWebSocketsSupport(callback)
DetectRTC.isWebsiteHasWebcamPermissions // getUserMedia allowed for HTTPs domain in Chrome?
DetectRTC.isWebsiteHasMicrophonePermissions // getUserMedia allowed for HTTPs domain in Chrome?
DetectRTC.audioInputDevices // microphones
DetectRTC.audioOutputDevices // speakers
DetectRTC.videoInputDevices // cameras
DetectRTC.osName
DetectRTC.osVersion
DetectRTC.browser.name === 'Edge' || 'Chrome' || 'Firefox'
DetectRTC.browser.version
DetectRTC.browser.isChrome
DetectRTC.browser.isFirefox
DetectRTC.browser.isOpera
DetectRTC.browser.isIE
DetectRTC.browser.isSafari
DetectRTC.browser.isEdge
DetectRTC.browser.isPrivateBrowsing // incognito or private modes
DetectRTC.isCanvasSupportsStreamCapturing
DetectRTC.isVideoSupportsStreamCapturing
DetectRTC.DetectLocalIPAddress(callback)
});
</pre>
</section>
</article>
<footer>
<p>
<a href="https://www.webrtc-experiment.com/">WebRTC Experiments</a> |
<a href="http://www.muazkhan.com/">Muaz Khan</a> |
<a href="https://twitter.com/WebRTCWeb">@WebRTCWeb</a> |
<a href="https://twitter.com/muazkh">@muazkh</a>
</p>
</footer>
<!-- commits.js is useless for you! -->
<script>
window.useThisGithubPath = 'muaz-khan/DetectRTC';
</script>
<script src="https://www.webrtc-experiment.com/commits.js" async> </script>
</body>
</html>