@microsoft/live-share-media 2.0.0-internal.6 → 2.0.0-internal.8

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 (150) hide show
  1. package/bin/cjs/LiveMediaSessionCoordinator.d.ts +38 -7
  2. package/bin/cjs/LiveMediaSessionCoordinator.d.ts.map +1 -1
  3. package/bin/cjs/LiveMediaSessionCoordinator.js +90 -9
  4. package/bin/cjs/LiveMediaSessionCoordinator.js.map +1 -1
  5. package/bin/cjs/internals/GroupCoordinatorState.d.ts +2 -1
  6. package/bin/cjs/internals/GroupCoordinatorState.d.ts.map +1 -1
  7. package/bin/cjs/internals/GroupCoordinatorState.js.map +1 -1
  8. package/bin/cjs/internals/GroupPlaybackPosition.d.ts +2 -2
  9. package/bin/cjs/internals/GroupPlaybackPosition.d.ts.map +1 -1
  10. package/bin/cjs/internals/GroupPlaybackPosition.js +1 -1
  11. package/bin/cjs/internals/GroupPlaybackPosition.js.map +1 -1
  12. package/bin/cjs/internals/PriorityTimeInterval.d.ts +33 -0
  13. package/bin/cjs/internals/PriorityTimeInterval.d.ts.map +1 -0
  14. package/bin/cjs/internals/PriorityTimeInterval.js +45 -0
  15. package/bin/cjs/internals/PriorityTimeInterval.js.map +1 -0
  16. package/bin/esm/LiveMediaSessionCoordinator.d.ts +38 -7
  17. package/bin/esm/LiveMediaSessionCoordinator.d.ts.map +1 -1
  18. package/bin/esm/LiveMediaSessionCoordinator.js +91 -10
  19. package/bin/esm/LiveMediaSessionCoordinator.js.map +1 -1
  20. package/bin/esm/internals/GroupCoordinatorState.d.ts +2 -1
  21. package/bin/esm/internals/GroupCoordinatorState.d.ts.map +1 -1
  22. package/bin/esm/internals/GroupCoordinatorState.js.map +1 -1
  23. package/bin/esm/internals/GroupPlaybackPosition.d.ts +2 -2
  24. package/bin/esm/internals/GroupPlaybackPosition.d.ts.map +1 -1
  25. package/bin/esm/internals/GroupPlaybackPosition.js +1 -1
  26. package/bin/esm/internals/GroupPlaybackPosition.js.map +1 -1
  27. package/bin/esm/internals/PriorityTimeInterval.d.ts +33 -0
  28. package/bin/esm/internals/PriorityTimeInterval.d.ts.map +1 -0
  29. package/bin/esm/internals/PriorityTimeInterval.js +41 -0
  30. package/bin/esm/internals/PriorityTimeInterval.js.map +1 -0
  31. package/package.json +3 -3
  32. package/src/LiveMediaSessionCoordinator.ts +96 -10
  33. package/src/internals/GroupCoordinatorState.ts +2 -1
  34. package/src/internals/GroupPlaybackPosition.ts +4 -4
  35. package/src/internals/PriorityTimeInterval.ts +76 -0
  36. package/.mocharc.cjs +0 -12
  37. package/.nycrc.json +0 -11
  38. package/bin/test/IMediaPlayer.d.ts +0 -21
  39. package/bin/test/IMediaPlayer.d.ts.map +0 -1
  40. package/bin/test/IMediaPlayer.js +0 -7
  41. package/bin/test/IMediaPlayer.js.map +0 -1
  42. package/bin/test/LiveMediaSession.d.ts +0 -97
  43. package/bin/test/LiveMediaSession.d.ts.map +0 -1
  44. package/bin/test/LiveMediaSession.js +0 -261
  45. package/bin/test/LiveMediaSession.js.map +0 -1
  46. package/bin/test/LiveMediaSessionCoordinator.d.ts +0 -273
  47. package/bin/test/LiveMediaSessionCoordinator.d.ts.map +0 -1
  48. package/bin/test/LiveMediaSessionCoordinator.js +0 -479
  49. package/bin/test/LiveMediaSessionCoordinator.js.map +0 -1
  50. package/bin/test/LiveMediaSessionCoordinatorSuspension.d.ts +0 -20
  51. package/bin/test/LiveMediaSessionCoordinatorSuspension.d.ts.map +0 -1
  52. package/bin/test/LiveMediaSessionCoordinatorSuspension.js +0 -28
  53. package/bin/test/LiveMediaSessionCoordinatorSuspension.js.map +0 -1
  54. package/bin/test/MediaPlayerSynchronizer.d.ts +0 -204
  55. package/bin/test/MediaPlayerSynchronizer.d.ts.map +0 -1
  56. package/bin/test/MediaPlayerSynchronizer.js +0 -574
  57. package/bin/test/MediaPlayerSynchronizer.js.map +0 -1
  58. package/bin/test/MediaSessionActionThrottler.d.ts +0 -12
  59. package/bin/test/MediaSessionActionThrottler.d.ts.map +0 -1
  60. package/bin/test/MediaSessionActionThrottler.js +0 -14
  61. package/bin/test/MediaSessionActionThrottler.js.map +0 -1
  62. package/bin/test/MediaSessionExtensions.d.ts +0 -177
  63. package/bin/test/MediaSessionExtensions.d.ts.map +0 -1
  64. package/bin/test/MediaSessionExtensions.js +0 -26
  65. package/bin/test/MediaSessionExtensions.js.map +0 -1
  66. package/bin/test/RepeatedActionThrottler.d.ts +0 -20
  67. package/bin/test/RepeatedActionThrottler.d.ts.map +0 -1
  68. package/bin/test/RepeatedActionThrottler.js +0 -63
  69. package/bin/test/RepeatedActionThrottler.js.map +0 -1
  70. package/bin/test/VolumeManager.d.ts +0 -84
  71. package/bin/test/VolumeManager.d.ts.map +0 -1
  72. package/bin/test/VolumeManager.js +0 -175
  73. package/bin/test/VolumeManager.js.map +0 -1
  74. package/bin/test/index.d.ts +0 -14
  75. package/bin/test/index.d.ts.map +0 -1
  76. package/bin/test/index.js +0 -30
  77. package/bin/test/index.js.map +0 -1
  78. package/bin/test/internals/GroupCoordinatorState.d.ts +0 -109
  79. package/bin/test/internals/GroupCoordinatorState.d.ts.map +0 -1
  80. package/bin/test/internals/GroupCoordinatorState.js +0 -516
  81. package/bin/test/internals/GroupCoordinatorState.js.map +0 -1
  82. package/bin/test/internals/GroupPlaybackPosition.d.ts +0 -71
  83. package/bin/test/internals/GroupPlaybackPosition.d.ts.map +0 -1
  84. package/bin/test/internals/GroupPlaybackPosition.js +0 -170
  85. package/bin/test/internals/GroupPlaybackPosition.js.map +0 -1
  86. package/bin/test/internals/GroupPlaybackRate.d.ts +0 -38
  87. package/bin/test/internals/GroupPlaybackRate.d.ts.map +0 -1
  88. package/bin/test/internals/GroupPlaybackRate.js +0 -59
  89. package/bin/test/internals/GroupPlaybackRate.js.map +0 -1
  90. package/bin/test/internals/GroupPlaybackTrack.d.ts +0 -45
  91. package/bin/test/internals/GroupPlaybackTrack.d.ts.map +0 -1
  92. package/bin/test/internals/GroupPlaybackTrack.js +0 -122
  93. package/bin/test/internals/GroupPlaybackTrack.js.map +0 -1
  94. package/bin/test/internals/GroupPlaybackTrackData.d.ts +0 -40
  95. package/bin/test/internals/GroupPlaybackTrackData.d.ts.map +0 -1
  96. package/bin/test/internals/GroupPlaybackTrackData.js +0 -70
  97. package/bin/test/internals/GroupPlaybackTrackData.js.map +0 -1
  98. package/bin/test/internals/GroupTransportState.d.ts +0 -52
  99. package/bin/test/internals/GroupTransportState.d.ts.map +0 -1
  100. package/bin/test/internals/GroupTransportState.js +0 -120
  101. package/bin/test/internals/GroupTransportState.js.map +0 -1
  102. package/bin/test/internals/consts.d.ts +0 -83
  103. package/bin/test/internals/consts.d.ts.map +0 -1
  104. package/bin/test/internals/consts.js +0 -92
  105. package/bin/test/internals/consts.js.map +0 -1
  106. package/bin/test/internals/errors.d.ts +0 -17
  107. package/bin/test/internals/errors.d.ts.map +0 -1
  108. package/bin/test/internals/errors.js +0 -34
  109. package/bin/test/internals/errors.js.map +0 -1
  110. package/bin/test/internals/interfaces.d.ts +0 -23
  111. package/bin/test/internals/interfaces.d.ts.map +0 -1
  112. package/bin/test/internals/interfaces.js +0 -3
  113. package/bin/test/internals/interfaces.js.map +0 -1
  114. package/bin/test/package.json +0 -1
  115. package/bin/test/test/GroupPlaybackPosition.spec.d.ts +0 -6
  116. package/bin/test/test/GroupPlaybackPosition.spec.d.ts.map +0 -1
  117. package/bin/test/test/GroupPlaybackPosition.spec.js +0 -314
  118. package/bin/test/test/GroupPlaybackPosition.spec.js.map +0 -1
  119. package/bin/test/test/GroupPlaybackRate.spec.d.ts +0 -6
  120. package/bin/test/test/GroupPlaybackRate.spec.d.ts.map +0 -1
  121. package/bin/test/test/GroupPlaybackRate.spec.js +0 -47
  122. package/bin/test/test/GroupPlaybackRate.spec.js.map +0 -1
  123. package/bin/test/test/GroupPlaybackTrack.spec.d.ts +0 -6
  124. package/bin/test/test/GroupPlaybackTrack.spec.d.ts.map +0 -1
  125. package/bin/test/test/GroupPlaybackTrack.spec.js +0 -171
  126. package/bin/test/test/GroupPlaybackTrack.spec.js.map +0 -1
  127. package/bin/test/test/GroupPlaybackTrackData.spec.d.ts +0 -6
  128. package/bin/test/test/GroupPlaybackTrackData.spec.d.ts.map +0 -1
  129. package/bin/test/test/GroupPlaybackTrackData.spec.js +0 -63
  130. package/bin/test/test/GroupPlaybackTrackData.spec.js.map +0 -1
  131. package/bin/test/test/LiveMediaSession_ManualActionHandler.spec.d.ts +0 -6
  132. package/bin/test/test/LiveMediaSession_ManualActionHandler.spec.d.ts.map +0 -1
  133. package/bin/test/test/LiveMediaSession_ManualActionHandler.spec.js +0 -324
  134. package/bin/test/test/LiveMediaSession_ManualActionHandler.spec.js.map +0 -1
  135. package/bin/test/test/LiveMediaSession_Synchronizer.spec.d.ts +0 -6
  136. package/bin/test/test/LiveMediaSession_Synchronizer.spec.d.ts.map +0 -1
  137. package/bin/test/test/LiveMediaSession_Synchronizer.spec.js +0 -669
  138. package/bin/test/test/LiveMediaSession_Synchronizer.spec.js.map +0 -1
  139. package/bin/test/test/TestUtils.d.ts +0 -44
  140. package/bin/test/test/TestUtils.d.ts.map +0 -1
  141. package/bin/test/test/TestUtils.js +0 -116
  142. package/bin/test/test/TestUtils.js.map +0 -1
  143. package/bin/test/test/VolumeManager.spec.d.ts +0 -2
  144. package/bin/test/test/VolumeManager.spec.d.ts.map +0 -1
  145. package/bin/test/test/VolumeManager.spec.js +0 -163
  146. package/bin/test/test/VolumeManager.spec.js.map +0 -1
  147. package/nyc/junit-report.json +0 -850
  148. package/nyc/junit-report.xml +0 -54
  149. package/tsconfig.test.json +0 -9
  150. package/typedoc.json +0 -10
