From 644b22fe3778614c1568118445fff9e147a6bddd Mon Sep 17 00:00:00 2001 From: pabloFuente Date: Thu, 15 Mar 2018 12:43:30 +0100 Subject: [PATCH] 'BROWSER_NOT_SUPPORTED' and 'SCREEN_SHARING_NOT_SUPPORTED' errors --- openvidu-browser/ts/KurentoUtils/DetectRTC.js | 1097 +++++++++++++++++ openvidu-browser/ts/OpenVidu/OpenVidu.ts | 275 ++--- openvidu-browser/ts/OpenVidu/Session.ts | 40 +- .../ts/OpenViduInternal/OpenViduError.ts | 2 + .../ts/OpenViduInternal/Stream.ts | 4 +- .../ts/OpenViduInternal/WebRtcStats.ts | 11 +- 6 files changed, 1267 insertions(+), 162 deletions(-) create mode 100644 openvidu-browser/ts/KurentoUtils/DetectRTC.js diff --git a/openvidu-browser/ts/KurentoUtils/DetectRTC.js b/openvidu-browser/ts/KurentoUtils/DetectRTC.js new file mode 100644 index 00000000..859a494f --- /dev/null +++ b/openvidu-browser/ts/KurentoUtils/DetectRTC.js @@ -0,0 +1,1097 @@ +'use strict'; + +// Last Updated On: 2017-12-09 2:29:22 PM UTC + +// ________________ +// DetectRTC v1.3.6 + +// Open-Sourced: https://github.com/muaz-khan/DetectRTC + +// -------------------------------------------------- +// Muaz Khan - www.MuazKhan.com +// MIT License - www.WebRTC-Experiment.com/licence +// -------------------------------------------------- + +(function() { + + var browserFakeUserAgent = 'Fake/5.0 (FakeOS) AppleWebKit/123 (KHTML, like Gecko) Fake/12.3.4567.89 Fake/123.45'; + + var isNodejs = typeof process === 'object' && typeof process.versions === 'object' && process.versions.node && /*node-process*/ !process.browser; + if (isNodejs) { + var version = process.versions.node.toString().replace('v', ''); + browserFakeUserAgent = 'Nodejs/' + version + ' (NodeOS) AppleWebKit/' + version + ' (KHTML, like Gecko) Nodejs/' + version + ' Nodejs/' + version + } + + (function(that) { + if (typeof window !== 'undefined') { + return; + } + + if (typeof window === 'undefined' && typeof global !== 'undefined') { + global.navigator = { + userAgent: browserFakeUserAgent, + getUserMedia: function() {} + }; + + /*global window:true */ + that.window = global; + } else if (typeof window === 'undefined') { + // window = this; + } + + if (typeof location === 'undefined') { + /*global location:true */ + that.location = { + protocol: 'file:', + href: '', + hash: '' + }; + } + + if (typeof screen === 'undefined') { + /*global screen:true */ + that.screen = { + width: 0, + height: 0 + }; + } + })(typeof global !== 'undefined' ? global : window); + + /*global navigator:true */ + var navigator = window.navigator; + + if (typeof navigator !== 'undefined') { + if (typeof navigator.webkitGetUserMedia !== 'undefined') { + navigator.getUserMedia = navigator.webkitGetUserMedia; + } + + if (typeof navigator.mozGetUserMedia !== 'undefined') { + navigator.getUserMedia = navigator.mozGetUserMedia; + } + } else { + navigator = { + getUserMedia: function() {}, + userAgent: browserFakeUserAgent + }; + } + + var isMobileDevice = !!(/Android|webOS|iPhone|iPad|iPod|BB10|BlackBerry|IEMobile|Opera Mini|Mobile|mobile/i.test(navigator.userAgent || '')); + + var isEdge = navigator.userAgent.indexOf('Edge') !== -1 && (!!navigator.msSaveOrOpenBlob || !!navigator.msSaveBlob); + + var isOpera = !!window.opera || navigator.userAgent.indexOf(' OPR/') >= 0; + var isFirefox = typeof window.InstallTrigger !== 'undefined'; + var isSafari = /^((?!chrome|android).)*safari/i.test(navigator.userAgent); + var isChrome = !!window.chrome && !isOpera; + var isIE = typeof document !== 'undefined' && !!document.documentMode && !isEdge; + + // this one can also be used: + // https://www.websocket.org/js/stuff.js (DetectBrowser.js) + + function getBrowserInfo() { + var nVer = navigator.appVersion; + var nAgt = navigator.userAgent; + var browserName = navigator.appName; + var fullVersion = '' + parseFloat(navigator.appVersion); + var majorVersion = parseInt(navigator.appVersion, 10); + var nameOffset, verOffset, ix; + + // In Opera, the true version is after 'Opera' or after 'Version' + if (isOpera) { + browserName = 'Opera'; + try { + fullVersion = navigator.userAgent.split('OPR/')[1].split(' ')[0]; + majorVersion = fullVersion.split('.')[0]; + } catch (e) { + fullVersion = '0.0.0.0'; + majorVersion = 0; + } + } + // In MSIE version <=10, the true version is after 'MSIE' in userAgent + // In IE 11, look for the string after 'rv:' + else if (isIE) { + verOffset = nAgt.indexOf('rv:'); + if (verOffset > 0) { //IE 11 + fullVersion = nAgt.substring(verOffset + 3); + } else { //IE 10 or earlier + verOffset = nAgt.indexOf('MSIE'); + fullVersion = nAgt.substring(verOffset + 5); + } + browserName = 'IE'; + } + // In Chrome, the true version is after 'Chrome' + else if (isChrome) { + verOffset = nAgt.indexOf('Chrome'); + browserName = 'Chrome'; + fullVersion = nAgt.substring(verOffset + 7); + } + // In Safari, the true version is after 'Safari' or after 'Version' + else if (isSafari) { + verOffset = nAgt.indexOf('Safari'); + + browserName = 'Safari'; + fullVersion = nAgt.substring(verOffset + 7); + + if ((verOffset = nAgt.indexOf('Version')) !== -1) { + fullVersion = nAgt.substring(verOffset + 8); + } + + if (navigator.userAgent.indexOf('Version/') !== -1) { + fullVersion = navigator.userAgent.split('Version/')[1].split(' ')[0]; + } + } + // In Firefox, the true version is after 'Firefox' + else if (isFirefox) { + verOffset = nAgt.indexOf('Firefox'); + browserName = 'Firefox'; + fullVersion = nAgt.substring(verOffset + 8); + } + + // In most other browsers, 'name/version' is at the end of userAgent + else if ((nameOffset = nAgt.lastIndexOf(' ') + 1) < (verOffset = nAgt.lastIndexOf('/'))) { + browserName = nAgt.substring(nameOffset, verOffset); + fullVersion = nAgt.substring(verOffset + 1); + + if (browserName.toLowerCase() === browserName.toUpperCase()) { + browserName = navigator.appName; + } + } + + if (isEdge) { + browserName = 'Edge'; + fullVersion = navigator.userAgent.split('Edge/')[1]; + // fullVersion = parseInt(navigator.userAgent.match(/Edge\/(\d+).(\d+)$/)[2], 10).toString(); + } + + // trim the fullVersion string at semicolon/space/bracket if present + if ((ix = fullVersion.search(/[; \)]/)) !== -1) { + fullVersion = fullVersion.substring(0, ix); + } + + majorVersion = parseInt('' + fullVersion, 10); + + if (isNaN(majorVersion)) { + fullVersion = '' + parseFloat(navigator.appVersion); + majorVersion = parseInt(navigator.appVersion, 10); + } + + return { + fullVersion: fullVersion, + version: majorVersion, + name: browserName, + isPrivateBrowsing: false + }; + } + + // via: https://gist.github.com/cou929/7973956 + + function retry(isDone, next) { + var currentTrial = 0, + maxRetry = 50, + interval = 10, + isTimeout = false; + var id = window.setInterval( + function() { + if (isDone()) { + window.clearInterval(id); + next(isTimeout); + } + if (currentTrial++ > maxRetry) { + window.clearInterval(id); + isTimeout = true; + next(isTimeout); + } + }, + 10 + ); + } + + function isIE10OrLater(userAgent) { + var ua = userAgent.toLowerCase(); + if (ua.indexOf('msie') === 0 && ua.indexOf('trident') === 0) { + return false; + } + var match = /(?:msie|rv:)\s?([\d\.]+)/.exec(ua); + if (match && parseInt(match[1], 10) >= 10) { + return true; + } + return false; + } + + function detectPrivateMode(callback) { + var isPrivate; + + try { + + if (window.webkitRequestFileSystem) { + window.webkitRequestFileSystem( + window.TEMPORARY, 1, + function() { + isPrivate = false; + }, + function(e) { + isPrivate = true; + } + ); + } else if (window.indexedDB && /Firefox/.test(window.navigator.userAgent)) { + var db; + try { + db = window.indexedDB.open('test'); + db.onerror = function() { + return true; + }; + } catch (e) { + isPrivate = true; + } + + if (typeof isPrivate === 'undefined') { + retry( + function isDone() { + return db.readyState === 'done' ? true : false; + }, + function next(isTimeout) { + if (!isTimeout) { + isPrivate = db.result ? false : true; + } + } + ); + } + } else if (isIE10OrLater(window.navigator.userAgent)) { + isPrivate = false; + try { + if (!window.indexedDB) { + isPrivate = true; + } + } catch (e) { + isPrivate = true; + } + } else if (window.localStorage && /Safari/.test(window.navigator.userAgent)) { + try { + window.localStorage.setItem('test', 1); + } catch (e) { + isPrivate = true; + } + + if (typeof isPrivate === 'undefined') { + isPrivate = false; + window.localStorage.removeItem('test'); + } + } + + } catch (e) { + isPrivate = false; + } + + retry( + function isDone() { + return typeof isPrivate !== 'undefined' ? true : false; + }, + function next(isTimeout) { + callback(isPrivate); + } + ); + } + + var isMobile = { + Android: function() { + return navigator.userAgent.match(/Android/i); + }, + BlackBerry: function() { + return navigator.userAgent.match(/BlackBerry|BB10/i); + }, + iOS: function() { + return navigator.userAgent.match(/iPhone|iPad|iPod/i); + }, + Opera: function() { + return navigator.userAgent.match(/Opera Mini/i); + }, + Windows: function() { + return navigator.userAgent.match(/IEMobile/i); + }, + any: function() { + return (isMobile.Android() || isMobile.BlackBerry() || isMobile.iOS() || isMobile.Opera() || isMobile.Windows()); + }, + getOsName: function() { + var osName = 'Unknown OS'; + if (isMobile.Android()) { + osName = 'Android'; + } + + if (isMobile.BlackBerry()) { + osName = 'BlackBerry'; + } + + if (isMobile.iOS()) { + osName = 'iOS'; + } + + if (isMobile.Opera()) { + osName = 'Opera Mini'; + } + + if (isMobile.Windows()) { + osName = 'Windows'; + } + + return osName; + } + }; + + // via: http://jsfiddle.net/ChristianL/AVyND/ + function detectDesktopOS() { + var unknown = '-'; + + var nVer = navigator.appVersion; + var nAgt = navigator.userAgent; + + var os = unknown; + var clientStrings = [{ + s: 'Windows 10', + r: /(Windows 10.0|Windows NT 10.0)/ + }, { + s: 'Windows 8.1', + r: /(Windows 8.1|Windows NT 6.3)/ + }, { + s: 'Windows 8', + r: /(Windows 8|Windows NT 6.2)/ + }, { + s: 'Windows 7', + r: /(Windows 7|Windows NT 6.1)/ + }, { + s: 'Windows Vista', + r: /Windows NT 6.0/ + }, { + s: 'Windows Server 2003', + r: /Windows NT 5.2/ + }, { + s: 'Windows XP', + r: /(Windows NT 5.1|Windows XP)/ + }, { + s: 'Windows 2000', + r: /(Windows NT 5.0|Windows 2000)/ + }, { + s: 'Windows ME', + r: /(Win 9x 4.90|Windows ME)/ + }, { + s: 'Windows 98', + r: /(Windows 98|Win98)/ + }, { + s: 'Windows 95', + r: /(Windows 95|Win95|Windows_95)/ + }, { + s: 'Windows NT 4.0', + r: /(Windows NT 4.0|WinNT4.0|WinNT|Windows NT)/ + }, { + s: 'Windows CE', + r: /Windows CE/ + }, { + s: 'Windows 3.11', + r: /Win16/ + }, { + s: 'Android', + r: /Android/ + }, { + s: 'Open BSD', + r: /OpenBSD/ + }, { + s: 'Sun OS', + r: /SunOS/ + }, { + s: 'Linux', + r: /(Linux|X11)/ + }, { + s: 'iOS', + r: /(iPhone|iPad|iPod)/ + }, { + s: 'Mac OS X', + r: /Mac OS X/ + }, { + s: 'Mac OS', + r: /(MacPPC|MacIntel|Mac_PowerPC|Macintosh)/ + }, { + s: 'QNX', + r: /QNX/ + }, { + s: 'UNIX', + r: /UNIX/ + }, { + s: 'BeOS', + r: /BeOS/ + }, { + s: 'OS/2', + r: /OS\/2/ + }, { + s: 'Search Bot', + r: /(nuhk|Googlebot|Yammybot|Openbot|Slurp|MSNBot|Ask Jeeves\/Teoma|ia_archiver)/ + }]; + for (var i = 0, cs; cs = clientStrings[i]; i++) { + if (cs.r.test(nAgt)) { + os = cs.s; + break; + } + } + + var osVersion = unknown; + + if (/Windows/.test(os)) { + if (/Windows (.*)/.test(os)) { + osVersion = /Windows (.*)/.exec(os)[1]; + } + os = 'Windows'; + } + + switch (os) { + case 'Mac OS X': + if (/Mac OS X (10[\.\_\d]+)/.test(nAgt)) { + osVersion = /Mac OS X (10[\.\_\d]+)/.exec(nAgt)[1]; + } + break; + case 'Android': + if (/Android ([\.\_\d]+)/.test(nAgt)) { + osVersion = /Android ([\.\_\d]+)/.exec(nAgt)[1]; + } + break; + case 'iOS': + if (/OS (\d+)_(\d+)_?(\d+)?/.test(nAgt)) { + osVersion = /OS (\d+)_(\d+)_?(\d+)?/.exec(nVer); + osVersion = osVersion[1] + '.' + osVersion[2] + '.' + (osVersion[3] | 0); + } + break; + } + + return { + osName: os, + osVersion: osVersion + }; + } + + var osName = 'Unknown OS'; + var osVersion = 'Unknown OS Version'; + + function getAndroidVersion(ua) { + ua = (ua || navigator.userAgent).toLowerCase(); + var match = ua.match(/android\s([0-9\.]*)/); + return match ? match[1] : false; + } + + var osInfo = detectDesktopOS(); + + if (osInfo && osInfo.osName && osInfo.osName != '-') { + osName = osInfo.osName; + osVersion = osInfo.osVersion; + } else if (isMobile.any()) { + osName = isMobile.getOsName(); + + if (osName == 'Android') { + osVersion = getAndroidVersion(); + } + } + + var isNodejs = typeof process === 'object' && typeof process.versions === 'object' && process.versions.node; + + if (osName === 'Unknown OS' && isNodejs) { + osName = 'Nodejs'; + osVersion = process.versions.node.toString().replace('v', ''); + } + + var isCanvasSupportsStreamCapturing = false; + var isVideoSupportsStreamCapturing = false; + ['captureStream', 'mozCaptureStream', 'webkitCaptureStream'].forEach(function(item) { + if (typeof document === 'undefined' || typeof document.createElement !== 'function') { + return; + } + + if (!isCanvasSupportsStreamCapturing && item in document.createElement('canvas')) { + isCanvasSupportsStreamCapturing = true; + } + + if (!isVideoSupportsStreamCapturing && item in document.createElement('video')) { + isVideoSupportsStreamCapturing = true; + } + }); + + // via: https://github.com/diafygi/webrtc-ips + function DetectLocalIPAddress(callback, stream) { + if (!DetectRTC.isWebRTCSupported) { + return; + } + + getIPs(function(ip) { + if (ip.match(/^(192\.168\.|169\.254\.|10\.|172\.(1[6-9]|2\d|3[01]))/)) { + callback('Local: ' + ip); + } else { + callback('Public: ' + ip); + } + }, stream); + } + + function getIPs(callback, stream) { + if (typeof document === 'undefined' || typeof document.getElementById !== 'function') { + return; + } + + var ipDuplicates = {}; + + var RTCPeerConnection = window.RTCPeerConnection || window.mozRTCPeerConnection || window.webkitRTCPeerConnection; + + if (!RTCPeerConnection) { + var iframe = document.getElementById('iframe'); + if (!iframe) { + return; + } + var win = iframe.contentWindow; + RTCPeerConnection = win.RTCPeerConnection || win.mozRTCPeerConnection || win.webkitRTCPeerConnection; + } + + if (!RTCPeerConnection) { + return; + } + + var peerConfig = null; + + if (DetectRTC.browser === 'Chrome' && DetectRTC.browser.version < 58) { + // todo: add support for older Opera + peerConfig = { + optional: [{ + RtpDataChannels: true + }] + }; + } + + var servers = { + iceServers: [{ + urls: 'stun:stun.l.google.com:19302' + }] + }; + + var pc = new RTCPeerConnection(servers, peerConfig); + + if (stream) { + if (pc.addStream) { + pc.addStream(stream); + } else if (pc.addTrack && stream.getTracks()[0]) { + pc.addTrack(stream.getTracks()[0], stream); + } + } + + function handleCandidate(candidate) { + var ipRegex = /([0-9]{1,3}(\.[0-9]{1,3}){3})/; + var match = ipRegex.exec(candidate); + if (!match) { + return; + } + var ipAddress = match[1]; + + if (ipDuplicates[ipAddress] === undefined) { + callback(ipAddress); + } + + ipDuplicates[ipAddress] = true; + } + + // listen for candidate events + pc.onicecandidate = function(ice) { + if (ice.candidate) { + handleCandidate(ice.candidate.candidate); + } + }; + + // create data channel + if (!stream) { + try { + pc.createDataChannel('sctp', {}); + } catch (e) {} + } + + // create an offer sdp + if (DetectRTC.isPromisesSupported) { + pc.createOffer().then(function(result) { + pc.setLocalDescription(result).then(afterCreateOffer); + }); + } else { + pc.createOffer(function(result) { + pc.setLocalDescription(result, afterCreateOffer, function() {}); + }, function() {}); + } + + function afterCreateOffer() { + var lines = pc.localDescription.sdp.split('\n'); + + lines.forEach(function(line) { + if (line.indexOf('a=candidate:') === 0) { + handleCandidate(line); + } + }); + } + } + + var MediaDevices = []; + + var audioInputDevices = []; + var audioOutputDevices = []; + var videoInputDevices = []; + + if (navigator.mediaDevices && navigator.mediaDevices.enumerateDevices) { + // Firefox 38+ seems having support of enumerateDevices + // Thanks @xdumaine/enumerateDevices + navigator.enumerateDevices = function(callback) { + var enumerateDevices = navigator.mediaDevices.enumerateDevices(); + if (enumerateDevices && enumerateDevices.then) { + navigator.mediaDevices.enumerateDevices().then(callback).catch(function() { + callback([]); + }); + } else { + callback([]); + } + }; + } + + // Media Devices detection + var canEnumerate = false; + + /*global MediaStreamTrack:true */ + if (typeof MediaStreamTrack !== 'undefined' && 'getSources' in MediaStreamTrack) { + canEnumerate = true; + } else if (navigator.mediaDevices && !!navigator.mediaDevices.enumerateDevices) { + canEnumerate = true; + } + + var hasMicrophone = false; + var hasSpeakers = false; + var hasWebcam = false; + + var isWebsiteHasMicrophonePermissions = false; + var isWebsiteHasWebcamPermissions = false; + + // http://dev.w3.org/2011/webrtc/editor/getusermedia.html#mediadevices + function checkDeviceSupport(callback) { + if (!canEnumerate) { + if (callback) { + callback(); + } + return; + } + + if (!navigator.enumerateDevices && window.MediaStreamTrack && window.MediaStreamTrack.getSources) { + navigator.enumerateDevices = window.MediaStreamTrack.getSources.bind(window.MediaStreamTrack); + } + + if (!navigator.enumerateDevices && navigator.enumerateDevices) { + navigator.enumerateDevices = navigator.enumerateDevices.bind(navigator); + } + + if (!navigator.enumerateDevices) { + if (callback) { + callback(); + } + return; + } + + MediaDevices = []; + + audioInputDevices = []; + audioOutputDevices = []; + videoInputDevices = []; + + hasMicrophone = false; + hasSpeakers = false; + hasWebcam = false; + + isWebsiteHasMicrophonePermissions = false; + isWebsiteHasWebcamPermissions = false; + + // to prevent duplication + var alreadyUsedDevices = {}; + + navigator.enumerateDevices(function(devices) { + devices.forEach(function(_device) { + var device = {}; + for (var d in _device) { + try { + if (typeof _device[d] !== 'function') { + device[d] = _device[d]; + } + } catch (e) {} + } + + if (alreadyUsedDevices[device.deviceId + device.label + device.kind]) { + return; + } + + // if it is MediaStreamTrack.getSources + if (device.kind === 'audio') { + device.kind = 'audioinput'; + } + + if (device.kind === 'video') { + device.kind = 'videoinput'; + } + + if (!device.deviceId) { + device.deviceId = device.id; + } + + if (!device.id) { + device.id = device.deviceId; + } + + if (!device.label) { + device.isCustomLabel = true; + + if (device.kind === 'videoinput') { + device.label = 'Camera ' + (videoInputDevices.length + 1); + } else if (device.kind === 'audioinput') { + device.label = 'Microphone ' + (audioInputDevices.length + 1); + } else if (device.kind === 'audiooutput') { + device.label = 'Speaker ' + (audioOutputDevices.length + 1); + } else { + device.label = 'Please invoke getUserMedia once.'; + } + + if (typeof DetectRTC !== 'undefined' && DetectRTC.browser.isChrome && DetectRTC.browser.version >= 46 && !/^(https:|chrome-extension:)$/g.test(location.protocol || '')) { + if (typeof document !== 'undefined' && typeof document.domain === 'string' && document.domain.search && document.domain.search(/localhost|127.0./g) === -1) { + device.label = 'HTTPs is required to get label of this ' + device.kind + ' device.'; + } + } + } else { + // Firefox on Android still returns empty label + if (device.kind === 'videoinput' && !isWebsiteHasWebcamPermissions) { + isWebsiteHasWebcamPermissions = true; + } + + if (device.kind === 'audioinput' && !isWebsiteHasMicrophonePermissions) { + isWebsiteHasMicrophonePermissions = true; + } + } + + if (device.kind === 'audioinput') { + hasMicrophone = true; + + if (audioInputDevices.indexOf(device) === -1) { + audioInputDevices.push(device); + } + } + + if (device.kind === 'audiooutput') { + hasSpeakers = true; + + if (audioOutputDevices.indexOf(device) === -1) { + audioOutputDevices.push(device); + } + } + + if (device.kind === 'videoinput') { + hasWebcam = true; + + if (videoInputDevices.indexOf(device) === -1) { + videoInputDevices.push(device); + } + } + + // there is no 'videoouput' in the spec. + MediaDevices.push(device); + + alreadyUsedDevices[device.deviceId + device.label + device.kind] = device; + }); + + if (typeof DetectRTC !== 'undefined') { + // to sync latest outputs + DetectRTC.MediaDevices = MediaDevices; + DetectRTC.hasMicrophone = hasMicrophone; + DetectRTC.hasSpeakers = hasSpeakers; + DetectRTC.hasWebcam = hasWebcam; + + DetectRTC.isWebsiteHasWebcamPermissions = isWebsiteHasWebcamPermissions; + DetectRTC.isWebsiteHasMicrophonePermissions = isWebsiteHasMicrophonePermissions; + + DetectRTC.audioInputDevices = audioInputDevices; + DetectRTC.audioOutputDevices = audioOutputDevices; + DetectRTC.videoInputDevices = videoInputDevices; + } + + if (callback) { + callback(); + } + }); + } + + var DetectRTC = window.DetectRTC || {}; + + // ---------- + // DetectRTC.browser.name || DetectRTC.browser.version || DetectRTC.browser.fullVersion + DetectRTC.browser = getBrowserInfo(); + + detectPrivateMode(function(isPrivateBrowsing) { + DetectRTC.browser.isPrivateBrowsing = !!isPrivateBrowsing; + }); + + // DetectRTC.isChrome || DetectRTC.isFirefox || DetectRTC.isEdge + DetectRTC.browser['is' + DetectRTC.browser.name] = true; + + // ----------- + DetectRTC.osName = osName; + DetectRTC.osVersion = osVersion; + + var isNodeWebkit = typeof process === 'object' && typeof process.versions === 'object' && process.versions['node-webkit']; + + // --------- Detect if system supports WebRTC 1.0 or WebRTC 1.1. + var isWebRTCSupported = false; + ['RTCPeerConnection', 'webkitRTCPeerConnection', 'mozRTCPeerConnection', 'RTCIceGatherer'].forEach(function(item) { + if (isWebRTCSupported) { + return; + } + + if (item in window) { + isWebRTCSupported = true; + } + }); + DetectRTC.isWebRTCSupported = isWebRTCSupported; + + //------- + DetectRTC.isORTCSupported = typeof RTCIceGatherer !== 'undefined'; + + // --------- Detect if WebAudio API are supported + var webAudio = { + isSupported: false, + isCreateMediaStreamSourceSupported: false + }; + + ['AudioContext', 'webkitAudioContext', 'mozAudioContext', 'msAudioContext'].forEach(function(item) { + if (webAudio.isSupported) { + return; + } + + if (item in window) { + webAudio.isSupported = true; + + if (window[item] && 'createMediaStreamSource' in window[item].prototype) { + webAudio.isCreateMediaStreamSourceSupported = true; + } + } + }); + DetectRTC.isAudioContextSupported = webAudio.isSupported; + DetectRTC.isCreateMediaStreamSourceSupported = webAudio.isCreateMediaStreamSourceSupported; + + // ---------- Detect if SCTP/RTP channels are supported. + + var isRtpDataChannelsSupported = false; + if (DetectRTC.browser.isChrome && DetectRTC.browser.version > 31) { + isRtpDataChannelsSupported = true; + } + DetectRTC.isRtpDataChannelsSupported = isRtpDataChannelsSupported; + + var isSCTPSupportd = false; + if (DetectRTC.browser.isFirefox && DetectRTC.browser.version > 28) { + isSCTPSupportd = true; + } else if (DetectRTC.browser.isChrome && DetectRTC.browser.version > 25) { + isSCTPSupportd = true; + } else if (DetectRTC.browser.isOpera && DetectRTC.browser.version >= 11) { + isSCTPSupportd = true; + } + DetectRTC.isSctpDataChannelsSupported = isSCTPSupportd; + + // --------- + + DetectRTC.isMobileDevice = isMobileDevice; // "isMobileDevice" boolean is defined in "getBrowserInfo.js" + + // ------ + var isGetUserMediaSupported = false; + if (navigator.getUserMedia) { + isGetUserMediaSupported = true; + } else if (navigator.mediaDevices && navigator.mediaDevices.getUserMedia) { + isGetUserMediaSupported = true; + } + + if (DetectRTC.browser.isChrome && DetectRTC.browser.version >= 46 && !/^(https:|chrome-extension:)$/g.test(location.protocol || '')) { + if (typeof document !== 'undefined' && typeof document.domain === 'string' && document.domain.search && document.domain.search(/localhost|127.0./g) === -1) { + isGetUserMediaSupported = 'Requires HTTPs'; + } + } + + if (DetectRTC.osName === 'Nodejs') { + isGetUserMediaSupported = false; + } + DetectRTC.isGetUserMediaSupported = isGetUserMediaSupported; + + var displayResolution = ''; + if (screen.width) { + var width = (screen.width) ? screen.width : ''; + var height = (screen.height) ? screen.height : ''; + displayResolution += '' + width + ' x ' + height; + } + DetectRTC.displayResolution = displayResolution; + + function getAspectRatio(w, h) { + function gcd(a, b) { + return (b == 0) ? a : gcd(b, a % b); + } + var r = gcd(w, h); + return (w / r) / (h / r); + } + + DetectRTC.displayAspectRatio = getAspectRatio(screen.width, screen.height).toFixed(2); + + // ---------- + DetectRTC.isCanvasSupportsStreamCapturing = isCanvasSupportsStreamCapturing; + DetectRTC.isVideoSupportsStreamCapturing = isVideoSupportsStreamCapturing; + + if (DetectRTC.browser.name == 'Chrome' && DetectRTC.browser.version >= 53) { + if (!DetectRTC.isCanvasSupportsStreamCapturing) { + DetectRTC.isCanvasSupportsStreamCapturing = 'Requires chrome flag: enable-experimental-web-platform-features'; + } + + if (!DetectRTC.isVideoSupportsStreamCapturing) { + DetectRTC.isVideoSupportsStreamCapturing = 'Requires chrome flag: enable-experimental-web-platform-features'; + } + } + + // ------ + DetectRTC.DetectLocalIPAddress = DetectLocalIPAddress; + + DetectRTC.isWebSocketsSupported = 'WebSocket' in window && 2 === window.WebSocket.CLOSING; + DetectRTC.isWebSocketsBlocked = !DetectRTC.isWebSocketsSupported; + + if (DetectRTC.osName === 'Nodejs') { + DetectRTC.isWebSocketsSupported = true; + DetectRTC.isWebSocketsBlocked = false; + } + + DetectRTC.checkWebSocketsSupport = function(callback) { + callback = callback || function() {}; + try { + var starttime; + var websocket = new WebSocket('wss://echo.websocket.org:443/'); + websocket.onopen = function() { + DetectRTC.isWebSocketsBlocked = false; + starttime = (new Date).getTime(); + websocket.send('ping'); + }; + websocket.onmessage = function() { + DetectRTC.WebsocketLatency = (new Date).getTime() - starttime + 'ms'; + callback(); + websocket.close(); + websocket = null; + }; + websocket.onerror = function() { + DetectRTC.isWebSocketsBlocked = true; + callback(); + }; + } catch (e) { + DetectRTC.isWebSocketsBlocked = true; + callback(); + } + }; + + // ------- + DetectRTC.load = function(callback) { + callback = callback || function() {}; + checkDeviceSupport(callback); + }; + + // check for microphone/camera support! + if (typeof checkDeviceSupport === 'function') { + // checkDeviceSupport(); + } + + if (typeof MediaDevices !== 'undefined') { + DetectRTC.MediaDevices = MediaDevices; + } else { + DetectRTC.MediaDevices = []; + } + + DetectRTC.hasMicrophone = hasMicrophone; + DetectRTC.hasSpeakers = hasSpeakers; + DetectRTC.hasWebcam = hasWebcam; + + DetectRTC.isWebsiteHasWebcamPermissions = isWebsiteHasWebcamPermissions; + DetectRTC.isWebsiteHasMicrophonePermissions = isWebsiteHasMicrophonePermissions; + + DetectRTC.audioInputDevices = audioInputDevices; + DetectRTC.audioOutputDevices = audioOutputDevices; + DetectRTC.videoInputDevices = videoInputDevices; + + // ------ + var isSetSinkIdSupported = false; + if (typeof document !== 'undefined' && typeof document.createElement === 'function' && 'setSinkId' in document.createElement('video')) { + isSetSinkIdSupported = true; + } + DetectRTC.isSetSinkIdSupported = isSetSinkIdSupported; + + // ----- + var isRTPSenderReplaceTracksSupported = false; + if (DetectRTC.browser.isFirefox && typeof mozRTCPeerConnection !== 'undefined' /*&& DetectRTC.browser.version > 39*/ ) { + /*global mozRTCPeerConnection:true */ + if ('getSenders' in mozRTCPeerConnection.prototype) { + isRTPSenderReplaceTracksSupported = true; + } + } else if (DetectRTC.browser.isChrome && typeof webkitRTCPeerConnection !== 'undefined') { + /*global webkitRTCPeerConnection:true */ + if ('getSenders' in webkitRTCPeerConnection.prototype) { + isRTPSenderReplaceTracksSupported = true; + } + } + DetectRTC.isRTPSenderReplaceTracksSupported = isRTPSenderReplaceTracksSupported; + + //------ + var isRemoteStreamProcessingSupported = false; + if (DetectRTC.browser.isFirefox && DetectRTC.browser.version > 38) { + isRemoteStreamProcessingSupported = true; + } + DetectRTC.isRemoteStreamProcessingSupported = isRemoteStreamProcessingSupported; + + //------- + var isApplyConstraintsSupported = false; + + /*global MediaStreamTrack:true */ + if (typeof MediaStreamTrack !== 'undefined' && 'applyConstraints' in MediaStreamTrack.prototype) { + isApplyConstraintsSupported = true; + } + DetectRTC.isApplyConstraintsSupported = isApplyConstraintsSupported; + + //------- + var isMultiMonitorScreenCapturingSupported = false; + if (DetectRTC.browser.isFirefox && DetectRTC.browser.version >= 43) { + // version 43 merely supports platforms for multi-monitors + // version 44 will support exact multi-monitor selection i.e. you can select any monitor for screen capturing. + isMultiMonitorScreenCapturingSupported = true; + } + DetectRTC.isMultiMonitorScreenCapturingSupported = isMultiMonitorScreenCapturingSupported; + + DetectRTC.isPromisesSupported = !!('Promise' in window); + + if (typeof DetectRTC === 'undefined') { + window.DetectRTC = {}; + } + + var MediaStream = window.MediaStream; + + if (typeof MediaStream === 'undefined' && typeof webkitMediaStream !== 'undefined') { + MediaStream = webkitMediaStream; + } + + if (typeof MediaStream !== 'undefined') { + DetectRTC.MediaStream = Object.keys(MediaStream.prototype); + } else DetectRTC.MediaStream = false; + + if (typeof MediaStreamTrack !== 'undefined') { + DetectRTC.MediaStreamTrack = Object.keys(MediaStreamTrack.prototype); + } else DetectRTC.MediaStreamTrack = false; + + var RTCPeerConnection = window.RTCPeerConnection || window.mozRTCPeerConnection || window.webkitRTCPeerConnection; + + if (typeof RTCPeerConnection !== 'undefined') { + DetectRTC.RTCPeerConnection = Object.keys(RTCPeerConnection.prototype); + } else DetectRTC.RTCPeerConnection = false; + + window.DetectRTC = DetectRTC; + + if (typeof module !== 'undefined' /* && !!module.exports*/ ) { + module.exports = DetectRTC; + } + + if (typeof define === 'function' && define.amd) { + define('DetectRTC', [], function() { + return DetectRTC; + }); + } +})(); \ No newline at end of file diff --git a/openvidu-browser/ts/OpenVidu/OpenVidu.ts b/openvidu-browser/ts/OpenVidu/OpenVidu.ts index 80b39710..1bb320d2 100644 --- a/openvidu-browser/ts/OpenVidu/OpenVidu.ts +++ b/openvidu-browser/ts/OpenVidu/OpenVidu.ts @@ -25,6 +25,7 @@ import { LocalRecorder } from '../OpenViduInternal/LocalRecorder'; import * as adapter from 'webrtc-adapter'; import * as screenSharing from '../ScreenSharing/Screen-Capturing.js'; import * as screenSharingAuto from '../ScreenSharing/Screen-Capturing-Auto.js'; +import * as DetectRTC from '../KurentoUtils/DetectRTC'; if (window) { window["adapter"] = adapter; @@ -43,14 +44,10 @@ export class OpenVidu { initSession(sessionId: string): Session; initSession(param1, param2?): any { - if (this.checkSystemRequirements()) { - if (typeof param2 == "string") { - return new Session(this.openVidu.initSession(param2), this); - } else { - return new Session(this.openVidu.initSession(param1), this); - } + if (typeof param2 == "string") { + return new Session(this.openVidu.initSession(param2), this); } else { - alert("Browser not supported"); + return new Session(this.openVidu.initSession(param1), this); } } @@ -59,139 +56,139 @@ export class OpenVidu { initPublisher(parentId: string, cameraOptions: any, callback: any): Publisher; initPublisher(parentId: string, cameraOptions?: any, callback?: Function): any { - if (this.checkSystemRequirements()) { - let publisher: Publisher; - if (cameraOptions != null) { - cameraOptions.audio = cameraOptions.audio != null ? cameraOptions.audio : true; - cameraOptions.video = cameraOptions.video != null ? cameraOptions.video : true; + let publisher: Publisher; + if (cameraOptions != null) { - if (!cameraOptions.screen) { + cameraOptions.audio = cameraOptions.audio != null ? cameraOptions.audio : true; + cameraOptions.video = cameraOptions.video != null ? cameraOptions.video : true; - // Webcam and/or microphone is being requested + if (!cameraOptions.screen) { - let cameraOptionsAux = { - sendAudio: cameraOptions.audio != null ? cameraOptions.audio : true, - sendVideo: cameraOptions.video != null ? cameraOptions.video : true, - activeAudio: cameraOptions.audioActive != null ? cameraOptions.audioActive : true, - activeVideo: cameraOptions.videoActive != null ? cameraOptions.videoActive : true, - dataChannel: true, - mediaConstraints: this.openVidu.generateMediaConstraints(cameraOptions) - }; - cameraOptions = cameraOptionsAux; + // Webcam and/or microphone is being requested - publisher = new Publisher(this.openVidu.initPublisherTagged(parentId, cameraOptions, true, callback), parentId, false); - console.info("'Publisher' initialized"); - - return publisher; - - } else { - - publisher = new Publisher(this.openVidu.initPublisherScreen(parentId, true, callback), parentId, true); - if (adapter.browserDetails.browser === 'firefox' && adapter.browserDetails.version >= 52) { - screenSharingAuto.getScreenId((error, sourceId, screenConstraints) => { - cameraOptions = { - sendAudio: cameraOptions.audio, - sendVideo: cameraOptions.video, - activeAudio: cameraOptions.audioActive != null ? cameraOptions.audioActive : true, - activeVideo: cameraOptions.videoActive != null ? cameraOptions.videoActive : true, - dataChannel: true, - mediaConstraints: { - video: screenConstraints.video, - audio: false - } - } - - publisher.stream.configureScreenOptions(cameraOptions); - console.info("'Publisher' initialized"); - - publisher.stream.ee.emitEvent('can-request-screen'); - }); - return publisher; - } else if (adapter.browserDetails.browser === 'chrome') { - // Screen is being requested - - /*screenSharing.isChromeExtensionAvailable((availability) => { - switch (availability) { - case 'available': - console.warn('EXTENSION AVAILABLE!!!'); - screenSharing.getScreenConstraints((error, screenConstraints) => { - if (!error) { - console.warn(screenConstraints); - } - }); - break; - case 'unavailable': - console.warn('EXTENSION NOT AVAILABLE!!!'); - break; - case 'isFirefox': - console.warn('IT IS FIREFOX!!!'); - screenSharing.getScreenConstraints((error, screenConstraints) => { - if (!error) { - console.warn(screenConstraints); - } - }); - break; - } - });*/ - screenSharingAuto.getScreenId((error, sourceId, screenConstraints) => { - - if (error === 'not-installed') { - let error = new OpenViduError(OpenViduErrorName.SCREEN_EXTENSION_NOT_INSTALLED, 'https://chrome.google.com/webstore/detail/screen-capturing/ajhifddimkapgcifgcodmmfdlknahffk'); - console.error(error); - if (callback) callback(error); - return; - } else if (error === 'permission-denied') { - let error = new OpenViduError(OpenViduErrorName.SCREEN_CAPTURE_DENIED, 'You must allow access to one window of your desktop'); - console.error(error); - if (callback) callback(error); - return; - } - - cameraOptions = { - sendAudio: cameraOptions.audio != null ? cameraOptions.audio : true, - sendVideo: cameraOptions.video != null ? cameraOptions.video : true, - activeAudio: cameraOptions.audioActive != null ? cameraOptions.audioActive : true, - activeVideo: cameraOptions.videoActive != null ? cameraOptions.videoActive : true, - dataChannel: true, - mediaConstraints: { - video: screenConstraints.video, - audio: false - } - } - - publisher.stream.configureScreenOptions(cameraOptions); - - publisher.stream.ee.emitEvent('can-request-screen'); - }, (error) => { - console.error('getScreenId error', error); - return; - }); - console.info("'Publisher' initialized"); - return publisher; - } else { - console.error('Screen sharing not supported on ' + adapter.browserDetails.browser); - } - } - } else { - cameraOptions = { - sendAudio: true, - sendVideo: true, - activeAudio: true, - activeVideo: true, + let cameraOptionsAux = { + sendAudio: cameraOptions.audio != null ? cameraOptions.audio : true, + sendVideo: cameraOptions.video != null ? cameraOptions.video : true, + activeAudio: cameraOptions.audioActive != null ? cameraOptions.audioActive : true, + activeVideo: cameraOptions.videoActive != null ? cameraOptions.videoActive : true, dataChannel: true, - mediaConstraints: { - audio: true, - video: { width: { ideal: 1280 } } - } - } + mediaConstraints: this.openVidu.generateMediaConstraints(cameraOptions) + }; + cameraOptions = cameraOptionsAux; + publisher = new Publisher(this.openVidu.initPublisherTagged(parentId, cameraOptions, true, callback), parentId, false); console.info("'Publisher' initialized"); return publisher; + + } else { + + // Screen share is being requested + + publisher = new Publisher(this.openVidu.initPublisherScreen(parentId, true, callback), parentId, true); + if (DetectRTC.browser.name === 'Firefox' && DetectRTC.browser.version >= 52) { + screenSharingAuto.getScreenId((error, sourceId, screenConstraints) => { + cameraOptions = { + sendAudio: cameraOptions.audio, + sendVideo: cameraOptions.video, + activeAudio: cameraOptions.audioActive != null ? cameraOptions.audioActive : true, + activeVideo: cameraOptions.videoActive != null ? cameraOptions.videoActive : true, + dataChannel: true, + mediaConstraints: { + video: screenConstraints.video, + audio: false + } + } + + publisher.stream.configureScreenOptions(cameraOptions); + console.info("'Publisher' initialized"); + + publisher.stream.ee.emitEvent('can-request-screen'); + }); + return publisher; + } else if (DetectRTC.browser.name === 'Chrome') { + // Screen is being requested + + /*screenSharing.isChromeExtensionAvailable((availability) => { + switch (availability) { + case 'available': + console.warn('EXTENSION AVAILABLE!!!'); + screenSharing.getScreenConstraints((error, screenConstraints) => { + if (!error) { + console.warn(screenConstraints); + } + }); + break; + case 'unavailable': + console.warn('EXTENSION NOT AVAILABLE!!!'); + break; + case 'isFirefox': + console.warn('IT IS FIREFOX!!!'); + screenSharing.getScreenConstraints((error, screenConstraints) => { + if (!error) { + console.warn(screenConstraints); + } + }); + break; + } + });*/ + screenSharingAuto.getScreenId((error, sourceId, screenConstraints) => { + + if (error === 'not-installed') { + let error = new OpenViduError(OpenViduErrorName.SCREEN_EXTENSION_NOT_INSTALLED, 'https://chrome.google.com/webstore/detail/screen-capturing/ajhifddimkapgcifgcodmmfdlknahffk'); + console.error(error); + if (callback) callback(error); + return; + } else if (error === 'permission-denied') { + let error = new OpenViduError(OpenViduErrorName.SCREEN_CAPTURE_DENIED, 'You must allow access to one window of your desktop'); + console.error(error); + if (callback) callback(error); + return; + } + + cameraOptions = { + sendAudio: cameraOptions.audio != null ? cameraOptions.audio : true, + sendVideo: cameraOptions.video != null ? cameraOptions.video : true, + activeAudio: cameraOptions.audioActive != null ? cameraOptions.audioActive : true, + activeVideo: cameraOptions.videoActive != null ? cameraOptions.videoActive : true, + dataChannel: true, + mediaConstraints: { + video: screenConstraints.video, + audio: false + } + } + + publisher.stream.configureScreenOptions(cameraOptions); + + publisher.stream.ee.emitEvent('can-request-screen'); + }, (error) => { + console.error('getScreenId error', error); + return; + }); + console.info("'Publisher' initialized"); + return publisher; + } else { + console.error('Screen sharing not supported on ' + DetectRTC.browser.name); + if (!!callback) callback(new OpenViduError(OpenViduErrorName.SCREEN_SHARING_NOT_SUPPORTED, 'Screen sharing not supported on ' + DetectRTC.browser.name + ' ' + DetectRTC.browser.version)); + } } } else { - alert("Browser not supported"); + cameraOptions = { + sendAudio: true, + sendVideo: true, + activeAudio: true, + activeVideo: true, + dataChannel: true, + mediaConstraints: { + audio: true, + video: { width: { ideal: 1280 } } + } + } + publisher = new Publisher(this.openVidu.initPublisherTagged(parentId, cameraOptions, true, callback), parentId, false); + console.info("'Publisher' initialized"); + + return publisher; } } @@ -202,7 +199,7 @@ export class OpenVidu { return publisher; } else { publisher = new Publisher(this.openVidu.initPublisherScreen(publisher.stream.getParentId(), false), publisher.stream.getParentId(), true); - if (adapter.browserDetails.browser === 'firefox' && adapter.browserDetails.version >= 52) { + if (DetectRTC.browser.name === 'Firefox' && DetectRTC.browser.version >= 52) { screenSharingAuto.getScreenId((error, sourceId, screenConstraints) => { publisher.stream.outboundOptions.mediaConstraints.video = screenConstraints.video; @@ -212,7 +209,7 @@ export class OpenVidu { publisher.stream.ee.emitEvent('can-request-screen'); }); return publisher; - } else if (adapter.browserDetails.browser === 'chrome') { + } else if (DetectRTC.browser.name === 'Chrome') { screenSharingAuto.getScreenId((error, sourceId, screenConstraints) => { if (error === 'not-installed') { let error = new OpenViduError(OpenViduErrorName.SCREEN_EXTENSION_NOT_INSTALLED, 'https://chrome.google.com/webstore/detail/screen-capturing/ajhifddimkapgcifgcodmmfdlknahffk'); @@ -234,23 +231,21 @@ export class OpenVidu { console.info("'Publisher' initialized"); return publisher; } else { - console.error('Screen sharing not supported on ' + adapter.browserDetails.browser); + console.error('Screen sharing not supported on ' + DetectRTC.browser.name); } } } checkSystemRequirements(): number { - let browser = adapter.browserDetails.browser; - let version = adapter.browserDetails.version; - //Bug fix: 'navigator.userAgent' in Firefox for Ubuntu 14.04 does not return "Firefox/[version]" in the string, so version returned is null - if ((browser == 'firefox') && (version == null)) { - return 1; - } - if (((browser == 'chrome') && (version >= 28)) || ((browser == 'edge') && (version >= 12)) || ((browser == 'firefox') && (version >= 22))) { - return 1; - } else { + let defaultWebRTCSupport: boolean = DetectRTC.isWebRTCSupported; + let browser = DetectRTC.browser.name; + let version = DetectRTC.browser.version; + + if ((browser !== 'Chrome') && (browser !== 'Firefox') && (browser !== 'Opera')) { return 0; + } else { + return defaultWebRTCSupport ? 1 : 0; } } diff --git a/openvidu-browser/ts/OpenVidu/Session.ts b/openvidu-browser/ts/OpenVidu/Session.ts index c92b9691..67843e61 100644 --- a/openvidu-browser/ts/OpenVidu/Session.ts +++ b/openvidu-browser/ts/OpenVidu/Session.ts @@ -1,12 +1,14 @@ import { SessionInternal, SessionOptions, SignalOptions } from '../OpenViduInternal/SessionInternal'; import { Stream } from '../OpenViduInternal/Stream'; -import { Connection } from "../OpenViduInternal/Connection"; +import { Connection } from '../OpenViduInternal/Connection'; +import { OpenViduError, OpenViduErrorName } from '../OpenViduInternal/OpenViduError'; import { OpenVidu } from './OpenVidu'; import { Publisher } from './Publisher'; import { Subscriber } from './Subscriber'; import EventEmitter = require('wolfy87-eventemitter'); +import * as DetectRTC from '../KurentoUtils/DetectRTC'; export class Session { @@ -48,21 +50,29 @@ export class Session { connect(param1, param2, param3?) { // Early configuration to deactivate automatic subscription to streams if (param3) { - this.session.configure({ - sessionId: this.session.getSessionId(), - participantId: param1, - metadata: this.session.stringClientMetadata(param2), - subscribeToStreams: false - }); - this.session.connect(param1, param3); + if (this.openVidu.checkSystemRequirements()) { + this.session.configure({ + sessionId: this.session.getSessionId(), + participantId: param1, + metadata: this.session.stringClientMetadata(param2), + subscribeToStreams: false + }); + this.session.connect(param1, param3); + } else { + param3(new OpenViduError(OpenViduErrorName.BROWSER_NOT_SUPPORTED, 'Browser ' + DetectRTC.browser.name + ' ' + DetectRTC.browser.version + ' is not supported in OpenVidu')); + } } else { - this.session.configure({ - sessionId: this.session.getSessionId(), - participantId: param1, - metadata: '', - subscribeToStreams: false - }); - this.session.connect(param1, param2); + if (this.openVidu.checkSystemRequirements()) { + this.session.configure({ + sessionId: this.session.getSessionId(), + participantId: param1, + metadata: '', + subscribeToStreams: false + }); + this.session.connect(param1, param2); + } else { + param2(new OpenViduError(OpenViduErrorName.BROWSER_NOT_SUPPORTED, 'Browser ' + DetectRTC.browser.name + ' ' + DetectRTC.browser.version + ' is not supported in OpenVidu')); + } } } diff --git a/openvidu-browser/ts/OpenViduInternal/OpenViduError.ts b/openvidu-browser/ts/OpenViduInternal/OpenViduError.ts index 2a8b1c26..5aaebc33 100644 --- a/openvidu-browser/ts/OpenViduInternal/OpenViduError.ts +++ b/openvidu-browser/ts/OpenViduInternal/OpenViduError.ts @@ -1,9 +1,11 @@ export const enum OpenViduErrorName { + BROWSER_NOT_SUPPORTED = 'BROWSER_NOT_SUPPORTED', CAMERA_ACCESS_DENIED = 'CAMERA_ACCESS_DENIED', MICROPHONE_ACCESS_DENIED = 'MICROPHONE_ACCESS_DENIED', SCREEN_CAPTURE_DENIED = 'SCREEN_CAPTURE_DENIED', NO_VIDEO_DEVICE = 'NO_VIDEO_DEVICE', NO_INPUT_DEVICE = 'NO_INPUT_DEVICE', + SCREEN_SHARING_NOT_SUPPORTED = 'SCREEN_SHARING_NOT_SUPPORTED', SCREEN_EXTENSION_NOT_INSTALLED = 'SCREEN_EXTENSION_NOT_INSTALLED', GENERIC_ERROR = 'GENERIC_ERROR' } diff --git a/openvidu-browser/ts/OpenViduInternal/Stream.ts b/openvidu-browser/ts/OpenViduInternal/Stream.ts index a9b045ae..db7ca047 100644 --- a/openvidu-browser/ts/OpenViduInternal/Stream.ts +++ b/openvidu-browser/ts/OpenViduInternal/Stream.ts @@ -278,7 +278,7 @@ export class Stream { if (this.local && !this.displayMyRemote()) { this.video.muted = true; - this.video.onplaying = () => { + this.video.oncanplay = () => { console.info("Local 'Stream' with id [" + this.streamId + "] video is now playing"); this.ee.emitEvent('video-is-playing', [{ element: this.video @@ -609,7 +609,7 @@ export class Stream { if (!!this.video) { // let thumbnailId = this.video.thumb; - this.video.onplaying = () => { + this.video.oncanplay = () => { if (this.local && this.displayMyRemote()) { console.info("Your own remote 'Stream' with id [" + this.streamId + "] video is now playing"); this.ee.emitEvent('remote-video-is-playing', [{ diff --git a/openvidu-browser/ts/OpenViduInternal/WebRtcStats.ts b/openvidu-browser/ts/OpenViduInternal/WebRtcStats.ts index e806473d..de2e596c 100644 --- a/openvidu-browser/ts/OpenViduInternal/WebRtcStats.ts +++ b/openvidu-browser/ts/OpenViduInternal/WebRtcStats.ts @@ -1,5 +1,6 @@ import { Stream } from './Stream'; import * as adapter from 'webrtc-adapter'; +import * as DetectRTC from '../KurentoUtils/DetectRTC'; export class WebRtcStats { @@ -93,7 +94,7 @@ export class WebRtcStats { let f = (stats) => { - if (adapter.browserDetails.browser === 'firefox') { + if (DetectRTC.browser.name === 'Firefox') { stats.forEach((stat) => { let json = {}; @@ -190,7 +191,7 @@ export class WebRtcStats { sendPost(JSON.stringify(json)); } }); - } else if (adapter.browserDetails.browser === 'chrome') { + } else if (DetectRTC.browser.name === 'Chrome') { for (let key of Object.keys(stats)) { let stat = stats[key]; if (stat.type === 'ssrc') { @@ -286,7 +287,7 @@ export class WebRtcStats { } private standardizeReport(response) { - if (adapter.browserDetails.browser === 'firefox') { + if (DetectRTC.browser.name === 'Firefox') { return response; } @@ -307,13 +308,13 @@ export class WebRtcStats { } private getStatsAgnostic(pc, selector, successCb, failureCb) { - if (adapter.browserDetails.browser === 'firefox') { + if (DetectRTC.browser.name === 'Firefox') { // getStats takes args in different order in Chrome and Firefox return pc.getStats(selector, (response) => { var report = this.standardizeReport(response); successCb(report); }, failureCb); - } else if (adapter.browserDetails.browser === 'chrome') { + } else if (DetectRTC.browser.name === 'Chrome') { // In Chrome, the first two arguments are reversed return pc.getStats((response) => { var report = this.standardizeReport(response);