@microsoft/live-share-media 1.0.0-preview.11 → 1.0.0-preview.13

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.
Files changed (100) hide show
  1. package/README.md +1 -1
  2. package/bin/EphemeralMediaSession.d.ts +102 -0
  3. package/bin/EphemeralMediaSession.d.ts.map +1 -0
  4. package/bin/EphemeralMediaSession.js +226 -0
  5. package/bin/EphemeralMediaSession.js.map +1 -0
  6. package/bin/EphemeralMediaSessionCoordinator.d.ts +228 -0
  7. package/bin/EphemeralMediaSessionCoordinator.d.ts.map +1 -0
  8. package/bin/EphemeralMediaSessionCoordinator.js +396 -0
  9. package/bin/EphemeralMediaSessionCoordinator.js.map +1 -0
  10. package/bin/EphemeralMediaSessionCoordinatorSuspension.d.ts +20 -0
  11. package/bin/EphemeralMediaSessionCoordinatorSuspension.d.ts.map +1 -0
  12. package/bin/EphemeralMediaSessionCoordinatorSuspension.js +28 -0
  13. package/bin/EphemeralMediaSessionCoordinatorSuspension.js.map +1 -0
  14. package/bin/IMediaPlayer.d.ts +21 -0
  15. package/bin/IMediaPlayer.d.ts.map +1 -0
  16. package/bin/IMediaPlayer.js +7 -0
  17. package/bin/IMediaPlayer.js.map +1 -0
  18. package/bin/LiveMediaSession.d.ts +96 -0
  19. package/bin/LiveMediaSession.d.ts.map +1 -0
  20. package/bin/LiveMediaSession.js +236 -0
  21. package/bin/LiveMediaSession.js.map +1 -0
  22. package/bin/LiveMediaSessionCoordinator.d.ts +239 -0
  23. package/bin/LiveMediaSessionCoordinator.d.ts.map +1 -0
  24. package/bin/LiveMediaSessionCoordinator.js +477 -0
  25. package/bin/LiveMediaSessionCoordinator.js.map +1 -0
  26. package/bin/LiveMediaSessionCoordinatorSuspension.d.ts +20 -0
  27. package/bin/LiveMediaSessionCoordinatorSuspension.d.ts.map +1 -0
  28. package/bin/LiveMediaSessionCoordinatorSuspension.js +28 -0
  29. package/bin/LiveMediaSessionCoordinatorSuspension.js.map +1 -0
  30. package/bin/MediaPlayerSynchronizer.d.ts +174 -0
  31. package/bin/MediaPlayerSynchronizer.d.ts.map +1 -0
  32. package/bin/MediaPlayerSynchronizer.js +492 -0
  33. package/bin/MediaPlayerSynchronizer.js.map +1 -0
  34. package/bin/MediaSessionActionThrottler.d.ts +12 -0
  35. package/bin/MediaSessionActionThrottler.d.ts.map +1 -0
  36. package/bin/MediaSessionActionThrottler.js +14 -0
  37. package/bin/MediaSessionActionThrottler.js.map +1 -0
  38. package/bin/MediaSessionExtensions.d.ts +35 -0
  39. package/bin/MediaSessionExtensions.d.ts.map +1 -0
  40. package/bin/MediaSessionExtensions.js +13 -0
  41. package/bin/MediaSessionExtensions.js.map +1 -0
  42. package/bin/RepeatedActionThrottler.d.ts +20 -0
  43. package/bin/RepeatedActionThrottler.d.ts.map +1 -0
  44. package/bin/RepeatedActionThrottler.js +63 -0
  45. package/bin/RepeatedActionThrottler.js.map +1 -0
  46. package/bin/VolumeLimiter.d.ts +70 -0
  47. package/bin/VolumeLimiter.d.ts.map +1 -0
  48. package/bin/VolumeLimiter.js +170 -0
  49. package/bin/VolumeLimiter.js.map +1 -0
  50. package/bin/VolumeManager.d.ts +84 -0
  51. package/bin/VolumeManager.d.ts.map +1 -0
  52. package/bin/VolumeManager.js +175 -0
  53. package/bin/VolumeManager.js.map +1 -0
  54. package/bin/index.d.ts +14 -0
  55. package/bin/index.d.ts.map +1 -0
  56. package/bin/index.js +30 -0
  57. package/bin/index.js.map +1 -0
  58. package/bin/internals/GroupCoordinatorState.d.ts +94 -0
  59. package/bin/internals/GroupCoordinatorState.d.ts.map +1 -0
  60. package/bin/internals/GroupCoordinatorState.js +408 -0
  61. package/bin/internals/GroupCoordinatorState.js.map +1 -0
  62. package/bin/internals/GroupPlaybackPosition.d.ts +68 -0
  63. package/bin/internals/GroupPlaybackPosition.d.ts.map +1 -0
  64. package/bin/internals/GroupPlaybackPosition.js +167 -0
  65. package/bin/internals/GroupPlaybackPosition.js.map +1 -0
  66. package/bin/internals/GroupPlaybackTrack.d.ts +46 -0
  67. package/bin/internals/GroupPlaybackTrack.d.ts.map +1 -0
  68. package/bin/internals/GroupPlaybackTrack.js +122 -0
  69. package/bin/internals/GroupPlaybackTrack.js.map +1 -0
  70. package/bin/internals/GroupPlaybackTrackData.d.ts +40 -0
  71. package/bin/internals/GroupPlaybackTrackData.d.ts.map +1 -0
  72. package/bin/internals/GroupPlaybackTrackData.js +70 -0
  73. package/bin/internals/GroupPlaybackTrackData.js.map +1 -0
  74. package/bin/internals/GroupTransportState.d.ts +50 -0
  75. package/bin/internals/GroupTransportState.d.ts.map +1 -0
  76. package/bin/internals/GroupTransportState.js +112 -0
  77. package/bin/internals/GroupTransportState.js.map +1 -0
  78. package/bin/internals/consts.d.ts +76 -0
  79. package/bin/internals/consts.d.ts.map +1 -0
  80. package/bin/internals/consts.js +85 -0
  81. package/bin/internals/consts.js.map +1 -0
  82. package/bin/internals/index.d.ts +11 -0
  83. package/bin/internals/index.d.ts.map +1 -0
  84. package/bin/internals/index.js +27 -0
  85. package/bin/internals/index.js.map +1 -0
  86. package/package.json +4 -4
  87. package/src/LiveMediaSession.ts +24 -12
  88. package/src/LiveMediaSessionCoordinator.ts +101 -29
  89. package/src/MediaPlayerSynchronizer.ts +30 -14
  90. package/src/internals/GroupCoordinatorState.ts +49 -35
  91. package/src/internals/GroupPlaybackPosition.ts +6 -2
  92. package/src/internals/GroupPlaybackTrack.ts +2 -2
  93. package/src/internals/GroupPlaybackTrackData.ts +2 -2
  94. package/src/internals/GroupTransportState.ts +11 -4
  95. package/src/internals/consts.ts +4 -0
  96. package/src/test/GroupPlaybackPosition.spec.ts +0 -600
  97. package/src/test/GroupPlaybackTrack.spec.ts +0 -122
  98. package/src/test/SharedMediaSession.spec.ts +0 -149
  99. package/src/test/SharedMediaSessionCoordinator.spec.ts +0 -271
  100. package/src/test/VolumeManager.spec.ts +0 -219