@@ -40,7 +40,7 @@ import {
40
40
  TrackMetadataNotSetError,
41
41
  ActionBlockedError,
42
42
  } from "./internals/errors.js";
43
-
43
+ import { PriorityTimeInterval } from "./internals/PriorityTimeInterval.js";
44
44
  import { LiveMediaSessionCoordinatorSuspension } from "./LiveMediaSessionCoordinatorSuspension.js";
45
45
  import { TypedEventEmitter } from "@fluid-internal/client-utils";
46
46
  import { IEvent } from "@fluidframework/core-interfaces";
@@ -97,8 +97,27 @@ export class LiveMediaSessionCoordinator extends TypedEventEmitter<ILiveMediaSes
97
97
  private readonly _liveRuntime: LiveShareRuntime;
98
98
  private readonly _logger: LiveTelemetryLogger;
99
99
  private readonly _getPlayerState: () => IMediaPlayerState;
100
- private _positionUpdateInterval = new TimeInterval(2000);
101
- private _maxPlaybackDrift = new TimeInterval(1000);
100
+ private _positionUpdateInterval = new PriorityTimeInterval(
101
+ 2000,
102
+ // Scale by function
103
+ () => {
104
+ const audience = this._liveRuntime.audience;
105
+ if (!audience) return 1;
106
+ // As the audience size gets bigger, we relax the update interval, since more variance is expected
107
+ const count = audience.getMembers().size;
108
+ return 1 + count / 5;
109
+ }
110
+ );
111
+ private _maxPlaybackDrift = new PriorityTimeInterval(
112
+ 1500, // Scale by function
113
+ () => {
114
+ const audience = this._liveRuntime.audience;
115
+ if (!audience) return 1;
116
+ // As the audience size gets bigger, we relax the playback drift, since more variance is expected
117
+ const count = audience.getMembers().size;
118
+ return 1 + count / 25;
119
+ }
120
+ );
102
121
  private _lastWaitPoint?: CoordinationWaitPoint;
