avbridge 2.7.0 → 2.8.2
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 +106 -0
- package/README.md +35 -0
- package/dist/{chunk-6SOFJV44.cjs → chunk-IUSFLVLJ.cjs} +21 -6
- package/dist/chunk-IUSFLVLJ.cjs.map +1 -0
- package/dist/{chunk-OGYHFY6K.js → chunk-JSQOBUQB.js} +21 -6
- package/dist/chunk-JSQOBUQB.js.map +1 -0
- package/dist/element-browser.js +146 -7
- package/dist/element-browser.js.map +1 -1
- package/dist/element.cjs +129 -5
- package/dist/element.cjs.map +1 -1
- package/dist/element.d.cts +52 -3
- package/dist/element.d.ts +52 -3
- package/dist/element.js +128 -4
- package/dist/element.js.map +1 -1
- package/dist/index.cjs +8 -8
- package/dist/index.d.cts +2 -2
- package/dist/index.d.ts +2 -2
- package/dist/index.js +1 -1
- package/dist/{player-DGXeCNfD.d.cts → player-DXEKOky8.d.cts} +3 -0
- package/dist/{player-DGXeCNfD.d.ts → player-DXEKOky8.d.ts} +3 -0
- package/dist/player.cjs +254 -12
- package/dist/player.cjs.map +1 -1
- package/dist/player.d.cts +62 -3
- package/dist/player.d.ts +62 -3
- package/dist/player.js +254 -12
- package/dist/player.js.map +1 -1
- package/package.json +1 -1
- package/src/classify/rules.ts +23 -0
- package/src/element/avbridge-player.ts +83 -7
- package/src/element/avbridge-video.ts +148 -4
- package/src/element/player-styles.ts +44 -0
- package/src/element.ts +3 -3
- package/src/strategies/fallback/decoder.ts +14 -7
- package/src/strategies/fallback/video-renderer.ts +7 -5
- package/src/types.ts +1 -0
- package/dist/chunk-6SOFJV44.cjs.map +0 -1
- package/dist/chunk-OGYHFY6K.js.map +0 -1
package/dist/player.d.cts
CHANGED
|
@@ -283,6 +283,9 @@ interface AvbridgeVideoElementEventMap {
|
|
|
283
283
|
buffered: TimeRanges;
|
|
284
284
|
}>;
|
|
285
285
|
loadstart: CustomEvent<Record<string, never>>;
|
|
286
|
+
fitchange: CustomEvent<{
|
|
287
|
+
fit: "contain" | "cover" | "fill";
|
|
288
|
+
}>;
|
|
286
289
|
}
|
|
287
290
|
|
|
288
291
|
/**
|
|
@@ -297,7 +300,7 @@ interface AvbridgeVideoElementEventMap {
|
|
|
297
300
|
*/
|
|
298
301
|
|
|
299
302
|
declare class AvbridgePlayerElement extends HTMLElement {
|
|
300
|
-
static readonly observedAttributes: ("src" | "muted" | "autoplay" | "loop" | "preload" | "poster" | "playsinline" | "crossorigin" | "disableremoteplayback" | "preferstrategy")[];
|
|
303
|
+
static readonly observedAttributes: ("src" | "muted" | "autoplay" | "loop" | "preload" | "poster" | "playsinline" | "crossorigin" | "disableremoteplayback" | "preferstrategy" | "fit" | "show-fit")[];
|
|
301
304
|
private _video;
|
|
302
305
|
private _playBtn;
|
|
303
306
|
private _overlayBtn;
|
|
@@ -328,6 +331,8 @@ declare class AvbridgePlayerElement extends HTMLElement {
|
|
|
328
331
|
private _statsEl;
|
|
329
332
|
private _statsInterval;
|
|
330
333
|
private _eventCleanup;
|
|
334
|
+
private _updateToolbarEmpty;
|
|
335
|
+
private _toolbarTop;
|
|
331
336
|
constructor();
|
|
332
337
|
private _template;
|
|
333
338
|
private _bindEvents;
|
|
@@ -357,6 +362,11 @@ declare class AvbridgePlayerElement extends HTMLElement {
|
|
|
357
362
|
private _scheduleHide;
|
|
358
363
|
/** Track whether the last interaction was touch so click handler can skip. */
|
|
359
364
|
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;
|
|
360
370
|
private _onContainerClick;
|
|
361
371
|
private _onContainerDblClick;
|
|
362
372
|
private _onPointerDown;
|
|
@@ -506,14 +516,17 @@ declare class UnifiedPlayer {
|
|
|
506
516
|
* 3. Give consumers a `<video>`-compatible primitive they can wrap with
|
|
507
517
|
* their own UI.
|
|
508
518
|
*
|
|
509
|
-
* **It is not a player UI framework.**
|
|
510
|
-
*
|
|
519
|
+
* **It is not a player UI framework.** For YouTube-style chrome (seek
|
|
520
|
+
* bar, play/pause, settings menu, fullscreen, auto-hiding controls) use
|
|
521
|
+
* `<avbridge-player>` — it wraps this element with a full UI. See
|
|
511
522
|
* `docs/dev/WEB_COMPONENT_SPEC.md` for the full spec, lifecycle invariants,
|
|
512
523
|
* and edge case list.
|
|
513
524
|
*/
|
|
514
525
|
|
|
515
526
|
/** Strategy preference passed via the `preferstrategy` attribute. */
|
|
516
527
|
type PreferredStrategy = "auto" | StrategyName;
|
|
528
|
+
/** Fit mode — how the video fills the element's box. Mirrors CSS object-fit. */
|
|
529
|
+
type FitMode = "contain" | "cover" | "fill";
|
|
517
530
|
/**
|
|
518
531
|
* `HTMLElement` is a browser-only global. SSR frameworks (Next.js, Astro,
|
|
519
532
|
* Remix, etc.) commonly import library modules on the server to extract
|
|
@@ -586,12 +599,26 @@ declare class AvbridgeVideoElement extends HTMLElementCtor {
|
|
|
586
599
|
* native fails.
|
|
587
600
|
*/
|
|
588
601
|
private _preferredStrategy;
|
|
602
|
+
/** Current fit mode. Applied to the inner `<video>` via object-fit, and
|
|
603
|
+
* to the fallback canvas via the `--avbridge-fit` CSS custom property on
|
|
604
|
+
* the stage wrapper (see `src/strategies/fallback/video-renderer.ts`). */
|
|
605
|
+
private _fit;
|
|
606
|
+
/** The stage wrapper — the element the canvas attaches into, and where
|
|
607
|
+
* the `--avbridge-fit` CSS custom property lives. */
|
|
608
|
+
private _stageEl;
|
|
589
609
|
/** Set if currentTime was assigned before the player was ready. */
|
|
590
610
|
private _pendingSeek;
|
|
591
611
|
/** Set if play() was called before the player was ready. */
|
|
592
612
|
private _pendingPlay;
|
|
593
613
|
/** MutationObserver tracking light-DOM `<track>` children. */
|
|
594
614
|
private _trackObserver;
|
|
615
|
+
/** Document-level fullscreenchange handler — installed while connected so
|
|
616
|
+
* the element can lock/unlock screen orientation to match the video's
|
|
617
|
+
* intrinsic aspect. */
|
|
618
|
+
private _fullscreenChangeHandler;
|
|
619
|
+
/** True if we successfully called screen.orientation.lock() on the last
|
|
620
|
+
* fullscreen entry. Used to know whether to unlock on exit. */
|
|
621
|
+
private _orientationLocked;
|
|
595
622
|
constructor();
|
|
596
623
|
connectedCallback(): void;
|
|
597
624
|
disconnectedCallback(): void;
|
|
@@ -635,6 +662,8 @@ declare class AvbridgeVideoElement extends HTMLElementCtor {
|
|
|
635
662
|
set preload(value: "none" | "metadata" | "auto");
|
|
636
663
|
get diagnostics(): boolean;
|
|
637
664
|
set diagnostics(value: boolean);
|
|
665
|
+
get fit(): FitMode;
|
|
666
|
+
set fit(value: FitMode);
|
|
638
667
|
get preferredStrategy(): PreferredStrategy;
|
|
639
668
|
set preferredStrategy(value: PreferredStrategy);
|
|
640
669
|
get currentTime(): number;
|
|
@@ -724,6 +753,36 @@ declare class AvbridgeVideoElement extends HTMLElementCtor {
|
|
|
724
753
|
language?: string;
|
|
725
754
|
format?: "vtt" | "srt";
|
|
726
755
|
}): Promise<void>;
|
|
756
|
+
/**
|
|
757
|
+
* Disable the automatic `screen.orientation.lock()` that runs on
|
|
758
|
+
* fullscreen entry. Set when you want to honor the device's native
|
|
759
|
+
* auto-rotate instead of matching the video's intrinsic orientation.
|
|
760
|
+
*/
|
|
761
|
+
get noOrientationLock(): boolean;
|
|
762
|
+
set noOrientationLock(value: boolean);
|
|
763
|
+
/** Called whenever `document.fullscreenchange` fires. If this element (or
|
|
764
|
+
* any of its ancestors) is now fullscreen, derive the target orientation
|
|
765
|
+
* from the video's intrinsic size and call `screen.orientation.lock()`.
|
|
766
|
+
* On exit, release the lock we took. iOS Safari rejects `lock()` — we
|
|
767
|
+
* swallow the rejection so nothing breaks on that path. */
|
|
768
|
+
private _onFullscreenChange;
|
|
769
|
+
/** Walk composed-tree ancestors to see if `target` is this element or
|
|
770
|
+
* any ancestor across shadow boundaries. `Node.contains()` can't cross
|
|
771
|
+
* shadow roots, so when `<avbridge-player>` (the fullscreen element)
|
|
772
|
+
* hosts this `<avbridge-video>` inside its shadow DOM, `contains()`
|
|
773
|
+
* returns false. */
|
|
774
|
+
private _isInsideOrEquals;
|
|
775
|
+
/** Derive "landscape" / "portrait" from the intrinsic video dimensions.
|
|
776
|
+
* Returns null when dimensions aren't known yet or the video is square.
|
|
777
|
+
* Uses `videoWidth` / `videoHeight` from the inner `<video>`, which the
|
|
778
|
+
* browser sets to the display-aspect-corrected size (so anamorphic
|
|
779
|
+
* content is judged by its display aspect, not pixel aspect). */
|
|
780
|
+
private _desiredOrientation;
|
|
781
|
+
/** Attempt to lock screen orientation. Swallows rejections — iOS Safari
|
|
782
|
+
* doesn't implement `lock()`, and desktop / non-fullscreen contexts will
|
|
783
|
+
* reject too. Records success so we know whether to unlock on exit. */
|
|
784
|
+
private _lockOrientation;
|
|
785
|
+
private _releaseOrientationLock;
|
|
727
786
|
/** Force a (re-)bootstrap if a source is currently set. */
|
|
728
787
|
load(): Promise<void>;
|
|
729
788
|
/**
|
package/dist/player.d.ts
CHANGED
|
@@ -283,6 +283,9 @@ interface AvbridgeVideoElementEventMap {
|
|
|
283
283
|
buffered: TimeRanges;
|
|
284
284
|
}>;
|
|
285
285
|
loadstart: CustomEvent<Record<string, never>>;
|
|
286
|
+
fitchange: CustomEvent<{
|
|
287
|
+
fit: "contain" | "cover" | "fill";
|
|
288
|
+
}>;
|
|
286
289
|
}
|
|
287
290
|
|
|
288
291
|
/**
|
|
@@ -297,7 +300,7 @@ interface AvbridgeVideoElementEventMap {
|
|
|
297
300
|
*/
|
|
298
301
|
|
|
299
302
|
declare class AvbridgePlayerElement extends HTMLElement {
|
|
300
|
-
static readonly observedAttributes: ("src" | "muted" | "autoplay" | "loop" | "preload" | "poster" | "playsinline" | "crossorigin" | "disableremoteplayback" | "preferstrategy")[];
|
|
303
|
+
static readonly observedAttributes: ("src" | "muted" | "autoplay" | "loop" | "preload" | "poster" | "playsinline" | "crossorigin" | "disableremoteplayback" | "preferstrategy" | "fit" | "show-fit")[];
|
|
301
304
|
private _video;
|
|
302
305
|
private _playBtn;
|
|
303
306
|
private _overlayBtn;
|
|
@@ -328,6 +331,8 @@ declare class AvbridgePlayerElement extends HTMLElement {
|
|
|
328
331
|
private _statsEl;
|
|
329
332
|
private _statsInterval;
|
|
330
333
|
private _eventCleanup;
|
|
334
|
+
private _updateToolbarEmpty;
|
|
335
|
+
private _toolbarTop;
|
|
331
336
|
constructor();
|
|
332
337
|
private _template;
|
|
333
338
|
private _bindEvents;
|
|
@@ -357,6 +362,11 @@ declare class AvbridgePlayerElement extends HTMLElement {
|
|
|
357
362
|
private _scheduleHide;
|
|
358
363
|
/** Track whether the last interaction was touch so click handler can skip. */
|
|
359
364
|
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;
|
|
360
370
|
private _onContainerClick;
|
|
361
371
|
private _onContainerDblClick;
|
|
362
372
|
private _onPointerDown;
|
|
@@ -506,14 +516,17 @@ declare class UnifiedPlayer {
|
|
|
506
516
|
* 3. Give consumers a `<video>`-compatible primitive they can wrap with
|
|
507
517
|
* their own UI.
|
|
508
518
|
*
|
|
509
|
-
* **It is not a player UI framework.**
|
|
510
|
-
*
|
|
519
|
+
* **It is not a player UI framework.** For YouTube-style chrome (seek
|
|
520
|
+
* bar, play/pause, settings menu, fullscreen, auto-hiding controls) use
|
|
521
|
+
* `<avbridge-player>` — it wraps this element with a full UI. See
|
|
511
522
|
* `docs/dev/WEB_COMPONENT_SPEC.md` for the full spec, lifecycle invariants,
|
|
512
523
|
* and edge case list.
|
|
513
524
|
*/
|
|
514
525
|
|
|
515
526
|
/** Strategy preference passed via the `preferstrategy` attribute. */
|
|
516
527
|
type PreferredStrategy = "auto" | StrategyName;
|
|
528
|
+
/** Fit mode — how the video fills the element's box. Mirrors CSS object-fit. */
|
|
529
|
+
type FitMode = "contain" | "cover" | "fill";
|
|
517
530
|
/**
|
|
518
531
|
* `HTMLElement` is a browser-only global. SSR frameworks (Next.js, Astro,
|
|
519
532
|
* Remix, etc.) commonly import library modules on the server to extract
|
|
@@ -586,12 +599,26 @@ declare class AvbridgeVideoElement extends HTMLElementCtor {
|
|
|
586
599
|
* native fails.
|
|
587
600
|
*/
|
|
588
601
|
private _preferredStrategy;
|
|
602
|
+
/** Current fit mode. Applied to the inner `<video>` via object-fit, and
|
|
603
|
+
* to the fallback canvas via the `--avbridge-fit` CSS custom property on
|
|
604
|
+
* the stage wrapper (see `src/strategies/fallback/video-renderer.ts`). */
|
|
605
|
+
private _fit;
|
|
606
|
+
/** The stage wrapper — the element the canvas attaches into, and where
|
|
607
|
+
* the `--avbridge-fit` CSS custom property lives. */
|
|
608
|
+
private _stageEl;
|
|
589
609
|
/** Set if currentTime was assigned before the player was ready. */
|
|
590
610
|
private _pendingSeek;
|
|
591
611
|
/** Set if play() was called before the player was ready. */
|
|
592
612
|
private _pendingPlay;
|
|
593
613
|
/** MutationObserver tracking light-DOM `<track>` children. */
|
|
594
614
|
private _trackObserver;
|
|
615
|
+
/** Document-level fullscreenchange handler — installed while connected so
|
|
616
|
+
* the element can lock/unlock screen orientation to match the video's
|
|
617
|
+
* intrinsic aspect. */
|
|
618
|
+
private _fullscreenChangeHandler;
|
|
619
|
+
/** True if we successfully called screen.orientation.lock() on the last
|
|
620
|
+
* fullscreen entry. Used to know whether to unlock on exit. */
|
|
621
|
+
private _orientationLocked;
|
|
595
622
|
constructor();
|
|
596
623
|
connectedCallback(): void;
|
|
597
624
|
disconnectedCallback(): void;
|
|
@@ -635,6 +662,8 @@ declare class AvbridgeVideoElement extends HTMLElementCtor {
|
|
|
635
662
|
set preload(value: "none" | "metadata" | "auto");
|
|
636
663
|
get diagnostics(): boolean;
|
|
637
664
|
set diagnostics(value: boolean);
|
|
665
|
+
get fit(): FitMode;
|
|
666
|
+
set fit(value: FitMode);
|
|
638
667
|
get preferredStrategy(): PreferredStrategy;
|
|
639
668
|
set preferredStrategy(value: PreferredStrategy);
|
|
640
669
|
get currentTime(): number;
|
|
@@ -724,6 +753,36 @@ declare class AvbridgeVideoElement extends HTMLElementCtor {
|
|
|
724
753
|
language?: string;
|
|
725
754
|
format?: "vtt" | "srt";
|
|
726
755
|
}): Promise<void>;
|
|
756
|
+
/**
|
|
757
|
+
* Disable the automatic `screen.orientation.lock()` that runs on
|
|
758
|
+
* fullscreen entry. Set when you want to honor the device's native
|
|
759
|
+
* auto-rotate instead of matching the video's intrinsic orientation.
|
|
760
|
+
*/
|
|
761
|
+
get noOrientationLock(): boolean;
|
|
762
|
+
set noOrientationLock(value: boolean);
|
|
763
|
+
/** Called whenever `document.fullscreenchange` fires. If this element (or
|
|
764
|
+
* any of its ancestors) is now fullscreen, derive the target orientation
|
|
765
|
+
* from the video's intrinsic size and call `screen.orientation.lock()`.
|
|
766
|
+
* On exit, release the lock we took. iOS Safari rejects `lock()` — we
|
|
767
|
+
* swallow the rejection so nothing breaks on that path. */
|
|
768
|
+
private _onFullscreenChange;
|
|
769
|
+
/** Walk composed-tree ancestors to see if `target` is this element or
|
|
770
|
+
* any ancestor across shadow boundaries. `Node.contains()` can't cross
|
|
771
|
+
* shadow roots, so when `<avbridge-player>` (the fullscreen element)
|
|
772
|
+
* hosts this `<avbridge-video>` inside its shadow DOM, `contains()`
|
|
773
|
+
* returns false. */
|
|
774
|
+
private _isInsideOrEquals;
|
|
775
|
+
/** Derive "landscape" / "portrait" from the intrinsic video dimensions.
|
|
776
|
+
* Returns null when dimensions aren't known yet or the video is square.
|
|
777
|
+
* Uses `videoWidth` / `videoHeight` from the inner `<video>`, which the
|
|
778
|
+
* browser sets to the display-aspect-corrected size (so anamorphic
|
|
779
|
+
* content is judged by its display aspect, not pixel aspect). */
|
|
780
|
+
private _desiredOrientation;
|
|
781
|
+
/** Attempt to lock screen orientation. Swallows rejections — iOS Safari
|
|
782
|
+
* doesn't implement `lock()`, and desktop / non-fullscreen contexts will
|
|
783
|
+
* reject too. Records success so we know whether to unlock on exit. */
|
|
784
|
+
private _lockOrientation;
|
|
785
|
+
private _releaseOrientationLock;
|
|
727
786
|
/** Force a (re-)bootstrap if a source is currently set. */
|
|
728
787
|
load(): Promise<void>;
|
|
729
788
|
/**
|