@@ -4,13 +4,12 @@
4
4
  */
5
5
 
6
6
  import {
7
- IEvent,
8
7
  ILiveEvent,
9
- LiveEvent,
10
8
  TimeInterval,
11
9
  IRuntimeSignaler,
12
10
  LiveTelemetryLogger,
13
- LiveShareClient,
11
+ LiveShareRuntime,
12
+ IEvent,
14
13
  } from "@microsoft/live-share";
15
14
  import EventEmitter from "events";
16
15
  import {
@@ -41,7 +40,7 @@ import { TelemetryEvents } from "./consts";
41
40
  /**
42
41
  * @hidden
43
42
  */
44
- export interface IPositionUpdateEvent extends ILiveEvent {
43
+ export interface IPositionUpdateEvent {
45
44
  track: IPlaybackTrack;
46
45
  trackData: IPlaybackTrackData;
47
46
  transport: ITransportState;
@@ -53,7 +52,7 @@ export interface IPositionUpdateEvent extends ILiveEvent {
53
52
  /**
54
53
  * @hidden
55
54
  */
56
- export interface ITransportCommandEvent extends ILiveEvent {
55
+ export interface ITransportCommandEvent {
57
56
  track: IPlaybackTrack;
58
57
  position: number;
59
58
  }
@@ -61,7 +60,7 @@ export interface ITransportCommandEvent extends ILiveEvent {
61
60
  /**
62
61
  * @hidden
63
62
  */
64
- export interface ISetTrackEvent extends ILiveEvent {
63
+ export interface ISetTrackEvent {
65
64
  metadata: ExtendedMediaMetadata | null;
66
65
  waitPoints: CoordinationWaitPoint[];
67
66
  }
@@ -69,7 +68,7 @@ export interface ISetTrackEvent extends ILiveEvent {
69
68
  /**
70
69
  * @hidden
71
70
  */
72
- export interface ISetTrackDataEvent extends ILiveEvent {
71
+ export interface ISetTrackDataEvent {
73
72
  data: object | null;
74
73
  }
75
74
 
@@ -93,6 +92,7 @@ export enum GroupCoordinatorStateEvents {
93
92
  */
94
93
  export class GroupCoordinatorState extends EventEmitter {
95
94
  private readonly _runtime: IRuntimeSignaler;
95
+ private readonly _liveRuntime: LiveShareRuntime;
96
96
  private readonly _logger: LiveTelemetryLogger;
97
97
  private readonly _maxPlaybackDrift: TimeInterval;
98
98
  private _getMediaPlayerState: () => IMediaPlayerState;
@@ -116,13 +116,15 @@ export class GroupCoordinatorState extends EventEmitter {
116
116
 
117
117
  constructor(
118
118
  runtime: IRuntimeSignaler,
119
+ liveRuntime: LiveShareRuntime,
119
120
  maxPlaybackDrift: TimeInterval,
120
121
  positionUpdateInterval: TimeInterval,
121
122
  getMediaPlayerState: () => IMediaPlayerState
122
123
  ) {
123
124
  super();
124
125
  this._runtime = runtime;
125
- this._logger = new LiveTelemetryLogger(runtime);
126
+ this._liveRuntime = liveRuntime;
127
+ this._logger = new LiveTelemetryLogger(runtime, liveRuntime);
126
128
  this._maxPlaybackDrift = maxPlaybackDrift;
127
129
  this._playbackTrack = new GroupPlaybackTrack(getMediaPlayerState);
128
130
  this._playbackTrackData = new GroupPlaybackTrackData(
@@ -130,11 +132,13 @@ export class GroupCoordinatorState extends EventEmitter {
130
132
  );
131
133
  this._transportState = new GroupTransportState(
132
134
  this._playbackTrack,
133
- getMediaPlayerState
135
+ getMediaPlayerState,
136
+ this._liveRuntime
134
137
  );
135
138
  this._playbackPosition = new GroupPlaybackPosition(
136
139
  this._transportState,
137
140
  this._runtime,
141
+ this._liveRuntime,
138
142
  positionUpdateInterval
139
143
  );
140
144
  this._getMediaPlayerState = getMediaPlayerState;
@@ -279,7 +283,7 @@ export class GroupCoordinatorState extends EventEmitter {
279
283
 
280
284
  public createPositionUpdateEvent(
281
285
  state: IMediaPlayerState
282
- ): Partial<IPositionUpdateEvent> {
286
+ ): IPositionUpdateEvent {
283
287
  const { positionState, playbackState } = state;
284
288
  if (this.isSuspended) {
285
289
  // Report suspension state
@@ -304,12 +308,15 @@ export class GroupCoordinatorState extends EventEmitter {
304
308
  }
305
309
  }
306
310
 
307
- public handleSetTrack(event: ISetTrackEvent, local: boolean): void {
311
+ public handleSetTrack(
312
+ event: ILiveEvent<ISetTrackEvent>,
313
+ local: boolean
314
+ ): void {
308
315
  // Update shared track
309
316
  // - Will trigger 'trackChange' event to update media session
310
317
  const updated = this.playbackTrack.updateTrack({
311
- metadata: event.metadata,
312
- waitPoints: event.waitPoints,
318
+ metadata: event.data.metadata,
319
+ waitPoints: event.data.waitPoints,
313
320
  timestamp: event.timestamp,
314
321
  clientId: event.clientId || "",
315
322
  });
@@ -328,11 +335,14 @@ export class GroupCoordinatorState extends EventEmitter {
328
335
  }
329
336
  }
330
337
 
331
- public handleSetTrackData(event: ISetTrackDataEvent, local: boolean): void {
338
+ public handleSetTrackData(
339
+ event: ILiveEvent<ISetTrackDataEvent>,
340
+ local: boolean
341
+ ): void {
332
342
  // Update shared track data
333
343
  // - Will trigger 'dataChange' event to update media session
334
344
  const updated = this.playbackTrackData.updateData({
335
- data: event.data,
345
+ data: event.data.data,
336
346
  timestamp: event.timestamp,
337
347
  clientId: event.clientId || "",
338
348
  });
@@ -352,13 +362,13 @@ export class GroupCoordinatorState extends EventEmitter {
352
362
  }
353
363
 
354
364
  public handleTransportCommand(
355
- event: ITransportCommandEvent,
365
+ event: ILiveEvent<ITransportCommandEvent>,
356
366
  local: boolean
357
367
  ): void {
358
368
  // Ensure change is for current track
359
369
  // - Will trigger a 'trackChange' event if newer track.
360
- this.playbackTrack.updateTrack(event.track);
361
- if (this.playbackTrack.compare(event.track.metadata)) {
370
+ this.playbackTrack.updateTrack(event.data.track);
371
+ if (this.playbackTrack.compare(event.data.track.metadata)) {
362
372
  // Update playback state
363
373
  let playbackState = this.transportState.playbackState;
364
374
  switch (event.name) {
@@ -373,7 +383,7 @@ export class GroupCoordinatorState extends EventEmitter {
373
383
  // Try to update playback state
374
384
  const newState: ITransportState = {
375
385
  playbackState: playbackState,
376
- startPosition: event.position,
386
+ startPosition: event.data.position,
377
387
  timestamp: event.timestamp,
378
388
  clientId: event.clientId || "",
379
389
  };
@@ -421,30 +431,30 @@ export class GroupCoordinatorState extends EventEmitter {
421
431
  }
422
432
 
423
433
  public handlePositionUpdate(
424
- event: IPositionUpdateEvent,
434
+ event: Omit<ILiveEvent<IPositionUpdateEvent>, "name">,
425
435
  local: boolean
426
436
  ): void {
427
437
  // Ensure change is for current track
428
438
  // - Will trigger a 'trackChange' event if newer track.
429
- this.playbackTrack.updateTrack(event.track);
430
- if (this.playbackTrack.compare(event.track.metadata)) {
439
+ this.playbackTrack.updateTrack(event.data.track);
440
+ if (this.playbackTrack.compare(event.data.track.metadata)) {
431
441
  // Ensure we have the latest track data
432
- this.playbackTrackData.updateData(event.trackData);
442
+ this.playbackTrackData.updateData(event.data.trackData);
433
443
 
434
444
  // Update transport state if needed
435
445
  // - Ignore transport state changes if the client has ended as this will cause the local
436
446
  // player to start playback even though the video may have ended for everyone.
437
- if (event.playbackState != "ended") {
438
- this.transportState.updateState(event.transport);
447
+ if (event.data.playbackState != "ended") {
448
+ this.transportState.updateState(event.data.transport);
439
449
  }
440
450
 
441
451
  // Ensure change is for current transport state
442
- if (this.transportState.compare(event.transport)) {
452
+ if (this.transportState.compare(event.data.transport)) {
443
453
  // Update playback position
444
454
  const position: ICurrentPlaybackPosition = {
445
- playbackState: event.playbackState,
446
- waitPoint: event.waitPoint,
447
- position: event.position,
455
+ playbackState: event.data.playbackState,
456
+ waitPoint: event.data.waitPoint,
457
+ position: event.data.position,
448
458
  timestamp: event.timestamp,
449
459
  clientId: event.clientId || "",
450
460
  };
@@ -456,20 +466,24 @@ export class GroupCoordinatorState extends EventEmitter {
456
466
  // - This is needed because the catchup logic can try to sink the client with
457
467
  // the rest of the group while the local player is trying to to seek to a
458
468
  // new position.
459
- switch (event.playbackState) {
469
+ switch (event.data.playbackState) {
460
470
  case "none":
461
471
  case "paused":
462
472
  case "playing":
463
- if (event.playbackState != this._lastStateChange) {
473
+ if (
474
+ event.data.playbackState !=
475
+ this._lastStateChange
476
+ ) {
464
477
  this._logger.sendTelemetryEvent(
465
478
  TelemetryEvents.GroupCoordinator
466
479
  .BeginSoftSuspension,
467
480
  null,
468
- { playbackState: event.playbackState }
481
+ { playbackState: event.data.playbackState }
469
482
  );
470
- this._lastStateChange = event.playbackState;
483
+ this._lastStateChange =
484
+ event.data.playbackState;
471
485
  this._lastStateChangeTime =
472
- LiveShareClient.getTimestamp();
486
+ this._liveRuntime.getTimestamp();
473
487
  }
474
488
  break;
475
489
  }
@@ -495,7 +509,7 @@ export class GroupCoordinatorState extends EventEmitter {
495
509
  public async syncLocalMediaSession(): Promise<void> {
496
510
  // Skip further syncs if we're waiting or in a "soft suspension".
497
511
  const softSuspensionDelta =
498
- LiveShareClient.getTimestamp() - this._lastStateChangeTime;
512
+ this._liveRuntime.getTimestamp() - this._lastStateChangeTime;
499
513
  if (!this.isWaiting && softSuspensionDelta >= 1000) {
500
514
  let { metadata, trackData, positionState, playbackState } =
501
515
  this._getMediaPlayerState();
@@ -7,6 +7,7 @@ import {
7
7
  IRuntimeSignaler,
8
8
  TimeInterval,
9
9
  LiveShareClient,
10
+ LiveShareRuntime,
10
11
  } from "@microsoft/live-share";
11
12
  import { GroupTransportState } from "./GroupTransportState";
12
13
  import { GroupPlaybackTrackEvents } from "./GroupPlaybackTrack";
@@ -34,16 +35,19 @@ export interface ICurrentPlaybackPosition {
34
35
  export class GroupPlaybackPosition {
35
36
  private _transportState: GroupTransportState;
36
37
  private _runtime: IRuntimeSignaler;
38
+ private _liveRuntime: LiveShareRuntime;
37
39
  private _updateInterval: TimeInterval;
38
40
  private _positions: Map<string, ICurrentPlaybackPosition>;
39
41
 
40
42
  constructor(
41
43
  transportState: GroupTransportState,
42
44
  runtime: IRuntimeSignaler,
45
+ liveRuntime: LiveShareRuntime,
43
46
  updateInterval: TimeInterval
44
47
  ) {
45
48
  this._transportState = transportState;
46
49
  this._runtime = runtime;
50
+ this._liveRuntime = liveRuntime;
47
51
  this._updateInterval = updateInterval;
48
52
  this._positions = new Map();
49
53
 
@@ -129,7 +133,7 @@ export class GroupPlaybackPosition {
129
133
  */
130
134
  public get maxPosition(): number {
131
135
  if (this._transportState.playbackState == "playing") {
132
- const now = LiveShareClient.getTimestamp();
136
+ const now = this._liveRuntime.getTimestamp();
133
137
  const projected =
134
138
  this._transportState.startPosition +
135
139
  (now - this._transportState.timestamp) / 1000;
@@ -162,7 +166,7 @@ export class GroupPlaybackPosition {
162
166
  projectedPosition: number
163
167
  ) => void
164
168
  ): void {
165
- const now = LiveShareClient.getTimestamp();
169
+ const now = this._liveRuntime.getTimestamp();
166
170
  const ignoreBefore = now - this._updateInterval.milliseconds * 2;
167
171
  const shouldProject = !this._transportState.track.metadata?.liveStream;
168
172
  this._positions.forEach((value, key) => {
@@ -3,7 +3,7 @@
3
3
  * Licensed under the Microsoft Live Share SDK License.
4
4
  */
5
5
 
6
- import { IEvent } from "@microsoft/live-share";
6
+ import { ILiveEvent } from "@microsoft/live-share";
7
7
  import EventEmitter from "events";
8
8
  import { IMediaPlayerState } from "../LiveMediaSessionCoordinator";
9
9
  import {
@@ -31,7 +31,7 @@ export enum GroupPlaybackTrackEvents {
31
31
  /**
32
32
  * @hidden
33
33
  */
34
- export interface IPlaybackTrackChangeEvent extends IEvent {
34
+ export interface IPlaybackTrackChangeEvent extends ILiveEvent {
35
35
  metadata: ExtendedMediaMetadata | null;
36
36
  }
37
37
 
@@ -3,7 +3,7 @@
3
3
  * Licensed under the Microsoft Live Share SDK License.
4
4
  */
5
5
 
6
- import { IEvent } from "@microsoft/live-share";
6
+ import { ILiveEvent } from "@microsoft/live-share";
7
7
  import EventEmitter from "events";
8
8
  import {
9
9
  GroupPlaybackTrack,
@@ -29,7 +29,7 @@ export enum PlaybackTrackDataEvents {
29
29
  /**
30
30
  * @hidden
31
31
  */
32
- export interface IPlaybackTrackDataChangeEvent extends IEvent {
32
+ export interface IPlaybackTrackDataChangeEvent extends ILiveEvent {
33
33
  data: object | null;
34
34
  }
35
35
 
@@ -3,7 +3,11 @@
3
3
  * Licensed under the Microsoft Live Share SDK License.
4
4
  */
5
5
 
6
- import { IEvent, LiveShareClient } from "@microsoft/live-share";
6
+ import {
7
+ ILiveEvent,
8
+ LiveShareRuntime,
9
+ LiveShareClient,
10
+ } from "@microsoft/live-share";
7
11
  import EventEmitter from "events";
8
12
  import { IMediaPlayerState } from "../LiveMediaSessionCoordinator";
9
13
  import {
@@ -35,7 +39,7 @@ export enum GroupTransportStateEvents {
35
39
  /**
36
40
  * @hidden
37
41
  */
38
- export interface ITransportStateChangeEvent extends IEvent {
42
+ export interface ITransportStateChangeEvent extends ILiveEvent {
39
43
  action: ExtendedMediaSessionAction;
40
44
  seekTime?: number;
41
45
  }
@@ -46,13 +50,16 @@ export interface ITransportStateChangeEvent extends IEvent {
46
50
  export class GroupTransportState extends EventEmitter {
47
51
  private readonly _getMediaPlayerState: () => IMediaPlayerState;
48
52
  private _track: GroupPlaybackTrack;
53
+ private readonly _liveRuntime: LiveShareRuntime;
49
54
  private _current: ITransportState;
50
55
 
51
56
  constructor(
52
57
  track: GroupPlaybackTrack,
53
- getMediaPlayerState: () => IMediaPlayerState
58
+ getMediaPlayerState: () => IMediaPlayerState,
59
+ liveRuntime: LiveShareRuntime
54
60
  ) {
55
61
  super();
62
+ this._liveRuntime = liveRuntime;
56
63
  this._getMediaPlayerState = getMediaPlayerState;
57
64
  this._track = track;
58
65
  this._current = {
@@ -136,7 +143,7 @@ export class GroupTransportState extends EventEmitter {
136
143
  seekTime: state.startPosition,
137
144
  });
138
145
  } else if (state.playbackState == "playing") {
139
- const now = LiveShareClient.getTimestamp();
146
+ const now = this._liveRuntime.getTimestamp();
140
147
  const projectedPosition =
141
148
  state.startPosition + (now - state.timestamp) / 1000;
142
149
  this.emit(GroupTransportStateEvents.transportStateChange, {
@@ -22,6 +22,8 @@ export const TelemetryEvents = {
22
22
  UserTappedVideoToPlay: transmit(
23
23
  "MediaPlayerSynchronizer:UserTappedVideoToPlay"
24
24
  ),
25
+ UserTappedVideoToPlayError:
26
+ "MediaPlayerSynchronizer:UserTappedVideoToPlayError",
25
27
  PlaybackRateChangeBlocked:
26
28
  "MediaPlayerSynchronizer:PlaybackRateChangeBlocked",
27
29
  PlayerBlockedOperation: transmit(
@@ -72,6 +74,8 @@ export const TelemetryEvents = {
72
74
  RemoteSeekToReceived: transmit(
73
75
  "SessionCoordinator:RemoteSeekToReceived"
74
76
  ),
77
+ PositionUpdateEventError: "SessionCoordinator:PositionUpdateEventError",
78
+ SendJoinedEventError: "SessionCoordinator:SendJoinedEventError",
75
79
  },
76
80
  GroupCoordinator: {
77
81
  TrackChanged: "GroupCoordinator:TrackChanged",