103
122
  private initializeState: LiveDataObjectInitializeState =
104
123
  LiveDataObjectInitializeState.needed;
@@ -222,13 +241,29 @@ export class LiveMediaSessionCoordinator extends TypedEventEmitter<ILiveMediaSes
222
241
  }
223
242
 
224
243
  /**
225
- * Max amount of playback drift allowed in seconds.
244
+ * Controls whether or not to scale {@link maxPlaybackDrift} by the number of users in the session.
226
245
  *
227
246
  * @remarks
228
- * Should the local clients playback position lag by more than the specified value, the
229
- * coordinator will trigger a `catchup` action.
247
+ * As more clients join a session, it is more likely that some users will fall behind the presenter.
248
+ * It is also less likely that users will notice drift as more clients are added.
249
+ * It is usually helpful to be more lenient as more clients are added so everyone can watch all the content.
250
+ * Default value is true.
251
+ */
252
+ public get shouldScaleMaxPlaybackDrift(): boolean {
253
+ return this._maxPlaybackDrift.shouldPrioritize;
254
+ }
255
+
256
+ public set shouldScaleMaxPlaybackDrift(value: boolean) {
257
+ this._maxPlaybackDrift.shouldPrioritize = value;
258
+ }
259
+
260
+ /**
261
+ * Max amount of playback drift allowed in seconds.
262
+ * This will scale automatically according to the number of participants in the session when {@link shouldScaleMaxPlaybackDrift} is true.
230
263
  *
231
- * Defaults to a value of `1` second.
264
+ * @remarks
265
+ * Should the local clients playback position lag by more than the specified value, the coordinator will trigger a `catchup` action.
266
+ * Default value is `1.5` seconds.
232
267
  */
