twilio-video 2.21.3 → 2.22.2
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/CHANGELOG.md +83 -1
- package/COMMON_ISSUES.md +34 -0
- package/README.md +1 -1
- package/dist/twilio-video.js +377 -116
- package/dist/twilio-video.min.js +20 -20
- package/es5/connect.js +9 -0
- package/es5/connect.js.map +1 -1
- package/es5/localparticipant.js +57 -33
- package/es5/localparticipant.js.map +1 -1
- package/es5/media/track/localtrackpublication.js +56 -4
- package/es5/media/track/localtrackpublication.js.map +1 -1
- package/es5/room.js +59 -0
- package/es5/room.js.map +1 -1
- package/es5/signaling/v2/cancelableroomsignalingpromise.js +2 -1
- package/es5/signaling/v2/cancelableroomsignalingpromise.js.map +1 -1
- package/es5/signaling/v2/localparticipant.js +13 -1
- package/es5/signaling/v2/localparticipant.js.map +1 -1
- package/es5/signaling/v2/localtrackpublication.js +38 -2
- package/es5/signaling/v2/localtrackpublication.js.map +1 -1
- package/es5/signaling/v2/peerconnection.js +23 -7
- package/es5/signaling/v2/peerconnection.js.map +1 -1
- package/es5/signaling/v2/room.js +9 -0
- package/es5/signaling/v2/room.js.map +1 -1
- package/es5/signaling/v2/twilioconnectiontransport.js +8 -1
- package/es5/signaling/v2/twilioconnectiontransport.js.map +1 -1
- package/es5/util/index.js +11 -0
- package/es5/util/index.js.map +1 -1
- package/es5/util/support.js +2 -0
- package/es5/util/support.js.map +1 -1
- package/es5/util/twiliowarning.js +12 -0
- package/es5/util/twiliowarning.js.map +1 -0
- package/es5/webrtc/util/sdp.js +10 -1
- package/es5/webrtc/util/sdp.js.map +1 -1
- package/lib/connect.js +9 -0
- package/lib/localparticipant.js +64 -37
- package/lib/media/track/localtrackpublication.js +32 -4
- package/lib/room.js +53 -0
- package/lib/signaling/v2/cancelableroomsignalingpromise.js +2 -0
- package/lib/signaling/v2/localparticipant.js +15 -1
- package/lib/signaling/v2/localtrackpublication.js +38 -1
- package/lib/signaling/v2/peerconnection.js +22 -7
- package/lib/signaling/v2/room.js +10 -0
- package/lib/signaling/v2/twilioconnectiontransport.js +10 -0
- package/lib/util/index.js +11 -0
- package/lib/util/support.js +2 -0
- package/lib/util/twiliowarning.js +13 -0
- package/lib/webrtc/util/sdp.js +11 -1
- package/package.json +2 -1
- package/tsdef/LocalParticipant.d.ts +2 -0
- package/tsdef/LocalTrackPublication.d.ts +2 -0
- package/tsdef/Room.d.ts +4 -1
- package/tsdef/twilio-video-tests.ts +38 -0
- package/tsdef/types.d.ts +3 -0
package/lib/room.js
CHANGED
|
@@ -49,6 +49,8 @@ let nInstances = 0;
|
|
|
49
49
|
* @emits Room#trackSwitchedOn
|
|
50
50
|
* @emits Room#trackUnpublished
|
|
51
51
|
* @emits Room#trackUnsubscribed
|
|
52
|
+
* @emits Room#trackWarning
|
|
53
|
+
* @emits Room#trackWarningsCleared
|
|
52
54
|
*/
|
|
53
55
|
class Room extends EventEmitter {
|
|
54
56
|
/**
|
|
@@ -125,6 +127,7 @@ class Room extends EventEmitter {
|
|
|
125
127
|
}
|
|
126
128
|
});
|
|
127
129
|
|
|
130
|
+
handleLocalParticipantEvents(this, localParticipant);
|
|
128
131
|
handleRecordingEvents(this, signaling.recording);
|
|
129
132
|
handleSignalingEvents(this, signaling);
|
|
130
133
|
|
|
@@ -455,6 +458,42 @@ function rewriteLocalTrackIds(room, trackStats) {
|
|
|
455
458
|
* });
|
|
456
459
|
*/
|
|
457
460
|
|
|
461
|
+
/**
|
|
462
|
+
* One of the {@link LocalParticipant}'s {@link LocalTrackPublication}s in the {@link Room} encountered a warning.
|
|
463
|
+
* This event is only raised if you enabled warnings using <code>notifyWarnings</code> in <code>ConnectOptions</code>.
|
|
464
|
+
* @param {string} name - The warning that was raised.
|
|
465
|
+
* @param {LocalTrackPublication} publication - The {@link LocalTrackPublication} that encountered the warning.
|
|
466
|
+
* @param {LocalParticipant} participant - The {@link LocalParticipant}
|
|
467
|
+
* @event Room#trackWarning
|
|
468
|
+
* @example
|
|
469
|
+
* room.on('trackWarning', (name, publication, participant) => {
|
|
470
|
+
* if (name === 'recording-media-lost') {
|
|
471
|
+
* log(`LocalTrack ${publication.track.name} is not recording media.`,
|
|
472
|
+
* name, publication, participant);
|
|
473
|
+
*
|
|
474
|
+
* // Wait a reasonable amount of time to clear the warning.
|
|
475
|
+
* const timer = setTimeout(() => {
|
|
476
|
+
* // If the warning is not cleared, you can manually
|
|
477
|
+
* // reconnect to the room, or show a dialog to the user
|
|
478
|
+
* }, 5000);
|
|
479
|
+
*
|
|
480
|
+
* room.once('trackWarningsCleared', (publication, participant) => {
|
|
481
|
+
* log('LocalTrack warnings have cleared!',
|
|
482
|
+
* publication, participant);
|
|
483
|
+
* clearTimeout(timer);
|
|
484
|
+
* });
|
|
485
|
+
* }
|
|
486
|
+
});
|
|
487
|
+
*/
|
|
488
|
+
|
|
489
|
+
/**
|
|
490
|
+
* One of the {@link LocalParticipant}'s {@link LocalTrackPublication}s in the {@link Room} cleared all warnings.
|
|
491
|
+
* This event is only raised if you enabled warnings using <code>notifyWarnings</code> in <code>ConnectOptions</code>.
|
|
492
|
+
* @param {LocalTrackPublication} publication - The {@link LocalTrackPublication} that cleared all warnings.
|
|
493
|
+
* @param {LocalParticipant} participant - The {@link LocalParticipant}
|
|
494
|
+
* @event Room#trackWarningsCleared
|
|
495
|
+
*/
|
|
496
|
+
|
|
458
497
|
function connectParticipant(room, participantSignaling) {
|
|
459
498
|
const { _log: log, _clientTrackSwitchOffControl: clientTrackSwitchOffControl, _contentPreferencesMode: contentPreferencesMode } = room;
|
|
460
499
|
const participant = new RemoteParticipant(participantSignaling, { log, clientTrackSwitchOffControl, contentPreferencesMode });
|
|
@@ -509,6 +548,20 @@ function connectParticipant(room, participantSignaling) {
|
|
|
509
548
|
});
|
|
510
549
|
}
|
|
511
550
|
|
|
551
|
+
function handleLocalParticipantEvents(room, localParticipant) {
|
|
552
|
+
const events = ['trackWarning', 'trackWarningsCleared'].map(event => ({
|
|
553
|
+
eventName: event,
|
|
554
|
+
handler: (...args) => room.emit(event, ...[...args, localParticipant]),
|
|
555
|
+
}));
|
|
556
|
+
|
|
557
|
+
events.forEach(({ eventName, handler }) =>
|
|
558
|
+
localParticipant.on(eventName, handler));
|
|
559
|
+
|
|
560
|
+
room.once('disconnected', () =>
|
|
561
|
+
events.forEach(({ eventName, handler }) =>
|
|
562
|
+
localParticipant.removeListener(eventName, handler)));
|
|
563
|
+
}
|
|
564
|
+
|
|
512
565
|
function handleRecordingEvents(room, recording) {
|
|
513
566
|
recording.on('updated', function updated() {
|
|
514
567
|
const started = recording.isEnabled;
|
|
@@ -68,6 +68,7 @@ function createCancelableRoomSignalingPromise(token, wsServer, localParticipant,
|
|
|
68
68
|
name,
|
|
69
69
|
networkMonitor,
|
|
70
70
|
networkQuality,
|
|
71
|
+
notifyWarnings,
|
|
71
72
|
realm,
|
|
72
73
|
sdpSemantics,
|
|
73
74
|
} = options;
|
|
@@ -89,6 +90,7 @@ function createCancelableRoomSignalingPromise(token, wsServer, localParticipant,
|
|
|
89
90
|
logLevel,
|
|
90
91
|
networkMonitor,
|
|
91
92
|
networkQuality,
|
|
93
|
+
notifyWarnings,
|
|
92
94
|
iceServers,
|
|
93
95
|
onIced,
|
|
94
96
|
realm,
|
|
@@ -165,6 +165,20 @@ class LocalParticipantV2 extends LocalParticipantSignaling {
|
|
|
165
165
|
return this;
|
|
166
166
|
}
|
|
167
167
|
|
|
168
|
+
updateMediaStates(mediaStates) {
|
|
169
|
+
if (!mediaStates || !mediaStates.tracks) {
|
|
170
|
+
return this;
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
Array.from(this.tracks.values()).forEach(publication => {
|
|
174
|
+
const states = mediaStates.tracks[publication.sid];
|
|
175
|
+
if (states) {
|
|
176
|
+
publication.updateMediaStates(states);
|
|
177
|
+
}
|
|
178
|
+
});
|
|
179
|
+
return this;
|
|
180
|
+
}
|
|
181
|
+
|
|
168
182
|
/**
|
|
169
183
|
* @protected
|
|
170
184
|
* @param {DataTrackSender|MediaTrackSender} trackSender
|
|
@@ -173,7 +187,7 @@ class LocalParticipantV2 extends LocalParticipantSignaling {
|
|
|
173
187
|
* @returns {LocalTrackPublicationV2}
|
|
174
188
|
*/
|
|
175
189
|
_createLocalTrackPublicationSignaling(trackSender, name, priority) {
|
|
176
|
-
return new this._LocalTrackPublicationV2(trackSender, name, priority);
|
|
190
|
+
return new this._LocalTrackPublicationV2(trackSender, name, priority, { log: this._log });
|
|
177
191
|
}
|
|
178
192
|
|
|
179
193
|
/**
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
3
|
const LocalTrackPublicationSignaling = require('../localtrackpublication');
|
|
4
|
+
const TwilioWarning = require('../../util/twiliowarning');
|
|
4
5
|
const createTwilioError = require('../../util/twilio-video-errors').createTwilioError;
|
|
5
6
|
|
|
6
7
|
/**
|
|
@@ -12,9 +13,19 @@ class LocalTrackPublicationV2 extends LocalTrackPublicationSignaling {
|
|
|
12
13
|
* @param {DataTrackSender|MediaTrackSender} trackSender
|
|
13
14
|
* @param {string} name
|
|
14
15
|
* @param {Track.Priority} priority
|
|
16
|
+
* @param {object} [options]
|
|
15
17
|
*/
|
|
16
|
-
constructor(trackSender, name, priority) {
|
|
18
|
+
constructor(trackSender, name, priority, options) {
|
|
17
19
|
super(trackSender, name, priority);
|
|
20
|
+
Object.defineProperties(this, {
|
|
21
|
+
_log: {
|
|
22
|
+
value: options.log.createLog('default', this)
|
|
23
|
+
},
|
|
24
|
+
_mediaStates: {
|
|
25
|
+
value: { recordings: null },
|
|
26
|
+
writable: true
|
|
27
|
+
}
|
|
28
|
+
});
|
|
18
29
|
}
|
|
19
30
|
|
|
20
31
|
/**
|
|
@@ -31,6 +42,10 @@ class LocalTrackPublicationV2 extends LocalTrackPublicationSignaling {
|
|
|
31
42
|
};
|
|
32
43
|
}
|
|
33
44
|
|
|
45
|
+
toString() {
|
|
46
|
+
return `[LocalTrackPublicationV2: ${this.sid}]`;
|
|
47
|
+
}
|
|
48
|
+
|
|
34
49
|
/**
|
|
35
50
|
* Compare the {@link LocalTrackPublicationV2} to a {@link LocalTrackPublicationV2#Representation} of itself
|
|
36
51
|
* and perform any updates necessary.
|
|
@@ -53,6 +68,28 @@ class LocalTrackPublicationV2 extends LocalTrackPublicationSignaling {
|
|
|
53
68
|
}
|
|
54
69
|
return this;
|
|
55
70
|
}
|
|
71
|
+
|
|
72
|
+
updateMediaStates(mediaStates) {
|
|
73
|
+
if (!mediaStates || !mediaStates.recordings ||
|
|
74
|
+
this._mediaStates.recordings === mediaStates.recordings) {
|
|
75
|
+
return this;
|
|
76
|
+
}
|
|
77
|
+
this._mediaStates.recordings = mediaStates.recordings;
|
|
78
|
+
switch (this._mediaStates.recordings) {
|
|
79
|
+
case 'OK':
|
|
80
|
+
this._log.info('Warnings have cleared.');
|
|
81
|
+
this.emit('warningsCleared');
|
|
82
|
+
break;
|
|
83
|
+
case 'NO_MEDIA':
|
|
84
|
+
this._log.warn('Recording media lost.');
|
|
85
|
+
this.emit('warning', TwilioWarning.recordingMediaLost);
|
|
86
|
+
break;
|
|
87
|
+
default:
|
|
88
|
+
this._log.warn(`Unknown media state detected: ${this._mediaStates.recordings}`);
|
|
89
|
+
break;
|
|
90
|
+
}
|
|
91
|
+
return this;
|
|
92
|
+
}
|
|
56
93
|
}
|
|
57
94
|
|
|
58
95
|
/**
|
|
@@ -1851,13 +1851,28 @@ function updateEncodingParameters(pcv2) {
|
|
|
1851
1851
|
setMaxBitrate(params, maxBitrate);
|
|
1852
1852
|
}
|
|
1853
1853
|
|
|
1854
|
-
if (!isFirefox &&
|
|
1855
|
-
|
|
1856
|
-
|
|
1857
|
-
|
|
1858
|
-
|
|
1859
|
-
|
|
1860
|
-
|
|
1854
|
+
if (!isFirefox && params.encodings.length > 0) {
|
|
1855
|
+
if (sender.track.kind === 'audio') {
|
|
1856
|
+
// NOTE(mmalavalli): "priority" is a per-sender property and not
|
|
1857
|
+
// a per-encoding-layer property. So, we set the value only on the first
|
|
1858
|
+
// encoding layer. Any attempt to set the value on subsequent encoding
|
|
1859
|
+
// layers (in the case of simulcast) will result in the Promise returned
|
|
1860
|
+
// by RTCRtpSender.setParameters() being rejected. With this, audio encoding
|
|
1861
|
+
// is prioritized the most.
|
|
1862
|
+
params.encodings[0].priority = 'high';
|
|
1863
|
+
} else if (pcv2._isChromeScreenShareTrack(sender.track)) {
|
|
1864
|
+
// NOTE(mmalavalli): Screen share encodings are prioritized more than those
|
|
1865
|
+
// of the camera.
|
|
1866
|
+
params.encodings[0].priority = 'medium';
|
|
1867
|
+
}
|
|
1868
|
+
if (pcv2._enableDscp) {
|
|
1869
|
+
// NOTE(mmalavalli): "networkPriority" is a per-sender property and not
|
|
1870
|
+
// a per-encoding-layer property. So, we set the value only on the first
|
|
1871
|
+
// encoding layer. Any attempt to set the value on subsequent encoding
|
|
1872
|
+
// layers (in the case of simulcast) will result in the Promise returned
|
|
1873
|
+
// by RTCRtpSender.setParameters() being rejected.
|
|
1874
|
+
params.encodings[0].networkPriority = 'high';
|
|
1875
|
+
}
|
|
1861
1876
|
}
|
|
1862
1877
|
|
|
1863
1878
|
// when a sender is reused, delete any active encodings set by server.
|
package/lib/signaling/v2/room.js
CHANGED
|
@@ -70,6 +70,10 @@ class RoomV2 extends RoomSignaling {
|
|
|
70
70
|
value: localParticipant.bandwidthProfileRevision,
|
|
71
71
|
writable: true
|
|
72
72
|
},
|
|
73
|
+
_mediaStatesWarningsRevision: {
|
|
74
|
+
value: 0,
|
|
75
|
+
writable: true
|
|
76
|
+
},
|
|
73
77
|
_networkQualityMonitor: {
|
|
74
78
|
value: null,
|
|
75
79
|
writable: true
|
|
@@ -442,6 +446,12 @@ class RoomV2 extends RoomSignaling {
|
|
|
442
446
|
}
|
|
443
447
|
});
|
|
444
448
|
|
|
449
|
+
if (roomState.type === 'warning' && roomState.states &&
|
|
450
|
+
roomState.states.revision > this._mediaStatesWarningsRevision) {
|
|
451
|
+
this._mediaStatesWarningsRevision = roomState.states.revision;
|
|
452
|
+
this.localParticipant.updateMediaStates(roomState.states);
|
|
453
|
+
}
|
|
454
|
+
|
|
445
455
|
return this;
|
|
446
456
|
}
|
|
447
457
|
|
|
@@ -10,6 +10,7 @@ const { SDK_NAME, SDK_VERSION, SDP_FORMAT } = require('../../util/constants');
|
|
|
10
10
|
const {
|
|
11
11
|
createBandwidthProfilePayload,
|
|
12
12
|
createMediaSignalingPayload,
|
|
13
|
+
createMediaWarningsPayload,
|
|
13
14
|
createSubscribePayload,
|
|
14
15
|
getUserAgent,
|
|
15
16
|
isNonArrayObject
|
|
@@ -132,6 +133,9 @@ class TwilioConnectionTransport extends StateMachine {
|
|
|
132
133
|
_networkQuality: {
|
|
133
134
|
value: isNonArrayObject(options.networkQuality) || options.networkQuality
|
|
134
135
|
},
|
|
136
|
+
_notifyWarnings: {
|
|
137
|
+
value: options.notifyWarnings
|
|
138
|
+
},
|
|
135
139
|
_options: {
|
|
136
140
|
value: options
|
|
137
141
|
},
|
|
@@ -226,6 +230,11 @@ class TwilioConnectionTransport extends StateMachine {
|
|
|
226
230
|
this._bandwidthProfile);
|
|
227
231
|
}
|
|
228
232
|
|
|
233
|
+
if (this._notifyWarnings) {
|
|
234
|
+
message.participant.media_warnings = createMediaWarningsPayload(
|
|
235
|
+
this._notifyWarnings);
|
|
236
|
+
}
|
|
237
|
+
|
|
229
238
|
message.media_signaling = createMediaSignalingPayload(
|
|
230
239
|
this._dominantSpeaker,
|
|
231
240
|
this._networkQuality,
|
|
@@ -524,6 +533,7 @@ function setupTransport(transport) {
|
|
|
524
533
|
case 'connected':
|
|
525
534
|
case 'synced':
|
|
526
535
|
case 'update':
|
|
536
|
+
case 'warning':
|
|
527
537
|
transport.emit('message', message);
|
|
528
538
|
return;
|
|
529
539
|
case 'disconnected':
|
package/lib/util/index.js
CHANGED
|
@@ -4,6 +4,7 @@ const constants = require('./constants');
|
|
|
4
4
|
const { typeErrors: E, trackPriority } = constants;
|
|
5
5
|
const util = require('../webrtc/util');
|
|
6
6
|
const { sessionSID } = require('./sid');
|
|
7
|
+
const TwilioWarning = require('./twiliowarning');
|
|
7
8
|
|
|
8
9
|
/**
|
|
9
10
|
* Return the given {@link LocalTrack} or a new {@link LocalTrack} for the
|
|
@@ -779,6 +780,15 @@ function createSubscribePayload(automaticSubscription) {
|
|
|
779
780
|
};
|
|
780
781
|
}
|
|
781
782
|
|
|
783
|
+
function createMediaWarningsPayload(notifyWarnings) {
|
|
784
|
+
const mediaWarnings = {
|
|
785
|
+
[TwilioWarning.recordingMediaLost]: 'recordings'
|
|
786
|
+
};
|
|
787
|
+
return notifyWarnings
|
|
788
|
+
.map(twilioWarningName => mediaWarnings[twilioWarningName])
|
|
789
|
+
.filter(name => !!name);
|
|
790
|
+
}
|
|
791
|
+
|
|
782
792
|
/**
|
|
783
793
|
* Add random jitter to a given value in the range [-jitter, jitter].
|
|
784
794
|
* @private
|
|
@@ -852,6 +862,7 @@ function waitForEvent(eventTarget, event) {
|
|
|
852
862
|
exports.constants = constants;
|
|
853
863
|
exports.createBandwidthProfilePayload = createBandwidthProfilePayload;
|
|
854
864
|
exports.createMediaSignalingPayload = createMediaSignalingPayload;
|
|
865
|
+
exports.createMediaWarningsPayload = createMediaWarningsPayload;
|
|
855
866
|
exports.createRoomConnectEventPayload = createRoomConnectEventPayload;
|
|
856
867
|
exports.createSubscribePayload = createSubscribePayload;
|
|
857
868
|
exports.asLocalTrack = asLocalTrack;
|
package/lib/util/support.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
3
|
const { guessBrowser, support: isWebRTCSupported } = require('../webrtc/util');
|
|
4
|
+
const { getSdpFormat } = require('../webrtc/util/sdp');
|
|
4
5
|
const { isAndroid, isMobile, isNonChromiumEdge, rebrandedChromeBrowser, mobileWebKitBrowser } = require('./browserdetection');
|
|
5
6
|
|
|
6
7
|
const SUPPORTED_CHROME_BASED_BROWSERS = [
|
|
@@ -41,6 +42,7 @@ function isSupported() {
|
|
|
41
42
|
|
|
42
43
|
return !!browser
|
|
43
44
|
&& isWebRTCSupported()
|
|
45
|
+
&& getSdpFormat() === 'unified'
|
|
44
46
|
&& (!rebrandedChrome || SUPPORTED_CHROME_BASED_BROWSERS.includes(rebrandedChrome))
|
|
45
47
|
&& !isNonChromiumEdge(browser)
|
|
46
48
|
&& (!mobileWebKit || SUPPORTED_MOBILE_WEBKIT_BASED_BROWSERS.includes(mobileWebKit))
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* @private
|
|
5
|
+
* Represents a warning encountered when
|
|
6
|
+
* interacting with one of Twilio's services.
|
|
7
|
+
*/
|
|
8
|
+
// eslint-disable-next-line
|
|
9
|
+
const TwilioWarning = {
|
|
10
|
+
recordingMediaLost: 'recording-media-lost'
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
module.exports = TwilioWarning;
|
package/lib/webrtc/util/sdp.js
CHANGED
|
@@ -35,6 +35,13 @@ function checkIfSdpSemanticsIsSupported() {
|
|
|
35
35
|
// instantiation of more than one RTCPeerConnection.
|
|
36
36
|
var chromeSdpFormat = null;
|
|
37
37
|
|
|
38
|
+
/**
|
|
39
|
+
* Clear cached Chrome's SDP format
|
|
40
|
+
*/
|
|
41
|
+
function clearChromeCachedSdpFormat() {
|
|
42
|
+
chromeSdpFormat = null;
|
|
43
|
+
}
|
|
44
|
+
|
|
38
45
|
/**
|
|
39
46
|
* Get Chrome's default SDP format.
|
|
40
47
|
* @returns {'planb'|'unified'}
|
|
@@ -43,12 +50,14 @@ function getChromeDefaultSdpFormat() {
|
|
|
43
50
|
if (!chromeSdpFormat) {
|
|
44
51
|
if (typeof RTCPeerConnection !== 'undefined'
|
|
45
52
|
&& 'addTransceiver' in RTCPeerConnection.prototype) {
|
|
53
|
+
const pc = new RTCPeerConnection();
|
|
46
54
|
try {
|
|
47
|
-
|
|
55
|
+
pc.addTransceiver('audio');
|
|
48
56
|
chromeSdpFormat = 'unified';
|
|
49
57
|
} catch (e) {
|
|
50
58
|
chromeSdpFormat = 'planb';
|
|
51
59
|
}
|
|
60
|
+
pc.close();
|
|
52
61
|
} else {
|
|
53
62
|
chromeSdpFormat = 'planb';
|
|
54
63
|
}
|
|
@@ -299,6 +308,7 @@ function updateUnifiedPlanTrackIdsToSSRCs(trackIdsToSSRCs, sdp) {
|
|
|
299
308
|
return updateTrackIdsToSSRCs(getUnifiedPlanTrackIdsToSSRCs, trackIdsToSSRCs, sdp);
|
|
300
309
|
}
|
|
301
310
|
|
|
311
|
+
exports.clearChromeCachedSdpFormat = clearChromeCachedSdpFormat;
|
|
302
312
|
exports.getSdpFormat = getSdpFormat;
|
|
303
313
|
exports.getMediaSections = getMediaSections;
|
|
304
314
|
exports.getPlanBTrackIds = getPlanBTrackIds;
|
package/package.json
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"name": "twilio-video",
|
|
3
3
|
"title": "Twilio Video",
|
|
4
4
|
"description": "Twilio Video JavaScript Library",
|
|
5
|
-
"version": "2.
|
|
5
|
+
"version": "2.22.2",
|
|
6
6
|
"homepage": "https://twilio.com",
|
|
7
7
|
"author": "Mark Andrus Roberts <mroberts@twilio.com>",
|
|
8
8
|
"contributors": [
|
|
@@ -99,6 +99,7 @@
|
|
|
99
99
|
"lint": "npm-run-all lint:js lint:ts",
|
|
100
100
|
"printVersion": "node --version && npm --version",
|
|
101
101
|
"test:unit": "npm-run-all printVersion build:es5 && nyc --report-dir=./coverage --include=lib/**/* --reporter=html --reporter=lcov --reporter=text mocha -r ts-node/register ./test/unit/*",
|
|
102
|
+
"test:unit:quick": "nyc --report-dir=./coverage --include=lib/**/* --reporter=html --reporter=lcov mocha -r ts-node/register",
|
|
102
103
|
"test:serversiderender": "mocha ./test/serversiderender/index.js",
|
|
103
104
|
"test:integration:adapter": "node ./scripts/karma.js karma/integration.adapter.conf.js",
|
|
104
105
|
"test:integration": "npm run build:es5 && node ./scripts/karma.js karma/integration.conf.js",
|
|
@@ -31,5 +31,7 @@ export class LocalParticipant extends Participant {
|
|
|
31
31
|
on(event: 'trackPublished', listener: (publication: LocalTrackPublication) => void): this;
|
|
32
32
|
on(event: 'trackStarted', listener: (track: LocalTrack) => void): this;
|
|
33
33
|
on(event: 'trackStopped', listener: (track: LocalTrack) => void): this;
|
|
34
|
+
on(event: 'trackWarning', listener: (name: string, publication: LocalTrackPublication) => void): this;
|
|
35
|
+
on(event: 'trackWarningsCleared', listener: (publication: LocalTrackPublication) => void): this;
|
|
34
36
|
on(event: string, listener: (...args: any[]) => void): this;
|
|
35
37
|
}
|
|
@@ -13,5 +13,7 @@ export class LocalTrackPublication extends TrackPublication {
|
|
|
13
13
|
|
|
14
14
|
on(event: 'trackDisabled', listener: () => void): this;
|
|
15
15
|
on(event: 'trackEnabled', listener: () => void): this;
|
|
16
|
+
on(event: 'warning', listener: (name: string) => void): this;
|
|
17
|
+
on(event: 'warningsCleared', listener: () => void): this;
|
|
16
18
|
on(event: string, listener: (...args: any[]) => void): this;
|
|
17
19
|
}
|
package/tsdef/Room.d.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
import { RemoteTrack, StatsReport } from './types';
|
|
1
|
+
import { LocalTrack, RemoteTrack, StatsReport } from './types';
|
|
2
2
|
import { EventEmitter } from 'events';
|
|
3
3
|
import { LocalParticipant } from './LocalParticipant';
|
|
4
|
+
import { LocalTrackPublication } from './LocalTrackPublication';
|
|
4
5
|
import { Participant } from './Participant';
|
|
5
6
|
import { RemoteDataTrack } from './RemoteDataTrack';
|
|
6
7
|
import { RemoteParticipant } from './RemoteParticipant';
|
|
@@ -49,4 +50,6 @@ export class Room extends EventEmitter {
|
|
|
49
50
|
on(event: 'trackSwitchedOn', listener: (track: RemoteTrack, publication: RemoteTrackPublication, participant: RemoteParticipant) => void): this;
|
|
50
51
|
on(event: 'trackUnpublished', listener: (publication: RemoteTrackPublication, participant: RemoteParticipant) => void): this;
|
|
51
52
|
on(event: 'trackUnsubscribed', listener: (track: RemoteTrack, publication: RemoteTrackPublication, participant: RemoteParticipant) => void): this;
|
|
53
|
+
on(event: 'trackWarning', listener: (name: string, publication: LocalTrackPublication, participant: LocalParticipant) => void): this;
|
|
54
|
+
on(event: 'trackWarningsCleared', listener: (publication: LocalTrackPublication, participant: LocalParticipant) => void): this;
|
|
52
55
|
}
|
|
@@ -392,6 +392,44 @@ function runPreflight() {
|
|
|
392
392
|
preflight.stop();
|
|
393
393
|
}
|
|
394
394
|
|
|
395
|
+
async function mediaWarnings() {
|
|
396
|
+
let room = await Video.connect('$TOKEN', {
|
|
397
|
+
notifyWarnings: []
|
|
398
|
+
});
|
|
399
|
+
room = await Video.connect('$TOKEN', {
|
|
400
|
+
notifyWarnings: ['recording-media-lost']
|
|
401
|
+
});
|
|
402
|
+
|
|
403
|
+
room.localParticipant.tracks.forEach((publication: Video.LocalTrackPublication) => {
|
|
404
|
+
publication.on('warning', (name: string) => {
|
|
405
|
+
// eslint-disable-next-line no-console
|
|
406
|
+
console.log(name);
|
|
407
|
+
});
|
|
408
|
+
publication.on('warningsCleared', () => {
|
|
409
|
+
// eslint-disable-next-line no-console
|
|
410
|
+
console.log('warningsCleared');
|
|
411
|
+
});
|
|
412
|
+
});
|
|
413
|
+
room.localParticipant.on('trackWarning', (name: string, publication: Video.LocalTrackPublication) => {
|
|
414
|
+
// eslint-disable-next-line no-console
|
|
415
|
+
console.log(name, publication);
|
|
416
|
+
});
|
|
417
|
+
room.localParticipant.on('trackWarningsCleared', (publication: Video.LocalTrackPublication) => {
|
|
418
|
+
// eslint-disable-next-line no-console
|
|
419
|
+
console.log('warningsCleared', publication);
|
|
420
|
+
});
|
|
421
|
+
|
|
422
|
+
room.on('trackWarning', (name: string, publication: Video.LocalTrackPublication, participant: Video.LocalParticipant) => {
|
|
423
|
+
// eslint-disable-next-line no-console
|
|
424
|
+
console.log(name, publication, participant);
|
|
425
|
+
});
|
|
426
|
+
room.on('trackWarningsCleared', (publication: Video.LocalTrackPublication, participant: Video.LocalParticipant) => {
|
|
427
|
+
// eslint-disable-next-line no-console
|
|
428
|
+
console.log('warningsCleared', publication, participant);
|
|
429
|
+
});
|
|
430
|
+
}
|
|
431
|
+
|
|
395
432
|
initRoom();
|
|
396
433
|
unpublishTracks();
|
|
397
434
|
runPreflight();
|
|
435
|
+
mediaWarnings();
|
package/tsdef/types.d.ts
CHANGED
|
@@ -98,6 +98,8 @@ export type BandwidthProfileMode = 'grid' | 'collaboration' | 'presentation';
|
|
|
98
98
|
export type VideoContentPreferencesMode = 'auto' | 'manual';
|
|
99
99
|
export type ClientTrackSwitchOffControl = 'auto' | 'manual';
|
|
100
100
|
|
|
101
|
+
export type NotifyWarning = 'recording-media-lost';
|
|
102
|
+
|
|
101
103
|
/**
|
|
102
104
|
* @deprecated
|
|
103
105
|
*/
|
|
@@ -188,6 +190,7 @@ export interface ConnectOptions {
|
|
|
188
190
|
maxVideoBitrate?: number | null;
|
|
189
191
|
name?: string | null;
|
|
190
192
|
networkQuality?: boolean | NetworkQualityConfiguration;
|
|
193
|
+
notifyWarnings?: Array<NotifyWarning>;
|
|
191
194
|
region?: string;
|
|
192
195
|
preferredAudioCodecs?: Array<AudioCodec | AudioCodecSettings | OpusCodecSettings>;
|
|
193
196
|
preferredVideoCodecs?: Array<VideoCodec | VideoCodecSettings | VP8CodecSettings> | VideoEncodingMode;
|