@vkontakte/media-streaming 1.0.1-dev.e965d10.0 → 1.0.1

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.
@@ -1,6 +1,6 @@
1
1
  /**
2
- * @vkontakte/media-streaming v1.0.1-dev.e965d10.0
3
- * Mon, 03 Aug 2026 10:45:14 GMT
2
+ * @vkontakte/media-streaming v1.0.1
3
+ * Mon, 28 Sep 2026 08:29:49 GMT
4
4
  */
5
5
  var __defProp = Object.defineProperty;
6
6
  var __getOwnPropNames = Object.getOwnPropertyNames;
@@ -56,18 +56,31 @@ __export(exports_src, {
56
56
  WebRTCStreamer: () => WebRTCStreamer,
57
57
  VERSION: () => VERSION,
58
58
  StreamerError: () => StreamerError,
59
+ PermissionName: () => PermissionName,
60
+ MediaUtils: () => MediaUtils,
59
61
  MediaErrorType: () => MediaErrorType
60
62
  });
61
63
  module.exports = __toCommonJS(exports_src);
62
64
 
63
- // src/env.ts
64
- var VERSION = "1.0.1-dev.e965d10.0";
65
+ // src/MediaError.ts
66
+ class StreamerMediaError extends Error {
67
+ constructor(name, message) {
68
+ super(message);
69
+ this.name = name;
70
+ }
71
+ }
72
+
65
73
  // src/constants.ts
66
74
  var DEFAULT_STUN_SERVERS = [{ urls: ["stun:videostun.mycdn.me:19302"] }];
67
75
  var DEFAULT_WS_SERVER = "wss://ovsu.mycdn.me/publish";
68
76
  var WS_CLOSE_CODE = 1000;
69
77
  var DEFAULT_FRAME_RATE = 15;
70
78
  var SCREEN_SHARE_CONTENT_TEXTHINT = "text";
79
+ var PermissionName;
80
+ ((PermissionName2) => {
81
+ PermissionName2["DISPLAY_MEDIA"] = "display_media";
82
+ PermissionName2["USER_MEDIA"] = "user_media";
83
+ })(PermissionName ||= {});
71
84
  var MediaErrorType;
72
85
  ((MediaErrorType2) => {
73
86
  MediaErrorType2["UNKNOWN"] = "unknown";
@@ -84,8 +97,6 @@ var StreamerError;
84
97
  StreamerError2["PEERCONNECTION"] = "peerconnection";
85
98
  StreamerError2["CONSTRAINTS"] = "constraints";
86
99
  })(StreamerError ||= {});
87
- // src/WebRTCStreamer.ts
88
- var import_videoplayer_shared = require("@vkontakte/videoplayer-shared");
89
100
 
90
101
  // src/MediaConstraints.ts
91
102
  class MediaConstraints {
@@ -121,14 +132,6 @@ class MediaConstraints {
121
132
  }
122
133
  }
123
134
 
124
- // src/MediaError.ts
125
- class MediaError2 extends Error {
126
- constructor(name, message) {
127
- super(message);
128
- this.name = name;
129
- }
130
- }
131
-
132
135
  // src/utils.ts
