@banou/media-player 0.10.20 → 0.10.22
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 +34 -22
- package/dist/audio/loudness-analysis.d.ts +38 -0
- package/dist/audio/playback-tap.d.ts +11 -0
- package/dist/audio/volume-normalizer.d.ts +4 -2
- package/dist/engine/index.d.ts +1 -1
- package/dist/engine/index.js +1 -1
- package/dist/engine/playback.d.ts +21 -0
- package/dist/{engine-C4Gj_4zs.js → engine-Cr_7OImR.js} +120 -103
- package/dist/index.d.ts +1 -1
- package/dist/index.js +929 -651
- package/dist/react/hooks/use-playback.d.ts +2 -1
- package/dist/react/hooks/use-volume-normalizer.d.ts +9 -1
- package/dist/react/video-player.d.ts +19 -7
- package/dist/utils/source.d.ts +6 -1
- package/dist/volume-normalizer-worklet.js +1200 -78
- package/package.json +3 -3
- package/src/lib/audio/loudness-analysis.ts +307 -0
- package/src/lib/audio/playback-tap.ts +37 -0
- package/src/lib/audio/volume-normalizer-worklet.d.ts +49 -0
- package/src/lib/audio/volume-normalizer-worklet.js +1200 -78
- package/src/lib/audio/volume-normalizer.ts +5 -3
- package/src/lib/engine/index.ts +1 -1
- package/src/lib/engine/playback.ts +21 -1
- package/src/lib/index.tsx +1 -0
- package/src/lib/react/hooks/use-playback.ts +5 -1
- package/src/lib/react/hooks/use-volume-normalizer.ts +40 -2
- package/src/lib/react/video-player.tsx +55 -15
- package/src/lib/utils/source.ts +6 -2
|
@@ -174,13 +174,13 @@ var i = (e) => Array(e.buffered.length).fill(void 0).map((t, n) => ({
|
|
|
174
174
|
constructor(e, t) {
|
|
175
175
|
super(e, t), this.name = "MediaElementError";
|
|
176
176
|
}
|
|
177
|
-
}, _ = (e) => !!e && typeof e == "object" && e.mediaElement === !0, v = -20, y = 60, b = 30, x = -5, S = 20, C = 5, w = 15e3, T = 1, E = 3,
|
|
177
|
+
}, _ = (e) => !!e && typeof e == "object" && e.mediaElement === !0, v = -20, y = 60, b = 30, x = -5, S = 20, C = 5, w = 15e3, T = 1, E = 3, ee = 12, D = 200, O = 250, k = 25e5, A = (e) => {
|
|
178
178
|
let { worker: t } = e, n = setTimeout(() => t.terminate(), 2e3);
|
|
179
179
|
e.destroy().catch(() => {}).finally(() => {
|
|
180
180
|
clearTimeout(n), t.terminate();
|
|
181
181
|
});
|
|
182
|
-
},
|
|
183
|
-
let { videoElement: n, subtitleContainer: r, read: a, length: s, publicPath: c, libavWorkerUrl: l, jassubWorkerUrl: u, jassubWasmUrl: d, jassubLegacyWasmUrl: f, defaultFontUrl: p, bufferSize: m =
|
|
182
|
+
}, te = async (t) => {
|
|
183
|
+
let { videoElement: n, subtitleContainer: r, read: a, length: s, publicPath: c, libavWorkerUrl: l, jassubWorkerUrl: u, jassubWasmUrl: d, jassubLegacyWasmUrl: f, defaultFontUrl: p, bufferSize: m = k, audioStreamIndex: _, onReady: te, onError: ne, onRecovered: re, onSeek: ie, onSubtitleStreams: ae, onAudioStreams: oe, onOutput: j } = t, M = await e({
|
|
184
184
|
publicPath: c,
|
|
185
185
|
workerUrl: l,
|
|
186
186
|
workerOptions: { type: "module" },
|
|
@@ -188,7 +188,7 @@ var i = (e) => Array(e.buffered.length).fill(void 0).map((t, n) => ({
|
|
|
188
188
|
length: s,
|
|
189
189
|
audioStreamIndex: _,
|
|
190
190
|
read: a
|
|
191
|
-
}), N = [], P = !1,
|
|
191
|
+
}), N = [], P = !1, se = () => {
|
|
192
192
|
if (!P) {
|
|
193
193
|
P = !0;
|
|
194
194
|
for (let e of [...N].reverse()) try {
|
|
@@ -196,10 +196,10 @@ var i = (e) => Array(e.buffered.length).fill(void 0).map((t, n) => ({
|
|
|
196
196
|
} catch {}
|
|
197
197
|
}
|
|
198
198
|
};
|
|
199
|
-
N.push(() =>
|
|
199
|
+
N.push(() => A(M));
|
|
200
200
|
try {
|
|
201
201
|
let e = await M.init(), t = e.audioStreams ?? [], a = t.some((e) => e.streamIndex === _) ? _ : t[0]?.streamIndex ?? -1;
|
|
202
|
-
|
|
202
|
+
oe?.(t, a);
|
|
203
203
|
let s = h({
|
|
204
204
|
video: n,
|
|
205
205
|
container: r,
|
|
@@ -207,19 +207,19 @@ var i = (e) => Array(e.buffered.length).fill(void 0).map((t, n) => ({
|
|
|
207
207
|
wasmUrl: d,
|
|
208
208
|
legacyWasmUrl: f,
|
|
209
209
|
defaultFontUrl: p,
|
|
210
|
-
onStreams:
|
|
210
|
+
onStreams: ae
|
|
211
211
|
});
|
|
212
212
|
if (N.push(() => s.destroy()), e.attachments?.length && s.pushAttachments(e.attachments), !e.info.output.videoMimeType) throw Error("The video codec in this file could not be identified");
|
|
213
213
|
let c = [e.info.output.videoMimeType, e.info.output.audioMimeType].filter(Boolean).join(","), l = `video/mp4; codecs="${c}"`;
|
|
214
214
|
if (!MediaSource.isTypeSupported(l)) throw Error(`This browser cannot play the codecs in this file: ${c}`);
|
|
215
|
-
let m = new MediaSource(),
|
|
216
|
-
N.push(() => URL.revokeObjectURL(
|
|
215
|
+
let m = new MediaSource(), k = URL.createObjectURL(m);
|
|
216
|
+
N.push(() => URL.revokeObjectURL(k)), n.src = k, N.push(() => {
|
|
217
217
|
try {
|
|
218
218
|
n.pause();
|
|
219
219
|
} catch {}
|
|
220
220
|
n.removeAttribute("src"), n.load();
|
|
221
221
|
});
|
|
222
|
-
let
|
|
222
|
+
let A = await new Promise((t, n) => {
|
|
223
223
|
let r = setTimeout(() => {
|
|
224
224
|
i(), n(/* @__PURE__ */ Error("The MediaSource never opened"));
|
|
225
225
|
}, w), i = () => {
|
|
@@ -237,138 +237,155 @@ var i = (e) => Array(e.buffered.length).fill(void 0).map((t, n) => ({
|
|
|
237
237
|
i(), n(/* @__PURE__ */ Error("The MediaSource closed before a SourceBuffer could be created"));
|
|
238
238
|
};
|
|
239
239
|
m.addEventListener("sourceopen", a, { once: !0 }), m.addEventListener("sourceclose", o, { once: !0 }), m.addEventListener("error", o, { once: !0 });
|
|
240
|
-
}), { appendBuffer:
|
|
241
|
-
await
|
|
242
|
-
|
|
240
|
+
}), { appendBuffer: F, unbufferRange: ce, updateTimestampOffset: le, endOfStream: ue } = o(A, m);
|
|
241
|
+
await F(e.data), j?.({
|
|
242
|
+
type: "init",
|
|
243
|
+
data: e.data,
|
|
244
|
+
audioMimeType: e.info.output.audioMimeType,
|
|
245
|
+
audioStreamIndex: a
|
|
246
|
+
}), j?.({
|
|
247
|
+
type: "run",
|
|
248
|
+
pts: 0
|
|
249
|
+
}), e.subtitles?.length && s.pushFragments(e.subtitles), te?.();
|
|
250
|
+
let I = !1, L = !1, R = 0, z, de = () => z ?? n.currentTime, B = !1, fe = !1, V = 0, H = 0, U = null, W = 0, G = 0, K = !1, pe = 0, q = !0, J = (e, t, n = !1) => {
|
|
243
251
|
let r = e?.message === "Cancelled";
|
|
244
|
-
t && r || (console.error(e), (!K || n) && (K = !0,
|
|
245
|
-
},
|
|
246
|
-
if (
|
|
247
|
-
let t = n.currentTime, r = e ? x : v, a = e ? S : y, o = i(
|
|
252
|
+
t && r || (console.error(e), (!K || n) && (K = !0, ne?.(r ? Error("Reading the video file failed", { cause: e }) : e)));
|
|
253
|
+
}, me = async (e = !1) => {
|
|
254
|
+
if (R > 0 && !e) return;
|
|
255
|
+
let t = n.currentTime, r = e ? x : v, a = e ? S : y, o = i(A), s = (e, t) => (q = !1, ce(e, t));
|
|
248
256
|
o.length && o[0].start < t + r && await s(0, t + r);
|
|
249
257
|
for (let { end: e } of o) e > t + a && await s(t + a, e);
|
|
250
|
-
},
|
|
251
|
-
let e = i(
|
|
258
|
+
}, he = () => {
|
|
259
|
+
let e = i(A);
|
|
252
260
|
if (!e.length) return !0;
|
|
253
|
-
let t =
|
|
254
|
-
return
|
|
255
|
-
},
|
|
256
|
-
let t =
|
|
261
|
+
let t = de(), n = e.find((e) => e.start <= t + T && t < e.end);
|
|
262
|
+
return be() && ve(t) && (!n || n.start <= t) || n && n.end >= t + y ? !1 : !n || n.end < t + b;
|
|
263
|
+
}, ge = (e) => i(A).find((t) => t.start <= e + T && e < t.end), _e = () => ge(n.currentTime), ve = (e = n.currentTime) => {
|
|
264
|
+
let t = ge(e);
|
|
257
265
|
return e >= G - .1 || !!t && t.end >= G - .1;
|
|
258
|
-
},
|
|
259
|
-
let e = i(
|
|
260
|
-
e.length && (G = Math.max(G, ...e)),
|
|
261
|
-
},
|
|
262
|
-
|
|
266
|
+
}, ye = () => {
|
|
267
|
+
let e = i(A).map((e) => e.end);
|
|
268
|
+
e.length && (G = Math.max(G, ...e)), B && (fe = !0);
|
|
269
|
+
}, be = () => B || fe && (i(A).at(-1)?.end ?? 0) >= G - .1, Y = async (e) => {
|
|
270
|
+
L = !0, U = null, W = 0, pe = e, q = !0;
|
|
263
271
|
let t = ++H;
|
|
264
272
|
try {
|
|
265
273
|
let { data: n, pts: r, subtitles: i, finished: a } = await M.seek(e);
|
|
266
|
-
if (P || t !== H || (a && (
|
|
267
|
-
|
|
274
|
+
if (P || t !== H || (a && (B = !0), i?.length && s.pushFragments(i), await le(r), P || t !== H)) return;
|
|
275
|
+
j?.({
|
|
276
|
+
type: "run",
|
|
277
|
+
pts: r
|
|
278
|
+
}), n.byteLength && j?.({
|
|
279
|
+
type: "fragment",
|
|
280
|
+
data: n
|
|
281
|
+
}), a && j?.({ type: "end" }), n.byteLength && (await F(n), ye());
|
|
268
282
|
} catch (e) {
|
|
269
283
|
t === H && (q = !1), J(e, P || t !== H);
|
|
270
284
|
} finally {
|
|
271
|
-
t === H && (
|
|
285
|
+
t === H && (L = !1);
|
|
272
286
|
}
|
|
273
|
-
},
|
|
287
|
+
}, xe = async () => {
|
|
274
288
|
let e = U;
|
|
275
289
|
if (e) try {
|
|
276
|
-
await
|
|
290
|
+
await F(e), ye(), U === e && (U = null, W = 0);
|
|
277
291
|
} catch (t) {
|
|
278
292
|
if (U !== e) return;
|
|
279
293
|
if (t?.name === "QuotaExceededError") {
|
|
280
|
-
let t = await
|
|
294
|
+
let t = await me(!0).then(() => !0, () => !1);
|
|
281
295
|
if (U !== e) return;
|
|
282
296
|
if (t) {
|
|
283
|
-
|
|
297
|
+
B = !1, await Y(_e()?.end ?? n.currentTime);
|
|
284
298
|
return;
|
|
285
299
|
}
|
|
286
300
|
}
|
|
287
301
|
if (W += 1, W < C) return;
|
|
288
302
|
throw U = null, t;
|
|
289
303
|
}
|
|
290
|
-
},
|
|
291
|
-
if (
|
|
292
|
-
let e = ++
|
|
293
|
-
|
|
304
|
+
}, Se = async () => {
|
|
305
|
+
if (I || L || $ !== void 0 || P || !U && (B || !he())) return;
|
|
306
|
+
let e = ++V, t = H, n = () => P || e !== V || t !== H;
|
|
307
|
+
I = !0;
|
|
294
308
|
try {
|
|
295
309
|
if (!U) {
|
|
296
310
|
let { data: e, subtitles: t, finished: r } = await M.read();
|
|
297
|
-
if (n() || (r && (
|
|
311
|
+
if (n() || (r && (B = !0), t?.length && s.pushFragments(t), e.byteLength && j?.({
|
|
312
|
+
type: "fragment",
|
|
313
|
+
data: e
|
|
314
|
+
}), r && j?.({ type: "end" }), !e.byteLength)) return;
|
|
298
315
|
U = e, W = 0;
|
|
299
316
|
}
|
|
300
|
-
await
|
|
317
|
+
await xe(), !n() && K && (K = !1, re?.());
|
|
301
318
|
} catch (e) {
|
|
302
319
|
J(e, n());
|
|
303
320
|
} finally {
|
|
304
|
-
e ===
|
|
321
|
+
e === V && (I = !1);
|
|
305
322
|
}
|
|
306
|
-
},
|
|
307
|
-
let t =
|
|
323
|
+
}, Ce = (e) => e >= pe && we(e) && Te(e), we = (e) => i(A).some((t) => t.start <= e && e < t.end), X = (e) => {
|
|
324
|
+
let t = ge(e);
|
|
308
325
|
return t ? t.end - e : 0;
|
|
309
|
-
},
|
|
310
|
-
if (!P && !(
|
|
311
|
-
|
|
326
|
+
}, Te = (e) => X(e) >= E || be() && ve(e), Ee = async (e) => {
|
|
327
|
+
if (!P && !(we(e) && Te(e))) {
|
|
328
|
+
B = !1, R++, z = e;
|
|
312
329
|
try {
|
|
313
330
|
await Y(e);
|
|
314
331
|
let t = H;
|
|
315
|
-
for (let n = 0; n <
|
|
332
|
+
for (let n = 0; n < ee && !(P || t !== H || B || X(e) >= E); n++) {
|
|
316
333
|
let t = X(e);
|
|
317
|
-
if (await
|
|
334
|
+
if (await Se(), X(e) <= t) break;
|
|
318
335
|
}
|
|
319
336
|
} finally {
|
|
320
|
-
|
|
337
|
+
R--, z === e && (z = void 0);
|
|
321
338
|
}
|
|
322
339
|
}
|
|
323
|
-
},
|
|
324
|
-
let t = performance.now(), n = t -
|
|
325
|
-
if (n >=
|
|
326
|
-
|
|
340
|
+
}, De = 0, Z = null, Q, Oe = (e) => {
|
|
341
|
+
let t = performance.now(), n = t - De;
|
|
342
|
+
if (n >= D) {
|
|
343
|
+
De = t, Z = null, ie?.(e);
|
|
327
344
|
return;
|
|
328
345
|
}
|
|
329
346
|
Z = e, !Q && (Q = setTimeout(() => {
|
|
330
347
|
Q = void 0;
|
|
331
348
|
let e = Z;
|
|
332
|
-
Z = null, !(e === null || P) && (
|
|
333
|
-
},
|
|
349
|
+
Z = null, !(e === null || P) && (De = performance.now(), ie?.(e));
|
|
350
|
+
}, D - n));
|
|
334
351
|
};
|
|
335
352
|
N.push(() => {
|
|
336
353
|
Q && clearTimeout(Q);
|
|
337
354
|
});
|
|
338
|
-
let
|
|
355
|
+
let ke = 0, $;
|
|
339
356
|
N.push(() => {
|
|
340
357
|
$ && clearTimeout($);
|
|
341
358
|
});
|
|
342
|
-
let
|
|
359
|
+
let Ae = () => {
|
|
343
360
|
let t = n.currentTime, r = e.info.input.duration || n.duration;
|
|
344
|
-
r > 0 &&
|
|
345
|
-
let i = performance.now(), a = i -
|
|
346
|
-
if (
|
|
347
|
-
if (
|
|
361
|
+
r > 0 && Oe(Math.min(Math.max(t / r, 0), 1));
|
|
362
|
+
let i = performance.now(), a = i - ke < O;
|
|
363
|
+
if (ke = i, !Ce(t) && !(q && (L || X(t) > 0) && Math.abs(t - pe) < .001)) {
|
|
364
|
+
if (B = !1, $ && clearTimeout($), !a) {
|
|
348
365
|
$ = void 0, Y(t);
|
|
349
366
|
return;
|
|
350
367
|
}
|
|
351
368
|
$ = setTimeout(() => {
|
|
352
369
|
if ($ = void 0, P) return;
|
|
353
370
|
let e = n.currentTime;
|
|
354
|
-
|
|
355
|
-
},
|
|
371
|
+
Ce(e) || (B = !1, Y(e));
|
|
372
|
+
}, O);
|
|
356
373
|
}
|
|
357
374
|
};
|
|
358
|
-
n.addEventListener("seeking",
|
|
359
|
-
let
|
|
360
|
-
if (
|
|
361
|
-
|
|
375
|
+
n.addEventListener("seeking", Ae), N.push(() => n.removeEventListener("seeking", Ae));
|
|
376
|
+
let je = !1, Me = () => {
|
|
377
|
+
if (je) return;
|
|
378
|
+
je = !0;
|
|
362
379
|
let e = n.error;
|
|
363
380
|
J(new g(`the media element failed: ${e?.message ?? "unknown"}`, { cause: e }), !1, !0);
|
|
364
381
|
};
|
|
365
|
-
n.addEventListener("error",
|
|
366
|
-
let
|
|
367
|
-
|
|
382
|
+
n.addEventListener("error", Me), N.push(() => n.removeEventListener("error", Me));
|
|
383
|
+
let Ne = setInterval(() => {
|
|
384
|
+
je || n.error || (me().catch(() => {}), Se().catch((e) => J(e, !1)), be() && !U && ve() && m.readyState === "open" && ue(() => !L).catch(() => {}));
|
|
368
385
|
}, 100);
|
|
369
|
-
return N.push(() => clearInterval(
|
|
370
|
-
destroy:
|
|
371
|
-
prepareSeek:
|
|
386
|
+
return N.push(() => clearInterval(Ne)), {
|
|
387
|
+
destroy: se,
|
|
388
|
+
prepareSeek: Ee,
|
|
372
389
|
videoElement: n,
|
|
373
390
|
selectSubtitleStream: (e) => s.selectStream(e),
|
|
374
391
|
indexes: e.indexes ?? [],
|
|
@@ -378,10 +395,10 @@ var i = (e) => Array(e.buffered.length).fill(void 0).map((t, n) => ({
|
|
|
378
395
|
audioMimeType: e.info.output.audioMimeType
|
|
379
396
|
};
|
|
380
397
|
} catch (e) {
|
|
381
|
-
throw
|
|
398
|
+
throw se(), e;
|
|
382
399
|
}
|
|
383
|
-
},
|
|
384
|
-
let { publicPath: n, workerUrl: r, length: i, read: a, onThumbnails: o, width: s =
|
|
400
|
+
}, ne = 5, re = 500, ie = 320, ae = 1e6, oe = 3, j = 1e4, M = 1.5, N = 4e6, P = 3e4, se = async (e) => {
|
|
401
|
+
let { publicPath: n, workerUrl: r, length: i, read: a, onThumbnails: o, width: s = ie } = e, c = await t({
|
|
385
402
|
publicPath: n,
|
|
386
403
|
workerUrl: r,
|
|
387
404
|
workerOptions: { type: "module" },
|
|
@@ -389,7 +406,7 @@ var i = (e) => Array(e.buffered.length).fill(void 0).map((t, n) => ({
|
|
|
389
406
|
read: a
|
|
390
407
|
});
|
|
391
408
|
try {
|
|
392
|
-
let t = await c.init(), n = t.duration, r = Math.max(e.interval ??
|
|
409
|
+
let t = await c.init(), n = t.duration, r = Math.max(e.interval ?? ne, n / re), a = [], l = (e) => {
|
|
393
410
|
let t = [];
|
|
394
411
|
for (let [a, o] of e.entries()) {
|
|
395
412
|
let s = t.at(-1);
|
|
@@ -397,7 +414,7 @@ var i = (e) => Array(e.buffered.length).fill(void 0).map((t, n) => ({
|
|
|
397
414
|
timestamp: o.timestamp,
|
|
398
415
|
endTime: n,
|
|
399
416
|
startByte: o.pos,
|
|
400
|
-
endByte: Math.min((e[a + 1]?.pos ?? i) +
|
|
417
|
+
endByte: Math.min((e[a + 1]?.pos ?? i) + ae, i),
|
|
401
418
|
done: !1,
|
|
402
419
|
attempts: 0
|
|
403
420
|
});
|
|
@@ -436,7 +453,7 @@ var i = (e) => Array(e.buffered.length).fill(void 0).map((t, n) => ({
|
|
|
436
453
|
}), o(e);
|
|
437
454
|
}, x = async (e) => {
|
|
438
455
|
if (d) return;
|
|
439
|
-
let t = await Promise.race([c.readKeyframe(e.timestamp), new Promise((e, t) => setTimeout(() => t(/* @__PURE__ */ Error("timed out")),
|
|
456
|
+
let t = await Promise.race([c.readKeyframe(e.timestamp), new Promise((e, t) => setTimeout(() => t(/* @__PURE__ */ Error("timed out")), j))]), n = await createImageBitmap(new Blob([t], { type: "image/png" })), r = new OffscreenCanvas(s, Math.max(1, Math.round(n.height * (s / n.width))));
|
|
440
457
|
r.getContext("2d").drawImage(n, 0, 0, r.width, r.height), n.close();
|
|
441
458
|
let i = await r.convertToBlob({
|
|
442
459
|
type: "image/webp",
|
|
@@ -460,7 +477,7 @@ var i = (e) => Array(e.buffered.length).fill(void 0).map((t, n) => ({
|
|
|
460
477
|
if (!f.length) return;
|
|
461
478
|
let e = f.splice(y(), 1)[0];
|
|
462
479
|
p = !0, x(e).catch(() => {
|
|
463
|
-
e.attempts += 1, e.done = e.attempts >=
|
|
480
|
+
e.attempts += 1, e.done = e.attempts >= oe;
|
|
464
481
|
}).finally(() => {
|
|
465
482
|
p = !1, S();
|
|
466
483
|
});
|
|
@@ -469,7 +486,7 @@ var i = (e) => Array(e.buffered.length).fill(void 0).map((t, n) => ({
|
|
|
469
486
|
}, w = async (e) => {
|
|
470
487
|
_ = !0;
|
|
471
488
|
try {
|
|
472
|
-
let t = await Promise.race([c.init(), new Promise((e, t) => setTimeout(() => t(/* @__PURE__ */ Error("timed out")),
|
|
489
|
+
let t = await Promise.race([c.init(), new Promise((e, t) => setTimeout(() => t(/* @__PURE__ */ Error("timed out")), P))]);
|
|
473
490
|
if (d) return;
|
|
474
491
|
h = e;
|
|
475
492
|
let n = l(t.indexes);
|
|
@@ -495,7 +512,7 @@ var i = (e) => Array(e.buffered.length).fill(void 0).map((t, n) => ({
|
|
|
495
512
|
if (d) return;
|
|
496
513
|
v = e;
|
|
497
514
|
let t = T(e);
|
|
498
|
-
h < 0 ? h = t : (t >= Math.max(h *
|
|
515
|
+
h < 0 ? h = t : (t >= Math.max(h * M, h + N) || t >= i && h < i) && (g = !0), E(e), S();
|
|
499
516
|
},
|
|
500
517
|
prioritize: (e) => {
|
|
501
518
|
d || (m = e);
|
|
@@ -503,14 +520,14 @@ var i = (e) => Array(e.buffered.length).fill(void 0).map((t, n) => ({
|
|
|
503
520
|
destroy: () => {
|
|
504
521
|
d = !0, f.length = 0;
|
|
505
522
|
for (let e of u) URL.revokeObjectURL(e.url);
|
|
506
|
-
u = [],
|
|
523
|
+
u = [], A(c);
|
|
507
524
|
}
|
|
508
525
|
};
|
|
509
526
|
} catch (e) {
|
|
510
|
-
throw
|
|
527
|
+
throw A(c), e;
|
|
511
528
|
}
|
|
512
|
-
},
|
|
513
|
-
let { video: t, subtitles: n } = e, r = e.mode ??
|
|
529
|
+
}, F = 1280, ce = 1920, le = 250, ue = 100, I = () => typeof HTMLCanvasElement < "u" && "captureStream" in HTMLCanvasElement.prototype, L = () => typeof document < "u" && typeof HTMLVideoElement < "u" && typeof HTMLVideoElement.prototype.requestPictureInPicture == "function" && !!document.pictureInPictureEnabled, R = () => typeof HTMLVideoElement < "u" && "mozCaptureStream" in HTMLVideoElement.prototype, z = () => I() ? L() ? "window" : R() ? "burn-in" : null : null, de = (e) => {
|
|
530
|
+
let { video: t, subtitles: n } = e, r = e.mode ?? z() ?? "window", i = e.maxWidth ?? (r === "burn-in" ? ce : F), a, o, s, c = !1, l = !1, u = !1, d = !1, f, p = () => r === "burn-in" ? !!a : !!a && document.pictureInPictureElement === a.mirror, m = (e, r) => {
|
|
514
531
|
r.drawImage(t, 0, 0, e.width, e.height);
|
|
515
532
|
let i = n.querySelector("canvas");
|
|
516
533
|
i && i.width > 0 && i.height > 0 && r.drawImage(i, 0, 0, e.width, e.height);
|
|
@@ -539,39 +556,39 @@ var i = (e) => Array(e.buffered.length).fill(void 0).map((t, n) => ({
|
|
|
539
556
|
l = !0;
|
|
540
557
|
let { mirror: e } = a;
|
|
541
558
|
h(), e.play().then(() => new Promise((e) => {
|
|
542
|
-
setTimeout(e,
|
|
559
|
+
setTimeout(e, ue);
|
|
543
560
|
})).catch(() => {}).finally(() => {
|
|
544
561
|
e.pause(), setTimeout(() => {
|
|
545
562
|
l = !1;
|
|
546
|
-
},
|
|
563
|
+
}, ue);
|
|
547
564
|
});
|
|
548
565
|
}, E = [["play", () => {
|
|
549
566
|
t.play().catch(() => {});
|
|
550
|
-
}], ["pause", () => t.pause()]],
|
|
567
|
+
}], ["pause", () => t.pause()]], ee = (e) => {
|
|
551
568
|
if ("mediaSession" in navigator) for (let [t, n] of E) try {
|
|
552
569
|
navigator.mediaSession.setActionHandler(t, e ? n : null);
|
|
553
570
|
} catch {}
|
|
554
|
-
},
|
|
555
|
-
if (y(),
|
|
571
|
+
}, D = () => {
|
|
572
|
+
if (y(), ee(!1), t.removeEventListener("play", C), t.removeEventListener("pause", w), t.removeEventListener("seeked", T), !a) {
|
|
556
573
|
f?.();
|
|
557
574
|
return;
|
|
558
575
|
}
|
|
559
576
|
let { stream: e, mirror: n } = a;
|
|
560
|
-
n.removeEventListener("play", x), n.removeEventListener("pause", S), n.removeEventListener("leavepictureinpicture",
|
|
577
|
+
n.removeEventListener("play", x), n.removeEventListener("pause", S), n.removeEventListener("leavepictureinpicture", O);
|
|
561
578
|
for (let t of e.getTracks()) t.stop();
|
|
562
579
|
n.remove(), a = void 0, f?.();
|
|
563
|
-
},
|
|
580
|
+
}, O = () => D(), k = (e) => {
|
|
564
581
|
let r = t.style.opacity, i = n.style.display;
|
|
565
582
|
e.style.cssText = "position:absolute;inset:0;width:100%;height:100%;object-fit:contain;background:#000;z-index:1", t.style.opacity = "0", n.style.display = "none", f = () => {
|
|
566
583
|
f = void 0, t.style.opacity = r, n.style.display = i;
|
|
567
584
|
};
|
|
568
|
-
},
|
|
585
|
+
}, A = async () => {
|
|
569
586
|
let n = Math.min(t.videoWidth || i, i), o = Math.round(n * ((t.videoHeight || 9) / (t.videoWidth || 16))), c = document.createElement("canvas");
|
|
570
587
|
c.width = n, c.height = o;
|
|
571
588
|
let l = c.getContext("2d");
|
|
572
589
|
if (!l) throw Error("the picture in picture composite has no 2d context");
|
|
573
590
|
let u = document.createElement("video");
|
|
574
|
-
u.muted = !0, u.playsInline = !0, r === "burn-in" ?
|
|
591
|
+
u.muted = !0, u.playsInline = !0, r === "burn-in" ? k(u) : u.style.cssText = "position:fixed;width:1px;height:1px;opacity:0;pointer-events:none;left:-1px;top:-1px", m(c, l);
|
|
575
592
|
let f = {
|
|
576
593
|
composite: c,
|
|
577
594
|
context: l,
|
|
@@ -580,7 +597,7 @@ var i = (e) => Array(e.buffered.length).fill(void 0).map((t, n) => ({
|
|
|
580
597
|
};
|
|
581
598
|
if (a = f, u.srcObject = f.stream, (e.container ?? t.parentElement ?? document.body).appendChild(u), v(), s = setInterval(() => {
|
|
582
599
|
t.paused && h();
|
|
583
|
-
},
|
|
600
|
+
}, le), u.play().catch(() => {}), u.readyState === 0 && await new Promise((e) => {
|
|
584
601
|
let t = () => {
|
|
585
602
|
clearTimeout(n), e();
|
|
586
603
|
}, n = setTimeout(t, 1e3);
|
|
@@ -589,7 +606,7 @@ var i = (e) => Array(e.buffered.length).fill(void 0).map((t, n) => ({
|
|
|
589
606
|
u.remove();
|
|
590
607
|
return;
|
|
591
608
|
}
|
|
592
|
-
if (u.addEventListener("play", x), u.addEventListener("pause", S), u.addEventListener("leavepictureinpicture",
|
|
609
|
+
if (u.addEventListener("play", x), u.addEventListener("pause", S), u.addEventListener("leavepictureinpicture", O), t.addEventListener("play", C), t.addEventListener("pause", w), t.addEventListener("seeked", T), ee(!0), b(), r === "burn-in") {
|
|
593
610
|
t.paused && u.pause(), e.onBurnedInChange?.(!0);
|
|
594
611
|
return;
|
|
595
612
|
}
|
|
@@ -602,7 +619,7 @@ var i = (e) => Array(e.buffered.length).fill(void 0).map((t, n) => ({
|
|
|
602
619
|
try {
|
|
603
620
|
if (p()) {
|
|
604
621
|
if (r === "burn-in") {
|
|
605
|
-
|
|
622
|
+
D(), e.onBurnedInChange?.(!1);
|
|
606
623
|
return;
|
|
607
624
|
}
|
|
608
625
|
await document.exitPictureInPicture().catch(() => {});
|
|
@@ -610,9 +627,9 @@ var i = (e) => Array(e.buffered.length).fill(void 0).map((t, n) => ({
|
|
|
610
627
|
}
|
|
611
628
|
r !== "burn-in" && document.pictureInPictureElement && await document.exitPictureInPicture().catch(() => {});
|
|
612
629
|
try {
|
|
613
|
-
await
|
|
630
|
+
await A();
|
|
614
631
|
} catch (t) {
|
|
615
|
-
console.warn("subtitle compositing for picture in picture failed", t),
|
|
632
|
+
console.warn("subtitle compositing for picture in picture failed", t), D(), r === "burn-in" && e.onBurnedInChange?.(!1);
|
|
616
633
|
}
|
|
617
634
|
} finally {
|
|
618
635
|
u = !1;
|
|
@@ -621,9 +638,9 @@ var i = (e) => Array(e.buffered.length).fill(void 0).map((t, n) => ({
|
|
|
621
638
|
},
|
|
622
639
|
mode: r,
|
|
623
640
|
destroy: () => {
|
|
624
|
-
d = !0, r !== "burn-in" && p() && document.exitPictureInPicture().catch(() => {}),
|
|
641
|
+
d = !0, r !== "burn-in" && p() && document.exitPictureInPicture().catch(() => {}), D(), r === "burn-in" && e.onBurnedInChange?.(!1);
|
|
625
642
|
}
|
|
626
643
|
};
|
|
627
644
|
};
|
|
628
645
|
//#endregion
|
|
629
|
-
export { g as a,
|
|
646
|
+
export { g as a, A as c, i as d, o as f, k as i, s as l, z as n, _ as o, se as r, te as s, de as t, h as u };
|
package/dist/index.d.ts
CHANGED
|
@@ -10,5 +10,5 @@ export { useSeekThumbnails } from './react/hooks/use-thumbnails';
|
|
|
10
10
|
export { usePictureInPicture } from './react/hooks/use-picture-in-picture';
|
|
11
11
|
export { inputToRemuxerInput } from './utils/source';
|
|
12
12
|
export type { RemuxerInput } from './utils/source';
|
|
13
|
-
export type { AudioStream, MediaChapter, MediaIndex, PictureInPictureController, PlaybackController, PlaybackOptions, SubtitleStream, ThumbnailImage, } from './engine';
|
|
13
|
+
export type { AudioStream, MediaChapter, MediaIndex, PictureInPictureController, PlaybackController, PlaybackOptions, PlaybackOutput, SubtitleStream, ThumbnailImage, } from './engine';
|
|
14
14
|
export { startPlayback, createThumbnailGenerator, createSubtitleRenderer, createPictureInPicture, SUBTITLES_OFF, } from './engine';
|