233
268
  public get maxPlaybackDrift(): number {
234
269
  return this._maxPlaybackDrift.seconds;
@@ -239,11 +274,30 @@ export class LiveMediaSessionCoordinator extends TypedEventEmitter<ILiveMediaSes
239
274
  }
240
275
 
241
276
  /**
242
- * Frequency with which position updates are broadcast to the rest of the group in
243
- * seconds.
277
+ * Controls whether or not to compute {@link positionUpdateInterval} based on whether user has initiated a playback command.
278
+ * Default value is true.
244
279
  *
245
280
  * @remarks
246
- * Defaults to a value of `2` seconds.
281
+ * When true, users that are simply watching but not controlling playback will report their positions less frequently.
282
+ * When a user has sent a transport command, they will begin sending position updates more frequently.
283
+ * Most Live Share apps have a concept of a primary presenter, and don't allow anyone to pause/play for the group.
284
+ * By ensuring only one/few users broadcast updates frequently, the server load is reduced considerably.
285
+ */
286
+ public get shouldScalePositionUpdateInterval(): boolean {
287
+ return this._positionUpdateInterval.shouldPrioritize;
288
+ }
289
+
290
+ public set shouldScalePositionUpdateInterval(value: boolean) {
291
+ this._positionUpdateInterval.shouldPrioritize = value;
292
+ }
293
+
294
+ /**
295
+ * Frequency with which position updates are broadcast to the rest of the group in seconds.
296
+ * When {@link shouldScalePositionUpdateInterval} is set to `true`, the value set is the minimum value.
297
+ * The value returned is the actual value used to send updates by the local user, which may be larger than the value set.
298
+ *
299
+ * @remarks
300
+ * Defaults to a minimum value of `2` seconds.
247
301
  */
248
302
  public get positionUpdateInterval(): number {
249
303
  return this._positionUpdateInterval.seconds;
@@ -293,6 +347,10 @@ export class LiveMediaSessionCoordinator extends TypedEventEmitter<ILiveMediaSes
293
347
  track: this._groupState.playbackTrack.current,
294
348
  position: position,
295
349
  });
350
+ if (this.canSendPositionUpdates) {
351
+ // User has taken initiative to send event, give priority for sending position updates
352
+ this._positionUpdateInterval.hasPriority = true;
353
+ }
296
354
  }
297
355
 
298
356
  /**
@@ -335,6 +393,10 @@ export class LiveMediaSessionCoordinator extends TypedEventEmitter<ILiveMediaSes
335
393
  track: this._groupState.playbackTrack.current,
336
394
  position: position,
337
395
  });
396
+ if (this.canSendPositionUpdates) {
397
+ // User has taken initiative to send event, give priority for sending position updates
398
+ this._positionUpdateInterval.hasPriority = true;
399
+ }
338
400
  }
339
401
 
340
402
  /**
@@ -375,12 +437,24 @@ export class LiveMediaSessionCoordinator extends TypedEventEmitter<ILiveMediaSes
375
437
  track: this._groupState.playbackTrack.current,
376
438
  position: time,
377
439
  });
440
+ if (this.canSendPositionUpdates) {
441
+ // User has taken initiative to send event, give priority for sending position updates
442
+ this._positionUpdateInterval.hasPriority = true;
443
+ }
378
444
  } catch (err) {
379
445
  await this._groupState!.syncLocalMediaSession();
380
446
  throw err;
381
447
  }
382
448
  }
383
449
 
450
+ /**
451
+ * Sets the playback rate for everyone in the session.
452
+ *
453
+ * @param playbackRate the playback rate to set.
454
+ *
455
+ * @throws
456
+ * Throws an exception if the session/coordinator hasn't been initialized or {@link canSetPlaybackRate} is false.
457
+ */
384
458
  public async setPlaybackRate(playbackRate: number): Promise<void> {
385
459
  LiveDataObjectNotInitializedError.assert(
386
460
  "LiveMediaSessionCoordinator:setPlaybackRate",
@@ -400,6 +474,10 @@ export class LiveMediaSessionCoordinator extends TypedEventEmitter<ILiveMediaSes
400
474
  { playbackRate }
401
475
  );
402
476
  await this._rateChangeEvent!.sendEvent({ playbackRate });
477
+ if (this.canSendPositionUpdates) {
478
+ // User has taken initiative to send event, give priority for sending position updates
479
+ this._positionUpdateInterval.hasPriority = true;
480
+ }
403
481
  }
