@scarlett-player/hls 0.5.2 → 0.5.3
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/{chunk-2BPI5GEH.js → chunk-5JANLXKE.js} +44 -1
- package/dist/index.cjs +44 -1
- package/dist/index.js +1 -1
- package/dist/light.cjs +44 -1
- package/dist/light.js +1 -1
- package/package.json +5 -5
|
@@ -128,12 +128,44 @@ function setupHlsEventHandlers(hls, api, callbacks) {
|
|
|
128
128
|
addHandler("hlsLevelLoaded", (_event, data) => {
|
|
129
129
|
if (data.details?.live !== void 0) {
|
|
130
130
|
api.setState("live", data.details.live);
|
|
131
|
+
if (data.details.live) {
|
|
132
|
+
const video = hls.media;
|
|
133
|
+
if (video && video.seekable && video.seekable.length > 0) {
|
|
134
|
+
const start = video.seekable.start(0);
|
|
135
|
+
const end = video.seekable.end(video.seekable.length - 1);
|
|
136
|
+
api.setState("seekableRange", { start, end });
|
|
137
|
+
const threshold = (data.details.targetduration ?? 3) * 3;
|
|
138
|
+
const isAtLiveEdge = end - video.currentTime < threshold;
|
|
139
|
+
api.setState("liveEdge", isAtLiveEdge);
|
|
140
|
+
const latency = end - video.currentTime;
|
|
141
|
+
api.setState("liveLatency", Math.max(0, latency));
|
|
142
|
+
}
|
|
143
|
+
}
|
|
131
144
|
callbacks.onLiveUpdate?.();
|
|
132
145
|
}
|
|
133
146
|
});
|
|
134
147
|
addHandler("hlsError", (_event, data) => {
|
|
135
148
|
const error = parseHlsError(data);
|
|
136
|
-
|
|
149
|
+
const isBufferHoleSeek = !error.fatal && (error.details?.includes("bufferStalledError") || data.reason?.includes("buffer holes"));
|
|
150
|
+
if (isBufferHoleSeek) {
|
|
151
|
+
api.logger.debug(`HLS buffer recovery: ${error.reason || error.details}`, {
|
|
152
|
+
details: error.details,
|
|
153
|
+
reason: error.reason
|
|
154
|
+
});
|
|
155
|
+
} else if (error.fatal) {
|
|
156
|
+
api.logger.error(`HLS fatal error: ${error.details} (type=${error.type})`, {
|
|
157
|
+
type: error.type,
|
|
158
|
+
details: error.details,
|
|
159
|
+
url: error.url
|
|
160
|
+
});
|
|
161
|
+
} else {
|
|
162
|
+
api.logger.warn(`HLS error: ${error.details} (type=${error.type}, fatal=${error.fatal})`, {
|
|
163
|
+
type: error.type,
|
|
164
|
+
details: error.details,
|
|
165
|
+
fatal: error.fatal,
|
|
166
|
+
url: error.url
|
|
167
|
+
});
|
|
168
|
+
}
|
|
137
169
|
callbacks.onError?.(error);
|
|
138
170
|
});
|
|
139
171
|
return () => {
|
|
@@ -155,6 +187,8 @@ function setupVideoEventHandlers(video, api) {
|
|
|
155
187
|
addHandler("playing", () => {
|
|
156
188
|
api.setState("playing", true);
|
|
157
189
|
api.setState("paused", false);
|
|
190
|
+
api.setState("waiting", false);
|
|
191
|
+
api.setState("buffering", false);
|
|
158
192
|
api.setState("playbackState", "playing");
|
|
159
193
|
});
|
|
160
194
|
addHandler("pause", () => {
|
|
@@ -171,6 +205,15 @@ function setupVideoEventHandlers(video, api) {
|
|
|
171
205
|
addHandler("timeupdate", () => {
|
|
172
206
|
api.setState("currentTime", video.currentTime);
|
|
173
207
|
api.emit("playback:timeupdate", { currentTime: video.currentTime });
|
|
208
|
+
const isLive = api.getState("live");
|
|
209
|
+
if (isLive && video.seekable && video.seekable.length > 0) {
|
|
210
|
+
const start = video.seekable.start(0);
|
|
211
|
+
const end = video.seekable.end(video.seekable.length - 1);
|
|
212
|
+
api.setState("seekableRange", { start, end });
|
|
213
|
+
const isAtLiveEdge = end - video.currentTime < 10;
|
|
214
|
+
api.setState("liveEdge", isAtLiveEdge);
|
|
215
|
+
api.setState("liveLatency", Math.max(0, end - video.currentTime));
|
|
216
|
+
}
|
|
174
217
|
});
|
|
175
218
|
addHandler("durationchange", () => {
|
|
176
219
|
api.setState("duration", video.duration || 0);
|
package/dist/index.cjs
CHANGED
|
@@ -217,12 +217,44 @@ function setupHlsEventHandlers(hls, api, callbacks) {
|
|
|
217
217
|
addHandler("hlsLevelLoaded", (_event, data) => {
|
|
218
218
|
if (data.details?.live !== void 0) {
|
|
219
219
|
api.setState("live", data.details.live);
|
|
220
|
+
if (data.details.live) {
|
|
221
|
+
const video = hls.media;
|
|
222
|
+
if (video && video.seekable && video.seekable.length > 0) {
|
|
223
|
+
const start = video.seekable.start(0);
|
|
224
|
+
const end = video.seekable.end(video.seekable.length - 1);
|
|
225
|
+
api.setState("seekableRange", { start, end });
|
|
226
|
+
const threshold = (data.details.targetduration ?? 3) * 3;
|
|
227
|
+
const isAtLiveEdge = end - video.currentTime < threshold;
|
|
228
|
+
api.setState("liveEdge", isAtLiveEdge);
|
|
229
|
+
const latency = end - video.currentTime;
|
|
230
|
+
api.setState("liveLatency", Math.max(0, latency));
|
|
231
|
+
}
|
|
232
|
+
}
|
|
220
233
|
callbacks.onLiveUpdate?.();
|
|
221
234
|
}
|
|
222
235
|
});
|
|
223
236
|
addHandler("hlsError", (_event, data) => {
|
|
224
237
|
const error = parseHlsError(data);
|
|
225
|
-
|
|
238
|
+
const isBufferHoleSeek = !error.fatal && (error.details?.includes("bufferStalledError") || data.reason?.includes("buffer holes"));
|
|
239
|
+
if (isBufferHoleSeek) {
|
|
240
|
+
api.logger.debug(`HLS buffer recovery: ${error.reason || error.details}`, {
|
|
241
|
+
details: error.details,
|
|
242
|
+
reason: error.reason
|
|
243
|
+
});
|
|
244
|
+
} else if (error.fatal) {
|
|
245
|
+
api.logger.error(`HLS fatal error: ${error.details} (type=${error.type})`, {
|
|
246
|
+
type: error.type,
|
|
247
|
+
details: error.details,
|
|
248
|
+
url: error.url
|
|
249
|
+
});
|
|
250
|
+
} else {
|
|
251
|
+
api.logger.warn(`HLS error: ${error.details} (type=${error.type}, fatal=${error.fatal})`, {
|
|
252
|
+
type: error.type,
|
|
253
|
+
details: error.details,
|
|
254
|
+
fatal: error.fatal,
|
|
255
|
+
url: error.url
|
|
256
|
+
});
|
|
257
|
+
}
|
|
226
258
|
callbacks.onError?.(error);
|
|
227
259
|
});
|
|
228
260
|
return () => {
|
|
@@ -244,6 +276,8 @@ function setupVideoEventHandlers(video, api) {
|
|
|
244
276
|
addHandler("playing", () => {
|
|
245
277
|
api.setState("playing", true);
|
|
246
278
|
api.setState("paused", false);
|
|
279
|
+
api.setState("waiting", false);
|
|
280
|
+
api.setState("buffering", false);
|
|
247
281
|
api.setState("playbackState", "playing");
|
|
248
282
|
});
|
|
249
283
|
addHandler("pause", () => {
|
|
@@ -260,6 +294,15 @@ function setupVideoEventHandlers(video, api) {
|
|
|
260
294
|
addHandler("timeupdate", () => {
|
|
261
295
|
api.setState("currentTime", video.currentTime);
|
|
262
296
|
api.emit("playback:timeupdate", { currentTime: video.currentTime });
|
|
297
|
+
const isLive = api.getState("live");
|
|
298
|
+
if (isLive && video.seekable && video.seekable.length > 0) {
|
|
299
|
+
const start = video.seekable.start(0);
|
|
300
|
+
const end = video.seekable.end(video.seekable.length - 1);
|
|
301
|
+
api.setState("seekableRange", { start, end });
|
|
302
|
+
const isAtLiveEdge = end - video.currentTime < 10;
|
|
303
|
+
api.setState("liveEdge", isAtLiveEdge);
|
|
304
|
+
api.setState("liveLatency", Math.max(0, end - video.currentTime));
|
|
305
|
+
}
|
|
263
306
|
});
|
|
264
307
|
addHandler("durationchange", () => {
|
|
265
308
|
api.setState("duration", video.duration || 0);
|
package/dist/index.js
CHANGED
package/dist/light.cjs
CHANGED
|
@@ -217,12 +217,44 @@ function setupHlsEventHandlers(hls, api, callbacks) {
|
|
|
217
217
|
addHandler("hlsLevelLoaded", (_event, data) => {
|
|
218
218
|
if (data.details?.live !== void 0) {
|
|
219
219
|
api.setState("live", data.details.live);
|
|
220
|
+
if (data.details.live) {
|
|
221
|
+
const video = hls.media;
|
|
222
|
+
if (video && video.seekable && video.seekable.length > 0) {
|
|
223
|
+
const start = video.seekable.start(0);
|
|
224
|
+
const end = video.seekable.end(video.seekable.length - 1);
|
|
225
|
+
api.setState("seekableRange", { start, end });
|
|
226
|
+
const threshold = (data.details.targetduration ?? 3) * 3;
|
|
227
|
+
const isAtLiveEdge = end - video.currentTime < threshold;
|
|
228
|
+
api.setState("liveEdge", isAtLiveEdge);
|
|
229
|
+
const latency = end - video.currentTime;
|
|
230
|
+
api.setState("liveLatency", Math.max(0, latency));
|
|
231
|
+
}
|
|
232
|
+
}
|
|
220
233
|
callbacks.onLiveUpdate?.();
|
|
221
234
|
}
|
|
222
235
|
});
|
|
223
236
|
addHandler("hlsError", (_event, data) => {
|
|
224
237
|
const error = parseHlsError(data);
|
|
225
|
-
|
|
238
|
+
const isBufferHoleSeek = !error.fatal && (error.details?.includes("bufferStalledError") || data.reason?.includes("buffer holes"));
|
|
239
|
+
if (isBufferHoleSeek) {
|
|
240
|
+
api.logger.debug(`HLS buffer recovery: ${error.reason || error.details}`, {
|
|
241
|
+
details: error.details,
|
|
242
|
+
reason: error.reason
|
|
243
|
+
});
|
|
244
|
+
} else if (error.fatal) {
|
|
245
|
+
api.logger.error(`HLS fatal error: ${error.details} (type=${error.type})`, {
|
|
246
|
+
type: error.type,
|
|
247
|
+
details: error.details,
|
|
248
|
+
url: error.url
|
|
249
|
+
});
|
|
250
|
+
} else {
|
|
251
|
+
api.logger.warn(`HLS error: ${error.details} (type=${error.type}, fatal=${error.fatal})`, {
|
|
252
|
+
type: error.type,
|
|
253
|
+
details: error.details,
|
|
254
|
+
fatal: error.fatal,
|
|
255
|
+
url: error.url
|
|
256
|
+
});
|
|
257
|
+
}
|
|
226
258
|
callbacks.onError?.(error);
|
|
227
259
|
});
|
|
228
260
|
return () => {
|
|
@@ -244,6 +276,8 @@ function setupVideoEventHandlers(video, api) {
|
|
|
244
276
|
addHandler("playing", () => {
|
|
245
277
|
api.setState("playing", true);
|
|
246
278
|
api.setState("paused", false);
|
|
279
|
+
api.setState("waiting", false);
|
|
280
|
+
api.setState("buffering", false);
|
|
247
281
|
api.setState("playbackState", "playing");
|
|
248
282
|
});
|
|
249
283
|
addHandler("pause", () => {
|
|
@@ -260,6 +294,15 @@ function setupVideoEventHandlers(video, api) {
|
|
|
260
294
|
addHandler("timeupdate", () => {
|
|
261
295
|
api.setState("currentTime", video.currentTime);
|
|
262
296
|
api.emit("playback:timeupdate", { currentTime: video.currentTime });
|
|
297
|
+
const isLive = api.getState("live");
|
|
298
|
+
if (isLive && video.seekable && video.seekable.length > 0) {
|
|
299
|
+
const start = video.seekable.start(0);
|
|
300
|
+
const end = video.seekable.end(video.seekable.length - 1);
|
|
301
|
+
api.setState("seekableRange", { start, end });
|
|
302
|
+
const isAtLiveEdge = end - video.currentTime < 10;
|
|
303
|
+
api.setState("liveEdge", isAtLiveEdge);
|
|
304
|
+
api.setState("liveLatency", Math.max(0, end - video.currentTime));
|
|
305
|
+
}
|
|
263
306
|
});
|
|
264
307
|
addHandler("durationchange", () => {
|
|
265
308
|
api.setState("duration", video.duration || 0);
|
package/dist/light.js
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@scarlett-player/hls",
|
|
3
|
-
"version": "0.5.
|
|
3
|
+
"version": "0.5.3",
|
|
4
4
|
"description": "HLS Provider Plugin for Scarlett Player",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.cjs",
|
|
@@ -22,8 +22,8 @@
|
|
|
22
22
|
"dist"
|
|
23
23
|
],
|
|
24
24
|
"peerDependencies": {
|
|
25
|
-
"@scarlett-player/core": "^0.5.
|
|
26
|
-
"hls.js": "^1.
|
|
25
|
+
"@scarlett-player/core": "^0.5.3",
|
|
26
|
+
"hls.js": "^1.5.0"
|
|
27
27
|
},
|
|
28
28
|
"peerDependenciesMeta": {
|
|
29
29
|
"hls.js": {
|
|
@@ -31,13 +31,13 @@
|
|
|
31
31
|
}
|
|
32
32
|
},
|
|
33
33
|
"devDependencies": {
|
|
34
|
-
"hls.js": "^1.
|
|
34
|
+
"hls.js": "^1.6.0",
|
|
35
35
|
"typescript": "^5.3.0",
|
|
36
36
|
"tsup": "^8.0.0",
|
|
37
37
|
"vitest": "^1.6.0",
|
|
38
38
|
"@vitest/coverage-v8": "^1.6.0",
|
|
39
39
|
"jsdom": "^24.0.0",
|
|
40
|
-
"@scarlett-player/core": "0.5.
|
|
40
|
+
"@scarlett-player/core": "0.5.3"
|
|
41
41
|
},
|
|
42
42
|
"keywords": [
|
|
43
43
|
"video",
|