avbridge 2.8.3 → 2.9.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.
Files changed (78) hide show
  1. package/CHANGELOG.md +165 -0
  2. package/README.md +74 -1
  3. package/dist/{avi-F6WZJK5T.cjs → avi-2ILLBNPQ.cjs} +8 -2
  4. package/dist/avi-2ILLBNPQ.cjs.map +1 -0
  5. package/dist/{avi-W6L3BTWU.cjs → avi-B5CQYB7L.cjs} +8 -2
  6. package/dist/avi-B5CQYB7L.cjs.map +1 -0
  7. package/dist/{avi-2JPBSHGA.js → avi-JXU4GQL2.js} +8 -2
  8. package/dist/avi-JXU4GQL2.js.map +1 -0
  9. package/dist/{avi-NJXAXUXK.js → avi-RWWPN2PR.js} +8 -2
  10. package/dist/avi-RWWPN2PR.js.map +1 -0
  11. package/dist/{chunk-X2K3GIWE.js → chunk-2NSOOMXW.js} +14 -3
  12. package/dist/chunk-2NSOOMXW.js.map +1 -0
  13. package/dist/{chunk-ZCUXHW55.cjs → chunk-BYGZN4Z5.cjs} +5 -5
  14. package/dist/{chunk-ZCUXHW55.cjs.map → chunk-BYGZN4Z5.cjs.map} +1 -1
  15. package/dist/{chunk-SMH6IOP2.js → chunk-CL6UEUQF.js} +4 -4
  16. package/dist/{chunk-SMH6IOP2.js.map → chunk-CL6UEUQF.js.map} +1 -1
  17. package/dist/{chunk-IUSFLVLJ.cjs → chunk-EY6DZEDT.cjs} +149 -24
  18. package/dist/chunk-EY6DZEDT.cjs.map +1 -0
  19. package/dist/{chunk-SR3MPV4D.js → chunk-GYIJU44C.js} +5 -5
  20. package/dist/{chunk-SR3MPV4D.js.map → chunk-GYIJU44C.js.map} +1 -1
  21. package/dist/{chunk-CPZ7PXAM.cjs → chunk-L7A3ECI2.cjs} +14 -2
  22. package/dist/chunk-L7A3ECI2.cjs.map +1 -0
  23. package/dist/{chunk-Q2VUO52Z.cjs → chunk-OTFS7DC4.cjs} +12 -12
  24. package/dist/{chunk-Q2VUO52Z.cjs.map → chunk-OTFS7DC4.cjs.map} +1 -1
  25. package/dist/{chunk-JSQOBUQB.js → chunk-SN4WZE24.js} +139 -14
  26. package/dist/chunk-SN4WZE24.js.map +1 -0
  27. package/dist/element-browser.js +164 -16
  28. package/dist/element-browser.js.map +1 -1
  29. package/dist/element.cjs +16 -10
  30. package/dist/element.cjs.map +1 -1
  31. package/dist/element.d.cts +11 -6
  32. package/dist/element.d.ts +11 -6
  33. package/dist/element.js +15 -9
  34. package/dist/element.js.map +1 -1
  35. package/dist/index.cjs +20 -20
  36. package/dist/index.d.cts +2 -2
  37. package/dist/index.d.ts +2 -2
  38. package/dist/index.js +8 -8
  39. package/dist/libav-demux-3N5Y3VQA.cjs +31 -0
  40. package/dist/{libav-demux-H2GS46GH.cjs.map → libav-demux-3N5Y3VQA.cjs.map} +1 -1
  41. package/dist/libav-demux-JXD4OTLM.js +6 -0
  42. package/dist/{libav-demux-OWZ4T2YW.js.map → libav-demux-JXD4OTLM.js.map} +1 -1
  43. package/dist/{player-DXEKOky8.d.cts → player-DEcidWk6.d.cts} +8 -1
  44. package/dist/{player-DXEKOky8.d.ts → player-DEcidWk6.d.ts} +8 -1
  45. package/dist/player.cjs +266 -36
  46. package/dist/player.cjs.map +1 -1
  47. package/dist/player.d.cts +37 -11
  48. package/dist/player.d.ts +37 -11
  49. package/dist/player.js +266 -36
  50. package/dist/player.js.map +1 -1
  51. package/dist/{remux-WBYIZBBX.js → remux-56V7LDAD.js} +5 -5
  52. package/dist/{remux-WBYIZBBX.js.map → remux-56V7LDAD.js.map} +1 -1
  53. package/dist/{remux-OBSMIENG.cjs → remux-KUS5GIL6.cjs} +10 -10
  54. package/dist/{remux-OBSMIENG.cjs.map → remux-KUS5GIL6.cjs.map} +1 -1
  55. package/package.json +1 -1
  56. package/src/classify/rules.ts +11 -0
  57. package/src/element/avbridge-player.ts +22 -11
  58. package/src/element/avbridge-video.ts +22 -6
  59. package/src/element/player-styles.ts +68 -3
  60. package/src/player.ts +96 -8
  61. package/src/probe/avi.ts +2 -0
  62. package/src/strategies/fallback/decoder.ts +30 -0
  63. package/src/strategies/fallback/index.ts +30 -0
  64. package/src/strategies/hybrid/decoder.ts +35 -0
  65. package/src/strategies/hybrid/index.ts +17 -0
  66. package/src/strategies/remux/index.ts +8 -0
  67. package/src/types.ts +6 -0
  68. package/src/util/libav-demux.ts +26 -0
  69. package/dist/avi-2JPBSHGA.js.map +0 -1
  70. package/dist/avi-F6WZJK5T.cjs.map +0 -1
  71. package/dist/avi-NJXAXUXK.js.map +0 -1
  72. package/dist/avi-W6L3BTWU.cjs.map +0 -1
  73. package/dist/chunk-CPZ7PXAM.cjs.map +0 -1
  74. package/dist/chunk-IUSFLVLJ.cjs.map +0 -1
  75. package/dist/chunk-JSQOBUQB.js.map +0 -1
  76. package/dist/chunk-X2K3GIWE.js.map +0 -1
  77. package/dist/libav-demux-H2GS46GH.cjs +0 -27
  78. package/dist/libav-demux-OWZ4T2YW.js +0 -6
