@nomercy-entertainment/nomercy-video-player 2.0.3 → 2.0.4
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/adapters/video-backend/IVideoBackend.d.ts +2 -2
- package/dist/adapters/video-backend/html5.js +2 -2
- package/dist/index.d.ts +2 -0
- package/dist/index.js +28 -9
- package/dist/nomercy-video-player.iife.js +1 -1
- package/dist/plugins/desktop-ui/helpers/responsive.js +5 -1
- package/dist/plugins/desktop-ui/index.js +1 -1
- package/dist/plugins/desktop-ui/mixins/feedbackMethods.js +11 -4
- package/dist/plugins/desktop-ui/styles.css +6 -1
- package/package.json +2 -2
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { AudioTrack, BackendLoaderState, BackendState, HdrOnSdrFallback, MinimalBackendEventPayload, QualityLevel, SubtitleCueChange, SubtitleTrack } from '@nomercy-entertainment/nomercy-player-core';
|
|
1
|
+
import type { AudioTrack, AuthHeaderProvider, BackendLoaderState, BackendState, HdrOnSdrFallback, MinimalBackendEventPayload, QualityLevel, SubtitleCueChange, SubtitleTrack } from '@nomercy-entertainment/nomercy-player-core';
|
|
2
2
|
import type { HtmlPreloadMode } from '../../types.js';
|
|
3
3
|
/**
|
|
4
4
|
* Per-event payload map. Each backend event has a fixed payload shape so
|
|
@@ -135,7 +135,7 @@ export interface IVideoBackend {
|
|
|
135
135
|
* manifests/segments). Optional — backends without their own network
|
|
136
136
|
* stack omit it.
|
|
137
137
|
*/
|
|
138
|
-
setAuthHeaderProvider?(provider:
|
|
138
|
+
setAuthHeaderProvider?(provider: AuthHeaderProvider): void;
|
|
139
139
|
/**
|
|
140
140
|
* Consumer policy for an all-HDR item on a display that can't show HDR and
|
|
141
141
|
* a backend that can't tone-map it. Optional — backends that never face the
|
|
@@ -219,7 +219,7 @@ export class Html5VideoBackend extends MediaElementBackend {
|
|
|
219
219
|
// what produces the ~8 s stall on auto-advance.
|
|
220
220
|
resetMediaElement(this.element);
|
|
221
221
|
performance.mark('nm:backend:load:start');
|
|
222
|
-
const headerValue =
|
|
222
|
+
const headerValue = this._authHeaderProvider?.(url);
|
|
223
223
|
if (hlsUrl && !nativeHls) {
|
|
224
224
|
const { default: Hls } = await import('hls.js');
|
|
225
225
|
if (!Hls?.isSupported?.()) {
|
|
@@ -239,7 +239,7 @@ export class Html5VideoBackend extends MediaElementBackend {
|
|
|
239
239
|
enableCEA708Captions: true,
|
|
240
240
|
startPosition: typeof opts?.startTime === 'number' && opts.startTime > 0 ? opts.startTime : -1,
|
|
241
241
|
startFragPrefetch: true,
|
|
242
|
-
xhrSetup: createAuthorizationXhrSetup(
|
|
242
|
+
xhrSetup: createAuthorizationXhrSetup(this._authHeaderProvider),
|
|
243
243
|
});
|
|
244
244
|
this.hls = hlsInstance;
|
|
245
245
|
this.hlsInstance = hlsInstance;
|
package/dist/index.d.ts
CHANGED
|
@@ -107,6 +107,8 @@ export declare class NMVideoPlayer<T extends VideoPlaylistItem = VideoPlaylistIt
|
|
|
107
107
|
private _checkItemEndingSoon;
|
|
108
108
|
/** @internal */
|
|
109
109
|
private _timeStateAt;
|
|
110
|
+
/** @internal */
|
|
111
|
+
private _mediaIsStale;
|
|
110
112
|
playbackRate: {
|
|
111
113
|
(): number;
|
|
112
114
|
(rate: number): Promise<void>;
|
package/dist/index.js
CHANGED
|
@@ -260,13 +260,9 @@ export class NMVideoPlayer extends EventEmitter {
|
|
|
260
260
|
// Authenticated media servers need the Authorization header on every
|
|
261
261
|
// hls.js manifest/segment request. The provider reads the auth config
|
|
262
262
|
// lazily so getter-style tokens (Vue refs, stores) stay live.
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
return undefined;
|
|
267
|
-
const token = typeof bearer === 'function' ? await bearer() : bearer;
|
|
268
|
-
return token ? `Bearer ${token}` : undefined;
|
|
269
|
-
});
|
|
263
|
+
// Read per request rather than captured, so a consumer whose token or
|
|
264
|
+
// rule changes mid-session is not answered from a stale closure.
|
|
265
|
+
instance.setAuthHeaderProvider?.((url) => this.options?.auth?.mediaAuthorization?.(url));
|
|
270
266
|
// Consumer's HDR-on-SDR policy, read once here rather than normalized
|
|
271
267
|
// into `options` — `hdrDecision`'s own default ('play') applies at the
|
|
272
268
|
// point of use when this was never pushed at all.
|
|
@@ -360,6 +356,15 @@ export class NMVideoPlayer extends EventEmitter {
|
|
|
360
356
|
this.emit('subtitleCue', data);
|
|
361
357
|
});
|
|
362
358
|
instance.on('timeupdate', () => {
|
|
359
|
+
// Between a `next()` and the incoming item's mount, this element is
|
|
360
|
+
// still the OUTGOING item's — the cursor already moved. Publishing
|
|
361
|
+
// its position here hands every listener the previous item's
|
|
362
|
+
// position stamped with the new item's identity. Optional call:
|
|
363
|
+
// the dependency range admits a core that predates the reader, and
|
|
364
|
+
// an older core must degrade to the old behaviour, not throw on
|
|
365
|
+
// every tick.
|
|
366
|
+
if (this._mediaIsStale?.())
|
|
367
|
+
return;
|
|
363
368
|
const currentTime = instance.currentTime();
|
|
364
369
|
const duration = instance.duration();
|
|
365
370
|
// The payload is core's full TimeState snapshot, built from the
|
|
@@ -702,9 +707,23 @@ composeMixins(NMVideoPlayer.prototype, ...playerCoreMethods);
|
|
|
702
707
|
{
|
|
703
708
|
const composedDispose = NMVideoPlayer.prototype.dispose;
|
|
704
709
|
NMVideoPlayer.prototype.dispose = async function () {
|
|
710
|
+
// The container id is released before the first await, not after the
|
|
711
|
+
// teardown resolves. Consumers re-create on the same container in the
|
|
712
|
+
// same tick — a responsive view handing `#player1` from its desktop
|
|
713
|
+
// variant to its mobile one does exactly that — and the registry still
|
|
714
|
+
// held this player, so they were given back the very instance they had
|
|
715
|
+
// just asked to dispose. `setup()` then threw `already-setup`, and the
|
|
716
|
+
// throw left that player attached and playing with nobody holding a
|
|
717
|
+
// reference to stop it.
|
|
718
|
+
const claimedId = this.playerId;
|
|
719
|
+
_instances.delete(claimedId);
|
|
705
720
|
await composedDispose.call(this);
|
|
706
|
-
if (this.phase() !== 'disposed')
|
|
707
|
-
|
|
721
|
+
if (this.phase() !== 'disposed') {
|
|
722
|
+
// beforeDispose was prevented — the player is still alive, so it
|
|
723
|
+
// takes its id back and the backend stays intact.
|
|
724
|
+
_instances.set(claimedId, this);
|
|
725
|
+
return;
|
|
726
|
+
}
|
|
708
727
|
this._disposeBackend();
|
|
709
728
|
};
|
|
710
729
|
}
|