mediasoup-client 3.15.7 → 3.16.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/lib/Device.d.ts CHANGED
@@ -18,15 +18,16 @@ export type DeviceOptions = {
18
18
  /**
19
19
  * Sync mediasoup-client Handler detection.
20
20
  */
21
- export declare function detectDevice(userAgent?: string): BuiltinHandlerName | undefined;
21
+ export declare function detectDevice(userAgent?: string, userAgentData?: NavigatorUAData): BuiltinHandlerName | undefined;
22
22
  /**
23
23
  * Async mediasoup-client Handler detection.
24
24
  *
25
25
  * @remarks
26
26
  * - Currently it runs same logic than `detectDevice()`.
27
- * - In the future this function could give better results than `detectDevice()`.
27
+ * - In the future this function could give better results than
28
+ * `detectDevice()`.
28
29
  */
29
- export declare function detectDeviceAsync(userAgent?: string): Promise<BuiltinHandlerName | undefined>;
30
+ export declare function detectDeviceAsync(userAgent?: string, userAgentData?: NavigatorUAData): Promise<BuiltinHandlerName | undefined>;
30
31
  export type DeviceObserver = EnhancedEventEmitter<DeviceObserverEvents>;
31
32
  export type DeviceObserverEvents = {
32
33
  newtransport: [Transport];
@@ -1 +1 @@
1
- {"version":3,"file":"Device.d.ts","sourceRoot":"","sources":["../src/Device.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"Device.d.ts","sourceRoot":"","sources":["../src/Device.ts"],"names":[],"mappings":"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"}
package/lib/Device.js CHANGED
@@ -3,7 +3,6 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.Device = void 0;
4
4
  exports.detectDevice = detectDevice;
5
5
  exports.detectDeviceAsync = detectDeviceAsync;
6
- const browser_dtector_1 = require("browser-dtector");
7
6
  const Logger_1 = require("./Logger");
8
7
  const enhancedEvents_1 = require("./enhancedEvents");
9
8
  const errors_1 = require("./errors");
@@ -19,28 +18,33 @@ const logger = new Logger_1.Logger('Device');
19
18
  /**
20
19
  * Sync mediasoup-client Handler detection.
21
20
  */
22
- function detectDevice(userAgent) {
23
- logger.debug('detectDevice() [userAgent:%s]', userAgent);
21
+ function detectDevice(userAgent, userAgentData) {
22
+ logger.debug('detectDevice()');
24
23
  if (!userAgent && typeof navigator === 'object') {
25
24
  userAgent = navigator.userAgent;
26
25
  }
27
- const browserDetector = new browser_dtector_1.default(userAgent);
28
- return detectDeviceImpl(browserDetector);
26
+ if (!userAgentData && typeof navigator === 'object') {
27
+ userAgentData = navigator.userAgentData;
28
+ }
29
+ return detectDeviceImpl(userAgent, userAgentData);
29
30
  }
30
31
  /**
31
32
  * Async mediasoup-client Handler detection.
32
33
  *
33
34
  * @remarks
34
35
  * - Currently it runs same logic than `detectDevice()`.
35
- * - In the future this function could give better results than `detectDevice()`.
36
+ * - In the future this function could give better results than
37
+ * `detectDevice()`.
36
38
  */
37
- async function detectDeviceAsync(userAgent) {
38
- logger.debug('detectDeviceAsync() [userAgent:%s]', userAgent);
39
+ async function detectDeviceAsync(userAgent, userAgentData) {
40
+ logger.debug('detectDeviceAsync()');
39
41
  if (!userAgent && typeof navigator === 'object') {
40
42
  userAgent = navigator.userAgent;
41
43
  }
42
- const browserDetector = new browser_dtector_1.default(userAgent);
43
- return detectDeviceImpl(browserDetector);
44
+ if (!userAgentData && typeof navigator === 'object') {
45
+ userAgentData = navigator.userAgentData;
46
+ }
47
+ return detectDeviceImpl(userAgent, userAgentData);
44
48
  }
45
49
  class Device {
46
50
  // RTC handler factory.
@@ -313,89 +317,188 @@ class Device {
313
317
  }
314
318
  }
315
319
  exports.Device = Device;
316
- function detectDeviceImpl(browserDetector) {
317
- // React-Native.
318
- if (typeof navigator === 'object' && navigator.product === 'ReactNative') {
319
- logger.debug('detectDeviceImpl() | React-Native detected');
320
- if (typeof RTCPeerConnection === 'undefined' ||
321
- typeof RTCRtpTransceiver === 'undefined') {
322
- logger.warn('detectDeviceImpl() | unsupported react-native-webrtc without RTCPeerConnection or RTCRtpTransceiver, forgot to call registerGlobals() on it?');
323
- return undefined;
324
- }
325
- return 'ReactNative106';
326
- }
327
- // Browser.
328
- else {
329
- const parsed = browserDetector.parseUserAgent();
330
- const browserMajorVersionMatch = /^\d+/.exec(parsed?.shortVersion ?? '0');
331
- const browserMajorVersion = parseInt(browserMajorVersionMatch?.[0] ?? '0', 10);
332
- const isIOS = parsed.platform === browser_dtector_1.KnownPlatforms.iphone ||
333
- parsed.platform === browser_dtector_1.KnownPlatforms.ipad ||
334
- (parsed.platform === browser_dtector_1.KnownPlatforms.mac &&
335
- (parsed.isMobile ||
336
- parsed.isTablet ||
337
- (typeof navigator === 'object' && navigator?.maxTouchPoints >= 2)));
338
- const isChrome = parsed.isChrome;
339
- const isFirefox = parsed.isFireFox;
340
- const isSafari = parsed.isSafari;
341
- const isEdge = parsed.isEdge;
342
- const isElectron = parsed.isDesktop && parsed.name === browser_dtector_1.KnownBrowsers.electron;
343
- // For logging purposes.
344
- const result = {
345
- browserMajorVersion,
346
- isIOS,
347
- isChrome,
348
- isFirefox,
349
- isSafari,
350
- isElectron,
351
- };
352
- logger.debug('detectDeviceImpl() | detected browser [userAgent:%s, parsed:%o, result:%o]', parsed.userAgent, parsed, result);
353
- // Chrome, Chromium, and Edge.
354
- if ((isChrome || isEdge) && !isIOS && browserMajorVersion >= 111) {
320
+ function detectDeviceImpl(userAgent, userAgentData) {
321
+ logger.debug('detectDeviceImpl() [userAgent:"%s", userAgentData:%o]', userAgent, userAgentData);
322
+ const chromiumMajorVersion = getChromiumMajorVersion(userAgent, userAgentData);
323
+ if (chromiumMajorVersion) {
324
+ if (chromiumMajorVersion >= 111) {
325
+ logger.debug('detectDeviceImpl() | using Chrome111 handler');
355
326
  return 'Chrome111';
356
327
  }
357
- else if ((isChrome && !isIOS && browserMajorVersion >= 74) ||
358
- (isEdge && !isIOS && browserMajorVersion >= 88)) {
328
+ else if (chromiumMajorVersion >= 74) {
329
+ logger.debug('detectDeviceImpl() | using Chrome74 handler');
359
330
  return 'Chrome74';
360
331
  }
361
- // Electron.
362
- else if (isElectron) {
363
- return 'Chrome111';
332
+ else {
333
+ logger.warn('detectDeviceImpl() | unsupported Chromium based browser/version');
334
+ return undefined;
364
335
  }
365
- // Firefox.
366
- else if (isFirefox && !isIOS && browserMajorVersion >= 120) {
336
+ }
337
+ const firefoxMajorVersion = getFirefoxMajorVersion(userAgent);
338
+ if (firefoxMajorVersion) {
339
+ if (firefoxMajorVersion >= 120) {
340
+ logger.debug('detectDeviceImpl() | using Firefox120 handler');
367
341
  return 'Firefox120';
368
342
  }
369
- // Safari.
370
- else if (isSafari &&
371
- browserMajorVersion >= 12 &&
372
- typeof RTCRtpTransceiver !== 'undefined' &&
373
- RTCRtpTransceiver.prototype.hasOwnProperty('currentDirection')) {
343
+ else {
344
+ logger.warn('detectDeviceImpl() | unsupported Firefox browser/version');
345
+ return undefined;
346
+ }
347
+ }
348
+ const macOSWebKitMajorVersion = getMacOSWebKitMajorVersion(userAgent);
349
+ if (macOSWebKitMajorVersion) {
350
+ if (macOSWebKitMajorVersion >= 605) {
351
+ logger.debug('detectDeviceImpl() | using Safari12 handler');
374
352
  return 'Safari12';
375
353
  }
376
- // Best effort for WebKit based browsers in iOS.
377
- else if (isIOS &&
378
- typeof RTCRtpTransceiver !== 'undefined' &&
379
- RTCRtpTransceiver.prototype.hasOwnProperty('currentDirection')) {
354
+ else {
355
+ logger.warn('detectDeviceImpl() | unsupported desktop Safari browser/version');
356
+ return undefined;
357
+ }
358
+ }
359
+ const iOSWebKitMajorVersion = getIOSWebKitMajorVersion(userAgent);
360
+ if (iOSWebKitMajorVersion) {
361
+ if (iOSWebKitMajorVersion >= 605) {
362
+ logger.debug('detectDeviceImpl() | using Safari12 handler');
380
363
  return 'Safari12';
381
364
  }
382
- // Best effort for Chromium based browsers.
383
365
  else {
384
- const match = browserDetector.userAgent?.match(/(?:(?:Chrome|Chromium))[ /](\w+)/i);
385
- if (match) {
386
- const version = Number(match[1]);
387
- if (version >= 111) {
388
- return 'Chrome111';
389
- }
390
- else {
391
- return 'Chrome74';
392
- }
393
- }
394
- // Unsupported browser.
395
- else {
396
- logger.warn('detectDeviceImpl() | browser not supported [userAgent:%s, parsed:%o, result:%o]', parsed.userAgent, parsed, result);
397
- return undefined;
398
- }
366
+ logger.warn('detectDeviceImpl() | unsupported iOS Safari based browser/version');
367
+ return undefined;
399
368
  }
400
369
  }
370
+ if (isReactNative()) {
371
+ if (typeof RTCPeerConnection !== 'undefined' &&
372
+ typeof RTCRtpTransceiver !== 'undefined') {
373
+ logger.debug('detectDeviceImpl() | using ReactNative106 handler');
374
+ return 'ReactNative106';
375
+ }
376
+ else {
377
+ logger.warn('detectDeviceImpl() | unsupported react-native-webrtc version without RTCPeerConnection or RTCRtpTransceiver, forgot to call registerGlobals() on it?');
378
+ return undefined;
379
+ }
380
+ }
381
+ logger.warn('detectDeviceImpl() | device not supported [userAgent:"%s", userAgentData:%o]', userAgent, userAgentData);
382
+ return undefined;
383
+ }
384
+ function getChromiumMajorVersion(userAgent, userAgentData) {
385
+ if (isIOS(userAgent, userAgentData)) {
386
+ logger.debug('getChromiumMajorVersion() | this is iOS => undefined');
387
+ return undefined;
388
+ }
389
+ if (isReactNative()) {
390
+ logger.debug('getChromiumMajorVersion() | this is React-Native => undefined');
391
+ return undefined;
392
+ }
393
+ if (userAgentData) {
394
+ const chromiumBrand = userAgentData.brands.find(b => b.brand === 'Chromium');
395
+ if (chromiumBrand) {
396
+ const majorVersion = Number(chromiumBrand.version);
397
+ logger.debug(`getChromiumMajorVersion() | Chromium major version based on NavigatorUAData => ${majorVersion}`);
398
+ return majorVersion;
399
+ }
400
+ }
401
+ const match = userAgent?.match(/\b(?:Chrome|Chromium)\/(\w+)/i);
402
+ if (match?.[1]) {
403
+ const majorVersion = Number(match[1]);
404
+ logger.debug(`getChromiumMajorVersion() | Chromium major version based on User-Agent => ${majorVersion}`);
405
+ return majorVersion;
406
+ }
407
+ logger.debug('getChromiumMajorVersion() | this is not Chromium => undefined');
408
+ return undefined;
409
+ }
410
+ function getFirefoxMajorVersion(userAgent) {
411
+ if (isIOS(userAgent)) {
412
+ logger.debug('getFirefoxMajorVersion() | this is iOS => undefined');
413
+ return undefined;
414
+ }
415
+ if (isReactNative()) {
416
+ logger.debug('getFirefoxMajorVersion() | this is React-Native => undefined');
417
+ return undefined;
418
+ }
419
+ const match = userAgent?.match(/\bFirefox\/(\w+)/i);
420
+ if (match?.[1]) {
421
+ const majorVersion = Number(match[1]);
422
+ logger.debug(`getFirefoxMajorVersion() | Firefox major version based on User-Agent => ${majorVersion}`);
423
+ return majorVersion;
424
+ }
425
+ logger.debug('getFirefoxMajorVersion() | this is not Firefox => undefined');
426
+ return undefined;
427
+ }
428
+ function getMacOSWebKitMajorVersion(userAgent) {
429
+ if (isIOS(userAgent)) {
430
+ logger.debug('getMacOSWebKitMajorVersion() | this is iOS => undefined');
431
+ return undefined;
432
+ }
433
+ if (isReactNative()) {
434
+ logger.debug('getMacOSWebKitMajorVersion() | this is React-Native => undefined');
435
+ return undefined;
436
+ }
437
+ const isSafari = userAgent &&
438
+ /\bSafari\b/i.test(userAgent) &&
439
+ !/\bChrome\b/i.test(userAgent) &&
440
+ !/\bChromium\b/i.test(userAgent) &&
441
+ !/\bFirefox\b/i.test(userAgent);
442
+ if (!isSafari) {
443
+ logger.debug('getMacOSWebKitMajorVersion() | this is not Safari => undefined');
444
+ return undefined;
445
+ }
446
+ const match = userAgent.match(/AppleWebKit\/(\w+)/i);
447
+ if (match?.[1]) {
448
+ const majorVersion = Number(match[1]);
449
+ logger.debug(`getMacOSWebKitMajorVersion() | WebKit major version based on User-Agent => ${majorVersion}`);
450
+ return majorVersion;
451
+ }
452
+ logger.debug('getMacOSWebKitMajorVersion() | this is not WebKit => undefined');
453
+ return undefined;
454
+ }
455
+ function getIOSWebKitMajorVersion(userAgent) {
456
+ if (!isIOS(userAgent)) {
457
+ logger.debug('getIOSWebKitMajorVersion() | this is not iOS => undefined');
458
+ return undefined;
459
+ }
460
+ if (isReactNative()) {
461
+ logger.debug('getIOSWebKitMajorVersion() | this is React-Native => undefined');
462
+ return undefined;
463
+ }
464
+ const match = userAgent?.match(/AppleWebKit\/(\w+)/i);
465
+ if (match?.[1]) {
466
+ const majorVersion = Number(match[1]);
467
+ logger.debug(`getIOSWebKitMajorVersion() | WebKit major version based on User-Agent => ${majorVersion}`);
468
+ return majorVersion;
469
+ }
470
+ logger.debug('getIOSWebKitMajorVersion() | this is not WebKit => undefined');
471
+ return undefined;
472
+ }
473
+ function isIOS(userAgent, userAgentData) {
474
+ if (userAgentData?.platform === 'iOS') {
475
+ logger.debug('isIOS() | this is iOS based on NavigatorUAData.platform => true');
476
+ return true;
477
+ }
478
+ if (userAgentData?.platform) {
479
+ logger.debug('isIOS() | this is not iOS based on NavigatorUAData.platform => false');
480
+ return false;
481
+ }
482
+ if (userAgent && /iPad|iPhone|iPod/.test(userAgent)) {
483
+ logger.debug('isIOS() | this is iOS based on User-Agent => true');
484
+ return true;
485
+ }
486
+ // iPadOS 13+ identifies itself as Mac (to force desktop view mode in some
487
+ // websites) but we know it's iOS if it has touch screen.
488
+ if (typeof navigator === 'object' &&
489
+ navigator.platform === 'MacIntel' &&
490
+ navigator.maxTouchPoints > 1) {
491
+ logger.debug('isIOS() | this is iPadOS 13+ based on User-Agent => true');
492
+ return true;
493
+ }
494
+ logger.debug('isIOS() | this is not iOS => false');
495
+ return false;
496
+ }
497
+ function isReactNative() {
498
+ if (typeof navigator === 'object' && navigator.product === 'ReactNative') {
499
+ logger.debug('isReactNative() | this is React-Native based on navigator.product');
500
+ return true;
501
+ }
502
+ logger.debug('isReactNative() | this is not React-Native => false');
503
+ return false;
401
504
  }
package/lib/index.d.ts CHANGED
@@ -6,7 +6,7 @@ export * as types from './types';
6
6
  /**
7
7
  * Expose mediasoup-client version.
8
8
  */
9
- export declare const version = "3.15.7";
9
+ export declare const version = "3.16.0";
10
10
  /**
11
11
  * Expose Device class and device detector helpers.
12
12
  */
package/lib/index.js CHANGED
@@ -10,7 +10,7 @@ exports.types = require("./types");
10
10
  /**
11
11
  * Expose mediasoup-client version.
12
12
  */
13
- exports.version = '3.15.7';
13
+ exports.version = '3.16.0';
14
14
  /**
15
15
  * Expose Device class and device detector helpers.
16
16
  */
package/lib/test/test.js CHANGED
@@ -1166,8 +1166,8 @@ describe('detectDevice() and detectDeviceAsync() assign proper handler based on
1166
1166
  stop() { }
1167
1167
  };
1168
1168
  }
1169
- expect(detectDevice(uaTestCase.ua)).toBe(uaTestCase.expect);
1170
- await expect(detectDeviceAsync(uaTestCase.ua)).resolves.toBe(uaTestCase.expect);
1169
+ expect(detectDevice(uaTestCase.userAgent, uaTestCase.userAgentData)).toBe(uaTestCase.expect);
1170
+ await expect(detectDeviceAsync(uaTestCase.userAgent, uaTestCase.userAgentData)).resolves.toBe(uaTestCase.expect);
1171
1171
  // Cleanup.
1172
1172
  global.RTCRtpTransceiver = originalRTCRtpTransceiver;
1173
1173
  }, 100);
@@ -1,7 +1,8 @@
1
1
  import type { BuiltinHandlerName } from '../Device';
2
2
  type UATestCase = {
3
3
  desc: string;
4
- ua: string;
4
+ userAgent: string;
5
+ userAgentData?: NavigatorUAData;
5
6
  expect?: BuiltinHandlerName;
6
7
  };
7
8
  export declare const uaTestCases: UATestCase[];
@@ -1 +1 @@
1
- {"version":3,"file":"uaTestCases.d.ts","sourceRoot":"","sources":["../../src/test/uaTestCases.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,WAAW,CAAC;AAEpD,KAAK,UAAU,GAAG;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,EAAE,EAAE,MAAM,CAAC;IACX,MAAM,CAAC,EAAE,kBAAkB,CAAC;CAC5B,CAAC;AAEF,eAAO,MAAM,WAAW,EAAE,UAAU,EAuFnC,CAAC"}
1
+ {"version":3,"file":"uaTestCases.d.ts","sourceRoot":"","sources":["../../src/test/uaTestCases.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,WAAW,CAAC;AAEpD,KAAK,UAAU,GAAG;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,CAAC;IAClB,aAAa,CAAC,EAAE,eAAe,CAAC;IAChC,MAAM,CAAC,EAAE,kBAAkB,CAAC;CAC5B,CAAC;AAEF,eAAO,MAAM,WAAW,EAAE,UAAU,EAkNnC,CAAC"}
@@ -2,90 +2,192 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.uaTestCases = void 0;
4
4
  exports.uaTestCases = [
5
+ {
6
+ desc: 'Chrome 140 (MacOS)',
7
+ userAgent: 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/140.0.0.0 Safari/537.36',
8
+ userAgentData: {
9
+ brands: [
10
+ {
11
+ brand: 'Chromium',
12
+ version: '140',
13
+ },
14
+ {
15
+ brand: 'Not=A?Brand',
16
+ version: '24',
17
+ },
18
+ {
19
+ brand: 'Google Chrome',
20
+ version: '140',
21
+ },
22
+ ],
23
+ mobile: false,
24
+ platform: 'macOS',
25
+ },
26
+ expect: 'Chrome111',
27
+ },
28
+ {
29
+ desc: 'Chrome Canary 142 (MacOS)',
30
+ userAgent: 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/142.0.0.0 Safari/537.36',
31
+ userAgentData: {
32
+ brands: [
33
+ {
34
+ brand: 'Chromium',
35
+ version: '142',
36
+ },
37
+ {
38
+ brand: 'Google Chrome',
39
+ version: '142',
40
+ },
41
+ {
42
+ brand: 'Not_A Brand',
43
+ version: '99',
44
+ },
45
+ ],
46
+ mobile: false,
47
+ platform: 'macOS',
48
+ },
49
+ expect: 'Chrome111',
50
+ },
51
+ {
52
+ desc: 'Microsoft Edge 140 (MacOS)',
53
+ userAgent: 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/140.0.0.0 Safari/537.36 Edg/140.0.0.0',
54
+ userAgentData: {
55
+ brands: [
56
+ {
57
+ brand: 'Chromium',
58
+ version: '140',
59
+ },
60
+ {
61
+ brand: 'Not=A?Brand',
62
+ version: '24',
63
+ },
64
+ {
65
+ brand: 'Microsoft Edge',
66
+ version: '140',
67
+ },
68
+ ],
69
+ mobile: false,
70
+ platform: 'macOS',
71
+ },
72
+ expect: 'Chrome111',
73
+ },
74
+ {
75
+ desc: 'Opera 122 (MacOS)',
76
+ userAgent: 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36 OPR/122.0.0.0',
77
+ userAgentData: {
78
+ brands: [
79
+ {
80
+ brand: 'Not)A;Brand',
81
+ version: '8',
82
+ },
83
+ {
84
+ brand: 'Chromium',
85
+ version: '138',
86
+ },
87
+ {
88
+ brand: 'Opera',
89
+ version: '122',
90
+ },
91
+ ],
92
+ mobile: false,
93
+ platform: 'macOS',
94
+ },
95
+ expect: 'Chrome111',
96
+ },
97
+ {
98
+ desc: 'Firefox 142 (on MacOS)',
99
+ userAgent: 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:142.0) Gecko/20100101 Firefox/142.0',
100
+ expect: 'Firefox120',
101
+ },
102
+ {
103
+ desc: 'Safari 18 (on MacOS)',
104
+ userAgent: 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/18.6 Safari/605.1.15',
105
+ expect: 'Safari12',
106
+ },
5
107
  {
6
108
  desc: 'Microsoft Edge 100',
7
- ua: 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/100.0.1108.55 Safari/537.36 Edg/100.0.1108.55',
109
+ userAgent: 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/100.0.1108.55 Safari/537.36 Edg/100.0.1108.55',
8
110
  expect: 'Chrome74',
9
111
  },
10
112
  {
11
113
  desc: 'Mac (Intel) Chrome 112',
12
- ua: 'Mozilla/5.0 (Macintosh; Intel Mac OS X 12_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36',
114
+ userAgent: 'Mozilla/5.0 (Macintosh; Intel Mac OS X 12_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36',
13
115
  expect: 'Chrome111',
14
116
  },
15
117
  {
16
118
  desc: 'iPhone iOS 16',
17
- ua: 'Mozilla/5.0 (iPhone; CPU iPhone OS 18_6_2 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/18.4 Mobile/15E148 Safari/604.1',
119
+ userAgent: 'Mozilla/5.0 (iPhone; CPU iPhone OS 18_6_2 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/18.4 Mobile/15E148 Safari/604.1',
18
120
  expect: 'Safari12',
19
121
  },
20
122
  {
21
123
  desc: 'Generic Android Chrome 112',
22
- ua: 'Mozilla/5.0 (Linux; Android 13; M2012K11AG) AppleWebKit/537.36 (KHTML, like Gecko) Soul/4.0 Chrome/112.0.5615.135 Mobile Safari/537.36',
124
+ userAgent: 'Mozilla/5.0 (Linux; Android 13; M2012K11AG) AppleWebKit/537.36 (KHTML, like Gecko) Soul/4.0 Chrome/112.0.5615.135 Mobile Safari/537.36',
23
125
  expect: 'Chrome111',
24
126
  },
25
127
  {
26
128
  desc: 'Motorola Edge Chrome 104',
27
- ua: 'Mozilla/5.0 (Linux; Android 10; motorola edge) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/104.0.0.0 Mobile Safari/537.36',
129
+ userAgent: 'Mozilla/5.0 (Linux; Android 10; motorola edge) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/104.0.0.0 Mobile Safari/537.36',
28
130
  expect: 'Chrome74',
29
131
  },
30
132
  {
31
133
  desc: 'In-app WebView (Android)',
32
- ua: 'Mozilla/5.0 (Linux; Android 11; G91 Pro Build/RP1A.200720.011; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/114.0.5735.130 Mobile Safari/537.36',
134
+ userAgent: 'Mozilla/5.0 (Linux; Android 11; G91 Pro Build/RP1A.200720.011; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/114.0.5735.130 Mobile Safari/537.36',
33
135
  expect: 'Chrome111',
34
136
  },
35
137
  {
36
138
  desc: 'Brave',
37
- ua: 'Mozilla/5.0 (Windows NT 10.0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/113.0.4044.113 Safari/5370.36 Brave/9085',
139
+ userAgent: 'Mozilla/5.0 (Windows NT 10.0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/113.0.4044.113 Safari/5370.36 Brave/9085',
38
140
  expect: 'Chrome111',
39
141
  },
40
142
  {
41
143
  desc: 'In-app WebView (Android) (Facebook)',
42
- ua: 'Mozilla/5.0 (Linux; Android 12; SM-S908U1 Build/SP1A.210812.016; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/100.0.4896.88 Mobile Safari/537.36 [FB_IAB/FB4A;FBAV/377.0.0.22.107;]',
144
+ userAgent: 'Mozilla/5.0 (Linux; Android 12; SM-S908U1 Build/SP1A.210812.016; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/100.0.4896.88 Mobile Safari/537.36 [FB_IAB/FB4A;FBAV/377.0.0.22.107;]',
43
145
  expect: 'Chrome74',
44
146
  },
45
147
  {
46
148
  desc: 'Firefox (iOS)',
47
- ua: 'Mozilla/5.0 (iPhone; CPU iPhone OS 18_6_2 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) FxiOS/142.0.1 Mobile/15E148 Safari/605.1.15',
149
+ userAgent: 'Mozilla/5.0 (iPhone; CPU iPhone OS 18_6_2 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) FxiOS/142.0.1 Mobile/15E148 Safari/605.1.15',
48
150
  expect: 'Safari12',
49
151
  },
50
152
  {
51
153
  desc: 'In-app WKWebView (iOS) (TikTok)',
52
- ua: 'Mozilla/5.0 (iPhone; CPU iPhone OS 14_8 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/15E148 musical_ly_21.1.0 JsSdk/2.0 NetType/4G Channel/App Store ByteLocale/ru Region/RU ByteFullLocale/ru-RU isDarkMode/1 WKWebView/1 BytedanceWebview/d8a21c6',
154
+ userAgent: 'Mozilla/5.0 (iPhone; CPU iPhone OS 14_8 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/15E148 musical_ly_21.1.0 JsSdk/2.0 NetType/4G Channel/App Store ByteLocale/ru Region/RU ByteFullLocale/ru-RU isDarkMode/1 WKWebView/1 BytedanceWebview/d8a21c6',
53
155
  expect: 'Safari12',
54
156
  },
55
157
  {
56
158
  desc: 'In-app WkWebView (iOS) (WeChat)',
57
- ua: 'Mozilla/5.0 (iPhone; CPU iPhone OS 16_0_3 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/15E148 MicroMessenger/8.0.37(0x1800252f) NetType/WIFI Language/zh_CN',
159
+ userAgent: 'Mozilla/5.0 (iPhone; CPU iPhone OS 16_0_3 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/15E148 MicroMessenger/8.0.37(0x1800252f) NetType/WIFI Language/zh_CN',
58
160
  expect: 'Safari12',
59
161
  },
60
162
  {
61
163
  desc: 'Custom Webview in iPad',
62
- ua: 'Mozilla/5.0 (iPad; CPU iPadOS 16_4 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/16.4 Mobile/15E148 Safari/604.1 MyApp/1.0',
164
+ userAgent: 'Mozilla/5.0 (iPad; CPU iPadOS 16_4 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/16.4 Mobile/15E148 Safari/604.1 MyApp/1.0',
63
165
  expect: 'Safari12',
64
166
  },
65
167
  {
66
168
  desc: 'Chrome Mobile (iOS)',
67
- ua: 'Mozilla/5.0 (iPhone; CPU iPhone OS 16_5 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) CriOS/114.0.5735.124 Mobile/15E148 Safari/604.1',
169
+ userAgent: 'Mozilla/5.0 (iPhone; CPU iPhone OS 16_5 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) CriOS/114.0.5735.124 Mobile/15E148 Safari/604.1',
68
170
  expect: 'Safari12',
69
171
  },
70
172
  {
71
173
  desc: 'Fake Foo Invalid Browser - Unsupported',
72
- ua: 'Fake/5.0 (Foo; Bar Lalala OS_19.5) Foo/22.2',
174
+ userAgent: 'Fake/5.0 (Foo; Bar Lalala OS_19.5) Foo/22.2',
73
175
  expect: undefined,
74
176
  },
75
177
  {
76
178
  // Zoom App Marketplace browser.
77
179
  desc: 'Zoom App Marketplace browser - Unsupported',
78
- ua: 'Mozilla/5.0 ZoomWebKit/537.36 (KHTML, like Gecko) ZoomApps/1.0',
180
+ userAgent: 'Mozilla/5.0 ZoomWebKit/537.36 (KHTML, like Gecko) ZoomApps/1.0',
79
181
  expect: undefined,
80
182
  },
81
183
  {
82
184
  desc: 'Electron in Windows',
83
- ua: 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Electron/37.4.0 Chrome/138.0.7204.243 Safari/537.36',
185
+ userAgent: 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Electron/37.4.0 Chrome/138.0.7204.243 Safari/537.36',
84
186
  expect: 'Chrome111',
85
187
  },
86
188
  {
87
189
  desc: 'Samsung Browser (Android)',
88
- ua: 'Mozilla/5.0 (Linux; Android 10; K) AppleWebKit/537.36 (KHTML, like Gecko) SamsungBrowser/28.0 Chrome/130.0.0.0 Mobile Safari/537.36',
190
+ userAgent: 'Mozilla/5.0 (Linux; Android 10; K) AppleWebKit/537.36 (KHTML, like Gecko) SamsungBrowser/28.0 Chrome/130.0.0.0 Mobile Safari/537.36',
89
191
  expect: 'Chrome111',
90
192
  },
91
193
  ];
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "mediasoup-client",
3
- "version": "3.15.7",
3
+ "version": "3.16.0",
4
4
  "description": "mediasoup client side TypeScript library",
5
5
  "contributors": [
6
6
  "Iñaki Baz Castillo <ibc@aliax.net> (https://inakibaz.me)",
@@ -74,7 +74,6 @@
74
74
  "@types/debug": "^4.1.12",
75
75
  "@types/events-alias": "npm:@types/events@^3.0.3",
76
76
  "awaitqueue": "^3.2.4",
77
- "browser-dtector": "^4.1.0",
78
77
  "debug": "^4.4.3",
79
78
  "events-alias": "npm:events@^3.3.0",
80
79
  "fake-mediastreamtrack": "^2.1.4",