@scarlett-player/media-session 1.7.0 → 1.8.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md ADDED
@@ -0,0 +1,86 @@
1
+ # @scarlett-player/media-session
2
+
3
+ Media Session plugin for [Scarlett Player](https://scarlettplayer.com). Wires the player into the browser's Media Session API so playback can be controlled from the lock screen, the notification shade, hardware media keys and the system media UI, with track title, artist, album, artwork and a live seek bar. Where the API is missing the plugin logs a notice and does nothing, so it is safe to include everywhere.
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ pnpm add @scarlett-player/media-session @scarlett-player/core
9
+ ```
10
+
11
+ `@scarlett-player/core` is a peer dependency.
12
+
13
+ ## Usage
14
+
15
+ ```ts
16
+ import { createPlayer } from '@scarlett-player/core';
17
+ import { createNativePlugin } from '@scarlett-player/native';
18
+ import { createMediaSessionPlugin } from '@scarlett-player/media-session';
19
+
20
+ const player = await createPlayer({
21
+ container: document.getElementById('player'),
22
+ src: 'https://example.com/track.mp3',
23
+ plugins: [
24
+ createNativePlugin(),
25
+ createMediaSessionPlugin({
26
+ seekOffset: 15,
27
+ defaultArtwork: [{ src: '/default-artwork.png', sizes: '512x512' }],
28
+ }),
29
+ ],
30
+ });
31
+ ```
32
+
33
+ With no configuration the plugin registers play, pause, stop, seek and track navigation handlers, mirrors the player's playing, paused and ended states, and updates the system seek bar about once a second while playing.
34
+
35
+ Metadata comes from three places, in order of arrival: the player's `title` and `poster` state (the poster becomes the artwork), a `playlist:change` event from `@scarlett-player/playlist` (title, artist, album and artwork are read from the track), and calls to `setMetadata()`. When no artwork is available `defaultArtwork` is used.
36
+
37
+ ## Configuration
38
+
39
+ | Option | Type | Default | Description |
40
+ |---|---|---|---|
41
+ | `enablePlayPause` | `boolean` | `true` | Register the `play`, `pause` and `stop` action handlers |
42
+ | `enableSeek` | `boolean` | `true` | Register the `seekbackward`, `seekforward` and `seekto` action handlers |
43
+ | `enableTrackNavigation` | `boolean` | `true` | Register `previoustrack` and `nexttrack`. Both call the playlist plugin when it is present; without one, previous seeks to 0 and next does nothing |
44
+ | `seekOffset` | `number` | `10` | Seconds to skip for `seekbackward` and `seekforward` when the OS does not supply its own offset |
45
+ | `defaultArtwork` | `MediaSessionArtwork[]` | `undefined` | Artwork used when the current metadata has none. Each entry is `{ src, sizes?, type? }`; `sizes` defaults to `'512x512'` and `type` to `'image/png'` |
46
+ | `updatePositionState` | `boolean` | `true` | Push duration, position and playback rate to the system seek bar on `playback:timeupdate` (throttled to once per second) and on `media:loadedmetadata` |
47
+
48
+ ## Plugin API
49
+
50
+ The plugin is registered under the id `media-session`:
51
+
52
+ ```ts
53
+ import type { IMediaSessionPlugin } from '@scarlett-player/media-session';
54
+
55
+ const session = player.getPlugin<IMediaSessionPlugin>('media-session');
56
+
57
+ session?.isSupported();
58
+ session?.setMetadata({
59
+ title: 'Track 1',
60
+ artist: 'Artist',
61
+ album: 'Album',
62
+ artwork: [{ src: '/art1.jpg', sizes: '512x512', type: 'image/jpeg' }],
63
+ });
64
+ session?.setPlaybackState('playing');
65
+ session?.setPositionState({ duration: 240, position: 12, playbackRate: 1 });
66
+ session?.setActionHandler('nexttrack', () => goToNextEpisode());
67
+ session?.setActionHandler('nexttrack', null); // remove it again
68
+ ```
69
+
70
+ | Method | Description |
71
+ |---|---|
72
+ | `isSupported()` | `true` when `navigator.mediaSession` exists |
73
+ | `setMetadata(metadata)` | Merge `title`, `artist`, `album` and `artwork` into the current metadata and push it to the OS |
74
+ | `setPlaybackState(state)` | Set `'none'`, `'paused'` or `'playing'` directly |
75
+ | `setPositionState({ duration, position, playbackRate })` | Update the system seek bar directly |
76
+ | `setActionHandler(action, handler)` | Replace one of the built-in handlers, or pass `null` to clear it |
77
+
78
+ ## Events
79
+
80
+ The plugin emits no events of its own. In response to OS actions it emits the core events `playback:play`, `playback:pause` and `playback:seeking`, and it listens to `playback:play`, `playback:pause`, `playback:ended`, `playback:timeupdate`, `media:loadedmetadata` and `playlist:change`.
81
+
82
+ On destroy every action handler is cleared, the metadata is set to `null` and the playback state returns to `'none'`.
83
+
84
+ ## License
85
+
86
+ MIT
package/dist/index.cjs CHANGED
@@ -24,6 +24,11 @@ __export(index_exports, {
24
24
  default: () => index_default
25
25
  });
26
26
  module.exports = __toCommonJS(index_exports);
27
+
28
+ // src/version.ts
29
+ var PKG_VERSION = true ? "1.8.1" : "0.0.0-dev";
30
+
31
+ // src/index.ts
27
32
  var DEFAULT_CONFIG = {
28
33
  enablePlayPause: true,
29
34
  enableSeek: true,
@@ -171,7 +176,7 @@ function createMediaSessionPlugin(config) {
171
176
  const plugin = {
172
177
  id: "media-session",
173
178
  name: "Media Session",
174
- version: "1.0.0",
179
+ version: PKG_VERSION,
175
180
  type: "feature",
176
181
  description: "Media Session API integration for system-level media controls",
177
182
  async init(pluginApi) {
package/dist/index.d.cts CHANGED
@@ -124,9 +124,10 @@ interface IMediaSessionPlugin extends Plugin<MediaSessionPluginConfig> {
124
124
  *
125
125
  * @example
126
126
  * ```ts
127
+ * import { createPlayer } from '@scarlett-player/core';
127
128
  * import { createMediaSessionPlugin } from '@scarlett-player/media-session';
128
129
  *
129
- * const player = new ScarlettPlayer({
130
+ * const player = await createPlayer({
130
131
  * container: document.getElementById('player'),
131
132
  * plugins: [
132
133
  * createMediaSessionPlugin({
package/dist/index.d.ts CHANGED
@@ -124,9 +124,10 @@ interface IMediaSessionPlugin extends Plugin<MediaSessionPluginConfig> {
124
124
  *
125
125
  * @example
126
126
  * ```ts
127
+ * import { createPlayer } from '@scarlett-player/core';
127
128
  * import { createMediaSessionPlugin } from '@scarlett-player/media-session';
128
129
  *
129
- * const player = new ScarlettPlayer({
130
+ * const player = await createPlayer({
130
131
  * container: document.getElementById('player'),
131
132
  * plugins: [
132
133
  * createMediaSessionPlugin({
package/dist/index.js CHANGED
@@ -1,3 +1,6 @@
1
+ // src/version.ts
2
+ var PKG_VERSION = true ? "1.8.1" : "0.0.0-dev";
3
+
1
4
  // src/index.ts
2
5
  var DEFAULT_CONFIG = {
3
6
  enablePlayPause: true,
@@ -146,7 +149,7 @@ function createMediaSessionPlugin(config) {
146
149
  const plugin = {
147
150
  id: "media-session",
148
151
  name: "Media Session",
149
- version: "1.0.0",
152
+ version: PKG_VERSION,
150
153
  type: "feature",
151
154
  description: "Media Session API integration for system-level media controls",
152
155
  async init(pluginApi) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@scarlett-player/media-session",
3
- "version": "1.7.0",
3
+ "version": "1.8.1",
4
4
  "description": "Media Session Plugin for Scarlett Player - Lock screen controls, media keys, and system media UI integration",
5
5
  "type": "module",
6
6
  "main": "dist/index.cjs",
@@ -22,14 +22,14 @@
22
22
  "dist"
23
23
  ],
24
24
  "peerDependencies": {
25
- "@scarlett-player/core": "^1.0.3"
25
+ "@scarlett-player/core": "^1.8.0"
26
26
  },
27
27
  "devDependencies": {
28
28
  "tsup": "^8.0.0",
29
29
  "typescript": "^5.3.0",
30
30
  "vitest": "^1.6.0",
31
31
  "jsdom": "^24.0.0",
32
- "@scarlett-player/core": "1.7.0"
32
+ "@scarlett-player/core": "1.8.1"
33
33
  },
34
34
  "keywords": [
35
35
  "video",
@@ -53,8 +53,8 @@
53
53
  },
54
54
  "homepage": "https://scarlettplayer.com",
55
55
  "scripts": {
56
- "build": "tsup src/index.ts --format esm,cjs --dts",
57
- "dev": "tsup src/index.ts --format esm,cjs --dts --watch",
56
+ "build": "tsup",
57
+ "dev": "tsup --watch",
58
58
  "test": "vitest --run",
59
59
  "test:watch": "vitest",
60
60
  "typecheck": "tsc --noEmit"