package/dist/player.d.cts CHANGED
@@ -15,7 +15,7 @@ type MediaInput = File | Blob | string | URL | ArrayBuffer | Uint8Array;
15
15
  /** Container format families we know about. */
16
16
  type ContainerKind = "mp4" | "mov" | "mkv" | "webm" | "avi" | "asf" | "flv" | "rm" | "ogg" | "wav" | "mp3" | "flac" | "adts" | "mpegts" | "unknown";
17
17
  /** Video codec families. Strings, not enums, so plugins can extend. */
18
- type VideoCodec = "h264" | "h265" | "vp8" | "vp9" | "av1" | "mpeg4" | "wmv3" | "vc1" | "rv10" | "rv20" | "rv30" | "rv40" | "mpeg2" | "mpeg1" | "theora" | (string & {});
18
+ type VideoCodec = "h264" | "h265" | "vp8" | "vp9" | "av1" | "mpeg4" | "wmv3" | "vc1" | "rv10" | "rv20" | "rv30" | "rv40" | "mpeg2" | "mpeg1" | "theora" | "dv" | "hq_hqa" | "rawvideo" | "qtrle" | "png" | "vp6f" | (string & {});
19
19
  /** Audio codec families. */
20
20
  type AudioCodec = "aac" | "mp3" | "opus" | "vorbis" | "flac" | "pcm" | "ac3" | "eac3" | "wmav2" | "wmapro" | "alac" | "cook" | "ra_144" | "ra_288" | "sipr" | "atrac3" | "dts" | "truehd" | (string & {});
