@stream-io/video-client 1.0.0 → 1.0.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 +14 -0
- package/dist/index.browser.es.js +332 -48
- package/dist/index.browser.es.js.map +1 -1
- package/dist/index.cjs.js +332 -48
- package/dist/index.cjs.js.map +1 -1
- package/dist/index.es.js +332 -48
- package/dist/index.es.js.map +1 -1
- package/dist/src/devices/InputMediaDeviceManager.d.ts +4 -5
- package/dist/src/devices/InputMediaDeviceManagerState.d.ts +14 -0
- package/dist/src/events/participant.d.ts +5 -1
- package/dist/src/gen/video/sfu/event/events.d.ts +71 -1
- package/dist/src/gen/video/sfu/models/models.d.ts +70 -0
- package/package.json +1 -1
- package/src/Call.ts +2 -12
- package/src/devices/CameraManager.ts +2 -2
- package/src/devices/InputMediaDeviceManager.ts +58 -36
- package/src/devices/InputMediaDeviceManagerState.ts +25 -0
- package/src/events/__tests__/participant.test.ts +28 -1
- package/src/events/callEventHandlers.ts +2 -0
- package/src/events/participant.ts +12 -0
- package/src/gen/video/sfu/event/events.ts +284 -0
- package/src/gen/video/sfu/models/models.ts +70 -0
- package/src/rtc/Dispatcher.ts +2 -0
- package/src/store/CallState.ts +3 -0
- package/src/store/__tests__/CallState.test.ts +9 -1
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,20 @@
|
|
|
2
2
|
|
|
3
3
|
This file was generated using [@jscutlery/semver](https://github.com/jscutlery/semver).
|
|
4
4
|
|
|
5
|
+
### [1.0.2](https://github.com/GetStream/stream-video-js/compare/@stream-io/video-client-1.0.1...@stream-io/video-client-1.0.2) (2024-05-13)
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
### Bug Fixes
|
|
9
|
+
|
|
10
|
+
* optimistically toggle device status ([#1342](https://github.com/GetStream/stream-video-js/issues/1342)) ([2e4e470](https://github.com/GetStream/stream-video-js/commit/2e4e470347fce7c7499dd21a931e5dec74bf9618))
|
|
11
|
+
|
|
12
|
+
### [1.0.1](https://github.com/GetStream/stream-video-js/compare/@stream-io/video-client-1.0.0...@stream-io/video-client-1.0.1) (2024-05-07)
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
### Bug Fixes
|
|
16
|
+
|
|
17
|
+
* **state:** handle participantUpdated event ([#1341](https://github.com/GetStream/stream-video-js/issues/1341)) ([96cb99f](https://github.com/GetStream/stream-video-js/commit/96cb99fe2b661e3f4899a7c16b4159cad7a085c6))
|
|
18
|
+
|
|
5
19
|
## [1.0.0](https://github.com/GetStream/stream-video-js/compare/@stream-io/video-client-0.8.0...@stream-io/video-client-1.0.0) (2024-05-07)
|
|
6
20
|
|
|
7
21
|
|
package/dist/index.browser.es.js
CHANGED
|
@@ -933,6 +933,9 @@ var TrackUnpublishReason;
|
|
|
933
933
|
TrackUnpublishReason[TrackUnpublishReason["MODERATION"] = 3] = "MODERATION";
|
|
934
934
|
})(TrackUnpublishReason || (TrackUnpublishReason = {}));
|
|
935
935
|
/**
|
|
936
|
+
* GoAwayReason represents the reason for the SFU to
|
|
937
|
+
* disconnect the client.
|
|
938
|
+
*
|
|
936
939
|
* @generated from protobuf enum stream.video.sfu.models.GoAwayReason
|
|
937
940
|
*/
|
|
938
941
|
var GoAwayReason;
|
|
@@ -950,6 +953,75 @@ var GoAwayReason;
|
|
|
950
953
|
*/
|
|
951
954
|
GoAwayReason[GoAwayReason["REBALANCE"] = 2] = "REBALANCE";
|
|
952
955
|
})(GoAwayReason || (GoAwayReason = {}));
|
|
956
|
+
/**
|
|
957
|
+
* CallEndedReason represents the reason for the call to end.
|
|
958
|
+
*
|
|
959
|
+
* @generated from protobuf enum stream.video.sfu.models.CallEndedReason
|
|
960
|
+
*/
|
|
961
|
+
var CallEndedReason;
|
|
962
|
+
(function (CallEndedReason) {
|
|
963
|
+
/**
|
|
964
|
+
* @generated from protobuf enum value: CALL_ENDED_REASON_UNSPECIFIED = 0;
|
|
965
|
+
*/
|
|
966
|
+
CallEndedReason[CallEndedReason["UNSPECIFIED"] = 0] = "UNSPECIFIED";
|
|
967
|
+
/**
|
|
968
|
+
* @generated from protobuf enum value: CALL_ENDED_REASON_ENDED = 1;
|
|
969
|
+
*/
|
|
970
|
+
CallEndedReason[CallEndedReason["ENDED"] = 1] = "ENDED";
|
|
971
|
+
/**
|
|
972
|
+
* @generated from protobuf enum value: CALL_ENDED_REASON_LIVE_ENDED = 2;
|
|
973
|
+
*/
|
|
974
|
+
CallEndedReason[CallEndedReason["LIVE_ENDED"] = 2] = "LIVE_ENDED";
|
|
975
|
+
/**
|
|
976
|
+
* @generated from protobuf enum value: CALL_ENDED_REASON_KICKED = 3;
|
|
977
|
+
*/
|
|
978
|
+
CallEndedReason[CallEndedReason["KICKED"] = 3] = "KICKED";
|
|
979
|
+
})(CallEndedReason || (CallEndedReason = {}));
|
|
980
|
+
/**
|
|
981
|
+
* WebsocketReconnectStrategy defines the ws strategies available for handling reconnections.
|
|
982
|
+
*
|
|
983
|
+
* @generated from protobuf enum stream.video.sfu.models.WebsocketReconnectStrategy
|
|
984
|
+
*/
|
|
985
|
+
var WebsocketReconnectStrategy;
|
|
986
|
+
(function (WebsocketReconnectStrategy) {
|
|
987
|
+
/**
|
|
988
|
+
* @generated from protobuf enum value: WEBSOCKET_RECONNECT_STRATEGY_UNSPECIFIED = 0;
|
|
989
|
+
*/
|
|
990
|
+
WebsocketReconnectStrategy[WebsocketReconnectStrategy["UNSPECIFIED"] = 0] = "UNSPECIFIED";
|
|
991
|
+
/**
|
|
992
|
+
* Sent after reaching the maximum reconnection attempts, leading to permanent disconnect.
|
|
993
|
+
*
|
|
994
|
+
* @generated from protobuf enum value: WEBSOCKET_RECONNECT_STRATEGY_DISCONNECT = 1;
|
|
995
|
+
*/
|
|
996
|
+
WebsocketReconnectStrategy[WebsocketReconnectStrategy["DISCONNECT"] = 1] = "DISCONNECT";
|
|
997
|
+
/**
|
|
998
|
+
* SDK should maintaining existing publisher/subscriber pc instances
|
|
999
|
+
* and establish a new WebSocket connection.
|
|
1000
|
+
*
|
|
1001
|
+
* @generated from protobuf enum value: WEBSOCKET_RECONNECT_STRATEGY_FAST = 2;
|
|
1002
|
+
*/
|
|
1003
|
+
WebsocketReconnectStrategy[WebsocketReconnectStrategy["FAST"] = 2] = "FAST";
|
|
1004
|
+
/**
|
|
1005
|
+
* SDK should drop existing pc instances and creates a fresh WebSocket connection,
|
|
1006
|
+
* ensuring a clean state for the reconnection.
|
|
1007
|
+
*
|
|
1008
|
+
* @generated from protobuf enum value: WEBSOCKET_RECONNECT_STRATEGY_CLEAN = 3;
|
|
1009
|
+
*/
|
|
1010
|
+
WebsocketReconnectStrategy[WebsocketReconnectStrategy["CLEAN"] = 3] = "CLEAN";
|
|
1011
|
+
/**
|
|
1012
|
+
* SDK should obtain new credentials from the coordinator, drops existing pc instances, and initializes
|
|
1013
|
+
* a completely new WebSocket connection, ensuring a comprehensive reset.
|
|
1014
|
+
*
|
|
1015
|
+
* @generated from protobuf enum value: WEBSOCKET_RECONNECT_STRATEGY_FULL = 4;
|
|
1016
|
+
*/
|
|
1017
|
+
WebsocketReconnectStrategy[WebsocketReconnectStrategy["FULL"] = 4] = "FULL";
|
|
1018
|
+
/**
|
|
1019
|
+
* SDK should migrate to a new SFU instance
|
|
1020
|
+
*
|
|
1021
|
+
* @generated from protobuf enum value: WEBSOCKET_RECONNECT_STRATEGY_MIGRATE = 5;
|
|
1022
|
+
*/
|
|
1023
|
+
WebsocketReconnectStrategy[WebsocketReconnectStrategy["MIGRATE"] = 5] = "MIGRATE";
|
|
1024
|
+
})(WebsocketReconnectStrategy || (WebsocketReconnectStrategy = {}));
|
|
953
1025
|
// @generated message type with reflection information, may provide speed optimized methods
|
|
954
1026
|
class CallState$Type extends MessageType {
|
|
955
1027
|
constructor() {
|
|
@@ -2412,6 +2484,7 @@ var models = /*#__PURE__*/Object.freeze({
|
|
|
2412
2484
|
__proto__: null,
|
|
2413
2485
|
Browser: Browser,
|
|
2414
2486
|
Call: Call$1,
|
|
2487
|
+
get CallEndedReason () { return CallEndedReason; },
|
|
2415
2488
|
CallGrants: CallGrants,
|
|
2416
2489
|
CallState: CallState$1,
|
|
2417
2490
|
ClientDetails: ClientDetails,
|
|
@@ -2435,7 +2508,8 @@ var models = /*#__PURE__*/Object.freeze({
|
|
|
2435
2508
|
get TrackUnpublishReason () { return TrackUnpublishReason; },
|
|
2436
2509
|
VideoDimension: VideoDimension,
|
|
2437
2510
|
VideoLayer: VideoLayer,
|
|
2438
|
-
get VideoQuality () { return VideoQuality; }
|
|
2511
|
+
get VideoQuality () { return VideoQuality; },
|
|
2512
|
+
get WebsocketReconnectStrategy () { return WebsocketReconnectStrategy; }
|
|
2439
2513
|
});
|
|
2440
2514
|
|
|
2441
2515
|
/* eslint-disable */
|
|
@@ -3844,6 +3918,20 @@ class SfuEvent$Type extends MessageType {
|
|
|
3844
3918
|
oneof: 'eventPayload',
|
|
3845
3919
|
T: () => PinsChanged,
|
|
3846
3920
|
},
|
|
3921
|
+
{
|
|
3922
|
+
no: 23,
|
|
3923
|
+
name: 'call_ended',
|
|
3924
|
+
kind: 'message',
|
|
3925
|
+
oneof: 'eventPayload',
|
|
3926
|
+
T: () => CallEnded,
|
|
3927
|
+
},
|
|
3928
|
+
{
|
|
3929
|
+
no: 24,
|
|
3930
|
+
name: 'participant_updated',
|
|
3931
|
+
kind: 'message',
|
|
3932
|
+
oneof: 'eventPayload',
|
|
3933
|
+
T: () => ParticipantUpdated,
|
|
3934
|
+
},
|
|
3847
3935
|
]);
|
|
3848
3936
|
}
|
|
3849
3937
|
create(value) {
|
|
@@ -3966,6 +4054,18 @@ class SfuEvent$Type extends MessageType {
|
|
|
3966
4054
|
pinsUpdated: PinsChanged.internalBinaryRead(reader, reader.uint32(), options, message.eventPayload.pinsUpdated),
|
|
3967
4055
|
};
|
|
3968
4056
|
break;
|
|
4057
|
+
case /* stream.video.sfu.event.CallEnded call_ended */ 23:
|
|
4058
|
+
message.eventPayload = {
|
|
4059
|
+
oneofKind: 'callEnded',
|
|
4060
|
+
callEnded: CallEnded.internalBinaryRead(reader, reader.uint32(), options, message.eventPayload.callEnded),
|
|
4061
|
+
};
|
|
4062
|
+
break;
|
|
4063
|
+
case /* stream.video.sfu.event.ParticipantUpdated participant_updated */ 24:
|
|
4064
|
+
message.eventPayload = {
|
|
4065
|
+
oneofKind: 'participantUpdated',
|
|
4066
|
+
participantUpdated: ParticipantUpdated.internalBinaryRead(reader, reader.uint32(), options, message.eventPayload.participantUpdated),
|
|
4067
|
+
};
|
|
4068
|
+
break;
|
|
3969
4069
|
default:
|
|
3970
4070
|
let u = options.readUnknownField;
|
|
3971
4071
|
if (u === 'throw')
|
|
@@ -4032,6 +4132,12 @@ class SfuEvent$Type extends MessageType {
|
|
|
4032
4132
|
/* stream.video.sfu.event.PinsChanged pins_updated = 22; */
|
|
4033
4133
|
if (message.eventPayload.oneofKind === 'pinsUpdated')
|
|
4034
4134
|
PinsChanged.internalBinaryWrite(message.eventPayload.pinsUpdated, writer.tag(22, WireType.LengthDelimited).fork(), options).join();
|
|
4135
|
+
/* stream.video.sfu.event.CallEnded call_ended = 23; */
|
|
4136
|
+
if (message.eventPayload.oneofKind === 'callEnded')
|
|
4137
|
+
CallEnded.internalBinaryWrite(message.eventPayload.callEnded, writer.tag(23, WireType.LengthDelimited).fork(), options).join();
|
|
4138
|
+
/* stream.video.sfu.event.ParticipantUpdated participant_updated = 24; */
|
|
4139
|
+
if (message.eventPayload.oneofKind === 'participantUpdated')
|
|
4140
|
+
ParticipantUpdated.internalBinaryWrite(message.eventPayload.participantUpdated, writer.tag(24, WireType.LengthDelimited).fork(), options).join();
|
|
4035
4141
|
let u = options.writeUnknownFields;
|
|
4036
4142
|
if (u !== false)
|
|
4037
4143
|
(u == true ? UnknownFieldHandler.onWrite : u)(this.typeName, message, writer);
|
|
@@ -4100,10 +4206,21 @@ class Error$Type extends MessageType {
|
|
|
4100
4206
|
constructor() {
|
|
4101
4207
|
super('stream.video.sfu.event.Error', [
|
|
4102
4208
|
{ no: 4, name: 'error', kind: 'message', T: () => Error$2 },
|
|
4209
|
+
{
|
|
4210
|
+
no: 5,
|
|
4211
|
+
name: 'reconnect_strategy',
|
|
4212
|
+
kind: 'enum',
|
|
4213
|
+
T: () => [
|
|
4214
|
+
'stream.video.sfu.models.WebsocketReconnectStrategy',
|
|
4215
|
+
WebsocketReconnectStrategy,
|
|
4216
|
+
'WEBSOCKET_RECONNECT_STRATEGY_',
|
|
4217
|
+
],
|
|
4218
|
+
},
|
|
4103
4219
|
]);
|
|
4104
4220
|
}
|
|
4105
4221
|
create(value) {
|
|
4106
4222
|
const message = globalThis.Object.create(this.messagePrototype);
|
|
4223
|
+
message.reconnectStrategy = 0;
|
|
4107
4224
|
if (value !== undefined)
|
|
4108
4225
|
reflectionMergePartial(this, message, value);
|
|
4109
4226
|
return message;
|
|
@@ -4116,6 +4233,9 @@ class Error$Type extends MessageType {
|
|
|
4116
4233
|
case /* stream.video.sfu.models.Error error */ 4:
|
|
4117
4234
|
message.error = Error$2.internalBinaryRead(reader, reader.uint32(), options, message.error);
|
|
4118
4235
|
break;
|
|
4236
|
+
case /* stream.video.sfu.models.WebsocketReconnectStrategy reconnect_strategy */ 5:
|
|
4237
|
+
message.reconnectStrategy = reader.int32();
|
|
4238
|
+
break;
|
|
4119
4239
|
default:
|
|
4120
4240
|
let u = options.readUnknownField;
|
|
4121
4241
|
if (u === 'throw')
|
|
@@ -4131,6 +4251,9 @@ class Error$Type extends MessageType {
|
|
|
4131
4251
|
/* stream.video.sfu.models.Error error = 4; */
|
|
4132
4252
|
if (message.error)
|
|
4133
4253
|
Error$2.internalBinaryWrite(message.error, writer.tag(4, WireType.LengthDelimited).fork(), options).join();
|
|
4254
|
+
/* stream.video.sfu.models.WebsocketReconnectStrategy reconnect_strategy = 5; */
|
|
4255
|
+
if (message.reconnectStrategy !== 0)
|
|
4256
|
+
writer.tag(5, WireType.Varint).int32(message.reconnectStrategy);
|
|
4134
4257
|
let u = options.writeUnknownFields;
|
|
4135
4258
|
if (u !== false)
|
|
4136
4259
|
(u == true ? UnknownFieldHandler.onWrite : u)(this.typeName, message, writer);
|
|
@@ -4924,6 +5047,60 @@ class ParticipantLeft$Type extends MessageType {
|
|
|
4924
5047
|
*/
|
|
4925
5048
|
const ParticipantLeft = new ParticipantLeft$Type();
|
|
4926
5049
|
// @generated message type with reflection information, may provide speed optimized methods
|
|
5050
|
+
class ParticipantUpdated$Type extends MessageType {
|
|
5051
|
+
constructor() {
|
|
5052
|
+
super('stream.video.sfu.event.ParticipantUpdated', [
|
|
5053
|
+
{ no: 1, name: 'call_cid', kind: 'scalar', T: 9 /*ScalarType.STRING*/ },
|
|
5054
|
+
{ no: 2, name: 'participant', kind: 'message', T: () => Participant },
|
|
5055
|
+
]);
|
|
5056
|
+
}
|
|
5057
|
+
create(value) {
|
|
5058
|
+
const message = globalThis.Object.create(this.messagePrototype);
|
|
5059
|
+
message.callCid = '';
|
|
5060
|
+
if (value !== undefined)
|
|
5061
|
+
reflectionMergePartial(this, message, value);
|
|
5062
|
+
return message;
|
|
5063
|
+
}
|
|
5064
|
+
internalBinaryRead(reader, length, options, target) {
|
|
5065
|
+
let message = target ?? this.create(), end = reader.pos + length;
|
|
5066
|
+
while (reader.pos < end) {
|
|
5067
|
+
let [fieldNo, wireType] = reader.tag();
|
|
5068
|
+
switch (fieldNo) {
|
|
5069
|
+
case /* string call_cid */ 1:
|
|
5070
|
+
message.callCid = reader.string();
|
|
5071
|
+
break;
|
|
5072
|
+
case /* stream.video.sfu.models.Participant participant */ 2:
|
|
5073
|
+
message.participant = Participant.internalBinaryRead(reader, reader.uint32(), options, message.participant);
|
|
5074
|
+
break;
|
|
5075
|
+
default:
|
|
5076
|
+
let u = options.readUnknownField;
|
|
5077
|
+
if (u === 'throw')
|
|
5078
|
+
throw new globalThis.Error(`Unknown field ${fieldNo} (wire type ${wireType}) for ${this.typeName}`);
|
|
5079
|
+
let d = reader.skip(wireType);
|
|
5080
|
+
if (u !== false)
|
|
5081
|
+
(u === true ? UnknownFieldHandler.onRead : u)(this.typeName, message, fieldNo, wireType, d);
|
|
5082
|
+
}
|
|
5083
|
+
}
|
|
5084
|
+
return message;
|
|
5085
|
+
}
|
|
5086
|
+
internalBinaryWrite(message, writer, options) {
|
|
5087
|
+
/* string call_cid = 1; */
|
|
5088
|
+
if (message.callCid !== '')
|
|
5089
|
+
writer.tag(1, WireType.LengthDelimited).string(message.callCid);
|
|
5090
|
+
/* stream.video.sfu.models.Participant participant = 2; */
|
|
5091
|
+
if (message.participant)
|
|
5092
|
+
Participant.internalBinaryWrite(message.participant, writer.tag(2, WireType.LengthDelimited).fork(), options).join();
|
|
5093
|
+
let u = options.writeUnknownFields;
|
|
5094
|
+
if (u !== false)
|
|
5095
|
+
(u == true ? UnknownFieldHandler.onWrite : u)(this.typeName, message, writer);
|
|
5096
|
+
return writer;
|
|
5097
|
+
}
|
|
5098
|
+
}
|
|
5099
|
+
/**
|
|
5100
|
+
* @generated MessageType for protobuf message stream.video.sfu.event.ParticipantUpdated
|
|
5101
|
+
*/
|
|
5102
|
+
const ParticipantUpdated = new ParticipantUpdated$Type();
|
|
5103
|
+
// @generated message type with reflection information, may provide speed optimized methods
|
|
4927
5104
|
class SubscriberOffer$Type extends MessageType {
|
|
4928
5105
|
constructor() {
|
|
4929
5106
|
super('stream.video.sfu.event.SubscriberOffer', [
|
|
@@ -5874,6 +6051,62 @@ class GoAway$Type extends MessageType {
|
|
|
5874
6051
|
* @generated MessageType for protobuf message stream.video.sfu.event.GoAway
|
|
5875
6052
|
*/
|
|
5876
6053
|
const GoAway = new GoAway$Type();
|
|
6054
|
+
// @generated message type with reflection information, may provide speed optimized methods
|
|
6055
|
+
class CallEnded$Type extends MessageType {
|
|
6056
|
+
constructor() {
|
|
6057
|
+
super('stream.video.sfu.event.CallEnded', [
|
|
6058
|
+
{
|
|
6059
|
+
no: 1,
|
|
6060
|
+
name: 'reason',
|
|
6061
|
+
kind: 'enum',
|
|
6062
|
+
T: () => [
|
|
6063
|
+
'stream.video.sfu.models.CallEndedReason',
|
|
6064
|
+
CallEndedReason,
|
|
6065
|
+
'CALL_ENDED_REASON_',
|
|
6066
|
+
],
|
|
6067
|
+
},
|
|
6068
|
+
]);
|
|
6069
|
+
}
|
|
6070
|
+
create(value) {
|
|
6071
|
+
const message = globalThis.Object.create(this.messagePrototype);
|
|
6072
|
+
message.reason = 0;
|
|
6073
|
+
if (value !== undefined)
|
|
6074
|
+
reflectionMergePartial(this, message, value);
|
|
6075
|
+
return message;
|
|
6076
|
+
}
|
|
6077
|
+
internalBinaryRead(reader, length, options, target) {
|
|
6078
|
+
let message = target ?? this.create(), end = reader.pos + length;
|
|
6079
|
+
while (reader.pos < end) {
|
|
6080
|
+
let [fieldNo, wireType] = reader.tag();
|
|
6081
|
+
switch (fieldNo) {
|
|
6082
|
+
case /* stream.video.sfu.models.CallEndedReason reason */ 1:
|
|
6083
|
+
message.reason = reader.int32();
|
|
6084
|
+
break;
|
|
6085
|
+
default:
|
|
6086
|
+
let u = options.readUnknownField;
|
|
6087
|
+
if (u === 'throw')
|
|
6088
|
+
throw new globalThis.Error(`Unknown field ${fieldNo} (wire type ${wireType}) for ${this.typeName}`);
|
|
6089
|
+
let d = reader.skip(wireType);
|
|
6090
|
+
if (u !== false)
|
|
6091
|
+
(u === true ? UnknownFieldHandler.onRead : u)(this.typeName, message, fieldNo, wireType, d);
|
|
6092
|
+
}
|
|
6093
|
+
}
|
|
6094
|
+
return message;
|
|
6095
|
+
}
|
|
6096
|
+
internalBinaryWrite(message, writer, options) {
|
|
6097
|
+
/* stream.video.sfu.models.CallEndedReason reason = 1; */
|
|
6098
|
+
if (message.reason !== 0)
|
|
6099
|
+
writer.tag(1, WireType.Varint).int32(message.reason);
|
|
6100
|
+
let u = options.writeUnknownFields;
|
|
6101
|
+
if (u !== false)
|
|
6102
|
+
(u == true ? UnknownFieldHandler.onWrite : u)(this.typeName, message, writer);
|
|
6103
|
+
return writer;
|
|
6104
|
+
}
|
|
6105
|
+
}
|
|
6106
|
+
/**
|
|
6107
|
+
* @generated MessageType for protobuf message stream.video.sfu.event.CallEnded
|
|
6108
|
+
*/
|
|
6109
|
+
const CallEnded = new CallEnded$Type();
|
|
5877
6110
|
|
|
5878
6111
|
var events = /*#__PURE__*/Object.freeze({
|
|
5879
6112
|
__proto__: null,
|
|
@@ -5881,6 +6114,7 @@ var events = /*#__PURE__*/Object.freeze({
|
|
|
5881
6114
|
AudioLevelChanged: AudioLevelChanged,
|
|
5882
6115
|
AudioMediaRequest: AudioMediaRequest,
|
|
5883
6116
|
AudioSender: AudioSender,
|
|
6117
|
+
CallEnded: CallEnded,
|
|
5884
6118
|
CallGrantsUpdated: CallGrantsUpdated,
|
|
5885
6119
|
ChangePublishQuality: ChangePublishQuality,
|
|
5886
6120
|
ConnectionQualityChanged: ConnectionQualityChanged,
|
|
@@ -5897,6 +6131,7 @@ var events = /*#__PURE__*/Object.freeze({
|
|
|
5897
6131
|
Migration: Migration,
|
|
5898
6132
|
ParticipantJoined: ParticipantJoined,
|
|
5899
6133
|
ParticipantLeft: ParticipantLeft,
|
|
6134
|
+
ParticipantUpdated: ParticipantUpdated,
|
|
5900
6135
|
PinsChanged: PinsChanged,
|
|
5901
6136
|
PublisherAnswer: PublisherAnswer,
|
|
5902
6137
|
SfuEvent: SfuEvent,
|
|
@@ -6177,6 +6412,8 @@ const sfuEventKinds = {
|
|
|
6177
6412
|
goAway: undefined,
|
|
6178
6413
|
iceRestart: undefined,
|
|
6179
6414
|
pinsUpdated: undefined,
|
|
6415
|
+
callEnded: undefined,
|
|
6416
|
+
participantUpdated: undefined,
|
|
6180
6417
|
};
|
|
6181
6418
|
const isSfuEvent = (eventName) => {
|
|
6182
6419
|
return Object.prototype.hasOwnProperty.call(sfuEventKinds, eventName);
|
|
@@ -7116,9 +7353,11 @@ class CallState {
|
|
|
7116
7353
|
this.setCurrentValue(this.thumbnailsSubject, call.thumbnails);
|
|
7117
7354
|
};
|
|
7118
7355
|
this.updateFromMemberRemoved = (event) => {
|
|
7356
|
+
this.updateFromCallResponse(event.call);
|
|
7119
7357
|
this.setCurrentValue(this.membersSubject, (members) => members.filter((m) => event.members.indexOf(m.user_id) === -1));
|
|
7120
7358
|
};
|
|
7121
7359
|
this.updateFromMemberAdded = (event) => {
|
|
7360
|
+
this.updateFromCallResponse(event.call);
|
|
7122
7361
|
this.setCurrentValue(this.membersSubject, (members) => [
|
|
7123
7362
|
...members,
|
|
7124
7363
|
...event.members,
|
|
@@ -7202,6 +7441,7 @@ class CallState {
|
|
|
7202
7441
|
});
|
|
7203
7442
|
};
|
|
7204
7443
|
this.updateMembers = (event) => {
|
|
7444
|
+
this.updateFromCallResponse(event.call);
|
|
7205
7445
|
this.setCurrentValue(this.membersSubject, (members) => members.map((member) => {
|
|
7206
7446
|
const memberUpdate = event.members.find((m) => m.user_id === member.user_id);
|
|
7207
7447
|
return memberUpdate ? memberUpdate : member;
|
|
@@ -9330,6 +9570,17 @@ const watchParticipantLeft = (state) => {
|
|
|
9330
9570
|
state.setParticipants((participants) => participants.filter((p) => p.sessionId !== participant.sessionId));
|
|
9331
9571
|
};
|
|
9332
9572
|
};
|
|
9573
|
+
/**
|
|
9574
|
+
* An event responder which handles the `participantUpdated` event.
|
|
9575
|
+
*/
|
|
9576
|
+
const watchParticipantUpdated = (state) => {
|
|
9577
|
+
return function onParticipantUpdated(e) {
|
|
9578
|
+
const { participant } = e;
|
|
9579
|
+
if (!participant)
|
|
9580
|
+
return;
|
|
9581
|
+
state.updateParticipant(participant.sessionId, participant);
|
|
9582
|
+
};
|
|
9583
|
+
};
|
|
9333
9584
|
/**
|
|
9334
9585
|
* An event responder which handles the `trackPublished` event.
|
|
9335
9586
|
* The SFU will send this event when a participant publishes a track.
|
|
@@ -9431,6 +9682,7 @@ const registerEventHandlers = (call, state, dispatcher) => {
|
|
|
9431
9682
|
watchParticipantCountChanged(dispatcher, state),
|
|
9432
9683
|
call.on('participantJoined', watchParticipantJoined(state)),
|
|
9433
9684
|
call.on('participantLeft', watchParticipantLeft(state)),
|
|
9685
|
+
call.on('participantUpdated', watchParticipantUpdated(state)),
|
|
9434
9686
|
call.on('trackPublished', watchTrackPublished(state)),
|
|
9435
9687
|
call.on('trackUnpublished', watchTrackUnpublished(state)),
|
|
9436
9688
|
watchAudioLevelChanged(dispatcher, state),
|
|
@@ -10617,18 +10869,27 @@ class InputMediaDeviceManager {
|
|
|
10617
10869
|
* Starts stream.
|
|
10618
10870
|
*/
|
|
10619
10871
|
async enable() {
|
|
10620
|
-
if (this.state.
|
|
10872
|
+
if (this.state.optimisticStatus === 'enabled') {
|
|
10873
|
+
await this.statusChangePromise;
|
|
10621
10874
|
return;
|
|
10622
|
-
this.enablePromise = this.unmuteStream();
|
|
10623
|
-
try {
|
|
10624
|
-
await this.enablePromise;
|
|
10625
|
-
this.state.setStatus('enabled');
|
|
10626
|
-
this.enablePromise = undefined;
|
|
10627
|
-
}
|
|
10628
|
-
catch (error) {
|
|
10629
|
-
this.enablePromise = undefined;
|
|
10630
|
-
throw error;
|
|
10631
10875
|
}
|
|
10876
|
+
const signal = this.nextAbortableStatusChangeRequest('enabled');
|
|
10877
|
+
const doEnable = async () => {
|
|
10878
|
+
if (signal.aborted)
|
|
10879
|
+
return;
|
|
10880
|
+
try {
|
|
10881
|
+
await this.unmuteStream();
|
|
10882
|
+
this.state.setStatus('enabled');
|
|
10883
|
+
}
|
|
10884
|
+
finally {
|
|
10885
|
+
if (!signal.aborted)
|
|
10886
|
+
this.resetStatusChangeRequest();
|
|
10887
|
+
}
|
|
10888
|
+
};
|
|
10889
|
+
this.statusChangePromise = this.statusChangePromise
|
|
10890
|
+
? this.statusChangePromise.then(doEnable)
|
|
10891
|
+
: doEnable();
|
|
10892
|
+
await this.statusChangePromise;
|
|
10632
10893
|
}
|
|
10633
10894
|
/**
|
|
10634
10895
|
* Stops or pauses the stream based on state.disableMode
|
|
@@ -10636,19 +10897,28 @@ class InputMediaDeviceManager {
|
|
|
10636
10897
|
*/
|
|
10637
10898
|
async disable(forceStop = false) {
|
|
10638
10899
|
this.state.prevStatus = this.state.status;
|
|
10639
|
-
if (!forceStop && this.state.
|
|
10900
|
+
if (!forceStop && this.state.optimisticStatus === 'disabled') {
|
|
10901
|
+
await this.statusChangePromise;
|
|
10640
10902
|
return;
|
|
10641
|
-
const stopTracks = forceStop || this.state.disableMode === 'stop-tracks';
|
|
10642
|
-
this.disablePromise = this.muteStream(stopTracks);
|
|
10643
|
-
try {
|
|
10644
|
-
await this.disablePromise;
|
|
10645
|
-
this.state.setStatus('disabled');
|
|
10646
|
-
this.disablePromise = undefined;
|
|
10647
|
-
}
|
|
10648
|
-
catch (error) {
|
|
10649
|
-
this.disablePromise = undefined;
|
|
10650
|
-
throw error;
|
|
10651
10903
|
}
|
|
10904
|
+
const stopTracks = forceStop || this.state.disableMode === 'stop-tracks';
|
|
10905
|
+
const signal = this.nextAbortableStatusChangeRequest('disabled');
|
|
10906
|
+
const doDisable = async () => {
|
|
10907
|
+
if (signal.aborted)
|
|
10908
|
+
return;
|
|
10909
|
+
try {
|
|
10910
|
+
await this.muteStream(stopTracks);
|
|
10911
|
+
this.state.setStatus('disabled');
|
|
10912
|
+
}
|
|
10913
|
+
finally {
|
|
10914
|
+
if (!signal.aborted)
|
|
10915
|
+
this.resetStatusChangeRequest();
|
|
10916
|
+
}
|
|
10917
|
+
};
|
|
10918
|
+
this.statusChangePromise = this.statusChangePromise
|
|
10919
|
+
? this.statusChangePromise.then(doDisable)
|
|
10920
|
+
: doDisable();
|
|
10921
|
+
await this.statusChangePromise;
|
|
10652
10922
|
}
|
|
10653
10923
|
/**
|
|
10654
10924
|
* If status was previously enabled, it will re-enable the device.
|
|
@@ -10664,7 +10934,7 @@ class InputMediaDeviceManager {
|
|
|
10664
10934
|
* else it will disable it.
|
|
10665
10935
|
*/
|
|
10666
10936
|
async toggle() {
|
|
10667
|
-
if (this.state.
|
|
10937
|
+
if (this.state.optimisticStatus === 'enabled') {
|
|
10668
10938
|
return this.disable();
|
|
10669
10939
|
}
|
|
10670
10940
|
else {
|
|
@@ -10851,11 +11121,8 @@ class InputMediaDeviceManager {
|
|
|
10851
11121
|
this.state.setMediaStream(stream, await rootStream);
|
|
10852
11122
|
this.getTracks().forEach((track) => {
|
|
10853
11123
|
track.addEventListener('ended', async () => {
|
|
10854
|
-
if (this.
|
|
10855
|
-
await this.
|
|
10856
|
-
}
|
|
10857
|
-
if (this.disablePromise) {
|
|
10858
|
-
await this.disablePromise;
|
|
11124
|
+
if (this.statusChangePromise) {
|
|
11125
|
+
await this.statusChangePromise;
|
|
10859
11126
|
}
|
|
10860
11127
|
if (this.state.status === 'enabled') {
|
|
10861
11128
|
this.isTrackStoppedDueToTrackEnd = true;
|
|
@@ -10885,11 +11152,8 @@ class InputMediaDeviceManager {
|
|
|
10885
11152
|
if (!deviceId) {
|
|
10886
11153
|
return;
|
|
10887
11154
|
}
|
|
10888
|
-
if (this.
|
|
10889
|
-
await this.
|
|
10890
|
-
}
|
|
10891
|
-
if (this.disablePromise) {
|
|
10892
|
-
await this.disablePromise;
|
|
11155
|
+
if (this.statusChangePromise) {
|
|
11156
|
+
await this.statusChangePromise;
|
|
10893
11157
|
}
|
|
10894
11158
|
let isDeviceDisconnected = false;
|
|
10895
11159
|
let isDeviceReplaced = false;
|
|
@@ -10923,6 +11187,16 @@ class InputMediaDeviceManager {
|
|
|
10923
11187
|
findDeviceInList(devices, deviceId) {
|
|
10924
11188
|
return devices.find((d) => d.deviceId === deviceId && d.kind === this.mediaDeviceKind);
|
|
10925
11189
|
}
|
|
11190
|
+
nextAbortableStatusChangeRequest(status) {
|
|
11191
|
+
this.statusChangeAbortController?.abort();
|
|
11192
|
+
this.statusChangeAbortController = new AbortController();
|
|
11193
|
+
this.state.setPendingStatus(status);
|
|
11194
|
+
return this.statusChangeAbortController.signal;
|
|
11195
|
+
}
|
|
11196
|
+
resetStatusChangeRequest() {
|
|
11197
|
+
this.statusChangePromise = undefined;
|
|
11198
|
+
this.statusChangeAbortController = undefined;
|
|
11199
|
+
}
|
|
10926
11200
|
}
|
|
10927
11201
|
|
|
10928
11202
|
class InputMediaDeviceManagerState {
|
|
@@ -10937,6 +11211,7 @@ class InputMediaDeviceManagerState {
|
|
|
10937
11211
|
this.disableMode = disableMode;
|
|
10938
11212
|
this.permissionName = permissionName;
|
|
10939
11213
|
this.statusSubject = new BehaviorSubject(undefined);
|
|
11214
|
+
this.optimisticStatusSubject = new BehaviorSubject(undefined);
|
|
10940
11215
|
this.mediaStreamSubject = new BehaviorSubject(undefined);
|
|
10941
11216
|
this.selectedDeviceSubject = new BehaviorSubject(undefined);
|
|
10942
11217
|
this.defaultConstraintsSubject = new BehaviorSubject(undefined);
|
|
@@ -10955,6 +11230,12 @@ class InputMediaDeviceManagerState {
|
|
|
10955
11230
|
* An Observable that emits the device status
|
|
10956
11231
|
*/
|
|
10957
11232
|
this.status$ = this.statusSubject.asObservable().pipe(distinctUntilChanged());
|
|
11233
|
+
/**
|
|
11234
|
+
* An Observable the reflects the requested device status. Useful for optimistic UIs
|
|
11235
|
+
*/
|
|
11236
|
+
this.optimisticStatus$ = this.optimisticStatusSubject
|
|
11237
|
+
.asObservable()
|
|
11238
|
+
.pipe(distinctUntilChanged());
|
|
10958
11239
|
/**
|
|
10959
11240
|
* The default constraints for the device.
|
|
10960
11241
|
*/
|
|
@@ -11022,6 +11303,12 @@ class InputMediaDeviceManagerState {
|
|
|
11022
11303
|
get status() {
|
|
11023
11304
|
return this.getCurrentValue(this.status$);
|
|
11024
11305
|
}
|
|
11306
|
+
/**
|
|
11307
|
+
* The requested device status. Useful for optimistic UIs
|
|
11308
|
+
*/
|
|
11309
|
+
get optimisticStatus() {
|
|
11310
|
+
return this.getCurrentValue(this.optimisticStatus$);
|
|
11311
|
+
}
|
|
11025
11312
|
/**
|
|
11026
11313
|
* The currently selected device
|
|
11027
11314
|
*/
|
|
@@ -11041,6 +11328,13 @@ class InputMediaDeviceManagerState {
|
|
|
11041
11328
|
setStatus(status) {
|
|
11042
11329
|
this.setCurrentValue(this.statusSubject, status);
|
|
11043
11330
|
}
|
|
11331
|
+
/**
|
|
11332
|
+
* @internal
|
|
11333
|
+
* @param pendingStatus
|
|
11334
|
+
*/
|
|
11335
|
+
setPendingStatus(pendingStatus) {
|
|
11336
|
+
this.setCurrentValue(this.optimisticStatusSubject, pendingStatus);
|
|
11337
|
+
}
|
|
11044
11338
|
/**
|
|
11045
11339
|
* Updates the `mediaStream` state variable.
|
|
11046
11340
|
*
|
|
@@ -11160,9 +11454,9 @@ class CameraManager extends InputMediaDeviceManager {
|
|
|
11160
11454
|
async selectTargetResolution(resolution) {
|
|
11161
11455
|
this.targetResolution.height = resolution.height;
|
|
11162
11456
|
this.targetResolution.width = resolution.width;
|
|
11163
|
-
if (this.
|
|
11457
|
+
if (this.statusChangePromise && this.state.optimisticStatus === 'enabled') {
|
|
11164
11458
|
try {
|
|
11165
|
-
await this.
|
|
11459
|
+
await this.statusChangePromise;
|
|
11166
11460
|
}
|
|
11167
11461
|
catch (error) {
|
|
11168
11462
|
// couldn't enable device, target resolution will be applied the next time user attempts to start the device
|
|
@@ -13303,12 +13597,7 @@ class Call {
|
|
|
13303
13597
|
}
|
|
13304
13598
|
async initCamera(options) {
|
|
13305
13599
|
// Wait for any in progress camera operation
|
|
13306
|
-
|
|
13307
|
-
await this.camera.enablePromise;
|
|
13308
|
-
}
|
|
13309
|
-
if (this.camera.disablePromise) {
|
|
13310
|
-
await this.camera.disablePromise;
|
|
13311
|
-
}
|
|
13600
|
+
await this.camera.statusChangePromise;
|
|
13312
13601
|
if (this.state.localParticipant?.videoStream ||
|
|
13313
13602
|
!this.permissionsContext.hasPermission('send-video')) {
|
|
13314
13603
|
return;
|
|
@@ -13345,12 +13634,7 @@ class Call {
|
|
|
13345
13634
|
}
|
|
13346
13635
|
async initMic(options) {
|
|
13347
13636
|
// Wait for any in progress mic operation
|
|
13348
|
-
|
|
13349
|
-
await this.microphone.enablePromise;
|
|
13350
|
-
}
|
|
13351
|
-
if (this.microphone.disablePromise) {
|
|
13352
|
-
await this.microphone.disablePromise;
|
|
13353
|
-
}
|
|
13637
|
+
await this.microphone.statusChangePromise;
|
|
13354
13638
|
if (this.state.localParticipant?.audioStream ||
|
|
13355
13639
|
!this.permissionsContext.hasPermission('send-audio')) {
|
|
13356
13640
|
return;
|
|
@@ -14893,7 +15177,7 @@ class StreamClient {
|
|
|
14893
15177
|
});
|
|
14894
15178
|
};
|
|
14895
15179
|
this.getUserAgent = () => {
|
|
14896
|
-
const version = "1.0.
|
|
15180
|
+
const version = "1.0.2" ;
|
|
14897
15181
|
return (this.userAgent ||
|
|
14898
15182
|
`stream-video-javascript-client-${this.node ? 'node' : 'browser'}-${version}`);
|
|
14899
15183
|
};
|