@microsoft/live-share-media 2.0.0-internal.2 → 2.0.0-internal.20
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +26 -27
- package/bin/esm/IMediaPlayer.d.ts.map +1 -0
- package/bin/{IMediaPlayer.js → esm/IMediaPlayer.js} +1 -2
- package/bin/esm/IMediaPlayer.js.map +1 -0
- package/bin/{LiveMediaSession.d.ts → esm/LiveMediaSession.d.ts} +16 -9
- package/bin/esm/LiveMediaSession.d.ts.map +1 -0
- package/bin/esm/LiveMediaSession.js +247 -0
- package/bin/esm/LiveMediaSession.js.map +1 -0
- package/bin/{LiveMediaSessionCoordinator.d.ts → esm/LiveMediaSessionCoordinator.d.ts} +57 -13
- package/bin/esm/LiveMediaSessionCoordinator.d.ts.map +1 -0
- package/bin/esm/LiveMediaSessionCoordinator.js +544 -0
- package/bin/esm/LiveMediaSessionCoordinator.js.map +1 -0
- package/bin/{LiveMediaSessionCoordinatorSuspension.d.ts → esm/LiveMediaSessionCoordinatorSuspension.d.ts} +1 -1
- package/bin/esm/LiveMediaSessionCoordinatorSuspension.d.ts.map +1 -0
- package/bin/{LiveMediaSessionCoordinatorSuspension.js → esm/LiveMediaSessionCoordinatorSuspension.js} +3 -5
- package/bin/esm/LiveMediaSessionCoordinatorSuspension.js.map +1 -0
- package/bin/{MediaPlayerSynchronizer.d.ts → esm/MediaPlayerSynchronizer.d.ts} +22 -8
- package/bin/esm/MediaPlayerSynchronizer.d.ts.map +1 -0
- package/bin/{MediaPlayerSynchronizer.js → esm/MediaPlayerSynchronizer.js} +130 -153
- package/bin/esm/MediaPlayerSynchronizer.js.map +1 -0
- package/bin/{MediaSessionActionThrottler.d.ts → esm/MediaSessionActionThrottler.d.ts} +1 -1
- package/bin/esm/MediaSessionActionThrottler.d.ts.map +1 -0
- package/bin/esm/MediaSessionActionThrottler.js +10 -0
- package/bin/esm/MediaSessionActionThrottler.js.map +1 -0
- package/bin/esm/MediaSessionExtensions.d.ts.map +1 -0
- package/bin/{MediaSessionExtensions.js → esm/MediaSessionExtensions.js} +2 -5
- package/bin/esm/MediaSessionExtensions.js.map +1 -0
- package/bin/{RepeatedActionThrottler.d.ts → esm/RepeatedActionThrottler.d.ts} +2 -2
- package/bin/esm/RepeatedActionThrottler.d.ts.map +1 -0
- package/bin/{RepeatedActionThrottler.js → esm/RepeatedActionThrottler.js} +12 -17
- package/bin/esm/RepeatedActionThrottler.js.map +1 -0
- package/bin/{VolumeManager.d.ts → esm/VolumeManager.d.ts} +6 -6
- package/bin/esm/VolumeManager.d.ts.map +1 -0
- package/bin/{VolumeManager.js → esm/VolumeManager.js} +19 -22
- package/bin/esm/VolumeManager.js.map +1 -0
- package/bin/esm/index.d.ts +14 -0
- package/bin/esm/index.d.ts.map +1 -0
- package/bin/esm/index.js +14 -0
- package/bin/esm/index.js.map +1 -0
- package/bin/{internals → esm/internals}/GroupCoordinatorState.d.ts +14 -12
- package/bin/esm/internals/GroupCoordinatorState.d.ts.map +1 -0
- package/bin/{internals → esm/internals}/GroupCoordinatorState.js +177 -185
- package/bin/esm/internals/GroupCoordinatorState.js.map +1 -0
- package/bin/{internals → esm/internals}/GroupPlaybackPosition.d.ts +6 -5
- package/bin/esm/internals/GroupPlaybackPosition.d.ts.map +1 -0
- package/bin/{internals → esm/internals}/GroupPlaybackPosition.js +16 -12
- package/bin/esm/internals/GroupPlaybackPosition.js.map +1 -0
- package/bin/{internals → esm/internals}/GroupPlaybackRate.d.ts +4 -5
- package/bin/esm/internals/GroupPlaybackRate.d.ts.map +1 -0
- package/bin/{internals → esm/internals}/GroupPlaybackRate.js +5 -11
- package/bin/esm/internals/GroupPlaybackRate.js.map +1 -0
- package/bin/{internals → esm/internals}/GroupPlaybackTrack.d.ts +5 -6
- package/bin/esm/internals/GroupPlaybackTrack.d.ts.map +1 -0
- package/bin/{internals → esm/internals}/GroupPlaybackTrack.js +6 -11
- package/bin/esm/internals/GroupPlaybackTrack.js.map +1 -0
- package/bin/{internals → esm/internals}/GroupPlaybackTrackData.d.ts +5 -6
- package/bin/esm/internals/GroupPlaybackTrackData.d.ts.map +1 -0
- package/bin/{internals → esm/internals}/GroupPlaybackTrackData.js +8 -13
- package/bin/esm/internals/GroupPlaybackTrackData.js.map +1 -0
- package/bin/{internals → esm/internals}/GroupTransportState.d.ts +8 -9
- package/bin/esm/internals/GroupTransportState.d.ts.map +1 -0
- package/bin/{internals → esm/internals}/GroupTransportState.js +11 -13
- package/bin/esm/internals/GroupTransportState.js.map +1 -0
- package/bin/esm/internals/PriorityTimeInterval.d.ts +33 -0
- package/bin/esm/internals/PriorityTimeInterval.d.ts.map +1 -0
- package/bin/esm/internals/PriorityTimeInterval.js +53 -0
- package/bin/esm/internals/PriorityTimeInterval.js.map +1 -0
- package/bin/esm/internals/consts.d.ts.map +1 -0
- package/bin/{internals → esm/internals}/consts.js +1 -4
- package/bin/esm/internals/consts.js.map +1 -0
- package/bin/esm/internals/errors.d.ts.map +1 -0
- package/bin/{internals → esm/internals}/errors.js +2 -7
- package/bin/esm/internals/errors.js.map +1 -0
- package/bin/esm/internals/interfaces.d.ts +23 -0
- package/bin/esm/internals/interfaces.d.ts.map +1 -0
- package/bin/esm/internals/interfaces.js +2 -0
- package/bin/{internals → esm/internals}/interfaces.js.map +1 -1
- package/package.json +21 -12
- package/src/LiveMediaSession.ts +29 -14
- package/src/LiveMediaSessionCoordinator.ts +149 -37
- package/src/LiveMediaSessionCoordinatorSuspension.ts +2 -4
- package/src/MediaPlayerSynchronizer.ts +26 -11
- package/src/MediaSessionActionThrottler.ts +1 -1
- package/src/RepeatedActionThrottler.ts +2 -2
- package/src/VolumeManager.ts +6 -6
- package/src/index.ts +9 -9
- package/src/internals/GroupCoordinatorState.ts +19 -15
- package/src/internals/GroupPlaybackPosition.ts +9 -9
- package/src/internals/GroupPlaybackRate.ts +4 -4
- package/src/internals/GroupPlaybackTrack.ts +5 -5
- package/src/internals/GroupPlaybackTrackData.ts +5 -5
- package/src/internals/GroupTransportState.ts +8 -8
- package/src/internals/PriorityTimeInterval.ts +76 -0
- package/src/internals/interfaces.ts +15 -1
- package/tsconfig.json +64 -74
- package/.nycrc.json +0 -11
- package/bin/IMediaPlayer.d.ts.map +0 -1
- package/bin/IMediaPlayer.js.map +0 -1
- package/bin/LiveMediaSession.d.ts.map +0 -1
- package/bin/LiveMediaSession.js +0 -255
- package/bin/LiveMediaSession.js.map +0 -1
- package/bin/LiveMediaSessionCoordinator.d.ts.map +0 -1
- package/bin/LiveMediaSessionCoordinator.js +0 -472
- package/bin/LiveMediaSessionCoordinator.js.map +0 -1
- package/bin/LiveMediaSessionCoordinatorSuspension.d.ts.map +0 -1
- package/bin/LiveMediaSessionCoordinatorSuspension.js.map +0 -1
- package/bin/MediaPlayerSynchronizer.d.ts.map +0 -1
- package/bin/MediaPlayerSynchronizer.js.map +0 -1
- package/bin/MediaSessionActionThrottler.d.ts.map +0 -1
- package/bin/MediaSessionActionThrottler.js +0 -14
- package/bin/MediaSessionActionThrottler.js.map +0 -1
- package/bin/MediaSessionExtensions.d.ts.map +0 -1
- package/bin/MediaSessionExtensions.js.map +0 -1
- package/bin/RepeatedActionThrottler.d.ts.map +0 -1
- package/bin/RepeatedActionThrottler.js.map +0 -1
- package/bin/VolumeManager.d.ts.map +0 -1
- package/bin/VolumeManager.js.map +0 -1
- package/bin/index.d.ts +0 -14
- package/bin/index.d.ts.map +0 -1
- package/bin/index.js +0 -30
- package/bin/index.js.map +0 -1
- package/bin/internals/GroupCoordinatorState.d.ts.map +0 -1
- package/bin/internals/GroupCoordinatorState.js.map +0 -1
- package/bin/internals/GroupPlaybackPosition.d.ts.map +0 -1
- package/bin/internals/GroupPlaybackPosition.js.map +0 -1
- package/bin/internals/GroupPlaybackRate.d.ts.map +0 -1
- package/bin/internals/GroupPlaybackRate.js.map +0 -1
- package/bin/internals/GroupPlaybackTrack.d.ts.map +0 -1
- package/bin/internals/GroupPlaybackTrack.js.map +0 -1
- package/bin/internals/GroupPlaybackTrackData.d.ts.map +0 -1
- package/bin/internals/GroupPlaybackTrackData.js.map +0 -1
- package/bin/internals/GroupTransportState.d.ts.map +0 -1
- package/bin/internals/GroupTransportState.js.map +0 -1
- package/bin/internals/consts.d.ts.map +0 -1
- package/bin/internals/consts.js.map +0 -1
- package/bin/internals/errors.d.ts.map +0 -1
- package/bin/internals/errors.js.map +0 -1
- package/bin/internals/index.d.ts +0 -13
- package/bin/internals/index.d.ts.map +0 -1
- package/bin/internals/index.js +0 -29
- package/bin/internals/index.js.map +0 -1
- package/bin/internals/interfaces.d.ts +0 -10
- package/bin/internals/interfaces.d.ts.map +0 -1
- package/bin/internals/interfaces.js +0 -3
- package/src/internals/index.ts +0 -13
- package/tsconfig.build.json +0 -9
- package/typedoc.json +0 -10
- /package/bin/{IMediaPlayer.d.ts → esm/IMediaPlayer.d.ts} +0 -0
- /package/bin/{MediaSessionExtensions.d.ts → esm/MediaSessionExtensions.d.ts} +0 -0
- /package/bin/{internals → esm/internals}/consts.d.ts +0 -0
- /package/bin/{internals → esm/internals}/errors.d.ts +0 -0
package/README.md
CHANGED
|
@@ -35,15 +35,15 @@ This will use npm workspaces to hoist and build all dependencies.
|
|
|
35
35
|
|
|
36
36
|
```html
|
|
37
37
|
<body>
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
38
|
+
<video id="player">
|
|
39
|
+
<source src="YOUR_VIDEO_SRC" type="video/mp4" />
|
|
40
|
+
</video>
|
|
41
|
+
<div class="player-controls">
|
|
42
|
+
<button id="play-button">Play</button>
|
|
43
|
+
<button id="pause-button">Pause</button>
|
|
44
|
+
<button id="restart-button">Restart</button>
|
|
45
|
+
<button id="change-track-button">Change track</button>
|
|
46
|
+
</div>
|
|
47
47
|
</body>
|
|
48
48
|
```
|
|
49
49
|
|
|
@@ -58,14 +58,12 @@ await microsoftTeams.app.initialize();
|
|
|
58
58
|
// Setup the Fluid container
|
|
59
59
|
const host = LiveShareHost.create();
|
|
60
60
|
const client = new LiveShareClient(host);
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
const { container } = await client.joinContainer(schema);
|
|
68
|
-
const { mediaSession } = container.initialObjects;
|
|
61
|
+
await client.join();
|
|
62
|
+
|
|
63
|
+
const mediaSession =
|
|
64
|
+
(await client.getDDS) <
|
|
65
|
+
LiveMediaSession >
|
|
66
|
+
("media-session-id", LiveMediaSession);
|
|
69
67
|
|
|
70
68
|
// Get the player from your document and create synchronizer
|
|
71
69
|
const player = document.getElementById("player");
|
|
@@ -78,21 +76,21 @@ await mediaSession.initialize(allowedRoles);
|
|
|
78
76
|
// Intercept user play, pause, seek, and set track actions through synchronizer
|
|
79
77
|
|
|
80
78
|
document.getElementById("play-button").onclick = () => {
|
|
81
|
-
|
|
79
|
+
synchronizer.play();
|
|
82
80
|
};
|
|
83
81
|
|
|
84
82
|
document.getElementById("pause-button").onclick = () => {
|
|
85
|
-
|
|
83
|
+
synchronizer.pause();
|
|
86
84
|
};
|
|
87
85
|
|
|
88
86
|
document.getElementById("restart-button").onclick = () => {
|
|
89
|
-
|
|
87
|
+
synchronizer.seekTo(0);
|
|
90
88
|
};
|
|
91
89
|
|
|
92
90
|
document.getElementById("change-track-button").onclick = () => {
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
91
|
+
synchronizer.setTrack({
|
|
92
|
+
trackIdentifier: "SOME_OTHER_VIDEO_SRC",
|
|
93
|
+
});
|
|
96
94
|
};
|
|
97
95
|
```
|
|
98
96
|
|
|
@@ -102,7 +100,7 @@ There are several code samples that are hosted in a separate GitHub repository.
|
|
|
102
100
|
|
|
103
101
|
| Sample name | Description | Javascript |
|
|
104
102
|
| -------------------- | ----------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------- |
|
|
105
|
-
| React Video | Basic example showing how the LiveMediaSession object works with HTML5 video.
|
|
103
|
+
| React Video | Basic example showing how the LiveMediaSession object works with HTML5 video. | [View](https://aka.ms/liveshare-reactvideo) |
|
|
106
104
|
| React Media Template | Enable all connected clients to watch videos together, build a shared playlist, transfer whom is in control, and annotate over the video. | [View](https://aka.ms/liveshare-mediatemplate) |
|
|
107
105
|
|
|
108
106
|
## Package Compatibility
|
|
@@ -111,9 +109,10 @@ The Live Share SDK contains dependencies for [@microsoft/teams-js](https://www.n
|
|
|
111
109
|
|
|
112
110
|
**It is critical that your app use the package dependencies listed in the table below.** Lookup the version of the `@microsoft/live-share` you're using and set any other dependencies in your package.json file to match:
|
|
113
111
|
|
|
114
|
-
| @microsoft/live-share | @microsoft/teams-js
|
|
115
|
-
| --------------------- |
|
|
116
|
-
| ^
|
|
112
|
+
| @microsoft/live-share | @microsoft/teams-js | fluid-framework | @microsoft/live-share-\* | @fluidframework/azure-client | @microsoft/TeamsFx | @microsoft/TeamsFx-react |
|
|
113
|
+
| --------------------- | ------------------- | --------------- | ------------------------ | ---------------------------- | ------------------ | ------------------------ |
|
|
114
|
+
| ^2.0.0 | ^2.11.0 | ^2.0.0 | ^2.0.0 | ^2.0.0 | ^2.5.0 | ^2.5.0 |
|
|
115
|
+
| ^1.0.0 | ^2.11.0 | ^1.2.3 | ^1.0.0 | ^1.0.0 | ^2.5.0 | ^2.5.0 |
|
|
117
116
|
|
|
118
117
|
## Contributing
|
|
119
118
|
|
|
@@ -0,0 +1 @@
|
|
|
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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"IMediaPlayer.js","sourceRoot":"","sources":["../../src/IMediaPlayer.ts"],"names":[],"mappings":"AAAA;;;GAGG"}
|
|
@@ -2,17 +2,19 @@
|
|
|
2
2
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
3
3
|
* Licensed under the Microsoft Live Share SDK License.
|
|
4
4
|
*/
|
|
5
|
-
import { DataObjectFactory } from "@fluidframework/aqueduct";
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
8
|
-
import {
|
|
9
|
-
import {
|
|
10
|
-
import {
|
|
11
|
-
import {
|
|
5
|
+
import { DataObjectFactory } from "@fluidframework/aqueduct/legacy";
|
|
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";
|
|
12
14
|
/**
|
|
13
15
|
* Live fluid object that synchronizes media playback across multiple clients.
|
|
14
16
|
*/
|
|
15
|
-
export declare class
|
|
17
|
+
export declare class LiveMediaSessionClass extends LiveDataObject {
|
|
16
18
|
private _actionThrottler;
|
|
17
19
|
private _logger?;
|
|
18
20
|
private _requestPlayerStateHandler?;
|
|
@@ -28,7 +30,7 @@ export declare class LiveMediaSession extends LiveDataObject {
|
|
|
28
30
|
/**
|
|
29
31
|
* The objects fluid type factory.
|
|
30
32
|
*/
|
|
31
|
-
static readonly factory: DataObjectFactory<
|
|
33
|
+
static readonly factory: DataObjectFactory<LiveMediaSessionClass, import("@fluidframework/aqueduct/legacy").DataObjectTypes>;
|
|
32
34
|
/**
|
|
33
35
|
* Extension point that lets applications replace the default logic for throttling the sessions
|
|
34
36
|
* local sync behavior.
|
|
@@ -87,4 +89,9 @@ export declare class LiveMediaSession extends LiveDataObject {
|
|
|
87
89
|
private getCurrentPlayerState;
|
|
88
90
|
private dispatchAction;
|
|
89
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>;
|
|
90
97
|
//# sourceMappingURL=LiveMediaSession.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"LiveMediaSession.d.ts","sourceRoot":"","sources":["../../src/LiveMediaSession.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,iBAAiB,EAAE,MAAM,iCAAiC,CAAC;AACpE,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,sGAK5B;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"}
|
|
@@ -0,0 +1,247 @@
|
|
|
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/legacy";
|
|
6
|
+
import { LiveDataObjectInitializeNotNeededError, LiveDataObjectInitializeState, LiveTelemetryLogger, } from "@microsoft/live-share";
|
|
7
|
+
import { DynamicObjectRegistry, LiveDataObject, } from "@microsoft/live-share/internal";
|
|
8
|
+
import { MediaPlayerSynchronizer } from "./MediaPlayerSynchronizer.js";
|
|
9
|
+
import { MediaSessionCoordinatorEvents, } from "./MediaSessionExtensions.js";
|
|
10
|
+
import { LiveMediaSessionCoordinator, } from "./LiveMediaSessionCoordinator.js";
|
|
11
|
+
import { RepeatedActionThrottler } from "./RepeatedActionThrottler.js";
|
|
12
|
+
import { TelemetryEvents } from "./internals/consts.js";
|
|
13
|
+
/**
|
|
14
|
+
* Live fluid object that synchronizes media playback across multiple clients.
|
|
15
|
+
*/
|
|
16
|
+
export class LiveMediaSessionClass extends LiveDataObject {
|
|
17
|
+
_actionThrottler = new RepeatedActionThrottler();
|
|
18
|
+
_logger;
|
|
19
|
+
_requestPlayerStateHandler;
|
|
20
|
+
_coordinator;
|
|
21
|
+
_actionHandlers = new Map();
|
|
22
|
+
_synchronizing;
|
|
23
|
+
// Position update timer
|
|
24
|
+
_updateTimer;
|
|
25
|
+
_lastUpdateTime = 0;
|
|
26
|
+
/**
|
|
27
|
+
* The objects fluid type name.
|
|
28
|
+
*/
|
|
29
|
+
static TypeName = `@microsoft/fluid-media:SharedMediaSession`;
|
|
30
|
+
/**
|
|
31
|
+
* The objects fluid type factory.
|
|
32
|
+
*/
|
|
33
|
+
static factory = new DataObjectFactory(LiveMediaSessionClass.TypeName, LiveMediaSessionClass, [], {});
|
|
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() {
|
|
48
|
+
return this._actionThrottler;
|
|
49
|
+
}
|
|
50
|
+
set actionThrottler(value) {
|
|
51
|
+
this._actionThrottler = value;
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* The group coordinator for the session.
|
|
55
|
+
*/
|
|
56
|
+
get coordinator() {
|
|
57
|
+
return this._coordinator;
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* Returns the logger used by the session and coordinator.
|
|
61
|
+
*
|
|
62
|
+
* @remarks
|
|
63
|
+
* This is used by the `MediaPlayerSynchronizer` to log events.
|
|
64
|
+
*/
|
|
65
|
+
get logger() {
|
|
66
|
+
return this._logger;
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* Initialize the object to begin sending/receiving group playback updates through this DDS.
|
|
70
|
+
*
|
|
71
|
+
* @param allowedRoles Optional. List of roles allowed to group transport operations like play/pause/seek/setTrack.
|
|
72
|
+
*
|
|
73
|
+
* @returns a void promise that resolves once complete.
|
|
74
|
+
*
|
|
75
|
+
* @throws error when `.initialize()` has already been called for this class instance.
|
|
76
|
+
*/
|
|
77
|
+
async initialize(allowedRoles) {
|
|
78
|
+
LiveDataObjectInitializeNotNeededError.assert("LiveMediaSession:initialize", this.initializeState);
|
|
79
|
+
// Update initialize state as pending
|
|
80
|
+
this.initializeState = LiveDataObjectInitializeState.pending;
|
|
81
|
+
if (allowedRoles) {
|
|
82
|
+
this._allowedRoles = allowedRoles;
|
|
83
|
+
}
|
|
84
|
+
try {
|
|
85
|
+
await this.coordinator.initialize(allowedRoles);
|
|
86
|
+
}
|
|
87
|
+
catch (error) {
|
|
88
|
+
this.initializeState = LiveDataObjectInitializeState.needed;
|
|
89
|
+
throw error;
|
|
90
|
+
}
|
|
91
|
+
// Update initialize state as succeeded
|
|
92
|
+
this.initializeState = LiveDataObjectInitializeState.succeeded;
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* Registers an action handler with the session.
|
|
96
|
+
* @param action Name of the action to register a handler for.
|
|
97
|
+
* @param handler Function called when the action is triggered.
|
|
98
|
+
*/
|
|
99
|
+
setActionHandler(action, handler) {
|
|
100
|
+
if (handler) {
|
|
101
|
+
// add handler
|
|
102
|
+
this._actionHandlers.set(action, handler);
|
|
103
|
+
}
|
|
104
|
+
else if (this._actionHandlers.has(action)) {
|
|
105
|
+
// remove handler
|
|
106
|
+
this._actionHandlers.delete(action);
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
/**
|
|
110
|
+
* Registers a handler that will be queried anytime the group coordinate needs to know the
|
|
111
|
+
* local players transport state and position.
|
|
112
|
+
*/
|
|
113
|
+
setRequestPlayerStateHandler(handler) {
|
|
114
|
+
this._requestPlayerStateHandler = handler;
|
|
115
|
+
}
|
|
116
|
+
/**
|
|
117
|
+
* Begins synchronizing the playback of a media element.
|
|
118
|
+
* @param player Something that "looks like" and HTML Media Element.
|
|
119
|
+
* @returns A new synchronizer instance. Call `synchronizer.end()` to stop synchronizing the elements playback.
|
|
120
|
+
*/
|
|
121
|
+
synchronize(player) {
|
|
122
|
+
// A session can only synchronize one player at a time
|
|
123
|
+
if (this._synchronizing) {
|
|
124
|
+
this._synchronizing.end();
|
|
125
|
+
}
|
|
126
|
+
// Start position update timer
|
|
127
|
+
if (!this._updateTimer) {
|
|
128
|
+
this.logger.sendTelemetryEvent(TelemetryEvents.MediaSession.BeginPositionUpdateTimer);
|
|
129
|
+
this._updateTimer = setInterval(() => {
|
|
130
|
+
// Get current state
|
|
131
|
+
const state = this.getCurrentPlayerState();
|
|
132
|
+
// Check for hit wait point
|
|
133
|
+
this.checkWaitPointHit(state);
|
|
134
|
+
// Send position update if interval hit
|
|
135
|
+
const now = new Date().getTime();
|
|
136
|
+
const delta = (now - this._lastUpdateTime) / 1000;
|
|
137
|
+
if (this.coordinator.isInitialized &&
|
|
138
|
+
delta >= this.coordinator.positionUpdateInterval) {
|
|
139
|
+
this._lastUpdateTime = now;
|
|
140
|
+
this.coordinator.sendPositionUpdate(state);
|
|
141
|
+
}
|
|
142
|
+
}, 500);
|
|
143
|
+
}
|
|
144
|
+
return new MediaPlayerSynchronizer(player, this, this.runtime, () => {
|
|
145
|
+
this._synchronizing = undefined;
|
|
146
|
+
});
|
|
147
|
+
}
|
|
148
|
+
async hasInitialized() {
|
|
149
|
+
this._logger = new LiveTelemetryLogger(this.runtime, this.liveRuntime);
|
|
150
|
+
// Create coordinator and listen for triggered actions
|
|
151
|
+
this._coordinator = new LiveMediaSessionCoordinator(this.id, this.runtime, this.liveRuntime, () => this.getCurrentPlayerState());
|
|
152
|
+
this._coordinator.on(MediaSessionCoordinatorEvents.triggeraction, (event) => {
|
|
153
|
+
// Pre-process actions
|
|
154
|
+
const details = event.details;
|
|
155
|
+
const seekTime = typeof details.seekTime == "number" ? details.seekTime : -1;
|
|
156
|
+
switch (details.action) {
|
|
157
|
+
case "play":
|
|
158
|
+
this.logger.sendTelemetryEvent(TelemetryEvents.MediaSession.PlayAction, null, {
|
|
159
|
+
position: seekTime,
|
|
160
|
+
});
|
|
161
|
+
break;
|
|
162
|
+
case "pause":
|
|
163
|
+
this.logger.sendTelemetryEvent(TelemetryEvents.MediaSession.PauseAction, null, {
|
|
164
|
+
position: seekTime,
|
|
165
|
+
});
|
|
166
|
+
break;
|
|
167
|
+
case "ratechange":
|
|
168
|
+
if (!details.playbackRate) {
|
|
169
|
+
break;
|
|
170
|
+
}
|
|
171
|
+
this.logger.sendTelemetryEvent(TelemetryEvents.MediaSession.RateChangeAction, null, {
|
|
172
|
+
playbackRate: details.playbackRate,
|
|
173
|
+
});
|
|
174
|
+
break;
|
|
175
|
+
case "seekto":
|
|
176
|
+
this.logger.sendTelemetryEvent(TelemetryEvents.MediaSession.SeekToAction, null, {
|
|
177
|
+
position: seekTime,
|
|
178
|
+
});
|
|
179
|
+
break;
|
|
180
|
+
case "settrack":
|
|
181
|
+
this.logger.sendTelemetryEvent(TelemetryEvents.MediaSession.SetTrackAction);
|
|
182
|
+
break;
|
|
183
|
+
case "datachange":
|
|
184
|
+
this.logger.sendTelemetryEvent(TelemetryEvents.MediaSession.DataChangeAction);
|
|
185
|
+
break;
|
|
186
|
+
case "catchup":
|
|
187
|
+
// Default to seekto if catchup not implemented
|
|
188
|
+
this.logger.sendTelemetryEvent(TelemetryEvents.MediaSession.CatchUpAction, null, {
|
|
189
|
+
position: seekTime,
|
|
190
|
+
});
|
|
191
|
+
if (!this._actionHandlers.has("catchup")) {
|
|
192
|
+
details.action = "seekto";
|
|
193
|
+
}
|
|
194
|
+
break;
|
|
195
|
+
}
|
|
196
|
+
// Dispatch action
|
|
197
|
+
this.dispatchAction(details);
|
|
198
|
+
});
|
|
199
|
+
}
|
|
200
|
+
checkWaitPointHit(state) {
|
|
201
|
+
// Was a wait point hit?
|
|
202
|
+
if (state.positionState && this.coordinator.isInitialized) {
|
|
203
|
+
const waitPoint = this.coordinator.findNextWaitPoint();
|
|
204
|
+
if (waitPoint &&
|
|
205
|
+
state.positionState.position != undefined &&
|
|
206
|
+
state.positionState.position >= waitPoint.position) {
|
|
207
|
+
// Ensure handler registered
|
|
208
|
+
if (!this._actionHandlers.has("wait")) {
|
|
209
|
+
throw new Error(`LiveMediaSession:checkWaitPointHit - wait point hit but no 'wait' action registered.\nTo fix this error, set a \`wait\` action using the \`setActionHandler()\` function.`);
|
|
210
|
+
}
|
|
211
|
+
// Begin suspension for wait point
|
|
212
|
+
this.waitUntilConnected().then((clientId) => {
|
|
213
|
+
const suspension = this.coordinator.beginSuspension(waitPoint);
|
|
214
|
+
this.dispatchAction({
|
|
215
|
+
action: "wait",
|
|
216
|
+
source: "system",
|
|
217
|
+
clientId,
|
|
218
|
+
local: true,
|
|
219
|
+
suspension,
|
|
220
|
+
});
|
|
221
|
+
});
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
getCurrentPlayerState() {
|
|
226
|
+
if (!this._requestPlayerStateHandler) {
|
|
227
|
+
throw new Error("LiveMediaSession:getCurrentPlayerState - no `requestPlayerStateHandler` callback configured.\nTo fix this error, ensure `setRequestPlayerStateHandler()` has been set with a delegate to retrieve your player's state, or use the `synchronize()` function to create a new `MediaPlayerSynchronizer` instance tied to your `IMediaPlayer` instance.");
|
|
228
|
+
}
|
|
229
|
+
return this._requestPlayerStateHandler();
|
|
230
|
+
}
|
|
231
|
+
dispatchAction(details) {
|
|
232
|
+
if (this._actionHandlers.has(details.action)) {
|
|
233
|
+
const handler = this._actionHandlers.get(details.action);
|
|
234
|
+
this._actionThrottler.throttled(details, handler);
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
// eslint-disable-next-line no-redeclare
|
|
239
|
+
export const LiveMediaSession = (() => {
|
|
240
|
+
const kind = LiveMediaSessionClass;
|
|
241
|
+
return kind;
|
|
242
|
+
})();
|
|
243
|
+
/**
|
|
244
|
+
* Register `LiveMediaSession` as an available `SharedObjectKind` for use in dynamic object loading.
|
|
245
|
+
*/
|
|
246
|
+
DynamicObjectRegistry.registerObjectClass(LiveMediaSession, LiveMediaSession.TypeName);
|
|
247
|
+
//# sourceMappingURL=LiveMediaSession.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"LiveMediaSession.js","sourceRoot":"","sources":["../../src/LiveMediaSession.ts"],"names":[],"mappings":"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"}
|
|
@@ -2,10 +2,11 @@
|
|
|
2
2
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
3
3
|
* Licensed under the Microsoft Live Share SDK License.
|
|
4
4
|
*/
|
|
5
|
-
|
|
6
|
-
import { IRuntimeSignaler,
|
|
7
|
-
import { CoordinationWaitPoint, ExtendedMediaMetadata, ExtendedMediaSessionPlaybackState, MediaSessionCoordinatorSuspension } from "./MediaSessionExtensions";
|
|
8
|
-
import
|
|
5
|
+
import { UserMeetingRole } from "@microsoft/live-share";
|
|
6
|
+
import { IRuntimeSignaler, LiveShareRuntime } from "@microsoft/live-share/internal";
|
|
7
|
+
import { CoordinationWaitPoint, ExtendedMediaMetadata, ExtendedMediaSessionPlaybackState, MediaSessionCoordinatorSuspension } from "./MediaSessionExtensions.js";
|
|
8
|
+
import { TypedEventEmitter } from "@fluid-internal/client-utils";
|
|
9
|
+
import { IEvent } from "@fluidframework/core-interfaces";
|
|
9
10
|
/**
|
|
10
11
|
* Most recent state of the media session.
|
|
11
12
|
*/
|
|
@@ -30,12 +31,24 @@ export interface IMediaPlayerState {
|
|
|
30
31
|
*/
|
|
31
32
|
positionState?: MediaPositionState;
|
|
32
33
|
}
|
|
34
|
+
/**
|
|
35
|
+
* @hidden
|
|
36
|
+
*/
|
|
37
|
+
export interface ILiveMediaSessionCoordinatorEvents extends IEvent {
|
|
38
|
+
/**
|
|
39
|
+
* Event listener for events emitted
|
|
40
|
+
* @param event update
|
|
41
|
+
* @param listener listener function
|
|
42
|
+
* @param listener.event the event instance
|
|
43
|
+
*/
|
|
44
|
+
(event: string, listener: (event: any) => void): void;
|
|
45
|
+
}
|
|
33
46
|
/**
|
|
34
47
|
* The `LiveMediaSessionCoordinator` tracks the playback & position state of all other
|
|
35
48
|
* clients being synchronized with. It is responsible for keeping the local media player
|
|
36
49
|
* in sync with the group.
|
|
37
50
|
*/
|
|
38
|
-
export declare class LiveMediaSessionCoordinator extends
|
|
51
|
+
export declare class LiveMediaSessionCoordinator extends TypedEventEmitter<ILiveMediaSessionCoordinatorEvents> {
|
|
39
52
|
private readonly _id;
|
|
40
53
|
private readonly _runtime;
|
|
41
54
|
private readonly _liveRuntime;
|
|
@@ -135,22 +148,45 @@ export declare class LiveMediaSessionCoordinator extends EventEmitter {
|
|
|
135
148
|
*/
|
|
136
149
|
get isSuspended(): boolean;
|
|
137
150
|
/**
|
|
138
|
-
*
|
|
151
|
+
* Controls whether or not to scale {@link maxPlaybackDrift} by the number of users in the session.
|
|
139
152
|
*
|
|
140
153
|
* @remarks
|
|
141
|
-
*
|
|
142
|
-
*
|
|
154
|
+
* As more clients join a session, it is more likely that some users will fall behind the presenter.
|
|
155
|
+
* It is also less likely that users will notice drift as more clients are added.
|
|
156
|
+
* It is usually helpful to be more lenient as more clients are added so everyone can watch all the content.
|
|
157
|
+
* Default value is true.
|
|
158
|
+
*/
|
|
159
|
+
get shouldScaleMaxPlaybackDrift(): boolean;
|
|
160
|
+
set shouldScaleMaxPlaybackDrift(value: boolean);
|
|
161
|
+
/**
|
|
162
|
+
* Max amount of playback drift allowed in seconds.
|
|
163
|
+
* This will scale automatically according to the number of participants in the session when {@link shouldScaleMaxPlaybackDrift} is true.
|
|
143
164
|
*
|
|
144
|
-
*
|
|
165
|
+
* @remarks
|
|
166
|
+
* Should the local clients playback position lag by more than the specified value, the coordinator will trigger a `catchup` action.
|
|
167
|
+
* Default value is `1.5` seconds.
|
|
145
168
|
*/
|
|
146
169
|
get maxPlaybackDrift(): number;
|
|
147
170
|
set maxPlaybackDrift(value: number);
|
|
148
171
|
/**
|
|
149
|
-
*
|
|
150
|
-
*
|
|
172
|
+
* Controls whether or not to compute {@link positionUpdateInterval} based on whether user has initiated a playback command.
|
|
173
|
+
* Default value is true.
|
|
174
|
+
*
|
|
175
|
+
* @remarks
|
|
176
|
+
* When true, users that are simply watching but not controlling playback will report their positions less frequently.
|
|
177
|
+
* When a user has sent a transport command, they will begin sending position updates more frequently.
|
|
178
|
+
* Most Live Share apps have a concept of a primary presenter, and don't allow anyone to pause/play for the group.
|
|
179
|
+
* By ensuring only one/few users broadcast updates frequently, the server load is reduced considerably.
|
|
180
|
+
*/
|
|
181
|
+
get shouldScalePositionUpdateInterval(): boolean;
|
|
182
|
+
set shouldScalePositionUpdateInterval(value: boolean);
|
|
183
|
+
/**
|
|
184
|
+
* Frequency with which position updates are broadcast to the rest of the group in seconds.
|
|
185
|
+
* When {@link shouldScalePositionUpdateInterval} is set to `true`, the value set is the minimum value.
|
|
186
|
+
* The value returned is the actual value used to send updates by the local user, which may be larger than the value set.
|
|
151
187
|
*
|
|
152
188
|
* @remarks
|
|
153
|
-
* Defaults to a value of `2` seconds.
|
|
189
|
+
* Defaults to a minimum value of `2` seconds.
|
|
154
190
|
*/
|
|
155
191
|
get positionUpdateInterval(): number;
|
|
156
192
|
set positionUpdateInterval(value: number);
|
|
@@ -184,6 +220,14 @@ export declare class LiveMediaSessionCoordinator extends EventEmitter {
|
|
|
184
220
|
* @returns a void promise that resolves once complete, throws if user does not have proper roles
|
|
185
221
|
*/
|
|
186
222
|
seekTo(time: number): Promise<void>;
|
|
223
|
+
/**
|
|
224
|
+
* Sets the playback rate for everyone in the session.
|
|
225
|
+
*
|
|
226
|
+
* @param playbackRate the playback rate to set.
|
|
227
|
+
*
|
|
228
|
+
* @throws
|
|
229
|
+
* Throws an exception if the session/coordinator hasn't been initialized or {@link canSetPlaybackRate} is false.
|
|
230
|
+
*/
|
|
187
231
|
setPlaybackRate(playbackRate: number): Promise<void>;
|
|
188
232
|
/**
|
|
189
233
|
* Instructs the group to load a new track.
|
|
@@ -253,7 +297,7 @@ export declare class LiveMediaSessionCoordinator extends EventEmitter {
|
|
|
253
297
|
* @hidden
|
|
254
298
|
* Called by MediaSession to trigger the sending of a position update.
|
|
255
299
|
*/
|
|
256
|
-
sendPositionUpdate(state: IMediaPlayerState): void;
|
|
300
|
+
sendPositionUpdate(state: IMediaPlayerState, targetClientId?: string): void;
|
|
257
301
|
protected createChildren(acceptTransportChangesFrom?: UserMeetingRole[]): Promise<void>;
|
|
258
302
|
private getPlayerPosition;
|
|
259
303
|
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"LiveMediaSessionCoordinator.d.ts","sourceRoot":"","sources":["../../src/LiveMediaSessionCoordinator.ts"],"names":[],"mappings":"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"}
|