@whereby.com/browser-sdk 2.0.0-alpha19 → 2.0.0-alpha20

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/dist/lib.cjs CHANGED
@@ -150,7 +150,7 @@ heresy.define("WherebyEmbed", {
150
150
  if (roomUrl.searchParams.get("roomKey")) {
151
151
  this.url.searchParams.append("roomKey", roomUrl.searchParams.get("roomKey"));
152
152
  }
153
- Object.entries(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign({ jsApi: true, we: "2.0.0-alpha19", iframeSource: subdomain }, (displayName && { displayName })), (lang && { lang })), (metadata && { metadata })), (groups && { groups })), (virtualBackgroundUrl && { virtualBackgroundUrl })), (avatarUrl && { avatarUrl })), (minimal != null && { embed: minimal })), boolAttrs.reduce(
153
+ Object.entries(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign({ jsApi: true, we: "2.0.0-alpha20", iframeSource: subdomain }, (displayName && { displayName })), (lang && { lang })), (metadata && { metadata })), (groups && { groups })), (virtualBackgroundUrl && { virtualBackgroundUrl })), (avatarUrl && { avatarUrl })), (minimal != null && { embed: minimal })), boolAttrs.reduce(
154
154
  // add to URL if set in any way
155
155
  (o, v) => (this[v.toLowerCase()] != null ? Object.assign(Object.assign({}, o), { [v]: this[v.toLowerCase()] }) : o), {}))).forEach(([k, v]) => {
156
156
  if (!this.url.searchParams.has(k) && typeof v === "string") {
@@ -3299,6 +3299,7 @@ class LocalMedia extends TypedLocalMediaEventTarget {
3299
3299
  this._constraints = constraints;
3300
3300
  this.stream = new MediaStream();
3301
3301
  this._rtcManagers = [];
3302
+ this.screenshareStream = undefined;
3302
3303
  navigator.mediaDevices.addEventListener("devicechange", this._updateDeviceList.bind(this));
3303
3304
  }
3304
3305
  addRtcManager(rtcManager) {
@@ -3341,6 +3342,21 @@ class LocalMedia extends TypedLocalMediaEventTarget {
3341
3342
  audioTrack.enabled = newValue;
3342
3343
  this.dispatchEvent(new CustomEvent("microphone_enabled", { detail: { enabled: newValue } }));
3343
3344
  }
3345
+ startScreenshare() {
3346
+ return tslib.__awaiter(this, void 0, void 0, function* () {
3347
+ if (this.screenshareStream) {
3348
+ return this.screenshareStream;
3349
+ }
3350
+ const screenshareStream = yield navigator.mediaDevices.getDisplayMedia();
3351
+ this.screenshareStream = screenshareStream;
3352
+ return this.screenshareStream;
3353
+ });
3354
+ }
3355
+ stopScreenshare() {
3356
+ var _a;
3357
+ (_a = this.screenshareStream) === null || _a === void 0 ? void 0 : _a.getTracks().forEach((track) => track.stop());
3358
+ this.screenshareStream = undefined;
3359
+ }
3344
3360
  setCameraDevice(deviceId) {
3345
3361
  return tslib.__awaiter(this, void 0, void 0, function* () {
3346
3362
  const newStream = yield navigator.mediaDevices.getUserMedia({ video: { deviceId } });
@@ -8687,7 +8703,10 @@ class RoomConnection extends TypedEventTarget {
8687
8703
  }
8688
8704
  remoteParticipant.addStream(id, "to_accept");
8689
8705
  this._handleAcceptStreams([remoteParticipant]);
8690
- this.screenshares = [...this.screenshares, { participantId, id, hasAudioTrack, stream: undefined }];
8706
+ this.screenshares = [
8707
+ ...this.screenshares,
8708
+ { participantId, id, hasAudioTrack, stream: undefined, isLocal: false },
8709
+ ];
8691
8710
  }
8692
8711
  _handleScreenshareStopped(screenshare) {
8693
8712
  const { clientId: participantId, streamId: id } = screenshare;
@@ -8793,7 +8812,9 @@ class RoomConnection extends TypedEventTarget {
8793
8812
  return;
8794
8813
  }
8795
8814
  // screenshare
8796
- this.dispatchEvent(new CustomEvent("screenshare_started", { detail: { participantId: clientId, stream, id: streamId } }));
8815
+ this.dispatchEvent(new CustomEvent("screenshare_started", {
8816
+ detail: { participantId: clientId, stream, id: streamId, isLocal: false },
8817
+ }));
8797
8818
  }
8798
8819
  _joinRoom() {
8799
8820
  this.signalSocket.emit("join_room", {
@@ -8921,6 +8942,42 @@ class RoomConnection extends TypedEventTarget {
8921
8942
  }
8922
8943
  reportedStreamResolutions.set(streamId, { width, height });
8923
8944
  }
8945
+ startScreenshare() {
8946
+ var _a;
8947
+ return tslib.__awaiter(this, void 0, void 0, function* () {
8948
+ const screenshareStream = this.localMedia.screenshareStream || (yield this.localMedia.startScreenshare());
8949
+ (_a = this.rtcManager) === null || _a === void 0 ? void 0 : _a.addNewStream(screenshareStream.id, screenshareStream, false, true);
8950
+ this.screenshares = [
8951
+ ...this.screenshares,
8952
+ {
8953
+ participantId: this.selfId || "",
8954
+ id: screenshareStream.id,
8955
+ hasAudioTrack: false,
8956
+ stream: screenshareStream,
8957
+ isLocal: true,
8958
+ },
8959
+ ];
8960
+ this.dispatchEvent(new CustomEvent("screenshare_started", {
8961
+ detail: {
8962
+ participantId: this.selfId || "",
8963
+ id: screenshareStream.id,
8964
+ hasAudioTrack: false,
8965
+ stream: screenshareStream,
8966
+ isLocal: true,
8967
+ },
8968
+ }));
8969
+ });
8970
+ }
8971
+ stopScreenshare() {
8972
+ var _a;
8973
+ if (this.localMedia.screenshareStream) {
8974
+ const { id } = this.localMedia.screenshareStream;
8975
+ (_a = this.rtcManager) === null || _a === void 0 ? void 0 : _a.removeStream(id, this.localMedia.screenshareStream, null);
8976
+ this.screenshares = this.screenshares.filter((s) => s.id !== id);
8977
+ this.dispatchEvent(new CustomEvent("screenshare_stopped", { detail: { participantId: this.selfId, id } }));
8978
+ this.localMedia.stopScreenshare();
8979
+ }
8980
+ }
8924
8981
  }
8925
8982
 
8926
8983
  const initialState = {
@@ -8930,7 +8987,9 @@ const initialState = {
8930
8987
  startedAt: null,
8931
8988
  },
8932
8989
  isJoining: false,
8990
+ isStartingScreenshare: false,
8933
8991
  joinError: null,
8992
+ startScreenshareError: null,
8934
8993
  mostRecentChatMessage: null,
8935
8994
  remoteParticipants: [],
8936
8995
  roomConnectionStatus: "",
@@ -9008,9 +9067,16 @@ function reducer(state, action) {
9008
9067
  id: action.payload.id,
9009
9068
  hasAudioTrack: action.payload.hasAudioTrack,
9010
9069
  stream: action.payload.stream,
9070
+ isLocal: action.payload.isLocal,
9011
9071
  }) });
9012
9072
  case "SCREENSHARE_STOPPED":
9013
- return Object.assign(Object.assign({}, state), { screenshares: state.screenshares.filter((ss) => ss.participantId !== action.payload.participantId || ss.id !== action.payload.id) });
9073
+ return Object.assign(Object.assign({}, state), { screenshares: state.screenshares.filter((ss) => ss.id !== action.payload.id) });
9074
+ case "LOCAL_SCREENSHARE_START_ERROR":
9075
+ return Object.assign(Object.assign({}, state), { isStartingScreenshare: false, startScreenshareError: action.payload });
9076
+ case "LOCAL_SCREENSHARE_STARTING":
9077
+ return Object.assign(Object.assign({}, state), { isStartingScreenshare: true });
9078
+ case "LOCAL_SCREENSHARE_STOPPED":
9079
+ return Object.assign(Object.assign({}, state), { screenshares: state.screenshares.filter((ss) => !ss.isLocal) });
9014
9080
  case "STREAMING_STARTED":
9015
9081
  return Object.assign(Object.assign({}, state), { streaming: {
9016
9082
  status: action.payload.status,
@@ -9095,10 +9161,10 @@ function useRoomConnection(roomUrl, roomConnectionOptions) {
9095
9161
  });
9096
9162
  }),
9097
9163
  createEventListener("screenshare_started", (e) => {
9098
- const { participantId, stream, id, hasAudioTrack } = e.detail;
9164
+ const { participantId, stream, id, hasAudioTrack, isLocal } = e.detail;
9099
9165
  dispatch({
9100
9166
  type: "SCREENSHARE_STARTED",
9101
- payload: { participantId, stream, id, hasAudioTrack },
9167
+ payload: { participantId, stream, id, hasAudioTrack, isLocal },
9102
9168
  });
9103
9169
  }),
9104
9170
  createEventListener("screenshare_stopped", (e) => {
@@ -9160,6 +9226,18 @@ function useRoomConnection(roomUrl, roomConnectionOptions) {
9160
9226
  rejectWaitingParticipant: (participantId) => {
9161
9227
  roomConnection.rejectWaitingParticipant(participantId);
9162
9228
  },
9229
+ startScreenshare: () => {
9230
+ dispatch({ type: "LOCAL_SCREENSHARE_STARTING" });
9231
+ try {
9232
+ roomConnection.startScreenshare();
9233
+ }
9234
+ catch (error) {
9235
+ dispatch({ type: "LOCAL_SCREENSHARE_START_ERROR", payload: error });
9236
+ }
9237
+ },
9238
+ stopScreenshare: () => {
9239
+ roomConnection.stopScreenshare();
9240
+ },
9163
9241
  },
9164
9242
  components: {
9165
9243
  VideoView: (props) => React__default["default"].createElement(VideoView, Object.assign({}, props, {
@@ -9176,7 +9254,7 @@ function useRoomConnection(roomUrl, roomConnectionOptions) {
9176
9254
  };
9177
9255
  }
9178
9256
 
9179
- const sdkVersion = "2.0.0-alpha19";
9257
+ const sdkVersion = "2.0.0-alpha20";
9180
9258
 
9181
9259
  exports.VideoView = VideoView;
9182
9260
  exports.sdkVersion = sdkVersion;
package/dist/lib.esm.js CHANGED
@@ -128,7 +128,7 @@ define("WherebyEmbed", {
128
128
  if (roomUrl.searchParams.get("roomKey")) {
129
129
  this.url.searchParams.append("roomKey", roomUrl.searchParams.get("roomKey"));
130
130
  }
131
- Object.entries(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign({ jsApi: true, we: "2.0.0-alpha19", iframeSource: subdomain }, (displayName && { displayName })), (lang && { lang })), (metadata && { metadata })), (groups && { groups })), (virtualBackgroundUrl && { virtualBackgroundUrl })), (avatarUrl && { avatarUrl })), (minimal != null && { embed: minimal })), boolAttrs.reduce(
131
+ Object.entries(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign({ jsApi: true, we: "2.0.0-alpha20", iframeSource: subdomain }, (displayName && { displayName })), (lang && { lang })), (metadata && { metadata })), (groups && { groups })), (virtualBackgroundUrl && { virtualBackgroundUrl })), (avatarUrl && { avatarUrl })), (minimal != null && { embed: minimal })), boolAttrs.reduce(
132
132
  // add to URL if set in any way
133
133
  (o, v) => (this[v.toLowerCase()] != null ? Object.assign(Object.assign({}, o), { [v]: this[v.toLowerCase()] }) : o), {}))).forEach(([k, v]) => {
134
134
  if (!this.url.searchParams.has(k) && typeof v === "string") {
@@ -3277,6 +3277,7 @@ class LocalMedia extends TypedLocalMediaEventTarget {
3277
3277
  this._constraints = constraints;
3278
3278
  this.stream = new MediaStream();
3279
3279
  this._rtcManagers = [];
3280
+ this.screenshareStream = undefined;
3280
3281
  navigator.mediaDevices.addEventListener("devicechange", this._updateDeviceList.bind(this));
3281
3282
  }
3282
3283
  addRtcManager(rtcManager) {
@@ -3319,6 +3320,21 @@ class LocalMedia extends TypedLocalMediaEventTarget {
3319
3320
  audioTrack.enabled = newValue;
3320
3321
  this.dispatchEvent(new CustomEvent("microphone_enabled", { detail: { enabled: newValue } }));
3321
3322
  }
3323
+ startScreenshare() {
3324
+ return __awaiter(this, void 0, void 0, function* () {
3325
+ if (this.screenshareStream) {
3326
+ return this.screenshareStream;
3327
+ }
3328
+ const screenshareStream = yield navigator.mediaDevices.getDisplayMedia();
3329
+ this.screenshareStream = screenshareStream;
3330
+ return this.screenshareStream;
3331
+ });
3332
+ }
3333
+ stopScreenshare() {
3334
+ var _a;
3335
+ (_a = this.screenshareStream) === null || _a === void 0 ? void 0 : _a.getTracks().forEach((track) => track.stop());
3336
+ this.screenshareStream = undefined;
3337
+ }
3322
3338
  setCameraDevice(deviceId) {
3323
3339
  return __awaiter(this, void 0, void 0, function* () {
3324
3340
  const newStream = yield navigator.mediaDevices.getUserMedia({ video: { deviceId } });
@@ -8665,7 +8681,10 @@ class RoomConnection extends TypedEventTarget {
8665
8681
  }
8666
8682
  remoteParticipant.addStream(id, "to_accept");
8667
8683
  this._handleAcceptStreams([remoteParticipant]);
8668
- this.screenshares = [...this.screenshares, { participantId, id, hasAudioTrack, stream: undefined }];
8684
+ this.screenshares = [
8685
+ ...this.screenshares,
8686
+ { participantId, id, hasAudioTrack, stream: undefined, isLocal: false },
8687
+ ];
8669
8688
  }
8670
8689
  _handleScreenshareStopped(screenshare) {
8671
8690
  const { clientId: participantId, streamId: id } = screenshare;
@@ -8771,7 +8790,9 @@ class RoomConnection extends TypedEventTarget {
8771
8790
  return;
8772
8791
  }
8773
8792
  // screenshare
8774
- this.dispatchEvent(new CustomEvent("screenshare_started", { detail: { participantId: clientId, stream, id: streamId } }));
8793
+ this.dispatchEvent(new CustomEvent("screenshare_started", {
8794
+ detail: { participantId: clientId, stream, id: streamId, isLocal: false },
8795
+ }));
8775
8796
  }
8776
8797
  _joinRoom() {
8777
8798
  this.signalSocket.emit("join_room", {
@@ -8899,6 +8920,42 @@ class RoomConnection extends TypedEventTarget {
8899
8920
  }
8900
8921
  reportedStreamResolutions.set(streamId, { width, height });
8901
8922
  }
8923
+ startScreenshare() {
8924
+ var _a;
8925
+ return __awaiter(this, void 0, void 0, function* () {
8926
+ const screenshareStream = this.localMedia.screenshareStream || (yield this.localMedia.startScreenshare());
8927
+ (_a = this.rtcManager) === null || _a === void 0 ? void 0 : _a.addNewStream(screenshareStream.id, screenshareStream, false, true);
8928
+ this.screenshares = [
8929
+ ...this.screenshares,
8930
+ {
8931
+ participantId: this.selfId || "",
8932
+ id: screenshareStream.id,
8933
+ hasAudioTrack: false,
8934
+ stream: screenshareStream,
8935
+ isLocal: true,
8936
+ },
8937
+ ];
8938
+ this.dispatchEvent(new CustomEvent("screenshare_started", {
8939
+ detail: {
8940
+ participantId: this.selfId || "",
8941
+ id: screenshareStream.id,
8942
+ hasAudioTrack: false,
8943
+ stream: screenshareStream,
8944
+ isLocal: true,
8945
+ },
8946
+ }));
8947
+ });
8948
+ }
8949
+ stopScreenshare() {
8950
+ var _a;
8951
+ if (this.localMedia.screenshareStream) {
8952
+ const { id } = this.localMedia.screenshareStream;
8953
+ (_a = this.rtcManager) === null || _a === void 0 ? void 0 : _a.removeStream(id, this.localMedia.screenshareStream, null);
8954
+ this.screenshares = this.screenshares.filter((s) => s.id !== id);
8955
+ this.dispatchEvent(new CustomEvent("screenshare_stopped", { detail: { participantId: this.selfId, id } }));
8956
+ this.localMedia.stopScreenshare();
8957
+ }
8958
+ }
8902
8959
  }
8903
8960
 
8904
8961
  const initialState = {
@@ -8908,7 +8965,9 @@ const initialState = {
8908
8965
  startedAt: null,
8909
8966
  },
8910
8967
  isJoining: false,
8968
+ isStartingScreenshare: false,
8911
8969
  joinError: null,
8970
+ startScreenshareError: null,
8912
8971
  mostRecentChatMessage: null,
8913
8972
  remoteParticipants: [],
8914
8973
  roomConnectionStatus: "",
@@ -8986,9 +9045,16 @@ function reducer(state, action) {
8986
9045
  id: action.payload.id,
8987
9046
  hasAudioTrack: action.payload.hasAudioTrack,
8988
9047
  stream: action.payload.stream,
9048
+ isLocal: action.payload.isLocal,
8989
9049
  }) });
8990
9050
  case "SCREENSHARE_STOPPED":
8991
- return Object.assign(Object.assign({}, state), { screenshares: state.screenshares.filter((ss) => ss.participantId !== action.payload.participantId || ss.id !== action.payload.id) });
9051
+ return Object.assign(Object.assign({}, state), { screenshares: state.screenshares.filter((ss) => ss.id !== action.payload.id) });
9052
+ case "LOCAL_SCREENSHARE_START_ERROR":
9053
+ return Object.assign(Object.assign({}, state), { isStartingScreenshare: false, startScreenshareError: action.payload });
9054
+ case "LOCAL_SCREENSHARE_STARTING":
9055
+ return Object.assign(Object.assign({}, state), { isStartingScreenshare: true });
9056
+ case "LOCAL_SCREENSHARE_STOPPED":
9057
+ return Object.assign(Object.assign({}, state), { screenshares: state.screenshares.filter((ss) => !ss.isLocal) });
8992
9058
  case "STREAMING_STARTED":
8993
9059
  return Object.assign(Object.assign({}, state), { streaming: {
8994
9060
  status: action.payload.status,
@@ -9073,10 +9139,10 @@ function useRoomConnection(roomUrl, roomConnectionOptions) {
9073
9139
  });
9074
9140
  }),
9075
9141
  createEventListener("screenshare_started", (e) => {
9076
- const { participantId, stream, id, hasAudioTrack } = e.detail;
9142
+ const { participantId, stream, id, hasAudioTrack, isLocal } = e.detail;
9077
9143
  dispatch({
9078
9144
  type: "SCREENSHARE_STARTED",
9079
- payload: { participantId, stream, id, hasAudioTrack },
9145
+ payload: { participantId, stream, id, hasAudioTrack, isLocal },
9080
9146
  });
9081
9147
  }),
9082
9148
  createEventListener("screenshare_stopped", (e) => {
@@ -9138,6 +9204,18 @@ function useRoomConnection(roomUrl, roomConnectionOptions) {
9138
9204
  rejectWaitingParticipant: (participantId) => {
9139
9205
  roomConnection.rejectWaitingParticipant(participantId);
9140
9206
  },
9207
+ startScreenshare: () => {
9208
+ dispatch({ type: "LOCAL_SCREENSHARE_STARTING" });
9209
+ try {
9210
+ roomConnection.startScreenshare();
9211
+ }
9212
+ catch (error) {
9213
+ dispatch({ type: "LOCAL_SCREENSHARE_START_ERROR", payload: error });
9214
+ }
9215
+ },
9216
+ stopScreenshare: () => {
9217
+ roomConnection.stopScreenshare();
9218
+ },
9141
9219
  },
9142
9220
  components: {
9143
9221
  VideoView: (props) => React.createElement(VideoView, Object.assign({}, props, {
@@ -9154,6 +9232,6 @@ function useRoomConnection(roomUrl, roomConnectionOptions) {
9154
9232
  };
9155
9233
  }
9156
9234
 
9157
- const sdkVersion = "2.0.0-alpha19";
9235
+ const sdkVersion = "2.0.0-alpha20";
9158
9236
 
9159
9237
  export { VideoView, sdkVersion, useLocalMedia, useRoomConnection };
package/dist/types.d.ts CHANGED
@@ -79,6 +79,7 @@ declare class LocalMedia extends TypedLocalMediaEventTarget {
79
79
  private _constraints;
80
80
  _rtcManagers: RtcManager[];
81
81
  stream: MediaStream;
82
+ screenshareStream?: MediaStream;
82
83
  constructor(constraints: MediaStreamConstraints);
83
84
  addRtcManager(rtcManager: RtcManager): void;
84
85
  removeRtcManager(rtcManager: RtcManager): void;
@@ -88,6 +89,8 @@ declare class LocalMedia extends TypedLocalMediaEventTarget {
88
89
  isMicrophoneEnabled(): boolean;
89
90
  toggleCameraEnabled(enabled?: boolean): void;
90
91
  toggleMichrophoneEnabled(enabled?: boolean): void;
92
+ startScreenshare(): Promise<MediaStream>;
93
+ stopScreenshare(): void;
91
94
  setCameraDevice(deviceId: string): Promise<void>;
92
95
  setMicrophoneDevice(deviceId: string): Promise<void>;
93
96
  private _updateDeviceList;
@@ -168,7 +171,8 @@ declare class Screenshare {
168
171
  readonly id: string;
169
172
  readonly hasAudioTrack: boolean;
170
173
  readonly stream?: MediaStream;
171
- constructor({ participantId, id, hasAudioTrack, stream }: Screenshare);
174
+ readonly isLocal: boolean;
175
+ constructor({ participantId, id, hasAudioTrack, stream, isLocal }: Screenshare);
172
176
  }
173
177
 
174
178
  type Logger = Pick<Console, "debug" | "error" | "log" | "warn">;
@@ -224,6 +228,7 @@ type ScreenshareStartedEvent = {
224
228
  id: string;
225
229
  hasAudioTrack: boolean;
226
230
  stream: MediaStream;
231
+ isLocal: boolean;
227
232
  };
228
233
  type ScreenshareStoppedEvent = {
229
234
  participantId: string;
@@ -326,6 +331,8 @@ declare class RoomConnection extends TypedEventTarget {
326
331
  width: number;
327
332
  height: number;
328
333
  }): void;
334
+ startScreenshare(): Promise<void>;
335
+ stopScreenshare(): void;
329
336
  }
330
337
 
331
338
  type RemoteParticipantState = Omit<RemoteParticipant, "updateStreamState">;
@@ -333,7 +340,9 @@ interface RoomConnectionState {
333
340
  chatMessages: ChatMessage[];
334
341
  cloudRecording: CloudRecordingState;
335
342
  isJoining: boolean;
343
+ isStartingScreenshare: boolean;
336
344
  joinError: unknown;
345
+ startScreenshareError: unknown;
337
346
  localParticipant?: LocalParticipant;
338
347
  mostRecentChatMessage: ChatMessage | null;
339
348
  remoteParticipants: RemoteParticipantState[];
@@ -353,6 +362,8 @@ interface RoomConnectionActions {
353
362
  toggleMicrophone(enabled?: boolean): void;
354
363
  acceptWaitingParticipant(participantId: string): void;
355
364
  rejectWaitingParticipant(participantId: string): void;
365
+ startScreenshare(): void;
366
+ stopScreenshare(): void;
356
367
  }
357
368
  type VideoViewComponentProps = Omit<React.ComponentProps<typeof _default>, "onResize">;
358
369
  interface RoomConnectionComponents {
@@ -366,6 +377,6 @@ type RoomConnectionRef = {
366
377
  };
367
378
  declare function useRoomConnection(roomUrl: string, roomConnectionOptions: UseRoomConnectionOptions): RoomConnectionRef;
368
379
 
369
- declare const sdkVersion = "2.0.0-alpha19";
380
+ declare const sdkVersion = "2.0.0-alpha20";
370
381
 
371
382
  export { _default as VideoView, sdkVersion, useLocalMedia, useRoomConnection };