404
482
 
405
483
  /**
@@ -436,6 +514,10 @@ export class LiveMediaSessionCoordinator extends TypedEventEmitter<ILiveMediaSes
436
514
  metadata: metadata,
437
515
  waitPoints: waitPoints || [],
438
516
  });
517
+ if (this.canSendPositionUpdates) {
518
+ // User has taken initiative to send event, give priority for sending position updates
519
+ this._positionUpdateInterval.hasPriority = true;
520
+ }
439
521
  }
440
522
 
441
523
  /**
@@ -470,6 +552,10 @@ export class LiveMediaSessionCoordinator extends TypedEventEmitter<ILiveMediaSes
470
552
  await this._setTrackDataEvent!.sendEvent({
471
553
  data: data,
472
554
  });
555
+ if (this.canSendPositionUpdates) {
556
+ // User has taken initiative to send event, give priority for sending position updates
557
+ this._positionUpdateInterval.hasPriority = true;
558
+ }
473
559
  }
474
560
 
475
561
  /**
@@ -53,6 +53,7 @@ import {
53
53
  } from "./GroupPlaybackRate.js";
54
54
  import { TypedEventEmitter } from "@fluid-internal/client-utils";
55
55
  import { IGenericTypedEvents } from "./interfaces.js";
56
+ import { PriorityTimeInterval } from "./PriorityTimeInterval.js";
56
57
 
57
58
  /**
58
59
  * @hidden
@@ -145,7 +146,7 @@ export class GroupCoordinatorState extends TypedEventEmitter<IGenericTypedEvents
145
146
  runtime: IRuntimeSignaler,
146
147
  liveRuntime: LiveShareRuntime,
147
148
  maxPlaybackDrift: TimeInterval,
148
- positionUpdateInterval: TimeInterval,
149
+ positionUpdateInterval: PriorityTimeInterval,
149
150
  getMediaPlayerState: () => IMediaPlayerState
150
151
  ) {
151
152
  super();
@@ -3,7 +3,6 @@
3
3
  * Licensed under the Microsoft Live Share SDK License.
4
4
  */
5
5
 