133
136
  var getWindow = () => {
134
137
  return globalThis;
@@ -149,29 +152,38 @@ var getSafariVersion = (userAgent) => {
149
152
  const version = parseInt(versionMatch[1], 10);
150
153
  return isNaN(version) ? undefined : version;
151
154
  };
152
- var enumerateDevices = async () => await getWindow().navigator.mediaDevices.enumerateDevices();
153
- var getUserMedia = (constraints) => getWindow().navigator.mediaDevices.getUserMedia(constraints).catch((e) => {
154
- if (e instanceof Error) {
155
- switch (e.name) {
156
- case "PermissionDismissedError":
157
- case "PermissionDeniedError":
158
- case "SecurityError":
159
- case "NotAllowedError":
160
- case "DOMException":
161
- throw new MediaError2(e.name, "permission" /* PERMISSION */);
162
- case "OverconstrainedError":
163
- case "NotFoundError":
164
- case "TypeError":
165
- throw new MediaError2(e.name, "unknown" /* UNKNOWN */);
166
- case "AbortError":
167
- case "NotReadableError":
168
- throw new MediaError2(e.name, "access" /* ACCESS */);
169
- default:
170
- throw new MediaError2(e.name, "unknown" /* UNKNOWN */);
155
+ var enumerateDevices = async () => {
156
+ const devices = await getWindow().navigator.mediaDevices.enumerateDevices();
157
+ return {
158
+ cameras: devices.filter((d) => d.kind === "videoinput"),
159
+ microphones: devices.filter((d) => d.kind === "audioinput")
160
+ };
161
+ };
162
+ var getUserStream = (config) => {
163
+ const constraints = new MediaConstraints(config).getNative();
164
+ return getWindow().navigator.mediaDevices.getUserMedia(constraints).catch((e) => {
165
+ if (e instanceof Error) {
166
+ switch (e.name) {
167
+ case "PermissionDismissedError":
168
+ case "PermissionDeniedError":
169
+ case "SecurityError":
170
+ case "NotAllowedError":
171
+ case "DOMException":
172
+ throw new StreamerMediaError(e.name, "permission" /* PERMISSION */);
173
+ case "OverconstrainedError":
174
+ case "NotFoundError":
175
+ case "TypeError":
176
+ throw new StreamerMediaError(e.name, "unknown" /* UNKNOWN */);
177
+ case "AbortError":
178
+ case "NotReadableError":
179
+ throw new StreamerMediaError(e.name, "access" /* ACCESS */);
180
+ default:
181
+ throw new StreamerMediaError(e.name, "unknown" /* UNKNOWN */);
182
+ }
171
183
  }
172
- }
173
- throw new Error("unknown");
174
- });
184
+ throw new Error("unknown");
185
+ });
186
+ };
175
187
  var getDisplayMedia = (constraints) => getWindow().navigator.mediaDevices.getDisplayMedia(constraints.getNative()).catch((e) => {
176
188
  if (e instanceof Error) {
177
189
  switch (e.name) {
@@ -205,7 +217,7 @@ var serializeConfig = (cfg) => {
205
217
  key: cfg.streamKey,
206
218
  ...cfg.audioOnly && { audioOnly: true },
207
219
  ...cfg.lockOrientation && { lockOrientation: true },
208
- ...cfg.mediaConstraints && { mediaConstraints: omitKeys(cfg.mediaConstraints, ["getNative"]) },
220
+ ...cfg.mediaConfig && { mediaConfig: cfg.mediaConfig },
209
221
  ...cfg.screenShare && { screenShare: omitKeys(cfg.screenShare, ["onEnded"]) }
210
222
  };
211
223
  };
@@ -217,6 +229,11 @@ var serializeMediaDevices = (devices) => {
217
229
  }));
218
230
  };
219
231
 
232
+ // src/env.ts
233
+ var VERSION = "1.0.1";
234
+ // src/WebRTCStreamer.ts
235
+ var import_videoplayer_shared = require("@vkontakte/videoplayer-shared");
236
+
220
237
  // src/ScreenConstraints.ts
221
238
  class ScreenConstraints extends MediaConstraints {
222
239
  constructor({ width, height, frameRate = DEFAULT_FRAME_RATE }) {
@@ -246,20 +263,20 @@ class ScreenConstraints extends MediaConstraints {
246
263
  // src/WebRTCStreamer.ts
247
264
  class WebRTCStreamer {
248
265
  config;
249
- messagesQueue = [];
250
- ws;
251
- peerConnection;
252
- stream;
253
- screenShareTrack = null;
254
- connected = false;
255
- destroying = false;
256
- cameraId;
257
- microphoneId;
258
- muted = false;
266
+ #messagesQueue = [];
267
+ #ws;
268
+ #peerConnection;
269
+ #stream;
270
+ #screenShareTrack = null;
271
+ #connected = false;
272
+ #destroying = false;
273
+ #cameraId;
274
+ #microphoneId;
275
+ #muted = false;
259
276
  static notDestroying(_target, _propertyKey, descriptor) {
260
277
  const original = descriptor.value;
261
278
  descriptor.value = function(...args) {
262
- if (this.destroying) {
279
+ if (this.#destroying) {
263
280
  return;
264
281
  }
265
282
  return original.apply(this, args);
@@ -271,23 +288,26 @@ class WebRTCStreamer {
271
288
  }
272
289
  callback(name, ...args) {
273
290
  const fn = this.config.callbacks[name];
274
- if (fn && !this.destroying) {
291
+ if (fn && !this.#destroying) {
275
292
  fn?.(...args);
276
293
  }
277
294
  }
295
+ get connected() {
296
+ return this.#connected;
297
+ }
278
298
  async init() {
299
+ const { cameras, microphones } = await enumerateDevices();
279
300
  this.tracerLog("init", {
280
301
  cfg: serializeConfig(this.config),
281
- d: serializeMediaDevices(await enumerateDevices())
302
+ d: serializeMediaDevices([...cameras, ...microphones])
282
303
  });
283
304
  let permissionName = "user_media" /* USER_MEDIA */;
284
- const { audioOnly, mediaConstraints, screenShare } = this.config;
305
+ const { audioOnly, mediaConfig, screenShare } = this.config;
285
306
  try {
286
- const constraints = mediaConstraints || new MediaConstraints({
307
+ this.#stream = await getUserStream(mediaConfig ?? {
287
308
  audio: true,
288
309
  video: !screenShare && !audioOnly
289
310
  });
290
- this.stream = await getUserMedia(constraints.getNative());
291
311
  if (!audioOnly && screenShare) {
292
312
  permissionName = "display_media" /* DISPLAY_MEDIA */;
293
313
  const screenShareTrack = await this.createScreenShareStream(screenShare);
@@ -298,18 +318,17 @@ class WebRTCStreamer {
298
318
  frameRate: { exact: frameRate }
299
319
  });
300
320
  } catch (e) {
301
- this.tracerLog("error", { type: "constraints" /* CONSTRAINTS */ });
302
- this.callback("onError", "constraints" /* CONSTRAINTS */);
321
+ this.handleScreenShareConstraintsError(frameRate);
303
322
  }
304
- this.stream.addTrack(screenShareTrack);
323
+ this.#stream.addTrack(screenShareTrack);
305
324
  }
306
- this.screenShareTrack = screenShareTrack;
325
+ this.#screenShareTrack = screenShareTrack;
307
326
  }
308
- this.tracerLog("streamChanged", serializeStream(this.stream));
309
- this.callback("onStreamChanged", this.stream);
327
+ this.tracerLog("streamChanged", serializeStream(this.#stream));
328
+ this.callback("onStreamChanged", this.#stream);
310
329
  } catch (err) {
311
- if (err instanceof MediaError) {
312
- this.tracerLog("permissionFailed", { name: permissionName, msg: err.message, code: err.code });
330
+ if (err instanceof StreamerMediaError) {
331
+ this.tracerLog("permissionFailed", { name: permissionName, msg: err.message, code: err.name });
313
332
  this.callback("onPermissionFailed", permissionName, err);
314
333
  } else {
315
334
  this.tracerLog("permissionFailed", { name: permissionName });
@@ -319,8 +338,9 @@ class WebRTCStreamer {
319
338
  }
320
339
  async connect() {
321
340
  this.tracerLog("connect");
341
+ this.callback("onConnecting");
322
342
  this.openSocket();
323
- if (!this.peerConnection) {
343
+ if (!this.#peerConnection) {
324
344
  await this.createPeerConnection();
325
345
  }
326
346
  }
@@ -330,59 +350,60 @@ class WebRTCStreamer {
330
350
  if (audioOnly) {
331
351
  return;
332
352
  }
333
- this.cameraId = deviceId;
334
- const constraints = new MediaConstraints({
335
- audio: this.microphoneId ? {
336
- deviceId: this.microphoneId
353
+ this.#cameraId = deviceId;
354
+ const newStream = await getUserStream({
355
+ audio: this.#microphoneId ? {
356
+ deviceId: this.#microphoneId
337
357
  } : true,
338
358
  video: {
339
- deviceId: this.cameraId
359
+ deviceId: this.#cameraId
340
360
  }
341
361
  });
342
- const newStream = await getUserMedia(constraints.getNative());
343
362
  this.replaceStream(newStream);
344
- if (this.muted) {
363
+ if (this.#muted) {
345
364
  this.setMicMuted(true);
346
365
  }
347
366
  }
348
367
  async switchMicrophone(deviceId) {
349
368
  this.tracerLog("switchMicrophone", { id: deviceId });
350
- this.microphoneId = deviceId;
351
- const constraints = new MediaConstraints({
369
+ this.#microphoneId = deviceId;
370
+ const newStream = await getUserStream({
352
371
  audio: {
353
- deviceId: this.microphoneId
372
+ deviceId: this.#microphoneId
354
373
  },
355
- video: this.screenShareTrack ? false : this.cameraId ? {
356
- deviceId: this.cameraId
374
+ video: this.#screenShareTrack ? false : this.#cameraId ? {
375
+ deviceId: this.#cameraId
357
376
  } : true
358
377
  });
359
- const newStream = await getUserMedia(constraints.getNative());
360
- if (this.screenShareTrack) {
361
- newStream.addTrack(this.screenShareTrack);
378
+ if (this.#screenShareTrack) {
379
+ newStream.addTrack(this.#screenShareTrack);
362
380
  }
363
381
  this.replaceStream(newStream, true);
364
- if (this.muted) {
382
+ if (this.#muted) {
365
383
  this.setMicMuted(true);
366
384
  }
367
385
  }
368
386
  async enableScreenShare(config) {
369
387
  this.tracerLog("enableScreenShare", omitKeys(config, ["onEnded"]));
370
- const constraints = new MediaConstraints({
371
- audio: this.microphoneId ? { deviceId: this.microphoneId } : true,
388
+ const newStream = await getUserStream({
389
+ audio: this.#microphoneId ? { deviceId: this.#microphoneId } : true,
372
390
  video: false
373
391
  });
374
- const newStream = await getUserMedia(constraints.getNative());
375
392
  const screenShareTrack = await this.createScreenShareStream(config);
376
393
  if (screenShareTrack) {
377
394
  const { frameRate = DEFAULT_FRAME_RATE } = config;
378
- await screenShareTrack.applyConstraints({
379
- frameRate: { exact: frameRate }
380
- });
395
+ try {
396
+ await screenShareTrack.applyConstraints({
397
+ frameRate: { exact: frameRate }
398
+ });
399
+ } catch (e) {
400
+ this.handleScreenShareConstraintsError(frameRate);
401
+ }
381
402
  newStream.addTrack(screenShareTrack);
382
403
  }
383
- this.screenShareTrack = screenShareTrack;
404
+ this.#screenShareTrack = screenShareTrack;
384
405
  this.replaceStream(newStream);
385
- if (this.muted) {
406
+ if (this.#muted) {
386
407
  this.setMicMuted(true);
387
408
  }
388
409
  }
@@ -391,37 +412,90 @@ class WebRTCStreamer {
391
412
  if (cameraDeviceId) {
392
413
  await this.switchCamera(cameraDeviceId);
393
414
  } else {
394
- const devices = await enumerateDevices();
395
- const defaultCamera = devices.find((d) => d.kind === "videoinput");
415
+ const { cameras } = await enumerateDevices();
416
+ const defaultCamera = cameras[0];
396
417
  if (defaultCamera) {
397
418
  await this.switchCamera(defaultCamera.deviceId);
398
419
  }
399
420
  }
400
421
  }
422
+ async switchMediaDevices({
423
+ cameraId,
424
+ microphoneId,
425
+ screenShare
426
+ }) {
427
+ if (cameraId === undefined && microphoneId === undefined && screenShare === undefined) {
428
+ return;
429
+ }
430
+ this.tracerLog("switchMediaDevices", {
431
+ ...cameraId !== undefined && { cam: cameraId },
432
+ ...microphoneId !== undefined && { mic: microphoneId },
433
+ ...screenShare !== undefined && { ss: screenShare === false ? false : omitKeys(screenShare, ["onEnded"]) }
434
+ });
435
+ const { audioOnly } = this.config;
436
+ const changingScreenShare = screenShare !== undefined;
437
+ const keepScreenShare = !changingScreenShare && Boolean(this.#screenShareTrack);
438
+ let audio = this.#microphoneId ? { deviceId: this.#microphoneId } : true;
439
+ let video = this.#cameraId ? { deviceId: this.#cameraId } : true;
440
+ if (microphoneId) {
441
+ this.#microphoneId = microphoneId;
442
+ audio = { deviceId: microphoneId };
443
+ } else if (microphoneId === false) {
444
+ audio = false;
445
+ }
446
+ if (audioOnly || cameraId === false) {
447
+ video = false;
448
+ } else if (cameraId) {
449
+ this.#cameraId = cameraId;
450
+ video = screenShare || keepScreenShare ? false : { deviceId: cameraId };
451
+ }
452
+ const newStream = await getUserStream({ audio, video });
453
+ if (screenShare) {
454
+ const screenShareTrack = await this.createScreenShareStream(screenShare);
455
+ if (screenShareTrack) {
456
+ const { frameRate = DEFAULT_FRAME_RATE } = screenShare;
457
+ try {
458
+ await screenShareTrack.applyConstraints({
459
+ frameRate: { exact: frameRate }
460
+ });
461
+ } catch (e) {
462
+ this.handleScreenShareConstraintsError(frameRate);
463
+ }
464
+ newStream.addTrack(screenShareTrack);
465
+ }
466
+ this.#screenShareTrack = screenShareTrack;
467
+ } else if (keepScreenShare && this.#screenShareTrack) {
468
+ newStream.addTrack(this.#screenShareTrack);
469
+ }
470
+ this.replaceStream(newStream, keepScreenShare);
471
+ if (this.#muted) {
472
+ this.setMicMuted(true);
473
+ }
474
+ }
401
475
  setMicMuted(muted) {
402
476
  this.tracerLog("setMicMuted", { m: muted });
403
- this.muted = muted;
404
- this.stream?.getAudioTracks().forEach((track) => {
477
+ this.#muted = muted;
478
+ this.#stream?.getAudioTracks().forEach((track) => {
405
479
  track.enabled = !muted;
406
480
  });
407
481
  }
408
482
  setCameraEnabled(enabled) {
409
483
  this.tracerLog("setCameraEnabled", { on: enabled });
410
- this.stream?.getVideoTracks().forEach((track) => {
484
+ this.#stream?.getVideoTracks().forEach((track) => {
411
485
  track.enabled = enabled;
412
486
  });
413
487
  }
414
488
  destroy() {
415
- this.destroying = true;
489
+ this.#destroying = true;
416
490
  this.tracerLog("destroy");
417
491
  this.disconnect();
418
- this.cameraId = undefined;
419
- this.microphoneId = undefined;
420
- this.muted = false;
421
- if (this.stream) {
422
- this.stream.getTracks().forEach((track) => track.stop());
423
- this.stream = undefined;
424
- this.screenShareTrack = null;
492
+ this.#cameraId = undefined;
493
+ this.#microphoneId = undefined;
494
+ this.#muted = false;
495
+ if (this.#stream) {
496
+ this.#stream.getTracks().forEach((track) => track.stop());
497
+ this.#stream = undefined;
498
+ this.#screenShareTrack = null;
425
499
  }
426
500
  }
427
501
  disconnect() {
@@ -433,26 +507,26 @@ class WebRTCStreamer {
433
507
  }
434
508
  }
435
509
  replaceStream(stream, keepScreenShare = false) {
436
- this.stream?.getTracks().forEach((track) => {
510
+ this.#stream?.getTracks().forEach((track) => {
437
511
  const isScreenShare = track.contentHint === SCREEN_SHARE_CONTENT_TEXTHINT;
438
512
  if (!isScreenShare || !keepScreenShare) {
439
513
  track.stop();
440
514
  if (isScreenShare) {
441
- this.screenShareTrack = null;
515
+ this.#screenShareTrack = null;
442
516
  }
443
517
  }
444
- this.stream?.removeTrack(track);
518
+ this.#stream?.removeTrack(track);
445
519
  });
446
- this.stream = stream;
520
+ this.#stream = stream;
447
521
  this.tracerLog("streamChanged", serializeStream(stream));
448
- this.callback("onStreamChanged", this.stream);
449
- this.replaceTracksInPeerConnection(this.stream);
522
+ this.callback("onStreamChanged", this.#stream);
523
+ this.replaceTracksInPeerConnection(this.#stream);
450
524
  }
451
525
  replaceTracksInPeerConnection(stream, keepScreenShare = false) {
452
- if (!this.peerConnection) {
526
+ if (!this.#peerConnection) {
453
527
  return;
454
528
  }
455
- this.peerConnection.getTransceivers().forEach(({ sender }) => {
529
+ this.#peerConnection.getTransceivers().forEach(({ sender }) => {
456
530
  const { track } = sender;
457
531
  if (track && (track.contentHint !== SCREEN_SHARE_CONTENT_TEXTHINT || !keepScreenShare)) {
458
532
  track.stop();
@@ -465,7 +539,7 @@ class WebRTCStreamer {
465
539
  });
466
540
  }
467
541
  get socketOpened() {
468
- return this.ws?.readyState === WebSocket.OPEN;
542
+ return this.#ws?.readyState === WebSocket.OPEN;
469
543
  }
470
544
  async createScreenShareStream(screenShare) {
471
545
  const { width, height, onEnded = null } = screenShare;
@@ -474,25 +548,25 @@ class WebRTCStreamer {
474
548
  if (screenShareTrack) {
475
549
  screenShareTrack.contentHint = SCREEN_SHARE_CONTENT_TEXTHINT;
476
550
  screenShareTrack.onended = () => {
477
- this.screenShareTrack = null;
551
+ this.#screenShareTrack = null;
478
552
  onEnded?.();
479
553
  };
480
554
  }
481
555
  return screenShareTrack;
482
556
  }
483
557
  openSocket() {
484
- if (!this.ws || this.ws.readyState === WebSocket.CLOSED) {
485
- this.ws = new WebSocket(this.config.serverUrl ?? DEFAULT_WS_SERVER);
486
- this.ws.onopen = this.handleWSOpen;
487
- this.ws.onmessage = this.handleWSMessage;
488
- this.ws.onclose = this.handleWSClose;
558
+ if (!this.#ws || this.#ws.readyState === WebSocket.CLOSED) {
559
+ this.#ws = new WebSocket(this.config.serverUrl ?? DEFAULT_WS_SERVER);
560
+ this.#ws.onopen = this.handleWSOpen;
561
+ this.#ws.onmessage = this.handleWSMessage;
562
+ this.#ws.onclose = this.handleWSClose;
489
563
  }
490
564
  }
491
565
  handleWSOpen = () => {
492
566
  this.sendMessageFromQueue();
493
567
  };
494
568
  handleWSMessage = (event) => {
495
- if (this.destroying || !this.ws || this.ws.readyState >= WebSocket.CLOSING) {
569
+ if (this.#destroying || !this.#ws || this.#ws.readyState >= WebSocket.CLOSING) {
496
570
  return;
497
571
  }
498
572
  const message = this.parseMessage(event.data);
@@ -510,26 +584,27 @@ class WebRTCStreamer {
510
584
  };
511
585
  handleWSClose = (event) => {
512
586
  this.closePeerConnection();
513
- if (!this.ws) {
587
+ if (!this.#ws) {
514
588
  return;
515
589
  }
516
- this.messagesQueue = [];
517
- this.connected = false;
518
- this.ws = undefined;
590
+ const isAbnormalClose = event.code > 1000;
591
+ this.#messagesQueue = [];
592
+ this.#connected = false;
593
+ this.#ws = undefined;
519
594
  this.tracerLog("disconnected", { code: event.code });
520
- this.callback("onDisconnected", event);
595
+ this.callback("onDisconnected", isAbnormalClose ? "connection" /* CONNECTION */ : undefined);
521
596
  };
522
597
  send(message) {
523
- this.messagesQueue.push(message);
598
+ this.#messagesQueue.push(message);
524
599
  if (this.socketOpened) {
525
600
  this.sendMessageFromQueue();
526
601
  }
527
602
  }
528
603
  sendMessageFromQueue() {
529
- while (this.messagesQueue.length > 0) {
604
+ while (this.#messagesQueue.length > 0) {
530
605
  if (this.socketOpened) {
531
- const message = this.messagesQueue.shift();
532
- this.ws?.send(JSON.stringify(message));
606
+ const message = this.#messagesQueue.shift();
607
+ this.#ws?.send(JSON.stringify(message));
533
608
  }
534
609
  }
535
610
  }
@@ -555,10 +630,14 @@ class WebRTCStreamer {
555
630
  }
556
631
  }
557
632
  handleAnswer(sdp) {
558
- this.peerConnection?.setRemoteDescription(new RTCSessionDescription({ type: "answer", sdp }));
633
+ this.#peerConnection?.setRemoteDescription(new RTCSessionDescription({ type: "answer", sdp }));
559
634
  }
560
635
  handleCandidate(candidate) {
561
- this.peerConnection?.addIceCandidate(new RTCIceCandidate(candidate));
636
+ this.#peerConnection?.addIceCandidate(new RTCIceCandidate(candidate));
637
+ }
638
+ handleScreenShareConstraintsError(frameRate) {
639
+ this.tracerLog("error", { type: "constraints" /* CONSTRAINTS */, frameRate });
640
+ this.callback("onError", "constraints" /* CONSTRAINTS */);
562
641
  }
563
642
  handleError(err, message) {
564
643
  if (["no_stream_data" /* NO_STREAM_DATA */, "peerconnection" /* PEERCONNECTION */].includes(err)) {
@@ -570,22 +649,27 @@ class WebRTCStreamer {
570
649
  this.callback("onError", err, reason);
571
650
  }
572
651
  async createPeerConnection() {
573
- this.peerConnection = new RTCPeerConnection({
574
- iceServers: this.config.stunServers ?? DEFAULT_STUN_SERVERS,
575
- rtcpMuxPolicy: "require",
576
- bundlePolicy: "max-compat"
577
- });
578
- this.peerConnection.onicecandidate = this.handleRTCIceCandidate;
579
- this.peerConnection.onsignalingstatechange = this.handleRTCSignalingStateChange;
580
- this.peerConnection.oniceconnectionstatechange = this.handleRTCIceConnectionStateChange;
581
- this.stream?.getTracks().forEach((track) => {
582
- if (track.kind === "video") {
583
- track.contentHint = "text";
584
- }
585
- this.stream && this.peerConnection?.addTrack(track, this.stream);
586
- });
587
652
  try {
588
- const offer = await this.peerConnection.createOffer();
653
+ this.#peerConnection = new RTCPeerConnection({
654
+ iceServers: this.config.stunServers ?? DEFAULT_STUN_SERVERS,
655
+ rtcpMuxPolicy: "require",
656
+ bundlePolicy: "max-compat"
657
+ });
658
+ this.#peerConnection.onicecandidate = this.handleRTCIceCandidate;
659
+ this.#peerConnection.onsignalingstatechange = this.handleRTCSignalingStateChange;
660
+ this.#peerConnection.oniceconnectionstatechange = this.handleRTCIceConnectionStateChange;
661
+ this.#stream?.getTracks().forEach((track) => {
662
+ if (track.kind === "video") {
663
+ track.contentHint = "text";
664
+ }
665
+ this.#stream && this.#peerConnection?.addTrack(track, this.#stream);
666
+ });
667
+ } catch (e) {
668
+ this.handleError("peerconnection" /* PEERCONNECTION */, "create peer connection failed");
669
+ return;
670
+ }
671
+ try {
672
+ const offer = await this.#peerConnection.createOffer();
589
673
  if (this.config.lockOrientation) {
590
674
  offer.sdp = offer.sdp?.replace(/a=extmap:[0-9]+ urn:3gpp:video-orientation[\r\n]+/g, "");
591
675
  }
@@ -608,12 +692,12 @@ class WebRTCStreamer {
608
692
  }
609
693
  };
610
694
  handleRTCSignalingStateChange = () => {
611
- if (!this.peerConnection) {
695
+ if (!this.#peerConnection) {
612
696
  return;
613
697
  }
614
- switch (this.peerConnection.signalingState) {
698
+ switch (this.#peerConnection.signalingState) {
615
699
  case "have-local-offer":
616
- const sdp = this.peerConnection.localDescription?.sdp;
700
+ const sdp = this.#peerConnection.localDescription?.sdp;
617
701
  this.send({
618
702
  type: "INVITE",
619
703
  inviteType: "OFFER",
@@ -628,10 +712,10 @@ class WebRTCStreamer {
628
712
  }
629
713
  };
630
714
  handleRTCIceConnectionStateChange = () => {
631
- if (!this.peerConnection) {
715
+ if (!this.#peerConnection) {
632
716
  return;
633
717
  }
634
- switch (this.peerConnection.iceConnectionState) {
718
+ switch (this.#peerConnection.iceConnectionState) {
635
719
  case "failed":
636
720
  this.handleError("peerconnection" /* PEERCONNECTION */, "ice connection failed");
637
721
  break;
@@ -639,7 +723,7 @@ class WebRTCStreamer {
639
723
  this.disconnect();
640
724
  break;
641
725
  case "connected":
642
- this.connected = true;
726
+ this.#connected = true;
643
727
  this.tracerLog("connected");
644
728
  this.callback("onConnected");
645
729
  break;
@@ -647,22 +731,22 @@ class WebRTCStreamer {
647
731
  };
648
732
  async setDescription(description) {
649
733
  try {
650
- await this.peerConnection?.setLocalDescription(description);
734
+ await this.#peerConnection?.setLocalDescription(description);
651
735
  } catch (e) {
652
736
  this.handleError("peerconnection" /* PEERCONNECTION */, "set local description failed");
653
737
  }
654
738
  }
655
739
  closePeerConnection() {
656
- if (this.peerConnection) {
657
- if (this.peerConnection.signalingState !== "closed") {
658
- this.peerConnection.close();
740
+ if (this.#peerConnection) {
741
+ if (this.#peerConnection.signalingState !== "closed") {
742
+ this.#peerConnection.close();
659
743
  }
660
- this.peerConnection = undefined;
744
+ this.#peerConnection = undefined;
661
745
  }
662
746
  }
663
747
  closeWSConnection() {
664
- if (this.ws && this.ws.readyState < WebSocket.CLOSING) {
665
- this.ws.close(WS_CLOSE_CODE);
748
+ if (this.#ws && this.#ws.readyState < WebSocket.CLOSING) {
749
+ this.#ws.close(WS_CLOSE_CODE);
666
750
  }
667
751
  }
668
752
  parseMessage(data) {
@@ -675,6 +759,9 @@ class WebRTCStreamer {
675
759
  tracerLog(event, data) {
676
760
  return this.config.tracer?.log(event, import_videoplayer_shared.flattenObject(data));
677
761
  }
762
+ logStat(event, data) {
763
+ this.config.statisticsLogger?.log(event, data);
764
+ }
678
765
  }
679
766
  __legacyDecorateClassTS([
680
767
  WebRTCStreamer.notDestroying
@@ -694,6 +781,9 @@ __legacyDecorateClassTS([
694
781
  __legacyDecorateClassTS([
695
782
  WebRTCStreamer.notDestroying
696
783
  ], WebRTCStreamer.prototype, "disableScreenShare", null);
784
+ __legacyDecorateClassTS([
785
+ WebRTCStreamer.notDestroying
786
+ ], WebRTCStreamer.prototype, "switchMediaDevices", null);
697
787
  __legacyDecorateClassTS([
698
788
  WebRTCStreamer.notDestroying
699
789
  ], WebRTCStreamer.prototype, "setMicMuted", null);
@@ -704,6 +794,9 @@ __legacyDecorateClassTS([
704
794
  WebRTCStreamer.notDestroying
705
795
  ], WebRTCStreamer.prototype, "destroy", null);
706
796
 
707
- //# debugId=710FC6A0B6D5946064756E2164756E21
797
+ // src/index.ts
798
+ var MediaUtils = { enumerateDevices, getUserStream };
799
+
800
+ //# debugId=47A20B45F14C6D9264756E2164756E21
708
801
 
709
802
  //# sourceMappingURL=media-streaming.cjs.map