21
21
  interface VideoTrackInfo {
@@ -347,6 +347,7 @@ declare class AvbridgePlayerElement extends HTMLElement {
347
347
  private _timeFromSeekPointer;
348
348
  private _onSeekPointerDown;
349
349
  private _onSeekHover;
350
+ private _updateSeekTooltip;
350
351
  private _updateSeekVisuals;
351
352
  private _updateTime;
352
353
  private _toggleMute;
@@ -358,15 +359,28 @@ declare class AvbridgePlayerElement extends HTMLElement {
358
359
  private _updateStats;
359
360
  private _toggleFullscreen;
360
361
  private _updateFullscreenIcon;
362
+ /**
363
+ * Reveal the auto-hiding chrome (top toolbar + bottom controls) and
364
+ * re-start the auto-hide timer. Call this from app-level code to
365
+ * briefly surface the player UI — e.g. to confirm "you just swiped to
366
+ * this video" in a carousel, or to flash the title on focus change.
367
+ *
368
+ * @param durationMs How long the chrome stays visible before fading.
369
+ * Defaults to the player's normal 3 s auto-hide.
370
+ * Pointer movement or any other interaction resets
371
+ * the timer, so a user hovering during the flash
372
+ * sees no flicker.
373
+ */
374
+ showControls(durationMs?: number): void;
361
375
  private _showControls;
362
376
  private _scheduleHide;
363
377
  /** Track whether the last interaction was touch so click handler can skip. */
364
378
  private _lastPointerTypeWasTouch;
365
- /** True if the event's composed path passes through consumer-slotted toolbar
366
- * content. Slotted content lives in the light DOM so `.closest(".avp-toolbar-top")`
367
- * on the event target won't find the shadow-DOM wrapper — `composedPath()`
368
- * does. */
369
- private _isToolbarEvent;
379
+ /** True if the event's composed path passes through consumer-slotted
380
+ * content (toolbar or content-overlay). Slotted content lives in the
381
+ * light DOM so `.closest(".avp-toolbar-top")` on the event target won't
382
+ * find the shadow-DOM wrapper — `composedPath()` does. */
383
+ private _isSlottedContentEvent;
370
384
  private _onContainerClick;
371
385
  private _onContainerDblClick;
372
386
  private _onPointerDown;
@@ -446,6 +460,13 @@ declare class UnifiedPlayer {
446
460
  private stallTimer;
447
461
  private lastProgressTime;
448
462
  private lastProgressPosition;
463
+ /** Last observed `HTMLVideoElement.getVideoPlaybackQuality().totalVideoFrames`
464
+ * (or `webkitDecodedFrameCount` fallback). Used by the silent-video
465
+ * watchdog — catches cases where `currentTime` advances (audio plays)
466
+ * but the decoder produces no frames, e.g. Firefox claiming `hev1.*`
467
+ * via MSE when the decoder actually can't decode HEVC. */
468
+ private lastVideoFrameCount;
469
+ private lastVideoFrameProgressTime;
449
470
  private errorListener;
450
471
  private endedListener;
451
472
  private userIntent;
@@ -674,11 +695,16 @@ declare class AvbridgeVideoElement extends HTMLElementCtor {
674
695
  get readyState(): number;
675
696
  /**
676
697
  * Buffered time ranges for the active source. Mirrors the standard
677
- * `<video>.buffered` `TimeRanges` API. For the native and remux strategies
678
- * this reflects the underlying SourceBuffer / progressive download state.
679
- * For the hybrid and fallback (canvas-rendered) strategies it currently
680
- * returns an empty TimeRanges; a future release will synthesize a coarse
681
- * range from the decoder's read position.
698
+ * `<video>.buffered` `TimeRanges` API.
699
+ *
700
+ * - **Native / remux:** pass-through to the real `<video>.buffered`
701
+ * (reflects the browser's SourceBuffer / progressive-download state).
702
+ * - **Hybrid / fallback:** a single `[0, frontier]` range synthesized
703
+ * from the demuxer's read progress — "how far libav has ever pumped
704
+ * packets through." Monotonic; does not shrink on seek. This is an
705
+ * approximation, not MSE-fidelity: decoded frames on canvas strategies
706
+ * are consumed in flight, so we can't report per-range availability
707
+ * the way MSE does. Enough for a seek-bar buffered indicator.
682
708
  */
683
709
  get buffered(): TimeRanges;
684
710
  get poster(): string;
package/dist/player.d.ts CHANGED
@@ -15,7 +15,7 @@ type MediaInput = File | Blob | string | URL | ArrayBuffer | Uint8Array;
15
15
  /** Container format families we know about. */
16
16
  type ContainerKind = "mp4" | "mov" | "mkv" | "webm" | "avi" | "asf" | "flv" | "rm" | "ogg" | "wav" | "mp3" | "flac" | "adts" | "mpegts" | "unknown";
17
17
  /** Video codec families. Strings, not enums, so plugins can extend. */
18
- type VideoCodec = "h264" | "h265" | "vp8" | "vp9" | "av1" | "mpeg4" | "wmv3" | "vc1" | "rv10" | "rv20" | "rv30" | "rv40" | "mpeg2" | "mpeg1" | "theora" | (string & {});
18
+ type VideoCodec = "h264" | "h265" | "vp8" | "vp9" | "av1" | "mpeg4" | "wmv3" | "vc1" | "rv10" | "rv20" | "rv30" | "rv40" | "mpeg2" | "mpeg1" | "theora" | "dv" | "hq_hqa" | "rawvideo" | "qtrle" | "png" | "vp6f" | (string & {});
19
19
  /** Audio codec families. */
20
20
  type AudioCodec = "aac" | "mp3" | "opus" | "vorbis" | "flac" | "pcm" | "ac3" | "eac3" | "wmav2" | "wmapro" | "alac" | "cook" | "ra_144" | "ra_288" | "sipr" | "atrac3" | "dts" | "truehd" | (string & {});
21
21
  interface VideoTrackInfo {
@@ -347,6 +347,7 @@ declare class AvbridgePlayerElement extends HTMLElement {
347
347
  private _timeFromSeekPointer;
348
348
  private _onSeekPointerDown;
349
349
  private _onSeekHover;
350
+ private _updateSeekTooltip;
350
351
  private _updateSeekVisuals;
351
352
  private _updateTime;
352
353
  private _toggleMute;
@@ -358,15 +359,28 @@ declare class AvbridgePlayerElement extends HTMLElement {
358
359
  private _updateStats;
359
360
  private _toggleFullscreen;
360
361
  private _updateFullscreenIcon;
362
+ /**
363
+ * Reveal the auto-hiding chrome (top toolbar + bottom controls) and
364
+ * re-start the auto-hide timer. Call this from app-level code to
365
+ * briefly surface the player UI — e.g. to confirm "you just swiped to
366
+ * this video" in a carousel, or to flash the title on focus change.
367
+ *
368
+ * @param durationMs How long the chrome stays visible before fading.
369
+ * Defaults to the player's normal 3 s auto-hide.
370
+ * Pointer movement or any other interaction resets
371
+ * the timer, so a user hovering during the flash
372
+ * sees no flicker.
373
+ */
374
+ showControls(durationMs?: number): void;
361
375
  private _showControls;
362
376
  private _scheduleHide;
363
377
  /** Track whether the last interaction was touch so click handler can skip. */
364
378
  private _lastPointerTypeWasTouch;
365
- /** True if the event's composed path passes through consumer-slotted toolbar
366
- * content. Slotted content lives in the light DOM so `.closest(".avp-toolbar-top")`
367
- * on the event target won't find the shadow-DOM wrapper — `composedPath()`
368
- * does. */
369
- private _isToolbarEvent;
379
+ /** True if the event's composed path passes through consumer-slotted
380
+ * content (toolbar or content-overlay). Slotted content lives in the
381
+ * light DOM so `.closest(".avp-toolbar-top")` on the event target won't
382
+ * find the shadow-DOM wrapper — `composedPath()` does. */
383
+ private _isSlottedContentEvent;
370
384
  private _onContainerClick;
371
385
  private _onContainerDblClick;
372
386
  private _onPointerDown;
@@ -446,6 +460,13 @@ declare class UnifiedPlayer {
446
460
  private stallTimer;
447
461
  private lastProgressTime;
448
462
  private lastProgressPosition;
463
+ /** Last observed `HTMLVideoElement.getVideoPlaybackQuality().totalVideoFrames`
464
+ * (or `webkitDecodedFrameCount` fallback). Used by the silent-video
465
+ * watchdog — catches cases where `currentTime` advances (audio plays)
466
+ * but the decoder produces no frames, e.g. Firefox claiming `hev1.*`
467
+ * via MSE when the decoder actually can't decode HEVC. */
468
+ private lastVideoFrameCount;
469
+ private lastVideoFrameProgressTime;
449
470
  private errorListener;
450
471
  private endedListener;
451
472
  private userIntent;
@@ -674,11 +695,16 @@ declare class AvbridgeVideoElement extends HTMLElementCtor {
674
695
  get readyState(): number;
675
696
  /**
676
697
  * Buffered time ranges for the active source. Mirrors the standard
677
- * `<video>.buffered` `TimeRanges` API. For the native and remux strategies
678
- * this reflects the underlying SourceBuffer / progressive download state.
679
- * For the hybrid and fallback (canvas-rendered) strategies it currently
680
- * returns an empty TimeRanges; a future release will synthesize a coarse
681
- * range from the decoder's read position.
698
+ * `<video>.buffered` `TimeRanges` API.
699
+ *
700
+ * - **Native / remux:** pass-through to the real `<video>.buffered`
701
+ * (reflects the browser's SourceBuffer / progressive-download state).
702
+ * - **Hybrid / fallback:** a single `[0, frontier]` range synthesized
703
+ * from the demuxer's read progress — "how far libav has ever pumped
704
+ * packets through." Monotonic; does not shrink on seek. This is an
705
+ * approximation, not MSE-fidelity: decoded frames on canvas strategies
706
+ * are consumed in flight, so we can't report per-range availability
707
+ * the way MSE does. Enough for a seek-bar buffered indicator.
682
708
  */
683
709
  get buffered(): TimeRanges;
684
710
  get poster(): string;