123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381 |
- const logger = require('jitsi-meet-logger').getLogger(__filename);
-
- let currentBrowser;
-
- const RTCBrowserType = {
-
- RTC_BROWSER_CHROME: 'rtc_browser.chrome',
-
- RTC_BROWSER_OPERA: 'rtc_browser.opera',
-
- RTC_BROWSER_FIREFOX: 'rtc_browser.firefox',
-
- RTC_BROWSER_IEXPLORER: 'rtc_browser.iexplorer',
-
- RTC_BROWSER_SAFARI: 'rtc_browser.safari',
-
- RTC_BROWSER_NWJS: 'rtc_browser.nwjs',
-
- RTC_BROWSER_ELECTRON: 'rtc_browser.electron',
-
- RTC_BROWSER_REACT_NATIVE: 'rtc_browser.react-native',
-
- /**
- * Gets current browser type.
- * @returns {string}
- */
- getBrowserType() {
- return currentBrowser;
- },
-
- /**
- * Gets current browser name, split from the type.
- * @returns {string}
- */
- getBrowserName() {
- let browser;
-
- if (RTCBrowserType.isAndroid()) {
- browser = 'android';
- } else {
- browser = currentBrowser.split('rtc_browser.')[1];
- }
-
- return browser;
- },
-
- /**
- * Checks if current browser is Chrome.
- * @returns {boolean}
- */
- isChrome() {
- return currentBrowser === RTCBrowserType.RTC_BROWSER_CHROME;
- },
-
- /**
- * Checks if current browser is Opera.
- * @returns {boolean}
- */
- isOpera() {
- return currentBrowser === RTCBrowserType.RTC_BROWSER_OPERA;
- },
-
- /**
- * Checks if current browser is Firefox.
- * @returns {boolean}
- */
- isFirefox() {
- return currentBrowser === RTCBrowserType.RTC_BROWSER_FIREFOX;
- },
-
- /**
- * Checks if current browser is Internet Explorer.
- * @returns {boolean}
- */
- isIExplorer() {
- return currentBrowser === RTCBrowserType.RTC_BROWSER_IEXPLORER;
- },
-
- /**
- * Checks if current browser is Safari.
- * @returns {boolean}
- */
- isSafari() {
- return currentBrowser === RTCBrowserType.RTC_BROWSER_SAFARI;
- },
-
- /**
- * Checks if current environment is NWJS.
- * @returns {boolean}
- */
- isNWJS() {
- return currentBrowser === RTCBrowserType.RTC_BROWSER_NWJS;
- },
-
- /**
- * Checks if current environment is Electron.
- * @returns {boolean}
- */
- isElectron() {
- return currentBrowser === RTCBrowserType.RTC_BROWSER_ELECTRON;
- },
-
- /**
- * Checks if current environment is React Native.
- * @returns {boolean}
- */
- isReactNative() {
- return currentBrowser === RTCBrowserType.RTC_BROWSER_REACT_NATIVE;
- },
-
- /**
- * Checks if Temasys RTC plugin is used.
- * @returns {boolean}
- */
- isTemasysPluginUsed() {
- // Temasys do not support Microsoft Edge:
- // http://support.temasys.com.sg/support/solutions/articles/5000654345-can-the-temasys-webrtc-plugin-be-used-with-microsoft-edge-
- if (RTCBrowserType.isIExplorer()
- && RTCBrowserType.getIExplorerVersion() < 12) {
- return true;
- }
-
- return RTCBrowserType.isSafari();
- },
-
- /**
- * Checks if the current browser triggers 'onmute'/'onunmute' events when
- * user's connection is interrupted and the video stops playback.
- * @returns {*|boolean} 'true' if the event is supported or 'false'
- * otherwise.
- */
- isVideoMuteOnConnInterruptedSupported() {
- return RTCBrowserType.isChrome();
- },
-
- /**
- * Returns Firefox version.
- * @returns {number|null}
- */
- getFirefoxVersion() {
- return RTCBrowserType.isFirefox() ? browserVersion : null;
- },
-
- /**
- * Returns Chrome version.
- * @returns {number|null}
- */
- getChromeVersion() {
- return RTCBrowserType.isChrome() ? browserVersion : null;
- },
-
- /**
- * Returns Internet Explorer version.
- *
- * @returns {number|null}
- */
- getIExplorerVersion() {
- return RTCBrowserType.isIExplorer() ? browserVersion : null;
- },
-
- usesPlanB() {
- return (
- RTCBrowserType.isChrome()
- || RTCBrowserType.isOpera()
- || RTCBrowserType.isReactNative()
- || RTCBrowserType.isTemasysPluginUsed());
- },
-
- usesUnifiedPlan() {
- return RTCBrowserType.isFirefox();
- },
-
- /**
- * Whether the browser is running on an android device.
- * @returns {boolean}
- */
- isAndroid() {
- return isAndroid;
- },
-
- /**
- * Whether jitsi-meet supports simulcast on the current browser.
- * @returns {boolean}
- */
- supportsSimulcast() {
- // This mirrors what sdp-simulcast uses (which is used when deciding
- // whether to actually enable simulcast or not).
- // TODO: the logic should be in one single place.
- return window.chrome !== undefined;
- }
-
- // Add version getters for other browsers when needed
- };
-
- // detectOpera() must be called before detectChrome() !!!
- // otherwise Opera wil be detected as Chrome
- function detectChrome() {
- if (navigator.webkitGetUserMedia) {
- currentBrowser = RTCBrowserType.RTC_BROWSER_CHROME;
- const userAgent = navigator.userAgent.toLowerCase();
-
- // We can assume that user agent is chrome, because it's
- // enforced when 'ext' streaming method is set
- const ver = parseInt(userAgent.match(/chrome\/(\d+)\./)[1], 10);
-
- logger.log(`This appears to be Chrome, ver: ${ver}`);
-
- return ver;
- }
-
- return null;
- }
-
- function detectOpera() {
- const userAgent = navigator.userAgent;
-
- if (userAgent.match(/Opera|OPR/)) {
- currentBrowser = RTCBrowserType.RTC_BROWSER_OPERA;
- const version = userAgent.match(/(Opera|OPR) ?\/?(\d+)\.?/)[2];
-
- logger.info(`This appears to be Opera, ver: ${version}`);
-
- return version;
- }
-
- return null;
- }
-
- function detectFirefox() {
- if (navigator.mozGetUserMedia) {
- currentBrowser = RTCBrowserType.RTC_BROWSER_FIREFOX;
- const version = parseInt(
- navigator.userAgent.match(/Firefox\/([0-9]+)\./)[1], 10);
-
- logger.log(`This appears to be Firefox, ver: ${version}`);
-
- return version;
- }
-
- return null;
- }
-
- function detectSafari() {
- if (/^((?!chrome).)*safari/i.test(navigator.userAgent)) {
- currentBrowser = RTCBrowserType.RTC_BROWSER_SAFARI;
- logger.info('This appears to be Safari');
-
- // FIXME detect Safari version when needed
- return 1;
- }
-
- return null;
- }
-
- function detectIE() {
- let version;
- const ua = window.navigator.userAgent;
-
- const msie = ua.indexOf('MSIE ');
-
- if (msie > 0) {
- // IE 10 or older => return version number
- version = parseInt(ua.substring(msie + 5, ua.indexOf('.', msie)), 10);
- }
-
- const trident = ua.indexOf('Trident/');
-
- if (!version && trident > 0) {
- // IE 11 => return version number
- const rv = ua.indexOf('rv:');
-
- version = parseInt(ua.substring(rv + 3, ua.indexOf('.', rv)), 10);
- }
-
- const edge = ua.indexOf('Edge/');
-
- if (!version && edge > 0) {
- // IE 12 => return version number
- version = parseInt(ua.substring(edge + 5, ua.indexOf('.', edge)), 10);
- }
-
- if (version) {
- currentBrowser = RTCBrowserType.RTC_BROWSER_IEXPLORER;
- logger.info(`This appears to be IExplorer, ver: ${version}`);
- }
-
- return version;
- }
-
- /**
- * Detects Electron environment.
- */
- function detectElectron() {
- const userAgent = navigator.userAgent;
-
- if (userAgent.match(/Electron/)) {
- currentBrowser = RTCBrowserType.RTC_BROWSER_ELECTRON;
- const version = userAgent.match(/Electron\/([\d.]+)/)[1];
-
- logger.info(`This appears to be Electron, ver: ${version}`);
-
- return version;
- }
-
- return null;
- }
-
- function detectNWJS() {
- const userAgent = navigator.userAgent;
-
- if (userAgent.match(/JitsiMeetNW/)) {
- currentBrowser = RTCBrowserType.RTC_BROWSER_NWJS;
- const version = userAgent.match(/JitsiMeetNW\/([\d.]+)/)[1];
-
- logger.info(`This appears to be JitsiMeetNW, ver: ${version}`);
-
- return version;
- }
-
- return null;
- }
-
- function detectReactNative() {
- const match
- = navigator.userAgent.match(/\b(react[ \t_-]*native)(?:\/(\S+))?/i);
- let version;
-
- // If we're remote debugging a React Native app, it may be treated as
- // Chrome. Check navigator.product as well and always return some version
- // even if we can't get the real one.
-
- if (match || navigator.product === 'ReactNative') {
- currentBrowser = RTCBrowserType.RTC_BROWSER_REACT_NATIVE;
- let name;
-
- if (match && match.length > 2) {
- name = match[1];
- version = match[2];
- }
- name || (name = 'react-native');
- version || (version = 'unknown');
- console.info(`This appears to be ${name}, ver: ${version}`);
- } else {
- // We're not running in a React Native environment.
- version = null;
- }
-
- return version;
- }
-
- function detectBrowser() {
- let version;
- const detectors = [
- detectReactNative,
- detectElectron,
- detectNWJS,
- detectOpera,
- detectChrome,
- detectFirefox,
- detectIE,
- detectSafari
- ];
-
- // Try all browser detectors
-
- for (let i = 0; i < detectors.length; i++) {
- version = detectors[i]();
- if (version) {
- return version;
- }
- }
- logger.warn('Browser type defaults to Safari ver 1');
- currentBrowser = RTCBrowserType.RTC_BROWSER_SAFARI;
-
- return 1;
- }
-
- const browserVersion = detectBrowser();
- const isAndroid = navigator.userAgent.indexOf('Android') != -1;
-
- module.exports = RTCBrowserType;
|