@microsoft/live-share-media 1.0.0-preview.1 → 1.0.0-preview.4

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 (96) hide show
  1. package/README.md +2 -1
  2. package/bin/IMediaPlayer.d.ts.map +1 -1
  3. package/bin/LiveMediaSession.d.ts +7 -7
  4. package/bin/LiveMediaSession.d.ts.map +1 -1
  5. package/bin/LiveMediaSession.js +28 -17
  6. package/bin/LiveMediaSession.js.map +1 -1
  7. package/bin/LiveMediaSessionCoordinator.d.ts +2 -2
  8. package/bin/LiveMediaSessionCoordinator.d.ts.map +1 -1
  9. package/bin/LiveMediaSessionCoordinator.js +34 -22
  10. package/bin/LiveMediaSessionCoordinator.js.map +1 -1
  11. package/bin/LiveMediaSessionCoordinatorSuspension.d.ts +1 -1
  12. package/bin/LiveMediaSessionCoordinatorSuspension.d.ts.map +1 -1
  13. package/bin/LiveMediaSessionCoordinatorSuspension.js.map +1 -1
  14. package/bin/MediaPlayerSynchronizer.d.ts +7 -7
  15. package/bin/MediaPlayerSynchronizer.d.ts.map +1 -1
  16. package/bin/MediaPlayerSynchronizer.js +127 -72
  17. package/bin/MediaPlayerSynchronizer.js.map +1 -1
  18. package/bin/MediaSessionActionThrottler.d.ts +1 -1
  19. package/bin/MediaSessionActionThrottler.d.ts.map +1 -1
  20. package/bin/MediaSessionActionThrottler.js.map +1 -1
  21. package/bin/MediaSessionExtensions.d.ts.map +1 -1
  22. package/bin/RepeatedActionThrottler.d.ts +2 -2
  23. package/bin/RepeatedActionThrottler.d.ts.map +1 -1
  24. package/bin/RepeatedActionThrottler.js +9 -3
  25. package/bin/RepeatedActionThrottler.js.map +1 -1
  26. package/bin/VolumeManager.d.ts +1 -1
  27. package/bin/VolumeManager.d.ts.map +1 -1
  28. package/bin/VolumeManager.js +4 -2
  29. package/bin/VolumeManager.js.map +1 -1
  30. package/bin/index.d.ts +9 -9
  31. package/bin/index.d.ts.map +1 -1
  32. package/bin/index.js.map +1 -1
  33. package/bin/internals/GroupCoordinatorState.d.ts +8 -8
  34. package/bin/internals/GroupCoordinatorState.d.ts.map +1 -1
  35. package/bin/internals/GroupCoordinatorState.js +91 -53
  36. package/bin/internals/GroupCoordinatorState.js.map +1 -1
  37. package/bin/internals/GroupPlaybackPosition.d.ts +3 -3
  38. package/bin/internals/GroupPlaybackPosition.d.ts.map +1 -1
  39. package/bin/internals/GroupPlaybackPosition.js +22 -13
  40. package/bin/internals/GroupPlaybackPosition.js.map +1 -1
  41. package/bin/internals/GroupPlaybackTrack.d.ts +4 -4
  42. package/bin/internals/GroupPlaybackTrack.d.ts.map +1 -1
  43. package/bin/internals/GroupPlaybackTrack.js +14 -4
  44. package/bin/internals/GroupPlaybackTrack.js.map +1 -1
  45. package/bin/internals/GroupPlaybackTrackData.d.ts +3 -3
  46. package/bin/internals/GroupPlaybackTrackData.d.ts.map +1 -1
  47. package/bin/internals/GroupPlaybackTrackData.js +8 -4
  48. package/bin/internals/GroupPlaybackTrackData.js.map +1 -1
  49. package/bin/internals/GroupTransportState.d.ts +5 -5
  50. package/bin/internals/GroupTransportState.d.ts.map +1 -1
  51. package/bin/internals/GroupTransportState.js +27 -12
  52. package/bin/internals/GroupTransportState.js.map +1 -1
  53. package/bin/internals/consts.d.ts.map +1 -1
  54. package/bin/internals/consts.js +54 -54
  55. package/bin/internals/consts.js.map +1 -1
  56. package/bin/internals/index.d.ts +6 -6
  57. package/package.json +3 -3
  58. package/src/IMediaPlayer.ts +10 -2
  59. package/src/LiveMediaSession.ts +133 -71
  60. package/src/LiveMediaSessionCoordinator.ts +302 -142
  61. package/src/LiveMediaSessionCoordinatorSuspension.ts +13 -5
  62. package/src/MediaPlayerSynchronizer.ts +329 -149
  63. package/src/MediaSessionActionThrottler.ts +5 -3
  64. package/src/MediaSessionExtensions.ts +15 -5
  65. package/src/RepeatedActionThrottler.ts +27 -9
  66. package/src/VolumeManager.ts +24 -12
  67. package/src/index.ts +9 -10
  68. package/src/internals/GroupCoordinatorState.ts +274 -114
  69. package/src/internals/GroupPlaybackPosition.ts +61 -27
  70. package/src/internals/GroupPlaybackTrack.ts +51 -22
  71. package/src/internals/GroupPlaybackTrackData.ts +24 -16
  72. package/src/internals/GroupTransportState.ts +53 -23
  73. package/src/internals/consts.ts +73 -55
  74. package/src/internals/index.ts +6 -6
  75. package/src/test/GroupPlaybackPosition.spec.ts +371 -111
  76. package/src/test/GroupPlaybackTrack.spec.ts +91 -35
  77. package/src/test/SharedMediaSession.spec.ts +64 -28
  78. package/src/test/SharedMediaSessionCoordinator.spec.ts +86 -46
  79. package/src/test/VolumeManager.spec.ts +38 -31
  80. package/tsconfig.json +1 -0
  81. package/bin/EphemeralMediaSession.d.ts +0 -102
  82. package/bin/EphemeralMediaSession.d.ts.map +0 -1
  83. package/bin/EphemeralMediaSession.js +0 -226
  84. package/bin/EphemeralMediaSession.js.map +0 -1
  85. package/bin/EphemeralMediaSessionCoordinator.d.ts +0 -228
  86. package/bin/EphemeralMediaSessionCoordinator.d.ts.map +0 -1
  87. package/bin/EphemeralMediaSessionCoordinator.js +0 -396
  88. package/bin/EphemeralMediaSessionCoordinator.js.map +0 -1
  89. package/bin/EphemeralMediaSessionCoordinatorSuspension.d.ts +0 -20
  90. package/bin/EphemeralMediaSessionCoordinatorSuspension.d.ts.map +0 -1
  91. package/bin/EphemeralMediaSessionCoordinatorSuspension.js +0 -28
  92. package/bin/EphemeralMediaSessionCoordinatorSuspension.js.map +0 -1
  93. package/bin/VolumeLimiter.d.ts +0 -70
  94. package/bin/VolumeLimiter.d.ts.map +0 -1
  95. package/bin/VolumeLimiter.js +0 -170
  96. package/bin/VolumeLimiter.js.map +0 -1