6
- import { TimeInterval } from "@microsoft/live-share";
7
6
  import {
8
7
  IRuntimeSignaler,
9
8
  LiveShareRuntime,
@@ -15,6 +14,7 @@ import {
15
14
  ExtendedMediaSessionPlaybackState,
16
15
  } from "../MediaSessionExtensions.js";
17
16
  import { GroupPlaybackRate } from "./GroupPlaybackRate.js";
17
+ import { PriorityTimeInterval } from "./PriorityTimeInterval.js";
18
18
 
19
19
  /**
20
20
  * Per client position
@@ -37,7 +37,7 @@ export class GroupPlaybackPosition {
37
37
  private _playbackRate: GroupPlaybackRate;
38
38
  private _runtime: IRuntimeSignaler;
39
39
  private _liveRuntime: LiveShareRuntime;
40
- private _updateInterval: TimeInterval;
40
+ private _updateInterval: PriorityTimeInterval;
41
41
  private _positions: Map<string, ICurrentPlaybackPosition>;
42
42
 
43
43
  constructor(
@@ -45,7 +45,7 @@ export class GroupPlaybackPosition {
45
45
  playbackRate: GroupPlaybackRate,
46
46
  runtime: IRuntimeSignaler,
47
47
  liveRuntime: LiveShareRuntime,
48
- updateInterval: TimeInterval
48
+ updateInterval: PriorityTimeInterval
49
49
  ) {
50
50
  this._transportState = transportState;
51
51
  this._playbackRate = playbackRate;
@@ -171,7 +171,7 @@ export class GroupPlaybackPosition {
171
171
  ) => void
172
172
  ): void {
173
173
  const now = this._liveRuntime.getTimestamp();
174
- const ignoreBefore = now - this._updateInterval.milliseconds * 2;
174
+ const ignoreBefore = now - this._updateInterval.maxMilliseconds * 2;
175
175
  const shouldProject = !this._transportState.track.metadata?.liveStream;
176
176
  this._positions.forEach((position, _) => {
177
177
  // Ignore any old updates
@@ -0,0 +1,76 @@
1
+ import { TimeInterval } from "@microsoft/live-share";
2
+
3
+ function getScaledPriorityTimeMs(
4
+ minMilliseconds: number,
5
+ hasPriority: boolean,
6
+ shouldPrioritize: boolean,
7
+ scaleBy: number
8
+ ): number {
9
+ if (!shouldPrioritize) return minMilliseconds;
10
+ if (hasPriority) return minMilliseconds;
11
+ return minMilliseconds * scaleBy;
12
+ }
13
+
14
+ /**
15
+ * @hidden
16
+ * Time interval that can scale based on a scaling function.
17
+ */
18
+ export class PriorityTimeInterval extends TimeInterval {
19
+ /**
20
+ * If true, local user has priority and will have the lowest possible millesecond value.
21
+ */
22
+ public hasPriority: boolean;
23
+ /**
24
+ * If true, milliseconds will be scaled when {@link hasPriority} is false.
25
+ */
26
+ public shouldPrioritize: boolean;
27
+ /**
28
+ * Function to get the scale ratio.
29
+ */
30
+ private getScaleBy: () => number;
31
+ /**
32
+ * Time interval that can scale based on a scaling function.
33
+ *
34
+ * @param defaultMilliseconds the default minimum milliseconds
35
+ * @param getScaleByFn a function to scale the milliseconds by when {@link hasPriority} is false and {@link shouldPrioritize} is true.
36
+ * @param defaultHasPriority the default {@link hasPriority} value
37
+ * @param defaultShouldPrioritize the default {@link shouldPrioritize} value
38
+ */
39
+ constructor(
40
+ defaultMilliseconds: number,
41
+ getScaleByFn: () => number,
42
+ defaultHasPriority: boolean = false,
43
+ defaultShouldPrioritize: boolean = true
44
+ ) {
45
+ super(defaultMilliseconds);
46
+ this.hasPriority = defaultHasPriority;
47
+ this.shouldPrioritize = defaultShouldPrioritize;
48
+ this.getScaleBy = getScaleByFn;
49
+ }
50
+
51
+ public get milliseconds(): number {
52
+ return getScaledPriorityTimeMs(
53
+ this._milliseconds,
54
+ this.hasPriority,
55
+ this.shouldPrioritize,
56
+ this.getScaleBy()
57
+ );
58
+ }
59
+
60
+ public set milliseconds(value: number) {
61
+ this._milliseconds = value;
62
+ }
63
+
64
+ public get minMilliseconds(): number {
65
+ return this._milliseconds;
66
+ }
67
+
68
+ public get maxMilliseconds(): number {
69
+ return getScaledPriorityTimeMs(
70
+ this._milliseconds,
71
+ false,
72
+ this.shouldPrioritize,
73
+ this.getScaleBy()
74
+ );
75
+ }
76
+ }
package/.mocharc.cjs DELETED
@@ -1,12 +0,0 @@
1
- /*!
2
- * Copyright (c) Microsoft Corporation and contributors. All rights reserved.
3
- * Licensed under the Microsoft Live Share SDK License.
4
- */
5
-
6
- "use strict";
7
-
8
- const packageDir = `${__dirname}/../..`;
9
-
10
- const getFluidTestMochaConfig = require("@fluidframework/mocha-test-setup/mocharc-common.js");
11
- const config = getFluidTestMochaConfig(packageDir);
12
- module.exports = config;
package/.nycrc.json DELETED
@@ -1,11 +0,0 @@
1
- {
2
- "cache": false,
3
- "extension": [".ts"],
4
- "check-coverage": true,
5
- "include": ["src/**"],
6
- "exclude": ["src/pps/**"],
7
- "statements": 90,
8
- "branches": 90,
9
- "functions": 95,
10
- "lines": 90
11
- }
@@ -1,21 +0,0 @@
1
- /**
2
- * Copyright (c) Microsoft Corporation. All rights reserved.
3
- * Licensed under the Microsoft Live Share SDK License.
4
- */
5
- export interface IMediaPlayer {
6
- readonly currentSrc: string;
7
- currentTime: number;
8
- readonly duration: number;
9
- readonly ended: boolean;
10
- muted: boolean;
11
- readonly paused: boolean;
12
- playbackRate: number;
13
- src: string;
14
- volume: number;
15
- load(): void;
16
- pause(): void;
17
- play(): Promise<void>;
18
- addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;
19
- removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void;
20
- }
21
- //# sourceMappingURL=IMediaPlayer.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"IMediaPlayer.d.ts","sourceRoot":"","sources":["../../src/IMediaPlayer.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,MAAM,WAAW,YAAY;IACzB,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAC;IACxB,KAAK,EAAE,OAAO,CAAC;IACf,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAC;IACzB,YAAY,EAAE,MAAM,CAAC;IACrB,GAAG,EAAE,MAAM,CAAC;IACZ,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,IAAI,IAAI,CAAC;IACb,KAAK,IAAI,IAAI,CAAC;IACd,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IACtB,gBAAgB,CACZ,IAAI,EAAE,MAAM,EACZ,QAAQ,EAAE,kCAAkC,EAC5C,OAAO,CAAC,EAAE,OAAO,GAAG,uBAAuB,GAC5C,IAAI,CAAC;IACR,mBAAmB,CACf,IAAI,EAAE,MAAM,EACZ,QAAQ,EAAE,kCAAkC,EAC5C,OAAO,CAAC,EAAE,OAAO,GAAG,oBAAoB,GACzC,IAAI,CAAC;CACX"}
@@ -1,7 +0,0 @@
1
- "use strict";
2
- /**
3
- * Copyright (c) Microsoft Corporation. All rights reserved.
4
- * Licensed under the Microsoft Live Share SDK License.
5
- */
6
- Object.defineProperty(exports, "__esModule", { value: true });
7
- //# sourceMappingURL=IMediaPlayer.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"IMediaPlayer.js","sourceRoot":"","sources":["../../src/IMediaPlayer.ts"],"names":[],"mappings":";AAAA;;;GAGG"}
@@ -1,97 +0,0 @@
1
- /**
2
- * Copyright (c) Microsoft Corporation. All rights reserved.
3
- * Licensed under the Microsoft Live Share SDK License.
4
- */
5
- import { DataObjectFactory } from "@fluidframework/aqueduct/internal";
6
- import { LiveTelemetryLogger, UserMeetingRole } from "@microsoft/live-share";
7
- import { LiveDataObject } from "@microsoft/live-share/internal";
8
- import { MediaPlayerSynchronizer } from "./MediaPlayerSynchronizer.js";
9
- import { ExtendedMediaSessionAction, ExtendedMediaSessionActionHandler } from "./MediaSessionExtensions.js";
10
- import { LiveMediaSessionCoordinator, IMediaPlayerState } from "./LiveMediaSessionCoordinator.js";
11
- import { MediaSessionActionThrottler } from "./MediaSessionActionThrottler.js";
12
- import { IMediaPlayer } from "./IMediaPlayer.js";
13
- import { SharedObjectKind } from "fluid-framework";
14
- /**
15
- * Live fluid object that synchronizes media playback across multiple clients.
16
- */
17
- export declare class LiveMediaSessionClass extends LiveDataObject {
18
- private _actionThrottler;
19
- private _logger?;
20
- private _requestPlayerStateHandler?;
21
- private _coordinator?;
22
- private readonly _actionHandlers;
23
- private _synchronizing?;
24
- private _updateTimer;
25
- private _lastUpdateTime;
26
- /**
27
- * The objects fluid type name.
28
- */
29
- static readonly TypeName = "@microsoft/fluid-media:SharedMediaSession";
30
- /**
31
- * The objects fluid type factory.
32
- */
33
- static readonly factory: DataObjectFactory<LiveMediaSessionClass, import("@fluidframework/aqueduct/internal").DataObjectTypes>;
34
- /**
35
- * Extension point that lets applications replace the default logic for throttling the sessions
36
- * local sync behavior.
37
- *
38
- * @remarks
39
- * The `LiveMediaCoordinator` is fairly aggressive at wanting to keep the local media player
40
- * in sync with the rest of the group. This aggressiveness can result in the coordinator sending
41
- * new sync actions before the local player has finished responding to the previous sync action.
42
- * The `ActionThrottler` gives apps fine grain control over how aggressive they want sync to be.
43
- *
44
- * By default, a `RepeatedAction` throttler is used which prevents the same sync action from
45
- * being sent within an adjustable time period.
46
- */
47
- get actionThrottler(): MediaSessionActionThrottler;
48
- set actionThrottler(value: MediaSessionActionThrottler);
49
- /**
50
- * The group coordinator for the session.
51
- */
52
- get coordinator(): LiveMediaSessionCoordinator;
53
- /**
54
- * Returns the logger used by the session and coordinator.
55
- *
56
- * @remarks
57
- * This is used by the `MediaPlayerSynchronizer` to log events.
58
- */
59
- get logger(): LiveTelemetryLogger;
60
- /**
61
- * Initialize the object to begin sending/receiving group playback updates through this DDS.
62
- *
63
- * @param allowedRoles Optional. List of roles allowed to group transport operations like play/pause/seek/setTrack.
64
- *
65
- * @returns a void promise that resolves once complete.
66
- *
67
- * @throws error when `.initialize()` has already been called for this class instance.
68
- */
69
- initialize(allowedRoles?: UserMeetingRole[]): Promise<void>;
70
- /**
71
- * Registers an action handler with the session.
72
- * @param action Name of the action to register a handler for.
73
- * @param handler Function called when the action is triggered.
74
- */
75
- setActionHandler(action: ExtendedMediaSessionAction, handler: ExtendedMediaSessionActionHandler | MediaSessionActionHandler | null): void;
76
- /**
77
- * Registers a handler that will be queried anytime the group coordinate needs to know the
78
- * local players transport state and position.
79
- */
80
- setRequestPlayerStateHandler(handler: () => IMediaPlayerState): void;
81
- /**
82
- * Begins synchronizing the playback of a media element.
83
- * @param player Something that "looks like" and HTML Media Element.
84
- * @returns A new synchronizer instance. Call `synchronizer.end()` to stop synchronizing the elements playback.
85
- */
86
- synchronize(player: IMediaPlayer): MediaPlayerSynchronizer;
87
- protected hasInitialized(): Promise<void>;
88
- private checkWaitPointHit;
89
- private getCurrentPlayerState;
90
- private dispatchAction;
91
- }
92
- /**
93
- * Live fluid object that synchronizes media playback across multiple clients.
94
- */
95
- export type LiveMediaSession = LiveMediaSessionClass;
96
- export declare const LiveMediaSession: typeof LiveMediaSessionClass & SharedObjectKind<LiveMediaSessionClass>;
97
- //# sourceMappingURL=LiveMediaSession.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"LiveMediaSession.d.ts","sourceRoot":"","sources":["../../src/LiveMediaSession.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EACH,iBAAiB,EAEpB,MAAM,mCAAmC,CAAC;AAC3C,OAAO,EAGH,mBAAmB,EACnB,eAAe,EAClB,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EAEH,cAAc,EACjB,MAAM,gCAAgC,CAAC;AACxC,OAAO,EAAE,uBAAuB,EAAE,MAAM,8BAA8B,CAAC;AAEvE,OAAO,EAEH,0BAA0B,EAE1B,iCAAiC,EACpC,MAAM,6BAA6B,CAAC;AACrC,OAAO,EACH,2BAA2B,EAC3B,iBAAiB,EACpB,MAAM,kCAAkC,CAAC;AAC1C,OAAO,EAAE,2BAA2B,EAAE,MAAM,kCAAkC,CAAC;AAE/E,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AACjD,OAAO,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AAGnD;;GAEG;AACH,qBAAa,qBAAsB,SAAQ,cAAc;IACrD,OAAO,CAAC,gBAAgB,CACU;IAClC,OAAO,CAAC,OAAO,CAAC,CAAsB;IACtC,OAAO,CAAC,0BAA0B,CAAC,CAA0B;IAC7D,OAAO,CAAC,YAAY,CAAC,CAA8B;IACnD,OAAO,CAAC,QAAQ,CAAC,eAAe,CAGlB;IACd,OAAO,CAAC,cAAc,CAAC,CAA0B;IAGjD,OAAO,CAAC,YAAY,CAAM;IAC1B,OAAO,CAAC,eAAe,CAAa;IAEpC;;OAEG;IACH,gBAAuB,QAAQ,+CAA+C;IAE9E;;OAEG;IACH,gBAAuB,OAAO,wGAK5B;IAEF;;;;;;;;;;;;OAYG;IACH,IAAW,eAAe,IAAI,2BAA2B,CAExD;IAED,IAAW,eAAe,CAAC,KAAK,EAAE,2BAA2B,EAE5D;IAED;;OAEG;IACH,IAAW,WAAW,IAAI,2BAA2B,CAEpD;IAED;;;;;OAKG;IACH,IAAW,MAAM,IAAI,mBAAmB,CAEvC;IAED;;;;;;;;OAQG;IACU,UAAU,CAAC,YAAY,CAAC,EAAE,eAAe,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;IAqBxE;;;;OAIG;IACI,gBAAgB,CACnB,MAAM,EAAE,0BAA0B,EAClC,OAAO,EACD,iCAAiC,GACjC,yBAAyB,GACzB,IAAI,GACX,IAAI;IAUP;;;OAGG;IACI,4BAA4B,CAAC,OAAO,EAAE,MAAM,iBAAiB;IAIpE;;;;OAIG;IACI,WAAW,CAAC,MAAM,EAAE,YAAY,GAAG,uBAAuB;cAoCjD,cAAc,IAAI,OAAO,CAAC,IAAI,CAAC;IAwF/C,OAAO,CAAC,iBAAiB;IAgCzB,OAAO,CAAC,qBAAqB;IAU7B,OAAO,CAAC,cAAc;CAQzB;AAED;;GAEG;AACH,MAAM,MAAM,gBAAgB,GAAG,qBAAqB,CAAC;AAGrD,eAAO,MAAM,gBAAgB,wEAGzB,CAAC"}