@webex/plugin-meetings 3.0.0-beta.5 → 3.0.0-beta.7
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.
|
@@ -38,7 +38,8 @@ function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflec
|
|
|
38
38
|
function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !_Reflect$construct) return false; if (_Reflect$construct.sham) return false; if (typeof Proxy === "function") return true; try { Boolean.prototype.valueOf.call(_Reflect$construct(Boolean, [], function () {})); return true; } catch (e) { return false; } }
|
|
39
39
|
|
|
40
40
|
var RemoteMediaEvents = {
|
|
41
|
-
SourceUpdate: _receiveSlot.ReceiveSlotEvents.SourceUpdate
|
|
41
|
+
SourceUpdate: _receiveSlot.ReceiveSlotEvents.SourceUpdate,
|
|
42
|
+
Stopped: 'stopped'
|
|
42
43
|
};
|
|
43
44
|
exports.RemoteMediaEvents = RemoteMediaEvents;
|
|
44
45
|
|
|
@@ -146,6 +147,10 @@ var RemoteMedia = /*#__PURE__*/function (_EventsScope) {
|
|
|
146
147
|
this.cancelMediaRequest(commit);
|
|
147
148
|
(_this$receiveSlot = this.receiveSlot) === null || _this$receiveSlot === void 0 ? void 0 : _this$receiveSlot.removeAllListeners();
|
|
148
149
|
this.receiveSlot = undefined;
|
|
150
|
+
this.emit({
|
|
151
|
+
file: 'multistream/remoteMedia',
|
|
152
|
+
function: 'stop'
|
|
153
|
+
}, RemoteMediaEvents.Stopped, {});
|
|
149
154
|
}
|
|
150
155
|
/**
|
|
151
156
|
* Sends a new media request. This method can only be used for receiver-selected policy,
|
|
@@ -203,7 +208,7 @@ var RemoteMedia = /*#__PURE__*/function (_EventsScope) {
|
|
|
203
208
|
|
|
204
209
|
if (this.receiveSlot) {
|
|
205
210
|
var scope = {
|
|
206
|
-
file: '
|
|
211
|
+
file: 'multistream/remoteMedia',
|
|
207
212
|
function: 'setupEventListeners'
|
|
208
213
|
};
|
|
209
214
|
this.receiveSlot.on(_receiveSlot.ReceiveSlotEvents.SourceUpdate, function (data) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["RemoteMediaEvents","SourceUpdate","ReceiveSlotEvents","getMaxFs","paneSize","maxFs","LoggerProxy","logger","warn","remoteMediaCounter","RemoteMedia","receiveSlot","mediaRequestManager","options","setupEventListeners","id","commit","cancelMediaRequest","removeAllListeners","undefined","csi","mediaRequestId","Error","addRequest","policyInfo","policy","receiveSlots","codecInfo","resolution","codec","cancelRequest","scope","
|
|
1
|
+
{"version":3,"names":["RemoteMediaEvents","SourceUpdate","ReceiveSlotEvents","Stopped","getMaxFs","paneSize","maxFs","LoggerProxy","logger","warn","remoteMediaCounter","RemoteMedia","receiveSlot","mediaRequestManager","options","setupEventListeners","id","commit","cancelMediaRequest","removeAllListeners","undefined","emit","file","function","csi","mediaRequestId","Error","addRequest","policyInfo","policy","receiveSlots","codecInfo","resolution","codec","cancelRequest","scope","on","data","mediaType","memberId","sourceState","stream","EventsScope"],"sources":["remoteMedia.ts"],"sourcesContent":["/* eslint-disable valid-jsdoc */\nimport LoggerProxy from '../common/logs/logger-proxy';\nimport EventsScope from '../common/events/events-scope';\n\nimport {MediaRequestId, MediaRequestManager} from './mediaRequestManager';\nimport {CSI, ReceiveSlot, ReceiveSlotEvents} from './receiveSlot';\n\nexport const RemoteMediaEvents = {\n SourceUpdate: ReceiveSlotEvents.SourceUpdate,\n Stopped: 'stopped',\n};\n\nexport type RemoteVideoResolution =\n | 'thumbnail' // the smallest possible resolution, 90p or less\n | 'very small' // 180p or less\n | 'small' // 360p or less\n | 'medium' // 720p or less\n | 'large' // 1080p or less\n | 'best'; // highest possible resolution\n\n/**\n * Converts pane size into h264 maxFs\n * @param {PaneSize} paneSize\n * @returns {number}\n */\nexport function getMaxFs(paneSize: RemoteVideoResolution): number {\n let maxFs;\n\n switch (paneSize) {\n case 'thumbnail':\n maxFs = 60;\n break;\n case 'very small':\n maxFs = 240;\n break;\n case 'small':\n maxFs = 920;\n break;\n case 'medium':\n maxFs = 3600;\n break;\n case 'large':\n maxFs = 8192;\n break;\n case 'best':\n maxFs = 8192; // for now 'best' is 1080p, so same as 'large'\n break;\n default:\n LoggerProxy.logger.warn(\n `RemoteMedia#getMaxFs --> unsupported paneSize: ${paneSize}, using \"medium\" instead`\n );\n maxFs = 3600;\n }\n\n return maxFs;\n}\n\ntype Options = {\n resolution?: RemoteVideoResolution; // applies only to groups of type MC.MediaType.VideoMain and MC.MediaType.VideoSlides\n};\n\nexport type RemoteMediaId = string;\n\nlet remoteMediaCounter = 0;\n\n/**\n * Class representing a remote audio/video stream.\n *\n * Internally it is associated with a specific receive slot\n * and a media request for it.\n */\nexport class RemoteMedia extends EventsScope {\n private receiveSlot?: ReceiveSlot;\n\n private readonly mediaRequestManager: MediaRequestManager;\n\n private readonly options: Options;\n\n private mediaRequestId?: MediaRequestId;\n\n public readonly id: RemoteMediaId;\n\n /**\n * Constructs RemoteMedia instance\n *\n * @param receiveSlot\n * @param mediaRequestManager\n * @param options\n */\n constructor(\n receiveSlot: ReceiveSlot,\n mediaRequestManager: MediaRequestManager,\n options?: Options\n ) {\n super();\n remoteMediaCounter += 1;\n this.receiveSlot = receiveSlot;\n this.mediaRequestManager = mediaRequestManager;\n this.options = options || {};\n this.setupEventListeners();\n this.id = `RM${remoteMediaCounter}-${this.receiveSlot.id}`;\n }\n\n /**\n * Invalidates the remote media by clearing the reference to a receive slot and\n * cancelling the media request.\n * After this call the remote media is unusable.\n *\n * @param {boolean} commit - whether to commit the cancellation of the media request\n * @internal\n */\n public stop(commit: boolean = true) {\n this.cancelMediaRequest(commit);\n this.receiveSlot?.removeAllListeners();\n this.receiveSlot = undefined;\n this.emit(\n {\n file: 'multistream/remoteMedia',\n function: 'stop',\n },\n RemoteMediaEvents.Stopped,\n {}\n );\n }\n\n /**\n * Sends a new media request. This method can only be used for receiver-selected policy,\n * because only in that policy we have a 1-1 relationship between RemoteMedia and MediaRequest\n * and the request id is then stored in this RemoteMedia instance.\n * For active-speaker policy, the same request is shared among many RemoteMedia instances,\n * so it's managed through RemoteMediaGroup\n *\n * @internal\n */\n public sendMediaRequest(csi: CSI, commit: boolean) {\n if (this.mediaRequestId) {\n this.cancelMediaRequest(false);\n }\n\n if (!this.receiveSlot) {\n throw new Error('sendMediaRequest() called on an invalidated RemoteMedia instance');\n }\n\n this.mediaRequestId = this.mediaRequestManager.addRequest(\n {\n policyInfo: {\n policy: 'receiver-selected',\n csi,\n },\n receiveSlots: [this.receiveSlot],\n codecInfo: this.options.resolution && {\n codec: 'h264',\n maxFs: getMaxFs(this.options.resolution),\n },\n },\n commit\n );\n }\n\n /**\n * @internal\n */\n public cancelMediaRequest(commit: boolean) {\n if (this.mediaRequestId) {\n this.mediaRequestManager.cancelRequest(this.mediaRequestId, commit);\n this.mediaRequestId = undefined;\n }\n }\n\n /**\n * registers event listeners on the receive slot and forwards all the events\n */\n private setupEventListeners() {\n if (this.receiveSlot) {\n const scope = {\n file: 'multistream/remoteMedia',\n function: 'setupEventListeners',\n };\n\n this.receiveSlot.on(ReceiveSlotEvents.SourceUpdate, (data) => {\n this.emit(scope, RemoteMediaEvents.SourceUpdate, data);\n });\n }\n }\n\n /**\n * Getter for mediaType\n */\n public get mediaType() {\n return this.receiveSlot?.mediaType;\n }\n\n /**\n * Getter for memberId\n */\n public get memberId() {\n return this.receiveSlot?.memberId;\n }\n\n /**\n * Getter for csi\n */\n public get csi() {\n return this.receiveSlot?.csi;\n }\n\n /**\n * Getter for source state\n */\n public get sourceState() {\n return this.receiveSlot?.sourceState;\n }\n\n /**\n * Getter for remote media stream\n */\n public get stream() {\n return this.receiveSlot?.stream;\n }\n\n /**\n * @internal\n * @returns {ReceiveSlot}\n */\n public getUnderlyingReceiveSlot() {\n return this.receiveSlot;\n }\n}\n"],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@webex/plugin-meetings",
|
|
3
|
-
"version": "3.0.0-beta.
|
|
3
|
+
"version": "3.0.0-beta.7",
|
|
4
4
|
"description": "",
|
|
5
5
|
"license": "Cisco EULA (https://www.cisco.com/c/en/us/products/end-user-license-agreement.html)",
|
|
6
6
|
"contributors": [
|
|
@@ -28,12 +28,12 @@
|
|
|
28
28
|
]
|
|
29
29
|
},
|
|
30
30
|
"devDependencies": {
|
|
31
|
-
"@webex/plugin-meetings": "3.0.0-beta.
|
|
32
|
-
"@webex/test-helper-chai": "3.0.0-beta.
|
|
33
|
-
"@webex/test-helper-mocha": "3.0.0-beta.
|
|
34
|
-
"@webex/test-helper-mock-webex": "3.0.0-beta.
|
|
35
|
-
"@webex/test-helper-retry": "3.0.0-beta.
|
|
36
|
-
"@webex/test-helper-test-users": "3.0.0-beta.
|
|
31
|
+
"@webex/plugin-meetings": "3.0.0-beta.7",
|
|
32
|
+
"@webex/test-helper-chai": "3.0.0-beta.7",
|
|
33
|
+
"@webex/test-helper-mocha": "3.0.0-beta.7",
|
|
34
|
+
"@webex/test-helper-mock-webex": "3.0.0-beta.7",
|
|
35
|
+
"@webex/test-helper-retry": "3.0.0-beta.7",
|
|
36
|
+
"@webex/test-helper-test-users": "3.0.0-beta.7",
|
|
37
37
|
"chai": "^4.3.4",
|
|
38
38
|
"chai-as-promised": "^7.1.1",
|
|
39
39
|
"jsdom-global": "3.0.2",
|
|
@@ -41,18 +41,18 @@
|
|
|
41
41
|
"typed-emitter": "^2.1.0"
|
|
42
42
|
},
|
|
43
43
|
"dependencies": {
|
|
44
|
-
"@webex/common": "3.0.0-beta.
|
|
44
|
+
"@webex/common": "3.0.0-beta.7",
|
|
45
45
|
"@webex/internal-media-core": "^0.0.17-beta",
|
|
46
|
-
"@webex/internal-plugin-conversation": "3.0.0-beta.
|
|
47
|
-
"@webex/internal-plugin-device": "3.0.0-beta.
|
|
48
|
-
"@webex/internal-plugin-mercury": "3.0.0-beta.
|
|
49
|
-
"@webex/internal-plugin-metrics": "3.0.0-beta.
|
|
50
|
-
"@webex/internal-plugin-support": "3.0.0-beta.
|
|
51
|
-
"@webex/internal-plugin-user": "3.0.0-beta.
|
|
52
|
-
"@webex/plugin-people": "3.0.0-beta.
|
|
53
|
-
"@webex/plugin-rooms": "3.0.0-beta.
|
|
46
|
+
"@webex/internal-plugin-conversation": "3.0.0-beta.7",
|
|
47
|
+
"@webex/internal-plugin-device": "3.0.0-beta.7",
|
|
48
|
+
"@webex/internal-plugin-mercury": "3.0.0-beta.7",
|
|
49
|
+
"@webex/internal-plugin-metrics": "3.0.0-beta.7",
|
|
50
|
+
"@webex/internal-plugin-support": "3.0.0-beta.7",
|
|
51
|
+
"@webex/internal-plugin-user": "3.0.0-beta.7",
|
|
52
|
+
"@webex/plugin-people": "3.0.0-beta.7",
|
|
53
|
+
"@webex/plugin-rooms": "3.0.0-beta.7",
|
|
54
54
|
"@webex/ts-sdp": "^1.0.1",
|
|
55
|
-
"@webex/webex-core": "3.0.0-beta.
|
|
55
|
+
"@webex/webex-core": "3.0.0-beta.7",
|
|
56
56
|
"bowser": "^2.11.0",
|
|
57
57
|
"btoa": "^1.2.1",
|
|
58
58
|
"dotenv": "^4.0.0",
|
|
@@ -7,6 +7,7 @@ import {CSI, ReceiveSlot, ReceiveSlotEvents} from './receiveSlot';
|
|
|
7
7
|
|
|
8
8
|
export const RemoteMediaEvents = {
|
|
9
9
|
SourceUpdate: ReceiveSlotEvents.SourceUpdate,
|
|
10
|
+
Stopped: 'stopped',
|
|
10
11
|
};
|
|
11
12
|
|
|
12
13
|
export type RemoteVideoResolution =
|
|
@@ -112,6 +113,14 @@ export class RemoteMedia extends EventsScope {
|
|
|
112
113
|
this.cancelMediaRequest(commit);
|
|
113
114
|
this.receiveSlot?.removeAllListeners();
|
|
114
115
|
this.receiveSlot = undefined;
|
|
116
|
+
this.emit(
|
|
117
|
+
{
|
|
118
|
+
file: 'multistream/remoteMedia',
|
|
119
|
+
function: 'stop',
|
|
120
|
+
},
|
|
121
|
+
RemoteMediaEvents.Stopped,
|
|
122
|
+
{}
|
|
123
|
+
);
|
|
115
124
|
}
|
|
116
125
|
|
|
117
126
|
/**
|
|
@@ -164,7 +173,7 @@ export class RemoteMedia extends EventsScope {
|
|
|
164
173
|
private setupEventListeners() {
|
|
165
174
|
if (this.receiveSlot) {
|
|
166
175
|
const scope = {
|
|
167
|
-
file: '
|
|
176
|
+
file: 'multistream/remoteMedia',
|
|
168
177
|
function: 'setupEventListeners',
|
|
169
178
|
};
|
|
170
179
|
|
|
@@ -184,8 +184,16 @@ describe('RemoteMedia', () => {
|
|
|
184
184
|
it('cancels media request, unsets the receive slot and removes all the listeners from it', () => {
|
|
185
185
|
const cancelMediaRequestSpy = sinon.spy(remoteMedia, 'cancelMediaRequest');
|
|
186
186
|
|
|
187
|
+
let stoppedListenerCalled = false;
|
|
188
|
+
|
|
189
|
+
remoteMedia.on(RemoteMediaEvents.Stopped, () => {
|
|
190
|
+
stoppedListenerCalled = true;
|
|
191
|
+
});
|
|
192
|
+
|
|
187
193
|
remoteMedia.stop(true);
|
|
188
194
|
|
|
195
|
+
assert.isTrue(stoppedListenerCalled);
|
|
196
|
+
|
|
189
197
|
assert.calledOnce(cancelMediaRequestSpy);
|
|
190
198
|
assert.calledWith(cancelMediaRequestSpy, true);
|
|
191
199
|
|
|
@@ -542,6 +542,64 @@ describe('RemoteMediaManager', () => {
|
|
|
542
542
|
});
|
|
543
543
|
});
|
|
544
544
|
|
|
545
|
+
it('stops all current video remoteMedia instances when switching to new layout', async () => {
|
|
546
|
+
const audioStopStubs = [];
|
|
547
|
+
const videoStopStubs = [];
|
|
548
|
+
|
|
549
|
+
const config = cloneDeep(DefaultTestConfiguration);
|
|
550
|
+
|
|
551
|
+
// start with the stage layout because it has both active speaker and receiver selected panes
|
|
552
|
+
config.video.initialLayoutId = 'Stage';
|
|
553
|
+
|
|
554
|
+
remoteMediaManager = new RemoteMediaManager(
|
|
555
|
+
fakeReceiveSlotManager,
|
|
556
|
+
fakeMediaRequestManagers,
|
|
557
|
+
config
|
|
558
|
+
);
|
|
559
|
+
|
|
560
|
+
// mock all stop() methods for all remote audio objects we get with AudioCreated event
|
|
561
|
+
remoteMediaManager.on(Event.AudioCreated, (audio: RemoteMediaGroup) => {
|
|
562
|
+
audio
|
|
563
|
+
.getRemoteMedia()
|
|
564
|
+
.forEach((remoteAudio) => audioStopStubs.push(sinon.stub(remoteAudio, 'stop')));
|
|
565
|
+
});
|
|
566
|
+
|
|
567
|
+
// mock all stop() methods for all remote video objects we get with VideoLayoutChanged event
|
|
568
|
+
remoteMediaManager.on(Event.VideoLayoutChanged, (layoutInfo: VideoLayoutChangedEventData) => {
|
|
569
|
+
Object.values(layoutInfo.activeSpeakerVideoPanes).forEach((group) =>
|
|
570
|
+
group
|
|
571
|
+
.getRemoteMedia()
|
|
572
|
+
.forEach((remoteMedia) => videoStopStubs.push(sinon.stub(remoteMedia, 'stop')))
|
|
573
|
+
);
|
|
574
|
+
|
|
575
|
+
Object.values(layoutInfo.memberVideoPanes).forEach((pane) => {
|
|
576
|
+
videoStopStubs.push(sinon.stub(pane, 'stop'));
|
|
577
|
+
});
|
|
578
|
+
});
|
|
579
|
+
|
|
580
|
+
await remoteMediaManager.start();
|
|
581
|
+
|
|
582
|
+
// sanity check that we've got all our stop() mocks setup correctly
|
|
583
|
+
assert.strictEqual(audioStopStubs.length, 3);
|
|
584
|
+
assert.strictEqual(videoStopStubs.length, 10); // 10 = 6 thumbnail panes + 4 stage panes
|
|
585
|
+
|
|
586
|
+
// next, we'll change the layout, we don't care about the new video panes from the new layout, so unregister the event listeners
|
|
587
|
+
remoteMediaManager.removeAllListeners();
|
|
588
|
+
|
|
589
|
+
await remoteMediaManager.setLayout('AllEqual');
|
|
590
|
+
|
|
591
|
+
// check that NONE of the audio RemoteMedia instances were stopped
|
|
592
|
+
audioStopStubs.forEach((audioStopStub) => {
|
|
593
|
+
assert.notCalled(audioStopStub);
|
|
594
|
+
});
|
|
595
|
+
|
|
596
|
+
// check that ALL of the video RemoteMedia instances were stopped
|
|
597
|
+
videoStopStubs.forEach((videoStopStub) => {
|
|
598
|
+
assert.calledOnce(videoStopStub);
|
|
599
|
+
assert.calledWith(videoStopStub, false);
|
|
600
|
+
});
|
|
601
|
+
});
|
|
602
|
+
|
|
545
603
|
describe('switching between different receiver selected layouts', () => {
|
|
546
604
|
let fakeSlots: {[key: ReceiveSlotId]: FakeSlot};
|
|
547
605
|
let slotCounter: number;
|