@nomercy-entertainment/nomercy-video-player 2.2.5 → 2.2.7

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/CHANGELOG.md CHANGED
@@ -2,6 +2,22 @@
2
2
 
3
3
  ## [Unreleased]
4
4
 
5
+ ## [2.2.7] — 2026-10-19
6
+
7
+ ### Changed
8
+
9
+ - Pin `@nomercy-entertainment/nomercy-player-core` 2.2.7 (the trio releases at one version).
10
+
11
+ ## [2.2.6] — 2026-10-18
12
+
13
+ ### Fixed
14
+
15
+ - Core 2.2.6: the 50 fixes listed in the core changelog.
16
+ - DRM: MediaKeys are created and bound, and the license exchange runs.
17
+ - Captions: the ASS renderer keeps its per-item font cache across subtitle loads, resolves manifest font URLs, reports fonts that fail, and drops a load that is no longer the active request; the Subtitle Settings back arrow returns to the main menu.
18
+ - Streams: `audioTracks` is emitted when hls.js publishes its audio list; the player leaves the error state when fragments load after an outage; a custom stream source is destroyed on unload and dispose; live transcoding holds `beforeLoad` until the transcoder reaches the resume point.
19
+ - UI: breakpoint `hideAfterRank` applies to button visibility; the TV aspect-ratio toast has a duration; `hasPIP()` asks the pip controller whether it is supported.
20
+
5
21
  ## [2.2.5] — 2026-10-08
6
22
 
7
23
  ### Changed
@@ -46,6 +46,8 @@ export declare class Html5VideoBackend extends MediaElementBackend<HTMLVideoElem
46
46
  * tells a restarting server's 404 apart from a video that is genuinely gone.
47
47
  */
48
48
  private _sawConnectionFailure;
49
+ /** The ladder was spent and the error escalated; a later fragment load clears it. */
50
+ private _networkErrorEscalated;
49
51
  /**
50
52
  * True while the ladder is riding out a source the server stopped serving.
51
53
  *
@@ -140,6 +142,7 @@ export declare class Html5VideoBackend extends MediaElementBackend<HTMLVideoElem
140
142
  private _teardownAudioGraph;
141
143
  private _streamResolver?;
142
144
  private _customSource?;
145
+ private _destroyCustomSource;
143
146
  /**
144
147
  * Wire the lookup that asks the player's stream registry for a consumer's
145
148
  * factory. Without it the backend keeps its own HLS and progressive handling
@@ -296,6 +299,7 @@ export declare class Html5VideoBackend extends MediaElementBackend<HTMLVideoElem
296
299
  * applies the ABR constraints for the current display and pane size.
297
300
  */
298
301
  private _emitHlsTrackLists;
302
+ private _emitAudioTracks;
299
303
  /**
300
304
  * Consumer policy for an all-HDR item on an SDR display with no converter.
301
305
  * Pushed once by `NMVideoPlayer` right after construction — see `IVideoBackend`.
@@ -76,6 +76,8 @@ export class Html5VideoBackend extends MediaElementBackend {
76
76
  * tells a restarting server's 404 apart from a video that is genuinely gone.
77
77
  */
78
78
  _sawConnectionFailure = false;
