twilio-video 2.26.2 → 2.28.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/CHANGELOG.md +46 -0
- package/README.md +1 -1
- package/dist/twilio-video.js +125 -55
- package/dist/twilio-video.min.js +19 -19
- package/es5/localparticipant.js +3 -1
- package/es5/localparticipant.js.map +1 -1
- package/es5/media/track/localmediatrack.js +21 -9
- package/es5/media/track/localmediatrack.js.map +1 -1
- package/es5/media/track/localvideotrack.js +4 -5
- package/es5/media/track/localvideotrack.js.map +1 -1
- package/es5/media/track/remotevideotrack.js +1 -1
- package/es5/media/track/videoprocessoreventobserver.js +3 -3
- package/es5/media/track/videoprocessoreventobserver.js.map +1 -1
- package/es5/media/track/videotrack.js +88 -22
- package/es5/media/track/videotrack.js.map +1 -1
- package/es5/util/index.js +0 -11
- package/es5/util/index.js.map +1 -1
- package/lib/localparticipant.js +3 -1
- package/lib/media/track/localmediatrack.js +28 -11
- package/lib/media/track/localvideotrack.js +4 -5
- package/lib/media/track/remotevideotrack.js +1 -1
- package/lib/media/track/videoprocessoreventobserver.js +11 -3
- package/lib/media/track/videotrack.js +92 -22
- package/lib/util/index.js +0 -13
- package/package.json +3 -1
- package/tsdef/VideoProcessor.d.ts +4 -1
- package/tsdef/VideoTrack.d.ts +2 -1
- package/tsdef/index.d.ts +1 -0
- package/tsdef/types.d.ts +5 -0
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,52 @@ The Twilio Programmable Video SDKs use [Semantic Versioning](http://www.semver.o
|
|
|
2
2
|
|
|
3
3
|
**Version 1.x reached End of Life on September 8th, 2021.** See the changelog entry [here](https://www.twilio.com/changelog/end-of-life-complete-for-unsupported-versions-of-the-programmable-video-sdk). Support for the 1.x version ended on December 4th, 2020.
|
|
4
4
|
|
|
5
|
+
2.28.0 (September 14, 2023)
|
|
6
|
+
===========================
|
|
7
|
+
|
|
8
|
+
Bug Fixes
|
|
9
|
+
---------
|
|
10
|
+
|
|
11
|
+
- Fixed a bug where a Chrome iOS 17 Participant's audio with Krisp Noise Cancellation did not recover after interacting with a system popup. (VIDEO-13012)
|
|
12
|
+
- Fixed a bug where a Chrome iOS 17 Participant's audio with Krisp Noise Cancellation did not recover after invoking Siri. (VIDEO-13013)
|
|
13
|
+
|
|
14
|
+
2.27.0 (March 21, 2023)
|
|
15
|
+
=======================
|
|
16
|
+
|
|
17
|
+
Changes
|
|
18
|
+
-------
|
|
19
|
+
|
|
20
|
+
`VideoTrack.addProcessor` now works on browsers that support `OffscreenCanvas` as well as `HTMLCanvasElement`. When used with
|
|
21
|
+
[@twilio/video-processors v2.0.0](https://github.com/twilio/twilio-video-processors.js/blob/2.0.0/CHANGELOG.md), the Virtual
|
|
22
|
+
Background feature will work on browsers that supports [WebGL2](https://developer.mozilla.org/en-US/docs/Web/API/WebGL2RenderingContext).
|
|
23
|
+
See [VideoTrack.addProcessor](https://sdk.twilio.com/js/video/releases/2.27.0/docs/VideoTrack.html#addProcessor__anchor) and
|
|
24
|
+
[@twilio/video-processors v2.0.0](https://github.com/twilio/twilio-video-processors.js/blob/2.0.0/CHANGELOG.md) for details.
|
|
25
|
+
|
|
26
|
+
### Example
|
|
27
|
+
|
|
28
|
+
```ts
|
|
29
|
+
import { createLocalVideoTrack } from 'twilio-video';
|
|
30
|
+
import { Pipeline, VirtualBackgroundProcessor } from '@twilio/video-processors';
|
|
31
|
+
|
|
32
|
+
const virtualBackgroundProcessor = new VirtualBackgroundProcessor({
|
|
33
|
+
pipeline: Pipeline.WebGL2,
|
|
34
|
+
// ...otherOptions
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
await virtualBackgroundProcessor.loadModel();
|
|
38
|
+
|
|
39
|
+
const videoTrack = await createLocalVideoTrack({
|
|
40
|
+
width: 640,
|
|
41
|
+
height: 480,
|
|
42
|
+
frameRate: 24
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
videoTrack.addProcessor(processor, {
|
|
46
|
+
inputFrameBufferType: 'video',
|
|
47
|
+
outputFrameBufferContextType: 'webgl2',
|
|
48
|
+
});
|
|
49
|
+
```
|
|
50
|
+
|
|
5
51
|
2.26.2 (February 21, 2023)
|
|
6
52
|
==========================
|
|
7
53
|
|
package/README.md
CHANGED
|
@@ -74,7 +74,7 @@ Releases of twilio-video.js are hosted on a CDN, and you can include these
|
|
|
74
74
|
directly in your web app using a <script> tag.
|
|
75
75
|
|
|
76
76
|
```html
|
|
77
|
-
<script src="//sdk.twilio.com/js/video/releases/2.
|
|
77
|
+
<script src="//sdk.twilio.com/js/video/releases/2.28.0/twilio-video.min.js"></script>
|
|
78
78
|
```
|
|
79
79
|
|
|
80
80
|
Using this method, twilio-video.js will set a browser global:
|
package/dist/twilio-video.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*! twilio-video.js 2.
|
|
1
|
+
/*! twilio-video.js 2.28.0
|
|
2
2
|
|
|
3
3
|
The following license applies to all parts of this software except as
|
|
4
4
|
documented below.
|
|
@@ -2627,7 +2627,9 @@ var LocalParticipant = /** @class */ (function (_super) {
|
|
|
2627
2627
|
* @event LocalParticipant#trackPublicationFailed
|
|
2628
2628
|
*/
|
|
2629
2629
|
/**
|
|
2630
|
-
* A {@link LocalTrack} was successfully published.
|
|
2630
|
+
* A {@link LocalTrack} that was added using {@link LocalParticipant#publishTrack} was successfully published. This event
|
|
2631
|
+
* is not raised for {@link LocalTrack}s added in {@link ConnectOptions}<code>.tracks</code> or auto-created within
|
|
2632
|
+
* <a href="module-twilio-video.html#.connect__anchor"><code>{@link connect}</code></a>.
|
|
2631
2633
|
* @param {LocalTrackPublication} publication - The resulting
|
|
2632
2634
|
* {@link LocalTrackPublication} for the published {@link LocalTrack}
|
|
2633
2635
|
* @event LocalParticipant#trackPublished
|
|
@@ -3593,7 +3595,7 @@ var __extends = (this && this.__extends) || (function () {
|
|
|
3593
3595
|
})();
|
|
3594
3596
|
var getUserMedia = require('../../webrtc').getUserMedia;
|
|
3595
3597
|
var isIOS = require('../../util/browserdetection').isIOS;
|
|
3596
|
-
var _a = require('../../util'), capitalize = _a.capitalize, defer = _a.defer,
|
|
3598
|
+
var _a = require('../../util'), capitalize = _a.capitalize, defer = _a.defer, waitForSometime = _a.waitForSometime, waitForEvent = _a.waitForEvent;
|
|
3597
3599
|
var ILLEGAL_INVOKE = require('../../util/constants').typeErrors.ILLEGAL_INVOKE;
|
|
3598
3600
|
var detectSilentAudio = require('../../util/detectsilentaudio');
|
|
3599
3601
|
var detectSilentVideo = require('../../util/detectsilentvideo');
|
|
@@ -3622,7 +3624,6 @@ function mixinLocalMediaTrack(AudioOrVideoTrack) {
|
|
|
3622
3624
|
function LocalMediaTrack(mediaStreamTrack, options) {
|
|
3623
3625
|
var _this = this;
|
|
3624
3626
|
var workaroundWebKitBug1208516 = isIOS()
|
|
3625
|
-
&& isUserMediaTrack(mediaStreamTrack)
|
|
3626
3627
|
&& typeof document === 'object'
|
|
3627
3628
|
&& typeof document.addEventListener === 'function'
|
|
3628
3629
|
&& typeof document.visibilityState === 'string';
|
|
@@ -3668,6 +3669,9 @@ function mixinLocalMediaTrack(AudioOrVideoTrack) {
|
|
|
3668
3669
|
_isCreatedByCreateLocalTracks: {
|
|
3669
3670
|
value: options.isCreatedByCreateLocalTracks
|
|
3670
3671
|
},
|
|
3672
|
+
_noiseCancellation: {
|
|
3673
|
+
value: options.noiseCancellation || null
|
|
3674
|
+
},
|
|
3671
3675
|
_trackSender: {
|
|
3672
3676
|
value: mediaTrackSender
|
|
3673
3677
|
},
|
|
@@ -3856,9 +3860,16 @@ function mixinLocalMediaTrack(AudioOrVideoTrack) {
|
|
|
3856
3860
|
* @returns {function} Clean up listeners attached by the workaround
|
|
3857
3861
|
*/
|
|
3858
3862
|
function restartWhenInadvertentlyStopped(localMediaTrack) {
|
|
3859
|
-
var log = localMediaTrack._log, kind = localMediaTrack.kind;
|
|
3860
|
-
var detectSilence = {
|
|
3861
|
-
|
|
3863
|
+
var log = localMediaTrack._log, kind = localMediaTrack.kind, noiseCancellation = localMediaTrack._noiseCancellation;
|
|
3864
|
+
var detectSilence = {
|
|
3865
|
+
audio: detectSilentAudio,
|
|
3866
|
+
video: detectSilentVideo
|
|
3867
|
+
}[kind];
|
|
3868
|
+
var getSourceMediaStreamTrack = function () { return noiseCancellation
|
|
3869
|
+
? noiseCancellation.sourceTrack
|
|
3870
|
+
: localMediaTrack.mediaStreamTrack; };
|
|
3871
|
+
var el = localMediaTrack._dummyEl;
|
|
3872
|
+
var mediaStreamTrack = getSourceMediaStreamTrack();
|
|
3862
3873
|
var trackChangeInProgress = null;
|
|
3863
3874
|
function checkSilence() {
|
|
3864
3875
|
// The dummy element is paused, so play it and then detect silence.
|
|
@@ -3873,13 +3884,16 @@ function restartWhenInadvertentlyStopped(localMediaTrack) {
|
|
|
3873
3884
|
}).catch(function (error) {
|
|
3874
3885
|
log.warn('Failed to detect silence:', error);
|
|
3875
3886
|
}).finally(function () {
|
|
3876
|
-
// Pause the dummy element again.
|
|
3877
|
-
|
|
3887
|
+
// Pause the dummy element again, if there is no processed track.
|
|
3888
|
+
if (!localMediaTrack.processedTrack) {
|
|
3889
|
+
el.pause();
|
|
3890
|
+
}
|
|
3878
3891
|
});
|
|
3879
3892
|
}
|
|
3880
3893
|
function shouldReacquireTrack() {
|
|
3881
|
-
var _workaroundWebKitBug1208516Cleanup = localMediaTrack._workaroundWebKitBug1208516Cleanup, isStopped = localMediaTrack.isStopped
|
|
3894
|
+
var _workaroundWebKitBug1208516Cleanup = localMediaTrack._workaroundWebKitBug1208516Cleanup, isStopped = localMediaTrack.isStopped;
|
|
3882
3895
|
var isInadvertentlyStopped = isStopped && !!_workaroundWebKitBug1208516Cleanup;
|
|
3896
|
+
var muted = getSourceMediaStreamTrack().muted;
|
|
3883
3897
|
// NOTE(mmalavalli): Restart the LocalMediaTrack if:
|
|
3884
3898
|
// 1. The app is foregrounded, and
|
|
3885
3899
|
// 2. A restart is not already in progress, and
|
|
@@ -3900,7 +3914,7 @@ function restartWhenInadvertentlyStopped(localMediaTrack) {
|
|
|
3900
3914
|
localMediaTrack._restart().finally(function () {
|
|
3901
3915
|
el = localMediaTrack._dummyEl;
|
|
3902
3916
|
removeMediaStreamTrackListeners();
|
|
3903
|
-
mediaStreamTrack =
|
|
3917
|
+
mediaStreamTrack = getSourceMediaStreamTrack();
|
|
3904
3918
|
addMediaStreamTrackListeners();
|
|
3905
3919
|
trackChangeInProgress.resolve();
|
|
3906
3920
|
trackChangeInProgress = null;
|
|
@@ -4144,7 +4158,6 @@ var isIOS = require('../../util/browserdetection').isIOS;
|
|
|
4144
4158
|
var detectSilentVideo = require('../../util/detectsilentvideo');
|
|
4145
4159
|
var mixinLocalMediaTrack = require('./localmediatrack');
|
|
4146
4160
|
var VideoTrack = require('./videotrack');
|
|
4147
|
-
var isUserMediaTrack = require('../../util').isUserMediaTrack;
|
|
4148
4161
|
var LocalMediaVideoTrack = mixinLocalMediaTrack(VideoTrack);
|
|
4149
4162
|
/**
|
|
4150
4163
|
* A {@link LocalVideoTrack} is a {@link VideoTrack} representing video that
|
|
@@ -4178,7 +4191,6 @@ var LocalVideoTrack = /** @class */ (function (_super) {
|
|
|
4178
4191
|
var _this = this;
|
|
4179
4192
|
options = Object.assign({
|
|
4180
4193
|
workaroundSilentLocalVideo: isIOS()
|
|
4181
|
-
&& isUserMediaTrack(mediaStreamTrack)
|
|
4182
4194
|
&& typeof document !== 'undefined'
|
|
4183
4195
|
&& typeof document.createElement === 'function'
|
|
4184
4196
|
}, options);
|
|
@@ -4232,8 +4244,8 @@ var LocalVideoTrack = /** @class */ (function (_super) {
|
|
|
4232
4244
|
};
|
|
4233
4245
|
/**
|
|
4234
4246
|
* Add a {@link VideoProcessor} to allow for custom processing of video frames belonging to a VideoTrack.
|
|
4235
|
-
* Only Chrome supports this as of now. Calling this API from a non-supported browser will result in a log warning.
|
|
4236
4247
|
* @param {VideoProcessor} processor - The {@link VideoProcessor} to use.
|
|
4248
|
+
* @param {AddProcessorOptions} [options] - {@link AddProcessorOptions} to provide.
|
|
4237
4249
|
* @returns {this}
|
|
4238
4250
|
* @example
|
|
4239
4251
|
* class GrayScaleProcessor {
|
|
@@ -4433,9 +4445,10 @@ function workaroundSilentLocalVideo(localVideoTrack, doc) {
|
|
|
4433
4445
|
}).catch(function (error) {
|
|
4434
4446
|
log.warn('Failed to detect silence and restart:', error);
|
|
4435
4447
|
}).finally(function () {
|
|
4436
|
-
// If silent frames were not detected, then pause the dummy element again
|
|
4448
|
+
// If silent frames were not detected, then pause the dummy element again,
|
|
4449
|
+
// if there is no processed track.
|
|
4437
4450
|
el = localVideoTrack._dummyEl;
|
|
4438
|
-
if (el && !el.paused) {
|
|
4451
|
+
if (el && !el.paused && !localVideoTrack.processedTrack) {
|
|
4439
4452
|
el.pause();
|
|
4440
4453
|
}
|
|
4441
4454
|
// Reset the unmute handler.
|
|
@@ -4491,7 +4504,7 @@ function workaroundSilentLocalVideo(localVideoTrack, doc) {
|
|
|
4491
4504
|
*/
|
|
4492
4505
|
module.exports = LocalVideoTrack;
|
|
4493
4506
|
|
|
4494
|
-
},{"../../util
|
|
4507
|
+
},{"../../util/browserdetection":123,"../../util/detectsilentvideo":127,"./localmediatrack":24,"./videotrack":43}],27:[function(require,module,exports){
|
|
4495
4508
|
'use strict';
|
|
4496
4509
|
var __extends = (this && this.__extends) || (function () {
|
|
4497
4510
|
var extendStatics = function (d, b) {
|
|
@@ -6351,8 +6364,8 @@ var RemoteVideoTrack = /** @class */ (function (_super) {
|
|
|
6351
6364
|
* Add a {@link VideoProcessor} to allow for custom processing of video frames belonging to a VideoTrack.
|
|
6352
6365
|
* When a Participant un-publishes and re-publishes a VideoTrack, a new RemoteVideoTrack is created and
|
|
6353
6366
|
* any VideoProcessors attached to the previous RemoteVideoTrack would have to be re-added again.
|
|
6354
|
-
* Only Chrome supports this as of now. Calling this API from a non-supported browser will result in a log warning.
|
|
6355
6367
|
* @param {VideoProcessor} processor - The {@link VideoProcessor} to use.
|
|
6368
|
+
* @param {AddProcessorOptions} [options] - {@link AddProcessorOptions} to provide.
|
|
6356
6369
|
* @returns {this}
|
|
6357
6370
|
* @example
|
|
6358
6371
|
* class GrayScaleProcessor {
|
|
@@ -7019,10 +7032,10 @@ var VideoProcessorEventObserver = /** @class */ (function (_super) {
|
|
|
7019
7032
|
if (!this._processorInfo) {
|
|
7020
7033
|
return {};
|
|
7021
7034
|
}
|
|
7022
|
-
var _a = this._processorInfo, processor = _a.processor, captureHeight = _a.captureHeight, captureWidth = _a.captureWidth, inputFrameRate = _a.inputFrameRate, isRemoteVideoTrack = _a.isRemoteVideoTrack;
|
|
7023
|
-
var data = { captureHeight: captureHeight, captureWidth: captureWidth, inputFrameRate: inputFrameRate, isRemoteVideoTrack: isRemoteVideoTrack };
|
|
7035
|
+
var _a = this._processorInfo, processor = _a.processor, captureHeight = _a.captureHeight, captureWidth = _a.captureWidth, inputFrameRate = _a.inputFrameRate, isRemoteVideoTrack = _a.isRemoteVideoTrack, inputFrameBufferType = _a.inputFrameBufferType, outputFrameBufferContextType = _a.outputFrameBufferContextType;
|
|
7036
|
+
var data = { captureHeight: captureHeight, captureWidth: captureWidth, inputFrameRate: inputFrameRate, isRemoteVideoTrack: isRemoteVideoTrack, inputFrameBufferType: inputFrameBufferType, outputFrameBufferContextType: outputFrameBufferContextType };
|
|
7024
7037
|
data.name = processor._name || 'VideoProcessor';
|
|
7025
|
-
['assetsPath', 'blurFilterRadius', 'fitType', 'isSimdEnabled', 'maskBlurRadius', 'version'].forEach(function (prop) {
|
|
7038
|
+
['assetsPath', 'blurFilterRadius', 'debounce', 'fitType', 'isSimdEnabled', 'maskBlurRadius', 'pipeline', 'version'].forEach(function (prop) {
|
|
7026
7039
|
var val = processor["_" + prop];
|
|
7027
7040
|
if (typeof val !== 'undefined') {
|
|
7028
7041
|
data[prop] = val;
|
|
@@ -7160,6 +7173,10 @@ var VideoTrack = /** @class */ (function (_super) {
|
|
|
7160
7173
|
value: null,
|
|
7161
7174
|
writable: true,
|
|
7162
7175
|
},
|
|
7176
|
+
_processorOptions: {
|
|
7177
|
+
value: {},
|
|
7178
|
+
writable: true,
|
|
7179
|
+
},
|
|
7163
7180
|
_unmuteHandler: {
|
|
7164
7181
|
value: null,
|
|
7165
7182
|
writable: true
|
|
@@ -7251,18 +7268,21 @@ var VideoTrack = /** @class */ (function (_super) {
|
|
|
7251
7268
|
var _a = _this.mediaStreamTrack.getSettings(), _b = _a.width, width = _b === void 0 ? 0 : _b, _c = _a.height, height = _c === void 0 ? 0 : _c;
|
|
7252
7269
|
// Setting the canvas' dimension triggers a redraw.
|
|
7253
7270
|
// Only set it if it has changed.
|
|
7254
|
-
if (_this.
|
|
7255
|
-
_this.
|
|
7256
|
-
_this.
|
|
7257
|
-
|
|
7258
|
-
|
|
7259
|
-
|
|
7271
|
+
if (_this._outputFrame && _this._outputFrame.width !== width) {
|
|
7272
|
+
_this._outputFrame.width = width;
|
|
7273
|
+
_this._outputFrame.height = height;
|
|
7274
|
+
}
|
|
7275
|
+
if (_this._inputFrame) {
|
|
7276
|
+
if (_this._inputFrame.width !== width) {
|
|
7277
|
+
_this._inputFrame.width = width;
|
|
7278
|
+
_this._inputFrame.height = height;
|
|
7260
7279
|
}
|
|
7280
|
+
_this._inputFrame.getContext('2d').drawImage(_this._dummyEl, 0, 0, width, height);
|
|
7261
7281
|
}
|
|
7262
|
-
_this._inputFrame.getContext('2d').drawImage(_this._dummyEl, 0, 0, width, height);
|
|
7263
7282
|
var result = null;
|
|
7264
7283
|
try {
|
|
7265
|
-
|
|
7284
|
+
var input = _this._processorOptions.inputFrameBufferType === 'video' ? _this._dummyEl : _this._inputFrame;
|
|
7285
|
+
result = _this.processor.processFrame(input, _this._outputFrame);
|
|
7266
7286
|
}
|
|
7267
7287
|
catch (ex) {
|
|
7268
7288
|
_this._log.debug('Exception detected after calling processFrame.', ex);
|
|
@@ -7270,7 +7290,9 @@ var VideoTrack = /** @class */ (function (_super) {
|
|
|
7270
7290
|
((result instanceof Promise) ? result : Promise.resolve(result))
|
|
7271
7291
|
.then(function () {
|
|
7272
7292
|
if (_this._outputFrame) {
|
|
7273
|
-
_this.processedTrack.requestFrame
|
|
7293
|
+
if (typeof _this.processedTrack.requestFrame === 'function') {
|
|
7294
|
+
_this.processedTrack.requestFrame();
|
|
7295
|
+
}
|
|
7274
7296
|
_this._processorEventObserver.emit('stats');
|
|
7275
7297
|
}
|
|
7276
7298
|
})
|
|
@@ -7313,8 +7335,9 @@ var VideoTrack = /** @class */ (function (_super) {
|
|
|
7313
7335
|
VideoTrack.prototype._restartProcessor = function () {
|
|
7314
7336
|
var processor = this.processor;
|
|
7315
7337
|
if (processor) {
|
|
7338
|
+
var processorOptions = Object.assign({}, this._processorOptions);
|
|
7316
7339
|
this.removeProcessor(processor);
|
|
7317
|
-
this.addProcessor(processor);
|
|
7340
|
+
this.addProcessor(processor, processorOptions);
|
|
7318
7341
|
}
|
|
7319
7342
|
};
|
|
7320
7343
|
/**
|
|
@@ -7329,8 +7352,8 @@ var VideoTrack = /** @class */ (function (_super) {
|
|
|
7329
7352
|
};
|
|
7330
7353
|
/**
|
|
7331
7354
|
* Add a {@link VideoProcessor} to allow for custom processing of video frames belonging to a VideoTrack.
|
|
7332
|
-
* Only Chrome supports this as of now. Calling this API from a non-supported browser will result in a log warning.
|
|
7333
7355
|
* @param {VideoProcessor} processor - The {@link VideoProcessor} to use.
|
|
7356
|
+
* @param {AddProcessorOptions} [options] - {@link AddProcessorOptions} to provide.
|
|
7334
7357
|
* @returns {this}
|
|
7335
7358
|
* @example
|
|
7336
7359
|
* class GrayScaleProcessor {
|
|
@@ -7348,11 +7371,8 @@ var VideoTrack = /** @class */ (function (_super) {
|
|
|
7348
7371
|
* videoTrack.addProcessor(new GrayScaleProcessor(100));
|
|
7349
7372
|
* });
|
|
7350
7373
|
*/
|
|
7351
|
-
VideoTrack.prototype.addProcessor = function (processor) {
|
|
7374
|
+
VideoTrack.prototype.addProcessor = function (processor, options) {
|
|
7352
7375
|
var _this = this;
|
|
7353
|
-
if (typeof OffscreenCanvas !== 'function') {
|
|
7354
|
-
return this._log.warn('Adding a VideoProcessor is not supported in this browser.');
|
|
7355
|
-
}
|
|
7356
7376
|
if (!processor || typeof processor.processFrame !== 'function') {
|
|
7357
7377
|
throw new Error('Received an invalid VideoProcessor from addProcessor.');
|
|
7358
7378
|
}
|
|
@@ -7376,12 +7396,46 @@ var VideoTrack = /** @class */ (function (_super) {
|
|
|
7376
7396
|
};
|
|
7377
7397
|
this.mediaStreamTrack.addEventListener('unmute', this._unmuteHandler);
|
|
7378
7398
|
}
|
|
7379
|
-
|
|
7380
|
-
this.
|
|
7399
|
+
this._processorOptions = options || {};
|
|
7400
|
+
var _a = this._processorOptions, inputFrameBufferType = _a.inputFrameBufferType, outputFrameBufferContextType = _a.outputFrameBufferContextType;
|
|
7401
|
+
if (typeof OffscreenCanvas === 'undefined' && inputFrameBufferType === 'offscreencanvas') {
|
|
7402
|
+
throw new Error('OffscreenCanvas is not supported by this browser.');
|
|
7403
|
+
}
|
|
7404
|
+
if (inputFrameBufferType && inputFrameBufferType !== 'video' && inputFrameBufferType !== 'canvas' && inputFrameBufferType !== 'offscreencanvas') {
|
|
7405
|
+
throw new Error("Invalid inputFrameBufferType of " + inputFrameBufferType);
|
|
7406
|
+
}
|
|
7407
|
+
if (!inputFrameBufferType) {
|
|
7408
|
+
inputFrameBufferType = typeof OffscreenCanvas === 'undefined' ? 'canvas' : 'offscreencanvas';
|
|
7409
|
+
}
|
|
7410
|
+
var _b = this.mediaStreamTrack.getSettings(), _c = _b.width, width = _c === void 0 ? 0 : _c, _d = _b.height, height = _d === void 0 ? 0 : _d, _e = _b.frameRate, frameRate = _e === void 0 ? DEFAULT_FRAME_RATE : _e;
|
|
7411
|
+
if (inputFrameBufferType === 'offscreencanvas') {
|
|
7412
|
+
this._inputFrame = new OffscreenCanvas(width, height);
|
|
7413
|
+
}
|
|
7414
|
+
if (inputFrameBufferType === 'canvas') {
|
|
7415
|
+
this._inputFrame = document.createElement('canvas');
|
|
7416
|
+
}
|
|
7417
|
+
if (this._inputFrame) {
|
|
7418
|
+
this._inputFrame.width = width;
|
|
7419
|
+
this._inputFrame.height = height;
|
|
7420
|
+
}
|
|
7381
7421
|
this._outputFrame = document.createElement('canvas');
|
|
7382
7422
|
this._outputFrame.width = width;
|
|
7383
7423
|
this._outputFrame.height = height;
|
|
7384
|
-
|
|
7424
|
+
// NOTE(csantos): Initialize the rendering context for future renders. This also ensures
|
|
7425
|
+
// that the correct type is used and on Firefox, it throws an exception if you try to capture
|
|
7426
|
+
// frames prior calling getContext https://bugzilla.mozilla.org/show_bug.cgi?id=1572422
|
|
7427
|
+
outputFrameBufferContextType = outputFrameBufferContextType || '2d';
|
|
7428
|
+
var ctx = this._outputFrame.getContext(outputFrameBufferContextType);
|
|
7429
|
+
if (!ctx) {
|
|
7430
|
+
throw new Error("Cannot get outputFrameBufferContextType: " + outputFrameBufferContextType + ".");
|
|
7431
|
+
}
|
|
7432
|
+
// NOTE(csantos): Zero FPS means we can control when to render the next frame by calling requestFrame.
|
|
7433
|
+
// Some browsers such as Firefox doesn't support requestFrame so we will use default, which is an undefined value.
|
|
7434
|
+
// This means, the browser will use the highest FPS available.
|
|
7435
|
+
var targetFps = typeof CanvasCaptureMediaStreamTrack !== 'undefined' && CanvasCaptureMediaStreamTrack.prototype &&
|
|
7436
|
+
// eslint-disable-next-line
|
|
7437
|
+
typeof CanvasCaptureMediaStreamTrack.prototype.requestFrame === 'function' ? 0 : undefined;
|
|
7438
|
+
this.processedTrack = this._outputFrame.captureStream(targetFps).getTracks()[0];
|
|
7385
7439
|
this.processedTrack.enabled = this.mediaStreamTrack.enabled;
|
|
7386
7440
|
this.processor = processor;
|
|
7387
7441
|
this._processorEventObserver.emit('add', {
|
|
@@ -7389,7 +7443,9 @@ var VideoTrack = /** @class */ (function (_super) {
|
|
|
7389
7443
|
captureHeight: height,
|
|
7390
7444
|
captureWidth: width,
|
|
7391
7445
|
inputFrameRate: frameRate,
|
|
7392
|
-
isRemoteVideoTrack: this.toString().includes('RemoteVideoTrack')
|
|
7446
|
+
isRemoteVideoTrack: this.toString().includes('RemoteVideoTrack'),
|
|
7447
|
+
inputFrameBufferType: inputFrameBufferType,
|
|
7448
|
+
outputFrameBufferContextType: outputFrameBufferContextType
|
|
7393
7449
|
});
|
|
7394
7450
|
this._updateElementsMediaStreamTrack();
|
|
7395
7451
|
this._captureFrames();
|
|
@@ -7526,12 +7582,11 @@ var VideoTrack = /** @class */ (function (_super) {
|
|
|
7526
7582
|
this._log.debug('Removing VideoProcessor from the VideoTrack', processor);
|
|
7527
7583
|
clearTimeout(this._captureTimeoutId);
|
|
7528
7584
|
this.mediaStreamTrack.removeEventListener('unmute', this._unmuteHandler);
|
|
7585
|
+
this._processorOptions = {};
|
|
7529
7586
|
this._unmuteHandler = null;
|
|
7530
7587
|
this._isCapturing = false;
|
|
7531
7588
|
this.processor = null;
|
|
7532
7589
|
this.processedTrack = null;
|
|
7533
|
-
this._inputFrame.getContext('2d').clearRect(0, 0, this._inputFrame.width, this._inputFrame.height);
|
|
7534
|
-
this._outputFrame.getContext('2d').clearRect(0, 0, this._outputFrame.width, this._outputFrame.height);
|
|
7535
7590
|
this._inputFrame = null;
|
|
7536
7591
|
this._outputFrame = null;
|
|
7537
7592
|
this._updateElementsMediaStreamTrack();
|
|
@@ -7565,7 +7620,7 @@ function dimensionsChanged(track, elem) {
|
|
|
7565
7620
|
* Any exception raised (either synchronously or asynchronously) in `processFrame` will result in the frame being dropped.
|
|
7566
7621
|
* This callback has the following signature:<br/><br/>
|
|
7567
7622
|
* <code>processFrame(</code><br/>
|
|
7568
|
-
* <code>inputFrameBuffer: OffscreenCanvas,</code><br/>
|
|
7623
|
+
* <code>inputFrameBuffer: OffscreenCanvas | HTMLCanvasElement | HTMLVideoElement,</code><br/>
|
|
7569
7624
|
* <code>outputFrameBuffer: HTMLCanvasElement</code><br/>
|
|
7570
7625
|
* <code>): Promise<void> | void;</code>
|
|
7571
7626
|
*
|
|
@@ -7581,6 +7636,30 @@ function dimensionsChanged(track, elem) {
|
|
|
7581
7636
|
* }
|
|
7582
7637
|
* }
|
|
7583
7638
|
*/
|
|
7639
|
+
/**
|
|
7640
|
+
* Possible options to provide to {@link LocalVideoTrack#addProcessor} and {@link RemoteVideoTrack#addProcessor}.
|
|
7641
|
+
* @typedef {object} AddProcessorOptions
|
|
7642
|
+
* @property {string} [inputFrameBufferType="offscreencanvas"] - This option allows you to specify what kind of input you want to receive in your
|
|
7643
|
+
* Video Processor. The default is `offscreencanvas` and will fallback to a regular `canvas` if the browser does not support it.
|
|
7644
|
+
* Possible values include the following.
|
|
7645
|
+
* <br/>
|
|
7646
|
+
* <br/>
|
|
7647
|
+
* `offscreencanvas` - Your Video Processor will receive an [OffscreenCanvas](https://developer.mozilla.org/en-US/docs/Web/API/OffscreenCanvas)
|
|
7648
|
+
* which is good for canvas-related processing that can be rendered off screen.
|
|
7649
|
+
* <br/>
|
|
7650
|
+
* <br/>
|
|
7651
|
+
* `canvas` - Your Video Processor will receive an [HTMLCanvasElement](https://developer.mozilla.org/en-US/docs/Web/API/HTMLCanvasElement).
|
|
7652
|
+
* This is recommended on browsers that doesn't support `OffscreenCanvas`, or if you need to render the frame on the screen.
|
|
7653
|
+
* <br/>
|
|
7654
|
+
* <br/>
|
|
7655
|
+
* `video` - Your Video Processor will receive an [HTMLVideoElement](https://developer.mozilla.org/en-US/docs/Web/API/HTMLVideoElement).
|
|
7656
|
+
* Use this option if you are processing the frame using WebGL or if you only need to [draw](https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/drawImage)
|
|
7657
|
+
* the frame directly to your output canvas.
|
|
7658
|
+
* @property {string} [outputFrameBufferContextType="2d"] - The SDK needs the [context type](https://developer.mozilla.org/en-US/docs/Web/API/HTMLCanvasElement/getContext)
|
|
7659
|
+
* that your Video Processor uses in order to properly generate the processed track. For example, if your Video Processor uses WebGL2 (`canvas.getContext('webgl2')`),
|
|
7660
|
+
* you should set `outputFrameBufferContextType` to `webgl2`. Or if you're using Canvas 2D processing (`canvas.getContext('2d')`),
|
|
7661
|
+
* you should set `outputFrameBufferContextType` to `2d`.
|
|
7662
|
+
*/
|
|
7584
7663
|
/**
|
|
7585
7664
|
* The {@link VideoTrack}'s dimensions changed.
|
|
7586
7665
|
* @param {VideoTrack} track - The {@link VideoTrack} whose dimensions changed
|
|
@@ -22595,16 +22674,6 @@ function isChromeScreenShareTrack(track) {
|
|
|
22595
22674
|
// we will check for label that starts with "screen:D" where D being a digit.
|
|
22596
22675
|
return util.guessBrowser() === 'chrome' && track.kind === 'video' && 'displaySurface' in track.getSettings();
|
|
22597
22676
|
}
|
|
22598
|
-
/**
|
|
22599
|
-
* returns true if given MediaStreamTrack is a user media track
|
|
22600
|
-
* @private
|
|
22601
|
-
* @param {MediaStreamTrack} track
|
|
22602
|
-
* @returns {boolean}
|
|
22603
|
-
*/
|
|
22604
|
-
function isUserMediaTrack(track) {
|
|
22605
|
-
// NOTE(mpatwardhan): tracks obtained from getUserMedia have a deviceId in its settings.
|
|
22606
|
-
return typeof track.getSettings().deviceId === 'string';
|
|
22607
|
-
}
|
|
22608
22677
|
/**
|
|
22609
22678
|
* Returns a promise that resolve after timeoutMS have passed.
|
|
22610
22679
|
* @param {number} timeoutMS - time to wait in milliseconds.
|
|
@@ -22660,7 +22729,6 @@ exports.trackPublicationClass = trackPublicationClass;
|
|
|
22660
22729
|
exports.valueToJSON = valueToJSON;
|
|
22661
22730
|
exports.withJitter = withJitter;
|
|
22662
22731
|
exports.isChromeScreenShareTrack = isChromeScreenShareTrack;
|
|
22663
|
-
exports.isUserMediaTrack = isUserMediaTrack;
|
|
22664
22732
|
exports.waitForSometime = waitForSometime;
|
|
22665
22733
|
exports.waitForEvent = waitForEvent;
|
|
22666
22734
|
|
|
@@ -30083,7 +30151,7 @@ module.exports={
|
|
|
30083
30151
|
"name": "twilio-video",
|
|
30084
30152
|
"title": "Twilio Video",
|
|
30085
30153
|
"description": "Twilio Video JavaScript Library",
|
|
30086
|
-
"version": "2.
|
|
30154
|
+
"version": "2.28.0",
|
|
30087
30155
|
"homepage": "https://twilio.com",
|
|
30088
30156
|
"author": "Mark Andrus Roberts <mroberts@twilio.com>",
|
|
30089
30157
|
"contributors": [
|
|
@@ -30105,6 +30173,8 @@ module.exports={
|
|
|
30105
30173
|
},
|
|
30106
30174
|
"devDependencies": {
|
|
30107
30175
|
"@babel/core": "^7.14.2",
|
|
30176
|
+
"@babel/plugin-proposal-class-properties": "^7.18.6",
|
|
30177
|
+
"@babel/plugin-proposal-object-rest-spread": "^7.20.7",
|
|
30108
30178
|
"@babel/preset-env": "^7.14.2",
|
|
30109
30179
|
"@babel/preset-typescript": "^7.13.0",
|
|
30110
30180
|
"@types/express": "^4.11.0",
|