@scarlett-player/media-session 1.9.0 → 1.10.0

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/dist/index.cjs CHANGED
@@ -26,7 +26,7 @@ __export(index_exports, {
26
26
  module.exports = __toCommonJS(index_exports);
27
27
 
28
28
  // src/version.ts
29
- var PKG_VERSION = true ? "1.9.0" : "0.0.0-dev";
29
+ var PKG_VERSION = true ? "1.10.0" : "0.0.0-dev";
30
30
 
31
31
  // src/index.ts
32
32
  var DEFAULT_CONFIG = {
@@ -85,6 +85,18 @@ function createMediaSessionPlugin(config) {
85
85
  const setupActionHandlers = () => {
86
86
  if (!isMediaSessionSupported()) return;
87
87
  const seekOffset = mergedConfig.seekOffset || 10;
88
+ const seekBounds = () => {
89
+ const live = api?.getState("live");
90
+ const seekable = api?.getState("seekableRange");
91
+ if (live && Number.isFinite(seekable?.start) && Number.isFinite(seekable?.end)) {
92
+ return { min: seekable.start, max: seekable.end };
93
+ }
94
+ const duration = api?.getState("duration") || 0;
95
+ return {
96
+ min: 0,
97
+ max: Number.isFinite(duration) && duration > 0 ? duration : Infinity
98
+ };
99
+ };
88
100
  if (mergedConfig.enablePlayPause) {
89
101
  try {
90
102
  navigator.mediaSession.setActionHandler("play", () => {
@@ -96,9 +108,10 @@ function createMediaSessionPlugin(config) {
96
108
  api?.emit("playback:pause", void 0);
97
109
  });
98
110
  navigator.mediaSession.setActionHandler("stop", () => {
99
- api?.logger.debug("Media session: stop");
111
+ const { min } = seekBounds();
112
+ api?.logger.debug("Media session: stop", { time: min });
100
113
  api?.emit("playback:pause", void 0);
101
- api?.emit("playback:seeking", { time: 0 });
114
+ api?.emit("playback:seeking", { time: min });
102
115
  });
103
116
  } catch (e) {
104
117
  api?.logger.debug("Some play/pause actions not supported", e);
@@ -109,22 +122,25 @@ function createMediaSessionPlugin(config) {
109
122
  navigator.mediaSession.setActionHandler("seekbackward", (details) => {
110
123
  const offset = details.seekOffset || seekOffset;
111
124
  const currentTime = api?.getState("currentTime") || 0;
112
- const newTime = Math.max(0, currentTime - offset);
125
+ const { min, max } = seekBounds();
126
+ const newTime = Math.min(max, Math.max(min, currentTime - offset));
113
127
  api?.logger.debug("Media session: seekbackward", { offset, newTime });
114
128
  api?.emit("playback:seeking", { time: newTime });
115
129
  });
116
130
  navigator.mediaSession.setActionHandler("seekforward", (details) => {
117
131
  const offset = details.seekOffset || seekOffset;
118
132
  const currentTime = api?.getState("currentTime") || 0;
119
- const duration = api?.getState("duration") || 0;
120
- const newTime = Math.min(duration, currentTime + offset);
133
+ const { min, max } = seekBounds();
134
+ const newTime = Math.max(min, Math.min(max, currentTime + offset));
121
135
  api?.logger.debug("Media session: seekforward", { offset, newTime });
122
136
  api?.emit("playback:seeking", { time: newTime });
123
137
  });
124
138
  navigator.mediaSession.setActionHandler("seekto", (details) => {
125
139
  if (details.seekTime !== void 0) {
126
- api?.logger.debug("Media session: seekto", { time: details.seekTime });
127
- api?.emit("playback:seeking", { time: details.seekTime });
140
+ const { min, max } = seekBounds();
141
+ const newTime = Math.max(min, Math.min(max, details.seekTime));
142
+ api?.logger.debug("Media session: seekto", { time: newTime });
143
+ api?.emit("playback:seeking", { time: newTime });
128
144
  }
129
145
  });
130
146
  } catch (e) {
package/dist/index.js CHANGED
@@ -1,5 +1,5 @@
1
1
  // src/version.ts
2
- var PKG_VERSION = true ? "1.9.0" : "0.0.0-dev";
2
+ var PKG_VERSION = true ? "1.10.0" : "0.0.0-dev";
3
3
 
4
4
  // src/index.ts
5
5
  var DEFAULT_CONFIG = {
@@ -58,6 +58,18 @@ function createMediaSessionPlugin(config) {
58
58
  const setupActionHandlers = () => {
59
59
  if (!isMediaSessionSupported()) return;
60
60
  const seekOffset = mergedConfig.seekOffset || 10;
61
+ const seekBounds = () => {
62
+ const live = api?.getState("live");
63
+ const seekable = api?.getState("seekableRange");
64
+ if (live && Number.isFinite(seekable?.start) && Number.isFinite(seekable?.end)) {
65
+ return { min: seekable.start, max: seekable.end };
66
+ }
67
+ const duration = api?.getState("duration") || 0;
68
+ return {
69
+ min: 0,
70
+ max: Number.isFinite(duration) && duration > 0 ? duration : Infinity
71
+ };
72
+ };
61
73
  if (mergedConfig.enablePlayPause) {
62
74
  try {
63
75
  navigator.mediaSession.setActionHandler("play", () => {
@@ -69,9 +81,10 @@ function createMediaSessionPlugin(config) {
69
81
  api?.emit("playback:pause", void 0);
70
82
  });
71
83
  navigator.mediaSession.setActionHandler("stop", () => {
72
- api?.logger.debug("Media session: stop");
84
+ const { min } = seekBounds();
85
+ api?.logger.debug("Media session: stop", { time: min });
73
86
  api?.emit("playback:pause", void 0);
74
- api?.emit("playback:seeking", { time: 0 });
87
+ api?.emit("playback:seeking", { time: min });
75
88
  });
76
89
  } catch (e) {
77
90
  api?.logger.debug("Some play/pause actions not supported", e);
@@ -82,22 +95,25 @@ function createMediaSessionPlugin(config) {
82
95
  navigator.mediaSession.setActionHandler("seekbackward", (details) => {
83
96
  const offset = details.seekOffset || seekOffset;
84
97
  const currentTime = api?.getState("currentTime") || 0;
85
- const newTime = Math.max(0, currentTime - offset);
98
+ const { min, max } = seekBounds();
99
+ const newTime = Math.min(max, Math.max(min, currentTime - offset));
86
100
  api?.logger.debug("Media session: seekbackward", { offset, newTime });
87
101
  api?.emit("playback:seeking", { time: newTime });
88
102
  });
89
103
  navigator.mediaSession.setActionHandler("seekforward", (details) => {
90
104
  const offset = details.seekOffset || seekOffset;
91
105
  const currentTime = api?.getState("currentTime") || 0;
92
- const duration = api?.getState("duration") || 0;
93
- const newTime = Math.min(duration, currentTime + offset);
106
+ const { min, max } = seekBounds();
107
+ const newTime = Math.max(min, Math.min(max, currentTime + offset));
94
108
  api?.logger.debug("Media session: seekforward", { offset, newTime });
95
109
  api?.emit("playback:seeking", { time: newTime });
96
110
  });
97
111
  navigator.mediaSession.setActionHandler("seekto", (details) => {
98
112
  if (details.seekTime !== void 0) {
99
- api?.logger.debug("Media session: seekto", { time: details.seekTime });
100
- api?.emit("playback:seeking", { time: details.seekTime });
113
+ const { min, max } = seekBounds();
114
+ const newTime = Math.max(min, Math.min(max, details.seekTime));
115
+ api?.logger.debug("Media session: seekto", { time: newTime });
116
+ api?.emit("playback:seeking", { time: newTime });
101
117
  }
102
118
  });
103
119
  } catch (e) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@scarlett-player/media-session",
3
- "version": "1.9.0",
3
+ "version": "1.10.0",
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",
@@ -29,7 +29,7 @@
29
29
  "typescript": "^5.3.0",
30
30
  "vitest": "^1.6.0",
31
31
  "jsdom": "^24.0.0",
32
- "@scarlett-player/core": "1.9.0"
32
+ "@scarlett-player/core": "1.10.0"
33
33
  },
34
34
  "keywords": [
35
35
  "video",