You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

RTCBrowserType.js 9.3KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350
  1. var logger = require("jitsi-meet-logger").getLogger(__filename);
  2. var currentBrowser;
  3. var browserVersion;
  4. var isAndroid;
  5. var RTCBrowserType = {
  6. RTC_BROWSER_CHROME: "rtc_browser.chrome",
  7. RTC_BROWSER_OPERA: "rtc_browser.opera",
  8. RTC_BROWSER_FIREFOX: "rtc_browser.firefox",
  9. RTC_BROWSER_IEXPLORER: "rtc_browser.iexplorer",
  10. RTC_BROWSER_SAFARI: "rtc_browser.safari",
  11. RTC_BROWSER_NWJS: "rtc_browser.nwjs",
  12. RTC_BROWSER_ELECTRON: "rtc_browser.electron",
  13. RTC_BROWSER_REACT_NATIVE: "rtc_browser.react-native",
  14. /**
  15. * Gets current browser type.
  16. * @returns {string}
  17. */
  18. getBrowserType() {
  19. return currentBrowser;
  20. },
  21. /**
  22. * Gets current browser name, split from the type.
  23. * @returns {string}
  24. */
  25. getBrowserName() {
  26. var browser;
  27. if (RTCBrowserType.isAndroid()) {
  28. browser = 'android';
  29. } else {
  30. browser = currentBrowser.split('rtc_browser.')[1];
  31. }
  32. return browser;
  33. },
  34. /**
  35. * Checks if current browser is Chrome.
  36. * @returns {boolean}
  37. */
  38. isChrome() {
  39. return currentBrowser === RTCBrowserType.RTC_BROWSER_CHROME;
  40. },
  41. /**
  42. * Checks if current browser is Opera.
  43. * @returns {boolean}
  44. */
  45. isOpera() {
  46. return currentBrowser === RTCBrowserType.RTC_BROWSER_OPERA;
  47. },
  48. /**
  49. * Checks if current browser is Firefox.
  50. * @returns {boolean}
  51. */
  52. isFirefox() {
  53. return currentBrowser === RTCBrowserType.RTC_BROWSER_FIREFOX;
  54. },
  55. /**
  56. * Checks if current browser is Internet Explorer.
  57. * @returns {boolean}
  58. */
  59. isIExplorer() {
  60. return currentBrowser === RTCBrowserType.RTC_BROWSER_IEXPLORER;
  61. },
  62. /**
  63. * Checks if current browser is Safari.
  64. * @returns {boolean}
  65. */
  66. isSafari() {
  67. return currentBrowser === RTCBrowserType.RTC_BROWSER_SAFARI;
  68. },
  69. /**
  70. * Checks if current environment is NWJS.
  71. * @returns {boolean}
  72. */
  73. isNWJS() {
  74. return currentBrowser === RTCBrowserType.RTC_BROWSER_NWJS;
  75. },
  76. /**
  77. * Checks if current environment is Electron.
  78. * @returns {boolean}
  79. */
  80. isElectron() {
  81. return currentBrowser === RTCBrowserType.RTC_BROWSER_ELECTRON;
  82. },
  83. /**
  84. * Checks if current environment is React Native.
  85. * @returns {boolean}
  86. */
  87. isReactNative() {
  88. return currentBrowser === RTCBrowserType.RTC_BROWSER_REACT_NATIVE;
  89. },
  90. /**
  91. * Checks if Temasys RTC plugin is used.
  92. * @returns {boolean}
  93. */
  94. isTemasysPluginUsed() {
  95. // Temasys do not support Microsoft Edge:
  96. // http://support.temasys.com.sg/support/solutions/articles/5000654345-can-the-temasys-webrtc-plugin-be-used-with-microsoft-edge-
  97. if (RTCBrowserType.isIExplorer()
  98. && RTCBrowserType.getIExplorerVersion() < 12) {
  99. return true;
  100. }
  101. return RTCBrowserType.isSafari();
  102. },
  103. /**
  104. * Checks if the current browser triggers 'onmute'/'onunmute' events when
  105. * user's connection is interrupted and the video stops playback.
  106. * @returns {*|boolean} 'true' if the event is supported or 'false'
  107. * otherwise.
  108. */
  109. isVideoMuteOnConnInterruptedSupported() {
  110. return RTCBrowserType.isChrome();
  111. },
  112. /**
  113. * Returns Firefox version.
  114. * @returns {number|null}
  115. */
  116. getFirefoxVersion() {
  117. return RTCBrowserType.isFirefox() ? browserVersion : null;
  118. },
  119. /**
  120. * Returns Chrome version.
  121. * @returns {number|null}
  122. */
  123. getChromeVersion() {
  124. return RTCBrowserType.isChrome() ? browserVersion : null;
  125. },
  126. /**
  127. * Returns Internet Explorer version.
  128. *
  129. * @returns {number|null}
  130. */
  131. getIExplorerVersion() {
  132. return RTCBrowserType.isIExplorer() ? browserVersion : null;
  133. },
  134. usesPlanB() {
  135. return (
  136. RTCBrowserType.isChrome()
  137. || RTCBrowserType.isOpera()
  138. || RTCBrowserType.isReactNative()
  139. || RTCBrowserType.isTemasysPluginUsed());
  140. },
  141. usesUnifiedPlan() {
  142. return RTCBrowserType.isFirefox();
  143. },
  144. /**
  145. * Whether the browser is running on an android device.
  146. * @returns {boolean}
  147. */
  148. isAndroid() {
  149. return isAndroid;
  150. },
  151. /**
  152. * Whether jitsi-meet supports simulcast on the current browser.
  153. * @returns {boolean}
  154. */
  155. supportsSimulcast() {
  156. // This mirrors what sdp-simulcast uses (which is used when deciding
  157. // whether to actually enable simulcast or not).
  158. // TODO: the logic should be in one single place.
  159. return !!window.chrome;
  160. }
  161. // Add version getters for other browsers when needed
  162. };
  163. // detectOpera() must be called before detectChrome() !!!
  164. // otherwise Opera wil be detected as Chrome
  165. function detectChrome() {
  166. if (navigator.webkitGetUserMedia) {
  167. currentBrowser = RTCBrowserType.RTC_BROWSER_CHROME;
  168. var userAgent = navigator.userAgent.toLowerCase();
  169. // We can assume that user agent is chrome, because it's
  170. // enforced when 'ext' streaming method is set
  171. var ver = parseInt(userAgent.match(/chrome\/(\d+)\./)[1], 10);
  172. logger.log("This appears to be Chrome, ver: " + ver);
  173. return ver;
  174. }
  175. return null;
  176. }
  177. function detectOpera() {
  178. var userAgent = navigator.userAgent;
  179. if (userAgent.match(/Opera|OPR/)) {
  180. currentBrowser = RTCBrowserType.RTC_BROWSER_OPERA;
  181. var version = userAgent.match(/(Opera|OPR) ?\/?(\d+)\.?/)[2];
  182. logger.info("This appears to be Opera, ver: " + version);
  183. return version;
  184. }
  185. return null;
  186. }
  187. function detectFirefox() {
  188. if (navigator.mozGetUserMedia) {
  189. currentBrowser = RTCBrowserType.RTC_BROWSER_FIREFOX;
  190. var version = parseInt(
  191. navigator.userAgent.match(/Firefox\/([0-9]+)\./)[1], 10);
  192. logger.log('This appears to be Firefox, ver: ' + version);
  193. return version;
  194. }
  195. return null;
  196. }
  197. function detectSafari() {
  198. if (/^((?!chrome).)*safari/i.test(navigator.userAgent)) {
  199. currentBrowser = RTCBrowserType.RTC_BROWSER_SAFARI;
  200. logger.info("This appears to be Safari");
  201. // FIXME detect Safari version when needed
  202. return 1;
  203. }
  204. return null;
  205. }
  206. function detectIE() {
  207. var version;
  208. var ua = window.navigator.userAgent;
  209. var msie = ua.indexOf('MSIE ');
  210. if (msie > 0) {
  211. // IE 10 or older => return version number
  212. version = parseInt(ua.substring(msie + 5, ua.indexOf('.', msie)), 10);
  213. }
  214. var trident = ua.indexOf('Trident/');
  215. if (!version && trident > 0) {
  216. // IE 11 => return version number
  217. var rv = ua.indexOf('rv:');
  218. version = parseInt(ua.substring(rv + 3, ua.indexOf('.', rv)), 10);
  219. }
  220. var edge = ua.indexOf('Edge/');
  221. if (!version && edge > 0) {
  222. // IE 12 => return version number
  223. version = parseInt(ua.substring(edge + 5, ua.indexOf('.', edge)), 10);
  224. }
  225. if (version) {
  226. currentBrowser = RTCBrowserType.RTC_BROWSER_IEXPLORER;
  227. logger.info("This appears to be IExplorer, ver: " + version);
  228. }
  229. return version;
  230. }
  231. /**
  232. * Detects Electron environment.
  233. */
  234. function detectElectron() {
  235. var userAgent = navigator.userAgent;
  236. if (userAgent.match(/Electron/)) {
  237. currentBrowser = RTCBrowserType.RTC_BROWSER_ELECTRON;
  238. var version = userAgent.match(/Electron\/([\d.]+)/)[1];
  239. logger.info("This appears to be Electron, ver: " + version);
  240. return version;
  241. }
  242. return null;
  243. }
  244. function detectNWJS() {
  245. var userAgent = navigator.userAgent;
  246. if (userAgent.match(/JitsiMeetNW/)) {
  247. currentBrowser = RTCBrowserType.RTC_BROWSER_NWJS;
  248. var version = userAgent.match(/JitsiMeetNW\/([\d.]+)/)[1];
  249. logger.info("This appears to be JitsiMeetNW, ver: " + version);
  250. return version;
  251. }
  252. return null;
  253. }
  254. function detectReactNative() {
  255. var match
  256. = navigator.userAgent.match(/\b(react[ \t_-]*native)(?:\/(\S+))?/i);
  257. var version;
  258. // If we're remote debugging a React Native app, it may be treated as
  259. // Chrome. Check navigator.product as well and always return some version
  260. // even if we can't get the real one.
  261. if (match || navigator.product === 'ReactNative') {
  262. currentBrowser = RTCBrowserType.RTC_BROWSER_REACT_NATIVE;
  263. var name;
  264. if (match && match.length > 2) {
  265. name = match[1];
  266. version = match[2];
  267. }
  268. name || (name = 'react-native');
  269. version || (version = 'unknown');
  270. console.info('This appears to be ' + name + ', ver: ' + version);
  271. } else {
  272. // We're not running in a React Native environment.
  273. version = null;
  274. }
  275. return version;
  276. }
  277. function detectBrowser() {
  278. var version;
  279. var detectors = [
  280. detectReactNative,
  281. detectElectron,
  282. detectNWJS,
  283. detectOpera,
  284. detectChrome,
  285. detectFirefox,
  286. detectIE,
  287. detectSafari
  288. ];
  289. // Try all browser detectors
  290. for (var i = 0; i < detectors.length; i++) {
  291. version = detectors[i]();
  292. if (version) {
  293. return version;
  294. }
  295. }
  296. logger.warn("Browser type defaults to Safari ver 1");
  297. currentBrowser = RTCBrowserType.RTC_BROWSER_SAFARI;
  298. return 1;
  299. }
  300. browserVersion = detectBrowser();
  301. isAndroid = navigator.userAgent.indexOf('Android') != -1;
  302. module.exports = RTCBrowserType;