@@ -3,16 +3,39 @@
3
3
  * Licensed under the Microsoft Live Share SDK License.
4
4
  */
5
5
 
6
- import { IEvent, ILiveEvent, LiveEvent, TimeInterval, IRuntimeSignaler, LiveTelemetryLogger } from '@microsoft/live-share';
7
- import EventEmitter from 'events';
8
- import { ExtendedMediaMetadata, CoordinationWaitPoint, ExtendedMediaSessionPlaybackState, ExtendedMediaSessionActionDetails } from '../MediaSessionExtensions';
9
- import { GroupPlaybackTrack, GroupPlaybackTrackEvents, IPlaybackTrack } from './GroupPlaybackTrack';
10
- import { GroupTransportState, ITransportState } from './GroupTransportState';
11
- import { GroupPlaybackPosition, ICurrentPlaybackPosition } from './GroupPlaybackPosition';
12
- import { IMediaPlayerState } from '../LiveMediaSessionCoordinator';
13
- import { GroupTransportStateEvents } from './GroupTransportState';
14
- import { GroupPlaybackTrackData, PlaybackTrackDataEvents, IPlaybackTrackData } from './GroupPlaybackTrackData';
15
- import { TelemetryEvents } from './consts';
6
+ import {
7
+ IEvent,
8
+ ILiveEvent,
9
+ LiveEvent,
10
+ TimeInterval,
11
+ IRuntimeSignaler,
12
+ LiveTelemetryLogger,
13
+ } from "@microsoft/live-share";
14
+ import EventEmitter from "events";
15
+ import {
16
+ ExtendedMediaMetadata,
17
+ CoordinationWaitPoint,
18
+ ExtendedMediaSessionPlaybackState,
19
+ ExtendedMediaSessionActionDetails,
20
+ } from "../MediaSessionExtensions";
21
+ import {
22
+ GroupPlaybackTrack,
23
+ GroupPlaybackTrackEvents,
24
+ IPlaybackTrack,
25
+ } from "./GroupPlaybackTrack";
26
+ import { GroupTransportState, ITransportState } from "./GroupTransportState";
27
+ import {
28
+ GroupPlaybackPosition,
29
+ ICurrentPlaybackPosition,
30
+ } from "./GroupPlaybackPosition";
31
+ import { IMediaPlayerState } from "../LiveMediaSessionCoordinator";
32
+ import { GroupTransportStateEvents } from "./GroupTransportState";
33
+ import {
34
+ GroupPlaybackTrackData,
35
+ PlaybackTrackDataEvents,
36
+ IPlaybackTrackData,
37
+ } from "./GroupPlaybackTrackData";
38
+ import { TelemetryEvents } from "./consts";
16
39
 