79
+ /** The ladder was spent and the error escalated; a later fragment load clears it. */
80
+ _networkErrorEscalated = false;
79
81
  /**
80
82
  * True while the ladder is riding out a source the server stopped serving.
81
83
  *
@@ -184,6 +186,7 @@ export class Html5VideoBackend extends MediaElementBackend {
184
186
  async load(url, opts) {
185
187
  this.currentUrl = url;
186
188
  this._hadError = false;
189
+ this._networkErrorEscalated = false;
187
190
  this._ended = false;
188
191
  this._state = 'loading';
189
192
  this.emit('loadstart');
@@ -242,10 +245,7 @@ export class Html5VideoBackend extends MediaElementBackend {
242
245
  // A consumer's factory is asked first, because the branches below cover
243
246
  // only HLS and whatever the element itself decodes. Nothing registered
244
247
  // means nothing returned, and the built-in path runs untouched.
245
- if (this._customSource) {
246
- this._customSource.destroy();
247
- this._customSource = undefined;
248
- }
248
+ this._destroyCustomSource();
249
249
  const customSource = this._streamResolver?.(url);
250
250
  if (customSource) {
251
251
  this._customSource = customSource;
@@ -281,6 +281,10 @@ export class Html5VideoBackend extends MediaElementBackend {
281
281
  performance.mark('nm:backend:manifest-parsed');
282
282
  this._emitHlsTrackLists();
283
283
  });
284
+ // hls.js fills its audio list after the manifest parse, then fires this.
285
+ hlsInstance.on(Hls.Events.AUDIO_TRACKS_UPDATED, () => {
286
+ this._emitAudioTracks();
287
+ });
284
288
  performance.mark('nm:backend:loadSource');
285
289
  hlsInstance.loadSource(url);
286
290
  performance.mark('nm:backend:attachMedia');
@@ -323,6 +327,7 @@ export class Html5VideoBackend extends MediaElementBackend {
323
327
  this.hls = undefined;
324
328
  this.hlsInstance = undefined;
325
329
  }
330
+ this._destroyCustomSource();
326
331
  resetMediaElement(this.element);
327
332
  this.currentUrl = undefined;
328
333
  this.emitEmptySubtitleCue();
@@ -367,6 +372,10 @@ export class Html5VideoBackend extends MediaElementBackend {
367
372
  // resumeLoader / loaderState / setAuthHeaderProvider
368
373
  _streamResolver;
369
374
  _customSource;
375
+ _destroyCustomSource() {
376
+ this._customSource?.destroy();
377
+ this._customSource = undefined;
378
+ }
370
379
  /**
371
380
  * Wire the lookup that asks the player's stream registry for a consumer's
372
381
  * factory. Without it the backend keeps its own HLS and progressive handling
@@ -858,6 +867,7 @@ export class Html5VideoBackend extends MediaElementBackend {
858
867
  this._netRetryCount = 0;
859
868
  this._mediaRecoveryStartMs = 0;
860
869
  this._sawConnectionFailure = false;
870
+ this._networkErrorEscalated = false;
861
871
  this._recoveringFromOutage = false;
862
872
  if (this._onlineHandler !== undefined) {
863
873
  globalThis.removeEventListener?.('online', this._onlineHandler);
@@ -902,6 +912,7 @@ export class Html5VideoBackend extends MediaElementBackend {
902
912
  // still deserves its session rather than a dead error overlay.
903
913
  this._watchForConnectivityReturn();
904
914
  this._recoveringFromOutage = false;
915
+ this._networkErrorEscalated = true;
905
916
  this._escalateHlsError(data.details, `HLS network error after ${limit} retries: ${data.details}`);
906
917
  return;
907
918
  }
@@ -1048,6 +1059,11 @@ export class Html5VideoBackend extends MediaElementBackend {
1048
1059
  this.hls.on(Hls.Events.FRAG_LOADED, () => {
1049
1060
  if (this._netRetryCount > 0)
1050
1061
  this._netRetryCount = 0;
1062
+ if (this._networkErrorEscalated) {
1063
+ this._networkErrorEscalated = false;
1064
+ this._hadError = false;
1065
+ this._state = 'ready';
1066
+ }
1051
1067
  });
1052
1068
  }
1053
1069
  /**
@@ -1067,6 +1083,9 @@ export class Html5VideoBackend extends MediaElementBackend {
1067
1083
  const levels = this.qualityLevels();
1068
1084
  this.emit('levels', { levels });
1069
1085
  });
1086
+ this._emitAudioTracks();
1087
+ }
1088
+ _emitAudioTracks() {
1070
1089
  const tracks = this.audioTracks();
1071
1090
  if (tracks.length > 0)
1072
1091
  this.emit('audioTracks', { tracks });
package/dist/index.js CHANGED
@@ -483,6 +483,8 @@ export class NMVideoPlayer extends EventEmitter {
483
483
  if (!data)
484
484
  return;
485
485
  this.emit('audioTracks', data);
486
+ // The list can arrive after mediaReady, when the defaults found nothing.
487
+ this._selectDefaultAudio();
486
488
  });
487
489
  return instance;
488
490
  }