17
40
  /**
18
41
  * @hidden
@@ -38,7 +61,7 @@ export interface ITransportCommandEvent extends ILiveEvent {
38
61
  * @hidden
39
62
  */
40
63
  export interface ISetTrackEvent extends ILiveEvent {
41
- metadata: ExtendedMediaMetadata|null;
64
+ metadata: ExtendedMediaMetadata | null;
42
65
  waitPoints: CoordinationWaitPoint[];
43
66
  }
44
67
 
@@ -46,13 +69,13 @@ export interface ISetTrackEvent extends ILiveEvent {
46
69
  * @hidden
47
70
  */
48
71
  export interface ISetTrackDataEvent extends ILiveEvent {
49
- data: object|null;
72
+ data: object | null;
50
73
  }
51
74
 
52
75
  /**
53
76
  * @hidden
54
77
  */
55
- export interface ITriggerActionEvent extends IEvent {
78
+ export interface ITriggerActionEvent extends IEvent {
56
79
  details: ExtendedMediaSessionActionDetails;
57
80
  }
58
81
 
@@ -60,14 +83,14 @@ export interface ISetTrackDataEvent extends ILiveEvent {
60
83
  * @hidden
61
84
  */
62
85
  export enum GroupCoordinatorStateEvents {
63
- newwaitpoint = 'newwaitpoint',
64
- triggeraction = 'triggeraction'
86
+ newwaitpoint = "newwaitpoint",
87
+ triggeraction = "triggeraction",
65
88
  }
66
89
 
67
90
  /**
68
91
  * @hidden
69
92
  */
70
- export class GroupCoordinatorState extends EventEmitter {
93
+ export class GroupCoordinatorState extends EventEmitter {
71
94
  private readonly _runtime: IRuntimeSignaler;
72
95
  private readonly _logger: LiveTelemetryLogger;
73
96
  private readonly _maxPlaybackDrift: TimeInterval;
@@ -87,69 +110,118 @@ export enum GroupCoordinatorStateEvents {
87
110
  // - Soft suspensions temporarily disconnect the local media session when transitioning between
88
111
  // paused, playing, and none states. This is to give the local client time to finish any inprogress
89
112
  // operations like sending a transport command or ending a suspension.
90
- private _lastStateChange: ExtendedMediaSessionPlaybackState = 'none';
113
+ private _lastStateChange: ExtendedMediaSessionPlaybackState = "none";
91
114
  private _lastStateChangeTime: number = 0;
92
115
 
93
- constructor (runtime: IRuntimeSignaler, maxPlaybackDrift: TimeInterval, positionUpdateInterval: TimeInterval, getMediaPlayerState: () => IMediaPlayerState) {
116
+ constructor(
117
+ runtime: IRuntimeSignaler,
118
+ maxPlaybackDrift: TimeInterval,
119
+ positionUpdateInterval: TimeInterval,
120
+ getMediaPlayerState: () => IMediaPlayerState
121
+ ) {
94
122
  super();
95
123
  this._runtime = runtime;
96
124
  this._logger = new LiveTelemetryLogger(runtime);
97
125
  this._maxPlaybackDrift = maxPlaybackDrift;
98
126
  this._playbackTrack = new GroupPlaybackTrack(getMediaPlayerState);
99
- this._playbackTrackData = new GroupPlaybackTrackData(this._playbackTrack);
100
- this._transportState = new GroupTransportState(this._playbackTrack, getMediaPlayerState);
101
- this._playbackPosition = new GroupPlaybackPosition(this._transportState, this._runtime, positionUpdateInterval);
127
+ this._playbackTrackData = new GroupPlaybackTrackData(
128
+ this._playbackTrack
129
+ );
130
+ this._transportState = new GroupTransportState(
131
+ this._playbackTrack,
132
+ getMediaPlayerState
133
+ );
134
+ this._playbackPosition = new GroupPlaybackPosition(
135
+ this._transportState,
136
+ this._runtime,
137
+ positionUpdateInterval
138
+ );
102
139
  this._getMediaPlayerState = getMediaPlayerState;
103
140
 
104
141
  // Listen track related events
105
- this._playbackTrack.on(GroupPlaybackTrackEvents.trackChange, evt => {
142
+ this._playbackTrack.on(GroupPlaybackTrackEvents.trackChange, (evt) => {
106
143
  if (!this.isSuspended) {
107
- this._logger.sendTelemetryEvent(TelemetryEvents.GroupCoordinator.TrackChanged);
144
+ this._logger.sendTelemetryEvent(
145
+ TelemetryEvents.GroupCoordinator.TrackChanged
146
+ );
108
147
  this.emitSetTrack(evt.metadata!);
109
148
  } else {
110
- this._logger.sendTelemetryEvent(TelemetryEvents.GroupCoordinator.TrackChangeDelayed);
149
+ this._logger.sendTelemetryEvent(
150
+ TelemetryEvents.GroupCoordinator.TrackChangeDelayed
151
+ );
111
152
  }
112
153
  });
113
154
 
114
155
  // Listen for track data changes
115
- this._playbackTrackData.on(PlaybackTrackDataEvents.dataChange, evt => {
116
- if (!this.isSuspended && !this.isWaiting) {
117
- this._logger.sendTelemetryEvent(TelemetryEvents.GroupCoordinator.TrackDataChanged);
118
- this.emitTriggerAction({action: 'datachange', data: evt.data});
119
- } else {
120
- this._logger.sendTelemetryEvent(TelemetryEvents.GroupCoordinator.TrackDataChangeDelayed);
156
+ this._playbackTrackData.on(
157
+ PlaybackTrackDataEvents.dataChange,
158
+ (evt) => {
159
+ if (!this.isSuspended && !this.isWaiting) {
160
+ this._logger.sendTelemetryEvent(
161
+ TelemetryEvents.GroupCoordinator.TrackDataChanged
162
+ );
163
+ this.emitTriggerAction({
164
+ action: "datachange",
165
+ data: evt.data,
166
+ });
167
+ } else {
168
+ this._logger.sendTelemetryEvent(
169
+ TelemetryEvents.GroupCoordinator.TrackDataChangeDelayed
170
+ );
171
+ }
121
172
  }
122
- });
173
+ );
123
174
 
124
175
  // Listen to transport related events
125
- this._transportState.on(GroupTransportStateEvents.transportStateChange, evt => {
126
- if (!this.isSuspended && !this.isWaiting) {
127
- this._logger.sendTelemetryEvent(TelemetryEvents.GroupCoordinator.TransportStateChanged, null, {
128
- action: evt.action,
129
- seekTime: evt.seekTime
130
- });
131
-
132
- // Trigger action
133
- switch (evt.action) {
134
- case 'play':
135
- this.emitTriggerAction({action: 'play', seekTime: evt.seekTime});
136
- break;
176
+ this._transportState.on(
177
+ GroupTransportStateEvents.transportStateChange,
178
+ (evt) => {
179
+ if (!this.isSuspended && !this.isWaiting) {
180
+ this._logger.sendTelemetryEvent(
181
+ TelemetryEvents.GroupCoordinator.TransportStateChanged,
182
+ null,
183
+ {
184
+ action: evt.action,
185
+ seekTime: evt.seekTime,
186
+ }
187
+ );
188
+
189
+ // Trigger action
190
+ switch (evt.action) {
191
+ case "play":
192
+ this.emitTriggerAction({
193
+ action: "play",
194
+ seekTime: evt.seekTime,
195
+ });
196
+ break;
137
197
 
138
- case 'pause':
139
- this.emitTriggerAction({action: 'pause', seekTime: evt.seekTime});
140
- break;
198
+ case "pause":
199
+ this.emitTriggerAction({
200
+ action: "pause",
201
+ seekTime: evt.seekTime,
202
+ });
203
+ break;
141
204
 
142
- case 'seekto':
143
- this.emitTriggerAction({action: 'seekto', seekTime: evt.seekTime});
144
- break;
205
+ case "seekto":
206
+ this.emitTriggerAction({
207
+ action: "seekto",
208
+ seekTime: evt.seekTime,
209
+ });
210
+ break;
211
+ }
212
+ } else {
213
+ this._logger.sendTelemetryEvent(
214
+ TelemetryEvents.GroupCoordinator
215
+ .TransportStateChangeDelayed,
216
+ null,
217
+ {
218
+ action: evt.action,
219
+ seekTime: evt.seekTime,
220
+ }
221
+ );
145
222
  }
146
- } else {
147
- this._logger.sendTelemetryEvent(TelemetryEvents.GroupCoordinator.TransportStateChangeDelayed, null, {
148
- action: evt.action,
149
- seekTime: evt.seekTime
150
- });
151
223
  }
152
- });
224
+ );
153
225
  }
154
226
 
155
227
  public get playbackTrack(): GroupPlaybackTrack {
@@ -168,7 +240,7 @@ export enum GroupCoordinatorStateEvents {
168
240
  return this._playbackPosition;
169
241
  }
170
242
 
171
- public get waitingAt(): CoordinationWaitPoint|undefined {
243
+ public get waitingAt(): CoordinationWaitPoint | undefined {
172
244
  return this._waitPoint;
173
245
  }
174
246
 
@@ -204,7 +276,9 @@ export enum GroupCoordinatorStateEvents {
204
276
  }
205
277
  }
206
278
 
207
- public createPositionUpdateEvent(state: IMediaPlayerState): Partial<IPositionUpdateEvent> {
279
+ public createPositionUpdateEvent(
280
+ state: IMediaPlayerState
281
+ ): Partial<IPositionUpdateEvent> {
208
282
  const { positionState, playbackState } = state;
209
283
  if (this.isSuspended) {
210
284
  // Report suspension state
@@ -212,9 +286,9 @@ export enum GroupCoordinatorStateEvents {
212
286
  track: this.playbackTrack.current,
213
287
  trackData: this.playbackTrackData.current,
214
288
  transport: this.transportState.current,
215
- playbackState: 'suspended',
289
+ playbackState: "suspended",
216
290
  position: positionState?.position || 0.0,
217
- waitPoint: this._waitPoint
291
+ waitPoint: this._waitPoint,
218
292
  };
219
293
  } else {
220
294
  // Report current position
@@ -222,9 +296,9 @@ export enum GroupCoordinatorStateEvents {
222
296
  track: this.playbackTrack.current,
223
297
  trackData: this.playbackTrackData.current,
224
298
  transport: this.transportState.current,
225
- playbackState: this._waitPoint ? 'waiting' : playbackState,
299
+ playbackState: this._waitPoint ? "waiting" : playbackState,
226
300
  position: positionState?.position || 0.0,
227
- waitPoint: this._waitPoint
301
+ waitPoint: this._waitPoint,
228
302
  };
229
303
  }
230
304
  }
@@ -236,11 +310,20 @@ export enum GroupCoordinatorStateEvents {
236
310
  metadata: event.metadata,
237
311
  waitPoints: event.waitPoints,
238
312
  timestamp: event.timestamp,
239
- clientId: event.clientId || ''
313
+ clientId: event.clientId || "",
240
314
  });
241
315
 
242
316
  if (updated) {
243
- this._logger.sendTelemetryEvent(TelemetryEvents.SessionCoordinator.RemoteSetTrackReceived, null, {correlationId: LiveTelemetryLogger.formatCorrelationId(event.clientId, event.timestamp)});
317
+ this._logger.sendTelemetryEvent(
318
+ TelemetryEvents.SessionCoordinator.RemoteSetTrackReceived,
319
+ null,
320
+ {
321
+ correlationId: LiveTelemetryLogger.formatCorrelationId(
322
+ event.clientId,
323
+ event.timestamp
324
+ ),
325
+ }
326
+ );
244
327
  }
245
328
  }
246
329
 
@@ -250,15 +333,27 @@ export enum GroupCoordinatorStateEvents {
250
333
  const updated = this.playbackTrackData.updateData({
251
334
  data: event.data,
252
335
  timestamp: event.timestamp,
253
- clientId: event.clientId || ''
336
+ clientId: event.clientId || "",
254
337
  });
255
338
 
256
339
  if (updated) {
257
- this._logger.sendTelemetryEvent(TelemetryEvents.SessionCoordinator.RemoteSetTrackReceived, null, {correlationId: LiveTelemetryLogger.formatCorrelationId(event.clientId, event.timestamp)});
340
+ this._logger.sendTelemetryEvent(
341
+ TelemetryEvents.SessionCoordinator.RemoteSetTrackReceived,
342
+ null,
343
+ {
344
+ correlationId: LiveTelemetryLogger.formatCorrelationId(
345
+ event.clientId,
346
+ event.timestamp
347
+ ),
348
+ }
349
+ );
258
350
  }
259
351
  }
260
352
 
261
- public handleTransportCommand(event: ITransportCommandEvent, local: boolean): void {
353
+ public handleTransportCommand(
354
+ event: ITransportCommandEvent,
355
+ local: boolean
356
+ ): void {
262
357
  // Ensure change is for current track
263
358
  // - Will trigger a 'trackChange' event if newer track.
264
359
  this.playbackTrack.updateTrack(event.track);
@@ -266,11 +361,11 @@ export enum GroupCoordinatorStateEvents {
266
361
  // Update playback state
267
362
  let playbackState = this.transportState.playbackState;
268
363
  switch (event.name) {
269
- case 'play':
270
- playbackState = 'playing';
364
+ case "play":
365
+ playbackState = "playing";
271
366
  break;
272
- case 'pause':
273
- playbackState = 'paused';
367
+ case "pause":
368
+ playbackState = "paused";
274
369
  break;
275
370
  }
276
371
 
@@ -279,29 +374,55 @@ export enum GroupCoordinatorStateEvents {
279
374
  playbackState: playbackState,
280
375
  startPosition: event.position,
281
376
  timestamp: event.timestamp,
282
- clientId: event.clientId || ''
377
+ clientId: event.clientId || "",
283
378
  };
284
379
  const updated = this.transportState.updateState(newState);
285
380
 
286
381
  if (updated) {
287
- const correlationId = LiveTelemetryLogger.formatCorrelationId(event.clientId, event.timestamp);
382
+ const correlationId = LiveTelemetryLogger.formatCorrelationId(
383
+ event.clientId,
384
+ event.timestamp
385
+ );
288
386
  switch (event.name) {
289
- case 'play':
290
- this._logger.sendTelemetryEvent(TelemetryEvents.SessionCoordinator.RemotePlayReceived, null, {correlationId: correlationId});
387
+ case "play":
388
+ this._logger.sendTelemetryEvent(
389
+ TelemetryEvents.SessionCoordinator
390
+ .RemotePlayReceived,
391
+ null,
392
+ {
393
+ correlationId: correlationId,
394
+ }
395
+ );
291
396
  break;
292
- case 'pause':
293
- this._logger.sendTelemetryEvent(TelemetryEvents.SessionCoordinator.RemotePauseReceived, null, {correlationId: correlationId});
397
+ case "pause":
398
+ this._logger.sendTelemetryEvent(
399
+ TelemetryEvents.SessionCoordinator
400
+ .RemotePauseReceived,
401
+ null,
402
+ {
403
+ correlationId: correlationId,
404
+ }
405
+ );
294
406
  break;
295
- case 'seekTo':
296
- this._logger.sendTelemetryEvent(TelemetryEvents.SessionCoordinator.RemoteSeekToReceived, null, {correlationId: correlationId});
407
+ case "seekTo":
408
+ this._logger.sendTelemetryEvent(
409
+ TelemetryEvents.SessionCoordinator
410
+ .RemoteSeekToReceived,
411
+ null,
412
+ {
413
+ correlationId: correlationId,
414
+ }
415
+ );
297
416
  break;
298
417
  }
299
-
300
418
  }
301
419
  }
302
420
  }
303
421
 
304
- public handlePositionUpdate(event: IPositionUpdateEvent, local: boolean): void {
422
+ public handlePositionUpdate(
423
+ event: IPositionUpdateEvent,
424
+ local: boolean
425
+ ): void {
305
426
  // Ensure change is for current track
306
427
  // - Will trigger a 'trackChange' event if newer track.
307
428
  this.playbackTrack.updateTrack(event.track);
@@ -312,7 +433,7 @@ export enum GroupCoordinatorStateEvents {
312
433
  // Update transport state if needed
313
434
  // - Ignore transport state changes if the client has ended as this will cause the local
314
435
  // player to start playback even though the video may have ended for everyone.
315
- if (event.playbackState != 'ended') {
436
+ if (event.playbackState != "ended") {
316
437
  this.transportState.updateState(event.transport);
317
438
  }
318
439
 
@@ -324,7 +445,7 @@ export enum GroupCoordinatorStateEvents {
324
445
  waitPoint: event.waitPoint,
325
446
  position: event.position,
326
447
  timestamp: event.timestamp,
327
- clientId: event.clientId || ''
448
+ clientId: event.clientId || "",
328
449
  };
329
450
  this.playbackPosition.UpdatePlaybackPosition(position);
330
451
 
@@ -335,13 +456,19 @@ export enum GroupCoordinatorStateEvents {
335
456
  // the rest of the group while the local player is trying to to seek to a
336
457
  // new position.
337
458
  switch (event.playbackState) {
338
- case 'none':
339
- case 'paused':
340
- case 'playing':
459
+ case "none":
460
+ case "paused":
461
+ case "playing":
341
462
  if (event.playbackState != this._lastStateChange) {
342
- this._logger.sendTelemetryEvent(TelemetryEvents.GroupCoordinator.BeginSoftSuspension, null, {playbackState: event.playbackState});
463
+ this._logger.sendTelemetryEvent(
464
+ TelemetryEvents.GroupCoordinator
465
+ .BeginSoftSuspension,
466
+ null,
467
+ { playbackState: event.playbackState }
468
+ );
343
469
  this._lastStateChange = event.playbackState;
344
- this._lastStateChangeTime = LiveEvent.getTimestamp();
470
+ this._lastStateChangeTime =
471
+ LiveEvent.getTimestamp();
345
472
  }
346
473
  break;
347
474
  }
@@ -366,14 +493,20 @@ export enum GroupCoordinatorStateEvents {
366
493
 
367
494
  public async syncLocalMediaSession(): Promise<void> {
368
495
  // Skip further syncs if we're waiting or in a "soft suspension".
369
- const softSuspensionDelta = LiveEvent.getTimestamp() - this._lastStateChangeTime;
496
+ const softSuspensionDelta =
497
+ LiveEvent.getTimestamp() - this._lastStateChangeTime;
370
498
  if (!this.isWaiting && softSuspensionDelta >= 1000) {
371
- let { metadata, trackData, positionState, playbackState } = this._getMediaPlayerState();
372
- this._logger.sendTelemetryEvent(TelemetryEvents.GroupCoordinator.CheckingForSyncIssues);
499
+ let { metadata, trackData, positionState, playbackState } =
500
+ this._getMediaPlayerState();
501
+ this._logger.sendTelemetryEvent(
502
+ TelemetryEvents.GroupCoordinator.CheckingForSyncIssues
503
+ );
373
504
 
374
505
  // Check for track change
375
506
  if (!this.playbackTrack.compare(metadata)) {
376
- this._logger.sendTelemetryEvent(TelemetryEvents.GroupCoordinator.TrackOutOfSync);
507
+ this._logger.sendTelemetryEvent(
508
+ TelemetryEvents.GroupCoordinator.TrackOutOfSync
509
+ );
377
510
  this.emitSetTrack(this.playbackTrack.metadata!);
378
511
  return;
379
512
  }
@@ -384,7 +517,10 @@ export enum GroupCoordinatorStateEvents {
384
517
  // else has finished the video.
385
518
  // - Should another user seek or press play after the video has ended that will cause
386
519
  // a transport action to trigger which will take the player out of the ended state.
387
- if (playbackState != "ended" && !this._playbackPosition.trackEnded) {
520
+ if (
521
+ playbackState != "ended" &&
522
+ !this._playbackPosition.trackEnded
523
+ ) {
388
524
  // Ensure we have a position
389
525
  let position = positionState?.position;
390
526
  if (position == undefined) {
@@ -394,37 +530,59 @@ export enum GroupCoordinatorStateEvents {
394
530
  // Check for catchup
395
531
  // - Target can return -1 in cases where there is no position tracking data
396
532
  const target = this.playbackPosition.targetPosition;
397
- if (target >= 0.0 && Math.abs(target - position) >= this._maxPlaybackDrift.seconds) {
398
- this._logger.sendTelemetryEvent(TelemetryEvents.GroupCoordinator.PositionOutOfSync, null, {
399
- current: position,
400
- target: target
533
+ if (
534
+ target >= 0.0 &&
535
+ Math.abs(target - position) >=
536
+ this._maxPlaybackDrift.seconds
537
+ ) {
538
+ this._logger.sendTelemetryEvent(
539
+ TelemetryEvents.GroupCoordinator.PositionOutOfSync,
540
+ null,
541
+ {
542
+ current: position,
543
+ target: target,
544
+ }
545
+ );
546
+ await this.emitTriggerAction({
547
+ action: "catchup",
548
+ seekTime: target,
401
549
  });
402
- await this.emitTriggerAction({action: 'catchup', seekTime: target});
403
550
  }
404
551
 
405
552
  // Sync transport state
406
553
  if (this.transportState.playbackState != playbackState) {
407
- this._logger.sendTelemetryEvent(TelemetryEvents.GroupCoordinator.TransportOutOfSync, null, {
408
- current: playbackState,
409
- target: this.transportState.playbackState
410
- });
554
+ this._logger.sendTelemetryEvent(
555
+ TelemetryEvents.GroupCoordinator.TransportOutOfSync,
556
+ null,
557
+ {
558
+ current: playbackState,
559
+ target: this.transportState.playbackState,
560
+ }
561
+ );
411
562
  switch (this.transportState.playbackState) {
412
- case 'playing':
413
- await this.emitTriggerAction({action: 'play'});
563
+ case "playing":
564
+ await this.emitTriggerAction({ action: "play" });
414
565
  break;
415
- case 'paused':
416
- await this.emitTriggerAction({action: 'pause'});
566
+ case "paused":
567
+ await this.emitTriggerAction({ action: "pause" });
417
568
  break;
418
569
  }
419
570
  }
420
571
 
421
572
  // Sync track data
422
- if (JSON.stringify(this.playbackTrackData.data) != JSON.stringify(trackData)) {
423
- this._logger.sendTelemetryEvent(TelemetryEvents.GroupCoordinator.TrackDataOutOfSync);
424
- await this.emitTriggerAction({action: 'datachange', data: this.playbackTrackData.data});
573
+ if (
574
+ JSON.stringify(this.playbackTrackData.data) !=
575
+ JSON.stringify(trackData)
576
+ ) {
577
+ this._logger.sendTelemetryEvent(
578
+ TelemetryEvents.GroupCoordinator.TrackDataOutOfSync
579
+ );
580
+ await this.emitTriggerAction({
581
+ action: "datachange",
582
+ data: this.playbackTrackData.data,
583
+ });
425
584
  }
426
585
  }
427
-
428
586
  }
429
587
  }
430
588
 
@@ -433,14 +591,16 @@ export enum GroupCoordinatorStateEvents {
433
591
  this._waitPoint = undefined;
434
592
 
435
593
  // Trigger settrack action
436
- this.emitTriggerAction({action: 'settrack', metadata: metadata});
594
+ this.emitTriggerAction({ action: "settrack", metadata: metadata });
437
595
  }
438
596
 
439
- private emitTriggerAction(details: ExtendedMediaSessionActionDetails): void {
597
+ private emitTriggerAction(
598
+ details: ExtendedMediaSessionActionDetails
599
+ ): void {
440
600
  const evt: ITriggerActionEvent = {
441
601
  name: GroupCoordinatorStateEvents.triggeraction,
442
- details: details
602
+ details: details,
443
603
  };
444
- this.emit(GroupCoordinatorStateEvents.triggeraction, evt);
604
+ this.emit(GroupCoordinatorStateEvents.triggeraction, evt);
445
605
  }
446
- }
606
+ }