@videojs/spf 10.0.0-beta.9 → 10.0.0-rc.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/README.md +19 -38
- package/dist/default/core/actors/create-machine-actor.js +89 -0
- package/dist/default/core/actors/create-machine-actor.js.map +1 -0
- package/dist/default/core/actors/create-transition-actor.js +44 -0
- package/dist/default/core/actors/create-transition-actor.js.map +1 -0
- package/dist/default/core/composition/create-composition.js +82 -0
- package/dist/default/core/composition/create-composition.js.map +1 -0
- package/dist/default/core/composition/share-signals.js +34 -0
- package/dist/default/core/composition/share-signals.js.map +1 -0
- package/dist/default/core/machine.js +25 -0
- package/dist/default/core/machine.js.map +1 -0
- package/dist/default/core/reactors/create-machine-reactor.js +84 -0
- package/dist/default/core/reactors/create-machine-reactor.js.map +1 -0
- package/dist/default/core/signals/effect.js +61 -0
- package/dist/default/core/signals/effect.js.map +1 -0
- package/dist/default/core/signals/primitives.js +50 -0
- package/dist/default/core/signals/primitives.js.map +1 -0
- package/dist/default/core/signals/when.js +36 -0
- package/dist/default/core/signals/when.js.map +1 -0
- package/dist/default/core/tasks/delayed-reschedule.js +27 -0
- package/dist/default/core/tasks/delayed-reschedule.js.map +1 -0
- package/dist/default/core/tasks/task.js +298 -0
- package/dist/default/core/tasks/task.js.map +1 -0
- package/dist/default/dom.js +9 -0
- package/dist/default/hls-audio.js +3 -0
- package/dist/default/hls-background-video.js +3 -0
- package/dist/default/hls-video.js +4 -0
- package/dist/default/hls.js +10 -0
- package/dist/default/index.js +22 -0
- package/dist/default/index.js.map +1 -0
- package/dist/default/media/abr/quality-selection.js +17 -0
- package/dist/default/media/abr/quality-selection.js.map +1 -0
- package/dist/default/media/buffer/back-buffer.js +42 -0
- package/dist/default/media/buffer/back-buffer.js.map +1 -0
- package/dist/default/media/buffer/forward-buffer.js +110 -0
- package/dist/default/media/buffer/forward-buffer.js.map +1 -0
- package/dist/default/media/dom/capabilities.js +61 -0
- package/dist/default/media/dom/capabilities.js.map +1 -0
- package/dist/default/media/dom/mse/append-segment.js +58 -0
- package/dist/default/media/dom/mse/append-segment.js.map +1 -0
- package/dist/default/media/dom/mse/buffer-flusher.js +55 -0
- package/dist/default/media/dom/mse/buffer-flusher.js.map +1 -0
- package/dist/default/media/dom/mse/duration.js +87 -0
- package/dist/default/media/dom/mse/duration.js.map +1 -0
- package/dist/default/media/dom/mse/end-of-stream.js +17 -0
- package/dist/default/media/dom/mse/end-of-stream.js.map +1 -0
- package/dist/default/media/dom/mse/mediasource-setup.js +227 -0
- package/dist/default/media/dom/mse/mediasource-setup.js.map +1 -0
- package/dist/default/media/dom/screen.js +95 -0
- package/dist/default/media/dom/screen.js.map +1 -0
- package/dist/default/media/dom/text/resolve-vtt-segment.js +50 -0
- package/dist/default/media/dom/text/resolve-vtt-segment.js.map +1 -0
- package/dist/default/media/dom/text/text-track-slots.js +61 -0
- package/dist/default/media/dom/text/text-track-slots.js.map +1 -0
- package/dist/default/media/errors.js +60 -0
- package/dist/default/media/errors.js.map +1 -0
- package/dist/default/media/hls/parse-attributes.js +131 -0
- package/dist/default/media/hls/parse-attributes.js.map +1 -0
- package/dist/default/media/hls/parse-media-playlist.js +253 -0
- package/dist/default/media/hls/parse-media-playlist.js.map +1 -0
- package/dist/default/media/hls/parse-multivariant.js +234 -0
- package/dist/default/media/hls/parse-multivariant.js.map +1 -0
- package/dist/default/media/hls/reload-policy.js +63 -0
- package/dist/default/media/hls/reload-policy.js.map +1 -0
- package/dist/default/media/hls/resolve-url.js +9 -0
- package/dist/default/media/hls/resolve-url.js.map +1 -0
- package/dist/default/media/live-window.js +32 -0
- package/dist/default/media/live-window.js.map +1 -0
- package/dist/default/media/media-tracks/media-tracks.js +96 -0
- package/dist/default/media/media-tracks/media-tracks.js.map +1 -0
- package/dist/default/media/mp4/box.js +57 -0
- package/dist/default/media/mp4/box.js.map +1 -0
- package/dist/default/media/mp4/timestamp-origin.js +95 -0
- package/dist/default/media/mp4/timestamp-origin.js.map +1 -0
- package/dist/default/media/primitives/resolution.js +26 -0
- package/dist/default/media/primitives/resolution.js.map +1 -0
- package/dist/default/media/primitives/select-tracks.js +97 -0
- package/dist/default/media/primitives/select-tracks.js.map +1 -0
- package/dist/default/media/text/parse-vtt-timestamp-map.js +40 -0
- package/dist/default/media/text/parse-vtt-timestamp-map.js.map +1 -0
- package/dist/default/media/text/resolve-vtt-metadata.js +22 -0
- package/dist/default/media/text/resolve-vtt-metadata.js.map +1 -0
- package/dist/default/media/types/index.js +42 -0
- package/dist/default/media/types/index.js.map +1 -0
- package/dist/default/media/utils/cdn.js +50 -0
- package/dist/default/media/utils/cdn.js.map +1 -0
- package/dist/default/media/utils/preload.js +21 -0
- package/dist/default/media/utils/preload.js.map +1 -0
- package/dist/default/media/utils/track-selection.js +43 -0
- package/dist/default/media/utils/track-selection.js.map +1 -0
- package/dist/default/media/utils/tracks.js +146 -0
- package/dist/default/media/utils/tracks.js.map +1 -0
- package/dist/default/media-tracks.js +2 -0
- package/dist/default/network/bandwidth-estimator.js +95 -0
- package/dist/default/network/bandwidth-estimator.js.map +1 -0
- package/dist/default/network/chunked-stream-iterable.js +47 -0
- package/dist/default/network/chunked-stream-iterable.js.map +1 -0
- package/dist/default/network/ewma.js +68 -0
- package/dist/default/network/ewma.js.map +1 -0
- package/dist/default/network/fetch.js +108 -0
- package/dist/default/network/fetch.js.map +1 -0
- package/dist/default/playback/actors/dom/segment-loader.js +233 -0
- package/dist/default/playback/actors/dom/segment-loader.js.map +1 -0
- package/dist/default/playback/actors/dom/source-buffer.js +139 -0
- package/dist/default/playback/actors/dom/source-buffer.js.map +1 -0
- package/dist/default/playback/actors/dom/text-tracks.js +46 -0
- package/dist/default/playback/actors/dom/text-tracks.js.map +1 -0
- package/dist/default/playback/actors/text-track-segment-loader.js +138 -0
- package/dist/default/playback/actors/text-track-segment-loader.js.map +1 -0
- package/dist/default/playback/adapters/hls-audio/adapter.js +8 -0
- package/dist/default/playback/adapters/hls-audio/adapter.js.map +1 -0
- package/dist/default/playback/adapters/hls-audio/mixin.js +178 -0
- package/dist/default/playback/adapters/hls-audio/mixin.js.map +1 -0
- package/dist/default/playback/adapters/hls-background-video/adapter.js +17 -0
- package/dist/default/playback/adapters/hls-background-video/adapter.js.map +1 -0
- package/dist/default/playback/adapters/hls-background-video/host.js +56 -0
- package/dist/default/playback/adapters/hls-background-video/host.js.map +1 -0
- package/dist/default/playback/adapters/hls-background-video/mixin.js +191 -0
- package/dist/default/playback/adapters/hls-background-video/mixin.js.map +1 -0
- package/dist/default/playback/adapters/hls-video/adapter.js +11 -0
- package/dist/default/playback/adapters/hls-video/adapter.js.map +1 -0
- package/dist/default/playback/adapters/hls-video/error-surface.js +46 -0
- package/dist/default/playback/adapters/hls-video/error-surface.js.map +1 -0
- package/dist/default/playback/adapters/hls-video/media-tracks.js +125 -0
- package/dist/default/playback/adapters/hls-video/media-tracks.js.map +1 -0
- package/dist/default/playback/adapters/hls-video/mixin.js +299 -0
- package/dist/default/playback/adapters/hls-video/mixin.js.map +1 -0
- package/dist/default/playback/behaviors/calculate-presentation-duration.js +33 -0
- package/dist/default/playback/behaviors/calculate-presentation-duration.js.map +1 -0
- package/dist/default/playback/behaviors/collect-errors.js +98 -0
- package/dist/default/playback/behaviors/collect-errors.js.map +1 -0
- package/dist/default/playback/behaviors/derive-cdn-priority.js +61 -0
- package/dist/default/playback/behaviors/derive-cdn-priority.js.map +1 -0
- package/dist/default/playback/behaviors/dom/airplay.js +188 -0
- package/dist/default/playback/behaviors/dom/airplay.js.map +1 -0
- package/dist/default/playback/behaviors/dom/apply-start-position.js +81 -0
- package/dist/default/playback/behaviors/dom/apply-start-position.js.map +1 -0
- package/dist/default/playback/behaviors/dom/end-of-stream.js +97 -0
- package/dist/default/playback/behaviors/dom/end-of-stream.js.map +1 -0
- package/dist/default/playback/behaviors/dom/load-segments.js +169 -0
- package/dist/default/playback/behaviors/dom/load-segments.js.map +1 -0
- package/dist/default/playback/behaviors/dom/recover-end-stall.js +72 -0
- package/dist/default/playback/behaviors/dom/recover-end-stall.js.map +1 -0
- package/dist/default/playback/behaviors/dom/seek-to-live-edge.js +113 -0
- package/dist/default/playback/behaviors/dom/seek-to-live-edge.js.map +1 -0
- package/dist/default/playback/behaviors/dom/setup-buffer-actors.js +181 -0
- package/dist/default/playback/behaviors/dom/setup-buffer-actors.js.map +1 -0
- package/dist/default/playback/behaviors/dom/setup-mediasource.js +100 -0
- package/dist/default/playback/behaviors/dom/setup-mediasource.js.map +1 -0
- package/dist/default/playback/behaviors/dom/setup-text-track-actors.js +40 -0
- package/dist/default/playback/behaviors/dom/setup-text-track-actors.js.map +1 -0
- package/dist/default/playback/behaviors/dom/sync-live-seekable-range.js +25 -0
- package/dist/default/playback/behaviors/dom/sync-live-seekable-range.js.map +1 -0
- package/dist/default/playback/behaviors/dom/sync-text-tracks.js +109 -0
- package/dist/default/playback/behaviors/dom/sync-text-tracks.js.map +1 -0
- package/dist/default/playback/behaviors/dom/track-current-time.js +50 -0
- package/dist/default/playback/behaviors/dom/track-current-time.js.map +1 -0
- package/dist/default/playback/behaviors/dom/track-load-triggers.js +86 -0
- package/dist/default/playback/behaviors/dom/track-load-triggers.js.map +1 -0
- package/dist/default/playback/behaviors/dom/track-playback-rate.js +35 -0
- package/dist/default/playback/behaviors/dom/track-playback-rate.js.map +1 -0
- package/dist/default/playback/behaviors/dom/track-player-resolution.js +53 -0
- package/dist/default/playback/behaviors/dom/track-player-resolution.js.map +1 -0
- package/dist/default/playback/behaviors/dom/track-screen-resolution.js +28 -0
- package/dist/default/playback/behaviors/dom/track-screen-resolution.js.map +1 -0
- package/dist/default/playback/behaviors/dom/update-mediasource-duration.js +98 -0
- package/dist/default/playback/behaviors/dom/update-mediasource-duration.js.map +1 -0
- package/dist/default/playback/behaviors/establish-start-media-time.js +187 -0
- package/dist/default/playback/behaviors/establish-start-media-time.js.map +1 -0
- package/dist/default/playback/behaviors/resolve-presentation.js +76 -0
- package/dist/default/playback/behaviors/resolve-presentation.js.map +1 -0
- package/dist/default/playback/behaviors/resolve-track.js +134 -0
- package/dist/default/playback/behaviors/resolve-track.js.map +1 -0
- package/dist/default/playback/behaviors/select-tracks.js +189 -0
- package/dist/default/playback/behaviors/select-tracks.js.map +1 -0
- package/dist/default/playback/behaviors/setup-failover-monitor.js +61 -0
- package/dist/default/playback/behaviors/setup-failover-monitor.js.map +1 -0
- package/dist/default/playback/behaviors/sync-preload.js +59 -0
- package/dist/default/playback/behaviors/sync-preload.js.map +1 -0
- package/dist/default/playback/behaviors/track-switching.js +407 -0
- package/dist/default/playback/behaviors/track-switching.js.map +1 -0
- package/dist/default/playback/engines/hls/engine-audio-only.js +94 -0
- package/dist/default/playback/engines/hls/engine-audio-only.js.map +1 -0
- package/dist/default/playback/engines/hls/engine-background-video.js +87 -0
- package/dist/default/playback/engines/hls/engine-background-video.js.map +1 -0
- package/dist/default/playback/engines/hls/engine.js +144 -0
- package/dist/default/playback/engines/hls/engine.js.map +1 -0
- package/dist/default/playback/primitives/error-messages.js +42 -0
- package/dist/default/playback/primitives/error-messages.js.map +1 -0
- package/dist/default/playback/primitives/failover-fetch.js +37 -0
- package/dist/default/playback/primitives/failover-fetch.js.map +1 -0
- package/dist/default/playback/primitives/head-peek.js +41 -0
- package/dist/default/playback/primitives/head-peek.js.map +1 -0
- package/dist/default/playback/primitives/live-window.js +63 -0
- package/dist/default/playback/primitives/live-window.js.map +1 -0
- package/dist/default/playback/primitives/relocation-pipelines.js +191 -0
- package/dist/default/playback/primitives/relocation-pipelines.js.map +1 -0
- package/dist/default/playback/primitives/report-track-conditions.js +74 -0
- package/dist/default/playback/primitives/report-track-conditions.js.map +1 -0
- package/dist/default/playback/primitives/segment-load-pipeline.js +96 -0
- package/dist/default/playback/primitives/segment-load-pipeline.js.map +1 -0
- package/dist/default/playback/primitives/selection-rules.js +115 -0
- package/dist/default/playback/primitives/selection-rules.js.map +1 -0
- package/dist/default/playback/primitives/text-segment-load-pipeline.js +36 -0
- package/dist/default/playback/primitives/text-segment-load-pipeline.js.map +1 -0
- package/dist/default/playback/primitives/track-types.js +53 -0
- package/dist/default/playback/primitives/track-types.js.map +1 -0
- package/dist/dev/core/actors/actor.d.ts +26 -0
- package/dist/dev/core/actors/actor.d.ts.map +1 -0
- package/dist/dev/core/actors/create-machine-actor.d.ts +119 -0
- package/dist/dev/core/actors/create-machine-actor.d.ts.map +1 -0
- package/dist/dev/core/actors/create-machine-actor.js +89 -0
- package/dist/dev/core/actors/create-machine-actor.js.map +1 -0
- package/dist/dev/core/actors/create-transition-actor.d.ts +37 -0
- package/dist/dev/core/actors/create-transition-actor.d.ts.map +1 -0
- package/dist/dev/core/actors/create-transition-actor.js +44 -0
- package/dist/dev/core/actors/create-transition-actor.js.map +1 -0
- package/dist/dev/core/composition/create-composition.d.ts +241 -0
- package/dist/dev/core/composition/create-composition.d.ts.map +1 -0
- package/dist/dev/core/composition/create-composition.js +82 -0
- package/dist/dev/core/composition/create-composition.js.map +1 -0
- package/dist/dev/core/composition/share-signals.d.ts +39 -0
- package/dist/dev/core/composition/share-signals.d.ts.map +1 -0
- package/dist/dev/core/composition/share-signals.js +34 -0
- package/dist/dev/core/composition/share-signals.js.map +1 -0
- package/dist/dev/core/machine.d.ts +21 -0
- package/dist/dev/core/machine.d.ts.map +1 -0
- package/dist/dev/core/machine.js +25 -0
- package/dist/dev/core/machine.js.map +1 -0
- package/dist/dev/core/reactors/create-machine-reactor.d.ts +87 -0
- package/dist/dev/core/reactors/create-machine-reactor.d.ts.map +1 -0
- package/dist/dev/core/reactors/create-machine-reactor.js +84 -0
- package/dist/dev/core/reactors/create-machine-reactor.js.map +1 -0
- package/dist/dev/core/signals/effect.d.ts +14 -0
- package/dist/dev/core/signals/effect.d.ts.map +1 -0
- package/dist/dev/core/signals/effect.js +61 -0
- package/dist/dev/core/signals/effect.js.map +1 -0
- package/dist/dev/core/signals/primitives.d.ts +44 -0
- package/dist/dev/core/signals/primitives.d.ts.map +1 -0
- package/dist/dev/core/signals/primitives.js +50 -0
- package/dist/dev/core/signals/primitives.js.map +1 -0
- package/dist/dev/core/signals/when.js +36 -0
- package/dist/dev/core/signals/when.js.map +1 -0
- package/dist/dev/core/tasks/delayed-reschedule.js +27 -0
- package/dist/dev/core/tasks/delayed-reschedule.js.map +1 -0
- package/dist/dev/core/tasks/task.d.ts +144 -0
- package/dist/dev/core/tasks/task.d.ts.map +1 -0
- package/dist/dev/core/tasks/task.js +298 -0
- package/dist/dev/core/tasks/task.js.map +1 -0
- package/dist/dev/dom.d.ts +9 -0
- package/dist/dev/dom.js +9 -0
- package/dist/dev/hls-audio.d.ts +3 -0
- package/dist/dev/hls-audio.js +3 -0
- package/dist/dev/hls-background-video.d.ts +4 -0
- package/dist/dev/hls-background-video.js +3 -0
- package/dist/dev/hls-video.d.ts +5 -0
- package/dist/dev/hls-video.js +4 -0
- package/dist/dev/hls.d.ts +11 -0
- package/dist/dev/hls.js +10 -0
- package/dist/dev/index.d.ts +23 -0
- package/dist/dev/index.d.ts.map +1 -0
- package/dist/dev/index.js +22 -0
- package/dist/dev/index.js.map +1 -0
- package/dist/dev/media/abr/quality-selection.d.ts +19 -0
- package/dist/dev/media/abr/quality-selection.d.ts.map +1 -0
- package/dist/dev/media/abr/quality-selection.js +17 -0
- package/dist/dev/media/abr/quality-selection.js.map +1 -0
- package/dist/dev/media/buffer/back-buffer.d.ts +9 -0
- package/dist/dev/media/buffer/back-buffer.d.ts.map +1 -0
- package/dist/dev/media/buffer/back-buffer.js +42 -0
- package/dist/dev/media/buffer/back-buffer.js.map +1 -0
- package/dist/dev/media/buffer/forward-buffer.d.ts +9 -0
- package/dist/dev/media/buffer/forward-buffer.d.ts.map +1 -0
- package/dist/dev/media/buffer/forward-buffer.js +110 -0
- package/dist/dev/media/buffer/forward-buffer.js.map +1 -0
- package/dist/dev/media/dom/capabilities.js +61 -0
- package/dist/dev/media/dom/capabilities.js.map +1 -0
- package/dist/dev/media/dom/mse/append-segment.d.ts +16 -0
- package/dist/dev/media/dom/mse/append-segment.d.ts.map +1 -0
- package/dist/dev/media/dom/mse/append-segment.js +58 -0
- package/dist/dev/media/dom/mse/append-segment.js.map +1 -0
- package/dist/dev/media/dom/mse/buffer-flusher.d.ts +24 -0
- package/dist/dev/media/dom/mse/buffer-flusher.d.ts.map +1 -0
- package/dist/dev/media/dom/mse/buffer-flusher.js +55 -0
- package/dist/dev/media/dom/mse/buffer-flusher.js.map +1 -0
- package/dist/dev/media/dom/mse/duration.js +87 -0
- package/dist/dev/media/dom/mse/duration.js.map +1 -0
- package/dist/dev/media/dom/mse/end-of-stream.js +17 -0
- package/dist/dev/media/dom/mse/end-of-stream.js.map +1 -0
- package/dist/dev/media/dom/mse/mediasource-setup.js +227 -0
- package/dist/dev/media/dom/mse/mediasource-setup.js.map +1 -0
- package/dist/dev/media/dom/screen.d.ts +7 -0
- package/dist/dev/media/dom/screen.d.ts.map +1 -0
- package/dist/dev/media/dom/screen.js +95 -0
- package/dist/dev/media/dom/screen.js.map +1 -0
- package/dist/dev/media/dom/text/resolve-vtt-segment.d.ts +6 -0
- package/dist/dev/media/dom/text/resolve-vtt-segment.d.ts.map +1 -0
- package/dist/dev/media/dom/text/resolve-vtt-segment.js +50 -0
- package/dist/dev/media/dom/text/resolve-vtt-segment.js.map +1 -0
- package/dist/dev/media/dom/text/text-track-slots.d.ts +24 -0
- package/dist/dev/media/dom/text/text-track-slots.d.ts.map +1 -0
- package/dist/dev/media/dom/text/text-track-slots.js +61 -0
- package/dist/dev/media/dom/text/text-track-slots.js.map +1 -0
- package/dist/dev/media/errors.d.ts +68 -0
- package/dist/dev/media/errors.d.ts.map +1 -0
- package/dist/dev/media/errors.js +60 -0
- package/dist/dev/media/errors.js.map +1 -0
- package/dist/dev/media/hls/parse-attributes.js +131 -0
- package/dist/dev/media/hls/parse-attributes.js.map +1 -0
- package/dist/dev/media/hls/parse-media-playlist.js +253 -0
- package/dist/dev/media/hls/parse-media-playlist.js.map +1 -0
- package/dist/dev/media/hls/parse-multivariant.js +234 -0
- package/dist/dev/media/hls/parse-multivariant.js.map +1 -0
- package/dist/dev/media/hls/reload-policy.js +63 -0
- package/dist/dev/media/hls/reload-policy.js.map +1 -0
- package/dist/dev/media/hls/resolve-url.js +9 -0
- package/dist/dev/media/hls/resolve-url.js.map +1 -0
- package/dist/dev/media/live-window.js +32 -0
- package/dist/dev/media/live-window.js.map +1 -0
- package/dist/dev/media/media-tracks/media-tracks.d.ts +46 -0
- package/dist/dev/media/media-tracks/media-tracks.d.ts.map +1 -0
- package/dist/dev/media/media-tracks/media-tracks.js +96 -0
- package/dist/dev/media/media-tracks/media-tracks.js.map +1 -0
- package/dist/dev/media/mp4/box.js +57 -0
- package/dist/dev/media/mp4/box.js.map +1 -0
- package/dist/dev/media/mp4/timestamp-origin.js +95 -0
- package/dist/dev/media/mp4/timestamp-origin.js.map +1 -0
- package/dist/dev/media/primitives/resolution.d.ts +22 -0
- package/dist/dev/media/primitives/resolution.d.ts.map +1 -0
- package/dist/dev/media/primitives/resolution.js +26 -0
- package/dist/dev/media/primitives/resolution.js.map +1 -0
- package/dist/dev/media/primitives/select-tracks.js +97 -0
- package/dist/dev/media/primitives/select-tracks.js.map +1 -0
- package/dist/dev/media/text/parse-vtt-timestamp-map.js +40 -0
- package/dist/dev/media/text/parse-vtt-timestamp-map.js.map +1 -0
- package/dist/dev/media/text/resolve-vtt-metadata.js +22 -0
- package/dist/dev/media/text/resolve-vtt-metadata.js.map +1 -0
- package/dist/dev/media/types/index.d.ts +306 -0
- package/dist/dev/media/types/index.d.ts.map +1 -0
- package/dist/dev/media/types/index.js +42 -0
- package/dist/dev/media/types/index.js.map +1 -0
- package/dist/dev/media/utils/cdn.d.ts +11 -0
- package/dist/dev/media/utils/cdn.d.ts.map +1 -0
- package/dist/dev/media/utils/cdn.js +50 -0
- package/dist/dev/media/utils/cdn.js.map +1 -0
- package/dist/dev/media/utils/preload.js +21 -0
- package/dist/dev/media/utils/preload.js.map +1 -0
- package/dist/dev/media/utils/track-selection.js +43 -0
- package/dist/dev/media/utils/track-selection.js.map +1 -0
- package/dist/dev/media/utils/tracks.js +146 -0
- package/dist/dev/media/utils/tracks.js.map +1 -0
- package/dist/dev/media-tracks.d.ts +3 -0
- package/dist/dev/media-tracks.js +2 -0
- package/dist/dev/network/bandwidth-estimator.d.ts +48 -0
- package/dist/dev/network/bandwidth-estimator.d.ts.map +1 -0
- package/dist/dev/network/bandwidth-estimator.js +95 -0
- package/dist/dev/network/bandwidth-estimator.js.map +1 -0
- package/dist/dev/network/chunked-stream-iterable.js +47 -0
- package/dist/dev/network/chunked-stream-iterable.js.map +1 -0
- package/dist/dev/network/ewma.js +68 -0
- package/dist/dev/network/ewma.js.map +1 -0
- package/dist/dev/network/fetch.js +108 -0
- package/dist/dev/network/fetch.js.map +1 -0
- package/dist/dev/playback/actors/dom/segment-loader.d.ts +44 -0
- package/dist/dev/playback/actors/dom/segment-loader.d.ts.map +1 -0
- package/dist/dev/playback/actors/dom/segment-loader.js +233 -0
- package/dist/dev/playback/actors/dom/segment-loader.js.map +1 -0
- package/dist/dev/playback/actors/dom/source-buffer.d.ts +45 -0
- package/dist/dev/playback/actors/dom/source-buffer.d.ts.map +1 -0
- package/dist/dev/playback/actors/dom/source-buffer.js +139 -0
- package/dist/dev/playback/actors/dom/source-buffer.js.map +1 -0
- package/dist/dev/playback/actors/dom/text-tracks.d.ts +3 -0
- package/dist/dev/playback/actors/dom/text-tracks.js +46 -0
- package/dist/dev/playback/actors/dom/text-tracks.js.map +1 -0
- package/dist/dev/playback/actors/text-track-segment-loader.d.ts +48 -0
- package/dist/dev/playback/actors/text-track-segment-loader.d.ts.map +1 -0
- package/dist/dev/playback/actors/text-track-segment-loader.js +138 -0
- package/dist/dev/playback/actors/text-track-segment-loader.js.map +1 -0
- package/dist/dev/playback/actors/text-tracks.d.ts +30 -0
- package/dist/dev/playback/actors/text-tracks.d.ts.map +1 -0
- package/dist/dev/playback/adapters/hls-audio/adapter.d.ts +11 -0
- package/dist/dev/playback/adapters/hls-audio/adapter.d.ts.map +1 -0
- package/dist/dev/playback/adapters/hls-audio/adapter.js +8 -0
- package/dist/dev/playback/adapters/hls-audio/adapter.js.map +1 -0
- package/dist/dev/playback/adapters/hls-audio/mixin.d.ts +52 -0
- package/dist/dev/playback/adapters/hls-audio/mixin.d.ts.map +1 -0
- package/dist/dev/playback/adapters/hls-audio/mixin.js +178 -0
- package/dist/dev/playback/adapters/hls-audio/mixin.js.map +1 -0
- package/dist/dev/playback/adapters/hls-background-video/adapter.d.ts +19 -0
- package/dist/dev/playback/adapters/hls-background-video/adapter.d.ts.map +1 -0
- package/dist/dev/playback/adapters/hls-background-video/adapter.js +17 -0
- package/dist/dev/playback/adapters/hls-background-video/adapter.js.map +1 -0
- package/dist/dev/playback/adapters/hls-background-video/host.d.ts +34 -0
- package/dist/dev/playback/adapters/hls-background-video/host.d.ts.map +1 -0
- package/dist/dev/playback/adapters/hls-background-video/host.js +56 -0
- package/dist/dev/playback/adapters/hls-background-video/host.js.map +1 -0
- package/dist/dev/playback/adapters/hls-background-video/mixin.d.ts +69 -0
- package/dist/dev/playback/adapters/hls-background-video/mixin.d.ts.map +1 -0
- package/dist/dev/playback/adapters/hls-background-video/mixin.js +191 -0
- package/dist/dev/playback/adapters/hls-background-video/mixin.js.map +1 -0
- package/dist/dev/playback/adapters/hls-video/adapter.d.ts +11 -0
- package/dist/dev/playback/adapters/hls-video/adapter.d.ts.map +1 -0
- package/dist/dev/playback/adapters/hls-video/adapter.js +11 -0
- package/dist/dev/playback/adapters/hls-video/adapter.js.map +1 -0
- package/dist/dev/playback/adapters/hls-video/error-surface.d.ts +17 -0
- package/dist/dev/playback/adapters/hls-video/error-surface.d.ts.map +1 -0
- package/dist/dev/playback/adapters/hls-video/error-surface.js +46 -0
- package/dist/dev/playback/adapters/hls-video/error-surface.js.map +1 -0
- package/dist/dev/playback/adapters/hls-video/media-tracks.d.ts +21 -0
- package/dist/dev/playback/adapters/hls-video/media-tracks.d.ts.map +1 -0
- package/dist/dev/playback/adapters/hls-video/media-tracks.js +125 -0
- package/dist/dev/playback/adapters/hls-video/media-tracks.js.map +1 -0
- package/dist/dev/playback/adapters/hls-video/mixin.d.ts +62 -0
- package/dist/dev/playback/adapters/hls-video/mixin.d.ts.map +1 -0
- package/dist/dev/playback/adapters/hls-video/mixin.js +299 -0
- package/dist/dev/playback/adapters/hls-video/mixin.js.map +1 -0
- package/dist/dev/playback/behaviors/calculate-presentation-duration.d.ts +23 -0
- package/dist/dev/playback/behaviors/calculate-presentation-duration.d.ts.map +1 -0
- package/dist/dev/playback/behaviors/calculate-presentation-duration.js +33 -0
- package/dist/dev/playback/behaviors/calculate-presentation-duration.js.map +1 -0
- package/dist/dev/playback/behaviors/collect-errors.d.ts +2 -0
- package/dist/dev/playback/behaviors/collect-errors.js +98 -0
- package/dist/dev/playback/behaviors/collect-errors.js.map +1 -0
- package/dist/dev/playback/behaviors/derive-cdn-priority.js +61 -0
- package/dist/dev/playback/behaviors/derive-cdn-priority.js.map +1 -0
- package/dist/dev/playback/behaviors/dom/airplay.js +188 -0
- package/dist/dev/playback/behaviors/dom/airplay.js.map +1 -0
- package/dist/dev/playback/behaviors/dom/apply-start-position.js +81 -0
- package/dist/dev/playback/behaviors/dom/apply-start-position.js.map +1 -0
- package/dist/dev/playback/behaviors/dom/end-of-stream.js +97 -0
- package/dist/dev/playback/behaviors/dom/end-of-stream.js.map +1 -0
- package/dist/dev/playback/behaviors/dom/load-segments.d.ts +69 -0
- package/dist/dev/playback/behaviors/dom/load-segments.d.ts.map +1 -0
- package/dist/dev/playback/behaviors/dom/load-segments.js +169 -0
- package/dist/dev/playback/behaviors/dom/load-segments.js.map +1 -0
- package/dist/dev/playback/behaviors/dom/recover-end-stall.js +72 -0
- package/dist/dev/playback/behaviors/dom/recover-end-stall.js.map +1 -0
- package/dist/dev/playback/behaviors/dom/seek-to-live-edge.js +113 -0
- package/dist/dev/playback/behaviors/dom/seek-to-live-edge.js.map +1 -0
- package/dist/dev/playback/behaviors/dom/setup-buffer-actors.js +181 -0
- package/dist/dev/playback/behaviors/dom/setup-buffer-actors.js.map +1 -0
- package/dist/dev/playback/behaviors/dom/setup-mediasource.js +100 -0
- package/dist/dev/playback/behaviors/dom/setup-mediasource.js.map +1 -0
- package/dist/dev/playback/behaviors/dom/setup-text-track-actors.d.ts +28 -0
- package/dist/dev/playback/behaviors/dom/setup-text-track-actors.d.ts.map +1 -0
- package/dist/dev/playback/behaviors/dom/setup-text-track-actors.js +40 -0
- package/dist/dev/playback/behaviors/dom/setup-text-track-actors.js.map +1 -0
- package/dist/dev/playback/behaviors/dom/sync-live-seekable-range.js +25 -0
- package/dist/dev/playback/behaviors/dom/sync-live-seekable-range.js.map +1 -0
- package/dist/dev/playback/behaviors/dom/sync-text-tracks.js +109 -0
- package/dist/dev/playback/behaviors/dom/sync-text-tracks.js.map +1 -0
- package/dist/dev/playback/behaviors/dom/track-current-time.d.ts +33 -0
- package/dist/dev/playback/behaviors/dom/track-current-time.d.ts.map +1 -0
- package/dist/dev/playback/behaviors/dom/track-current-time.js +50 -0
- package/dist/dev/playback/behaviors/dom/track-current-time.js.map +1 -0
- package/dist/dev/playback/behaviors/dom/track-load-triggers.d.ts +41 -0
- package/dist/dev/playback/behaviors/dom/track-load-triggers.d.ts.map +1 -0
- package/dist/dev/playback/behaviors/dom/track-load-triggers.js +86 -0
- package/dist/dev/playback/behaviors/dom/track-load-triggers.js.map +1 -0
- package/dist/dev/playback/behaviors/dom/track-playback-rate.d.ts +33 -0
- package/dist/dev/playback/behaviors/dom/track-playback-rate.d.ts.map +1 -0
- package/dist/dev/playback/behaviors/dom/track-playback-rate.js +35 -0
- package/dist/dev/playback/behaviors/dom/track-playback-rate.js.map +1 -0
- package/dist/dev/playback/behaviors/dom/track-player-resolution.d.ts +8 -0
- package/dist/dev/playback/behaviors/dom/track-player-resolution.d.ts.map +1 -0
- package/dist/dev/playback/behaviors/dom/track-player-resolution.js +53 -0
- package/dist/dev/playback/behaviors/dom/track-player-resolution.js.map +1 -0
- package/dist/dev/playback/behaviors/dom/track-screen-resolution.js +28 -0
- package/dist/dev/playback/behaviors/dom/track-screen-resolution.js.map +1 -0
- package/dist/dev/playback/behaviors/dom/update-mediasource-duration.js +98 -0
- package/dist/dev/playback/behaviors/dom/update-mediasource-duration.js.map +1 -0
- package/dist/dev/playback/behaviors/establish-start-media-time.d.ts +32 -0
- package/dist/dev/playback/behaviors/establish-start-media-time.d.ts.map +1 -0
- package/dist/dev/playback/behaviors/establish-start-media-time.js +187 -0
- package/dist/dev/playback/behaviors/establish-start-media-time.js.map +1 -0
- package/dist/dev/playback/behaviors/resolve-presentation.d.ts +8 -0
- package/dist/dev/playback/behaviors/resolve-presentation.d.ts.map +1 -0
- package/dist/dev/playback/behaviors/resolve-presentation.js +76 -0
- package/dist/dev/playback/behaviors/resolve-presentation.js.map +1 -0
- package/dist/dev/playback/behaviors/resolve-track.js +134 -0
- package/dist/dev/playback/behaviors/resolve-track.js.map +1 -0
- package/dist/dev/playback/behaviors/select-tracks.d.ts +61 -0
- package/dist/dev/playback/behaviors/select-tracks.d.ts.map +1 -0
- package/dist/dev/playback/behaviors/select-tracks.js +189 -0
- package/dist/dev/playback/behaviors/select-tracks.js.map +1 -0
- package/dist/dev/playback/behaviors/setup-failover-monitor.d.ts +11 -0
- package/dist/dev/playback/behaviors/setup-failover-monitor.d.ts.map +1 -0
- package/dist/dev/playback/behaviors/setup-failover-monitor.js +61 -0
- package/dist/dev/playback/behaviors/setup-failover-monitor.js.map +1 -0
- package/dist/dev/playback/behaviors/sync-preload.js +59 -0
- package/dist/dev/playback/behaviors/sync-preload.js.map +1 -0
- package/dist/dev/playback/behaviors/track-switching.d.ts +110 -0
- package/dist/dev/playback/behaviors/track-switching.d.ts.map +1 -0
- package/dist/dev/playback/behaviors/track-switching.js +407 -0
- package/dist/dev/playback/behaviors/track-switching.js.map +1 -0
- package/dist/dev/playback/engines/hls/engine-audio-only.d.ts +160 -0
- package/dist/dev/playback/engines/hls/engine-audio-only.d.ts.map +1 -0
- package/dist/dev/playback/engines/hls/engine-audio-only.js +94 -0
- package/dist/dev/playback/engines/hls/engine-audio-only.js.map +1 -0
- package/dist/dev/playback/engines/hls/engine-background-video.d.ts +131 -0
- package/dist/dev/playback/engines/hls/engine-background-video.d.ts.map +1 -0
- package/dist/dev/playback/engines/hls/engine-background-video.js +87 -0
- package/dist/dev/playback/engines/hls/engine-background-video.js.map +1 -0
- package/dist/dev/playback/engines/hls/engine.d.ts +289 -0
- package/dist/dev/playback/engines/hls/engine.d.ts.map +1 -0
- package/dist/dev/playback/engines/hls/engine.js +144 -0
- package/dist/dev/playback/engines/hls/engine.js.map +1 -0
- package/dist/dev/playback/primitives/derive-start-media-time.d.ts +16 -0
- package/dist/dev/playback/primitives/derive-start-media-time.d.ts.map +1 -0
- package/dist/dev/playback/primitives/error-messages.js +42 -0
- package/dist/dev/playback/primitives/error-messages.js.map +1 -0
- package/dist/dev/playback/primitives/failover-fetch.js +37 -0
- package/dist/dev/playback/primitives/failover-fetch.js.map +1 -0
- package/dist/dev/playback/primitives/head-peek.js +41 -0
- package/dist/dev/playback/primitives/head-peek.js.map +1 -0
- package/dist/dev/playback/primitives/live-window.js +63 -0
- package/dist/dev/playback/primitives/live-window.js.map +1 -0
- package/dist/dev/playback/primitives/relocation-pipelines.js +191 -0
- package/dist/dev/playback/primitives/relocation-pipelines.js.map +1 -0
- package/dist/dev/playback/primitives/report-track-conditions.d.ts +8 -0
- package/dist/dev/playback/primitives/report-track-conditions.d.ts.map +1 -0
- package/dist/dev/playback/primitives/report-track-conditions.js +74 -0
- package/dist/dev/playback/primitives/report-track-conditions.js.map +1 -0
- package/dist/dev/playback/primitives/segment-load-pipeline.d.ts +2 -0
- package/dist/dev/playback/primitives/segment-load-pipeline.js +96 -0
- package/dist/dev/playback/primitives/segment-load-pipeline.js.map +1 -0
- package/dist/dev/playback/primitives/selection-rules.d.ts +66 -0
- package/dist/dev/playback/primitives/selection-rules.d.ts.map +1 -0
- package/dist/dev/playback/primitives/selection-rules.js +115 -0
- package/dist/dev/playback/primitives/selection-rules.js.map +1 -0
- package/dist/dev/playback/primitives/source-buffer-messages.d.ts +40 -0
- package/dist/dev/playback/primitives/source-buffer-messages.d.ts.map +1 -0
- package/dist/dev/playback/primitives/text-segment-load-pipeline.d.ts +56 -0
- package/dist/dev/playback/primitives/text-segment-load-pipeline.d.ts.map +1 -0
- package/dist/dev/playback/primitives/text-segment-load-pipeline.js +36 -0
- package/dist/dev/playback/primitives/text-segment-load-pipeline.js.map +1 -0
- package/dist/dev/playback/primitives/text-track-messages.d.ts +14 -0
- package/dist/dev/playback/primitives/text-track-messages.d.ts.map +1 -0
- package/dist/dev/playback/primitives/track-types.js +53 -0
- package/dist/dev/playback/primitives/track-types.js.map +1 -0
- package/package.json +60 -41
- package/dist/adapter-25AtMN8s.d.ts +0 -719
- package/dist/adapter-25AtMN8s.d.ts.map +0 -1
- package/dist/adapter-CflgYzjF.js +0 -3556
- package/dist/adapter-CflgYzjF.js.map +0 -1
- package/dist/dom/index.d.ts +0 -221
- package/dist/dom/index.d.ts.map +0 -1
- package/dist/dom/index.js +0 -38
- package/dist/dom/index.js.map +0 -1
- package/dist/dom/playback-engine/index.d.ts +0 -2
- package/dist/dom/playback-engine/index.js +0 -4
- package/dist/index.d.ts +0 -13
- package/dist/index.d.ts.map +0 -1
- package/dist/index.js +0 -3
- package/dist/src-DRsS_H80.js +0 -14
- package/dist/src-DRsS_H80.js.map +0 -1
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
//#region src/playback/adapters/hls-background-video/host.ts
|
|
2
|
+
/**
|
|
3
|
+
* The `<video>` binding a background video uses: somewhere to keep the attached element, and the four properties the
|
|
4
|
+
* Media fixes on it.
|
|
5
|
+
*
|
|
6
|
+
* That is the whole surface anything here reaches. The engine drives playback, the element exposes `src` and nothing
|
|
7
|
+
* else, and the background player subscribes to no store features, so nothing asks a background video for
|
|
8
|
+
* `currentTime`, `play()`, picture-in-picture, fullscreen, forwarded events, or media components. Holding the host to
|
|
9
|
+
* what is reachable is what keeps this entry free of `@videojs/media`, and small enough to suit a component whose whole
|
|
10
|
+
* pitch is its size.
|
|
11
|
+
*
|
|
12
|
+
* An `EventTarget`, because a Media is one: the store and the element layers take anything they attach as an event
|
|
13
|
+
* source, and inheriting the three methods satisfies that for free rather than by stubbing them.
|
|
14
|
+
*
|
|
15
|
+
* ⚠️ It still implements too little to carry the rest of the media surface, which bounds what may consume it: a store
|
|
16
|
+
* feature reading a property outside this set gets `undefined` rather than an error. A Media needing more of that
|
|
17
|
+
* surface belongs on a host that provides it.
|
|
18
|
+
*/
|
|
19
|
+
var BackgroundVideoHost = class extends EventTarget {
|
|
20
|
+
#target = null;
|
|
21
|
+
attach(target) {
|
|
22
|
+
if (!target || this.#target === target) return;
|
|
23
|
+
this.#target = target;
|
|
24
|
+
}
|
|
25
|
+
detach() {
|
|
26
|
+
this.#target = null;
|
|
27
|
+
}
|
|
28
|
+
get loop() {
|
|
29
|
+
return this.#target?.loop ?? false;
|
|
30
|
+
}
|
|
31
|
+
set loop(value) {
|
|
32
|
+
if (this.#target) this.#target.loop = value;
|
|
33
|
+
}
|
|
34
|
+
get muted() {
|
|
35
|
+
return this.#target?.muted ?? false;
|
|
36
|
+
}
|
|
37
|
+
set muted(value) {
|
|
38
|
+
if (this.#target) this.#target.muted = value;
|
|
39
|
+
}
|
|
40
|
+
get autoplay() {
|
|
41
|
+
return this.#target?.autoplay ?? false;
|
|
42
|
+
}
|
|
43
|
+
set autoplay(value) {
|
|
44
|
+
if (this.#target) this.#target.autoplay = value;
|
|
45
|
+
}
|
|
46
|
+
get preload() {
|
|
47
|
+
return this.#target?.preload ?? "metadata";
|
|
48
|
+
}
|
|
49
|
+
set preload(value) {
|
|
50
|
+
if (this.#target) this.#target.preload = value;
|
|
51
|
+
}
|
|
52
|
+
};
|
|
53
|
+
//#endregion
|
|
54
|
+
export { BackgroundVideoHost };
|
|
55
|
+
|
|
56
|
+
//# sourceMappingURL=host.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"host.js","names":["#target"],"sources":["../../../../../src/playback/adapters/hls-background-video/host.ts"],"sourcesContent":["/**\n * The `<video>` binding a background video uses: somewhere to keep the attached element, and the four properties the\n * Media fixes on it.\n *\n * That is the whole surface anything here reaches. The engine drives playback, the element exposes `src` and nothing\n * else, and the background player subscribes to no store features, so nothing asks a background video for\n * `currentTime`, `play()`, picture-in-picture, fullscreen, forwarded events, or media components. Holding the host to\n * what is reachable is what keeps this entry free of `@videojs/media`, and small enough to suit a component whose whole\n * pitch is its size.\n *\n * An `EventTarget`, because a Media is one: the store and the element layers take anything they attach as an event\n * source, and inheriting the three methods satisfies that for free rather than by stubbing them.\n *\n * ⚠️ It still implements too little to carry the rest of the media surface, which bounds what may consume it: a store\n * feature reading a property outside this set gets `undefined` rather than an error. A Media needing more of that\n * surface belongs on a host that provides it.\n */\nexport class BackgroundVideoHost extends EventTarget {\n #target: HTMLVideoElement | null = null;\n\n attach(target: HTMLVideoElement): void {\n if (!target || this.#target === target) return;\n\n this.#target = target;\n }\n\n detach(): void {\n this.#target = null;\n }\n\n // Read back off the element rather than stored, so they describe what is\n // playing instead of what was asked for — see the adapter's note on why the\n // Media declares none of these itself.\n get loop(): boolean {\n return this.#target?.loop ?? false;\n }\n\n set loop(value: boolean) {\n if (this.#target) this.#target.loop = value;\n }\n\n get muted(): boolean {\n return this.#target?.muted ?? false;\n }\n\n set muted(value: boolean) {\n if (this.#target) this.#target.muted = value;\n }\n\n get autoplay(): boolean {\n return this.#target?.autoplay ?? false;\n }\n\n set autoplay(value: boolean) {\n if (this.#target) this.#target.autoplay = value;\n }\n\n get preload(): HTMLVideoElement['preload'] {\n return this.#target?.preload ?? 'metadata';\n }\n\n set preload(value: HTMLVideoElement['preload']) {\n if (this.#target) this.#target.preload = value;\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;AAiBA,IAAa,sBAAb,cAAyC,YAAY;CACnD,UAAmC;CAEnC,OAAO,QAAgC;EACrC,IAAI,CAAC,UAAU,KAAKA,YAAY,QAAQ;EAExC,KAAKA,UAAU;CACjB;CAEA,SAAe;EACb,KAAKA,UAAU;CACjB;CAKA,IAAI,OAAgB;EAClB,OAAO,KAAKA,SAAS,QAAQ;CAC/B;CAEA,IAAI,KAAK,OAAgB;EACvB,IAAI,KAAKA,SAAS,KAAKA,QAAQ,OAAO;CACxC;CAEA,IAAI,QAAiB;EACnB,OAAO,KAAKA,SAAS,SAAS;CAChC;CAEA,IAAI,MAAM,OAAgB;EACxB,IAAI,KAAKA,SAAS,KAAKA,QAAQ,QAAQ;CACzC;CAEA,IAAI,WAAoB;EACtB,OAAO,KAAKA,SAAS,YAAY;CACnC;CAEA,IAAI,SAAS,OAAgB;EAC3B,IAAI,KAAKA,SAAS,KAAKA,QAAQ,WAAW;CAC5C;CAEA,IAAI,UAAuC;EACzC,OAAO,KAAKA,SAAS,WAAW;CAClC;CAEA,IAAI,QAAQ,OAAoC;EAC9C,IAAI,KAAKA,SAAS,KAAKA,QAAQ,UAAU;CAC3C;AACF"}
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import { Composition } from "../../../core/composition/create-composition.js";
|
|
2
|
+
import { HlsVideoMediaError } from "../hls-video/error-surface.js";
|
|
3
|
+
import { BackgroundVideoEngineContext, BackgroundVideoEngineState } from "../../engines/hls/engine-background-video.js";
|
|
4
|
+
import { Constructor, MixinReturn } from "@videojs/utils/types";
|
|
5
|
+
//#region src/playback/adapters/hls-background-video/mixin.d.ts
|
|
6
|
+
interface HlsBackgroundVideoAdapterProps {
|
|
7
|
+
src: string;
|
|
8
|
+
}
|
|
9
|
+
interface HlsBackgroundVideoAdapterAPI extends HlsBackgroundVideoAdapterProps {
|
|
10
|
+
readonly engine: Composition<BackgroundVideoEngineState, BackgroundVideoEngineContext>;
|
|
11
|
+
readonly error: HlsVideoMediaError | null;
|
|
12
|
+
attach(mediaElement: HTMLMediaElement): void;
|
|
13
|
+
detach(): void;
|
|
14
|
+
destroy(): void;
|
|
15
|
+
play(): Promise<void>;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Mixin that adds the background-video SPF playback engine to any base class, for an HLS URL.
|
|
19
|
+
*
|
|
20
|
+
* `src` is the whole input surface, and `error` is the one output: nothing about an unplayable source reaches the media
|
|
21
|
+
* element on its own here — an unsupported container, encryption with no EME, and an undecodable codec all leave
|
|
22
|
+
* `HTMLMediaElement.error` null with the element stalled at `readyState 0` (measured on Chromium and WebKit) — so a
|
|
23
|
+
* consumer that watched only the `<video>` would see a source that never appears and never says why. The engine reports
|
|
24
|
+
* each condition onto `engine.state.errors` and logs it; this adapter promotes the first fatal one, mapping it the same
|
|
25
|
+
* way the video and audio Medias map theirs. See `internal/design/spf/features/errors.md`.
|
|
26
|
+
*
|
|
27
|
+
* Selection pins the largest rendition that _fits the screen_, and holds it for the session. The manifest is still the
|
|
28
|
+
* better place to narrow further: a delivery param — `?max_resolution=720p` on a Mux stream URL, for one — keeps the
|
|
29
|
+
* renditions it excludes out of the manifest entirely, rather than fetched-then-unpicked.
|
|
30
|
+
*
|
|
31
|
+
* The pin is given up, never moved, if the pick turns out to be unplayable: the container is only known once a media
|
|
32
|
+
* playlist resolves, which is after the pick is made, so the selection clears rather than quietly appending bytes
|
|
33
|
+
* nothing can decode.
|
|
34
|
+
*
|
|
35
|
+
* `<mux-background-video>` in html and react is this same Media under a Mux-flavored name — an alias, not a variant.
|
|
36
|
+
* Nothing about the surface changes with the name.
|
|
37
|
+
*
|
|
38
|
+
* Everything else the use case fixes rather than exposes: video-only, looping, muted, autoplaying, loading as soon as
|
|
39
|
+
* there is a source. `attach` writes that onto the element and nothing here declares `loop` / `muted` / `autoplay` /
|
|
40
|
+
* `preload` of its own — a host-bound Media inherits all four from the host already, and shadowing them with fixed
|
|
41
|
+
* values would only make reads describe an intention rather than what the element is doing.
|
|
42
|
+
*
|
|
43
|
+
* A new src re-resolves the presentation, tearing down the state, SourceBuffers, and in-flight requests the previous
|
|
44
|
+
* one built before the next begins. The engine instance and the attached media element are both kept, so neither has to
|
|
45
|
+
* be rewired.
|
|
46
|
+
*
|
|
47
|
+
* @example
|
|
48
|
+
* class HlsBackgroundVideoAdapter extends HlsBackgroundVideoMixin(BackgroundVideoHost) {}
|
|
49
|
+
*
|
|
50
|
+
* const media = new HlsBackgroundVideoAdapter();
|
|
51
|
+
* media.attach(document.querySelector('video'));
|
|
52
|
+
* media.src = 'https://stream.mux.com/PLAYBACK_ID.m3u8?max_resolution=720p';
|
|
53
|
+
* media.play();
|
|
54
|
+
*
|
|
55
|
+
* @fires error - Fired when a fatal condition is reported. Read `error` for it.
|
|
56
|
+
*/
|
|
57
|
+
declare function HlsBackgroundVideoMixin<Base extends Constructor<any>>(BaseClass: Base): MixinReturn<Base, HlsBackgroundVideoAdapterAPI> & {
|
|
58
|
+
readonly defaultProps: HlsBackgroundVideoAdapterProps;
|
|
59
|
+
};
|
|
60
|
+
declare const HlsBackgroundVideoAdapterCore_base: Constructor<{} & HlsBackgroundVideoAdapterAPI, any[]> & Omit<{
|
|
61
|
+
new (): {};
|
|
62
|
+
}, "prototype"> & {
|
|
63
|
+
readonly defaultProps: HlsBackgroundVideoAdapterProps;
|
|
64
|
+
};
|
|
65
|
+
/** Standalone SPF background-video adapter with no base class. */
|
|
66
|
+
declare class HlsBackgroundVideoAdapterCore extends HlsBackgroundVideoAdapterCore_base {}
|
|
67
|
+
//#endregion
|
|
68
|
+
export { HlsBackgroundVideoAdapterAPI, HlsBackgroundVideoAdapterCore, HlsBackgroundVideoAdapterProps, HlsBackgroundVideoMixin, type HlsVideoMediaError };
|
|
69
|
+
//# sourceMappingURL=mixin.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mixin.d.ts","names":[],"sources":["../../../../../src/playback/adapters/hls-background-video/mixin.ts"],"mappings":";;;;;UA0BiB;EACf;;UAGe,qCAAqC;WAC3C,QAAQ,YAAY,4BAA4B;WAChD,OAAO;EAChB,OAAO,cAAc;EACrB;EACA;EACA,QAAQ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAmEM,wBAAwB,aAAa,kBAAkB,WAAW,OAsMpC,YAAY,MAAM;WACnD,cAAc;;;;;WAAA,cAAA;;;cAKd,sCAAsC"}
|
|
@@ -0,0 +1,191 @@
|
|
|
1
|
+
import { effect } from "../../../core/signals/effect.js";
|
|
2
|
+
import { SVTA_NO_SUPPORTED_VIDEO_TRACK, SVTA_UNSUPPORTED_DRM_SYSTEM, SVTA_UNSUPPORTED_PLAYBACK_FEATURE, SVTA_UNSUPPORTED_VIDEO_FORMAT } from "../../../media/errors.js";
|
|
3
|
+
import { createBackgroundVideoEngine } from "../../engines/hls/engine-background-video.js";
|
|
4
|
+
import { UNPLAYABLE_SOURCE_MESSAGE } from "../../primitives/error-messages.js";
|
|
5
|
+
import { firstFatal, hasUnsupportedFeatureCause } from "../hls-video/error-surface.js";
|
|
6
|
+
//#region src/playback/adapters/hls-background-video/mixin.ts
|
|
7
|
+
/**
|
|
8
|
+
* Which reported conditions this composition treats as **fatal** — the ones that reach `error` and fire `'error'`.
|
|
9
|
+
* Severity isn't part of an SVTA code (§Approach: "impact varies with player implementation"), so it's decided at this
|
|
10
|
+
* boundary rather than by the reporter.
|
|
11
|
+
*
|
|
12
|
+
* **Causes are fatal here, unlike on the other two adapters.** There, a cause is context — one unplayable rendition
|
|
13
|
+
* doesn't fail a source whose others still play, and a verdict follows if the type empties. In the pinned variant a
|
|
14
|
+
* cause _is_ the verdict: only the pinned rendition's playlist is ever resolved, so a cause can only be about the pick
|
|
15
|
+
* itself, and dropping that pick is final — nothing here re-picks (that is what `switchVideoTrack` exists for, and this
|
|
16
|
+
* engine doesn't compose it). Measured on Chromium: an MPEG-TS source reports 1004 and an encrypted one 4008, each with
|
|
17
|
+
* no verdict behind it, and the element then sits at `readyState 0` with `error` null forever.
|
|
18
|
+
*
|
|
19
|
+
* The verdict is still listed, for the shapes that report nothing else: no video renditions at all, or a ladder pruned
|
|
20
|
+
* before anything resolves — both of which `reportAbsentTrackType` covers from the tail of the constraint chain.
|
|
21
|
+
*
|
|
22
|
+
* First-fatal-wins then surfaces the cause rather than the verdict when both are present, which is the more specific of
|
|
23
|
+
* the two.
|
|
24
|
+
*/
|
|
25
|
+
const FATAL_SVTA_CODES = /* @__PURE__ */ new Set([
|
|
26
|
+
SVTA_NO_SUPPORTED_VIDEO_TRACK,
|
|
27
|
+
SVTA_UNSUPPORTED_VIDEO_FORMAT,
|
|
28
|
+
SVTA_UNSUPPORTED_DRM_SYSTEM
|
|
29
|
+
]);
|
|
30
|
+
/**
|
|
31
|
+
* Mixin that adds the background-video SPF playback engine to any base class, for an HLS URL.
|
|
32
|
+
*
|
|
33
|
+
* `src` is the whole input surface, and `error` is the one output: nothing about an unplayable source reaches the media
|
|
34
|
+
* element on its own here — an unsupported container, encryption with no EME, and an undecodable codec all leave
|
|
35
|
+
* `HTMLMediaElement.error` null with the element stalled at `readyState 0` (measured on Chromium and WebKit) — so a
|
|
36
|
+
* consumer that watched only the `<video>` would see a source that never appears and never says why. The engine reports
|
|
37
|
+
* each condition onto `engine.state.errors` and logs it; this adapter promotes the first fatal one, mapping it the same
|
|
38
|
+
* way the video and audio Medias map theirs. See `internal/design/spf/features/errors.md`.
|
|
39
|
+
*
|
|
40
|
+
* Selection pins the largest rendition that _fits the screen_, and holds it for the session. The manifest is still the
|
|
41
|
+
* better place to narrow further: a delivery param — `?max_resolution=720p` on a Mux stream URL, for one — keeps the
|
|
42
|
+
* renditions it excludes out of the manifest entirely, rather than fetched-then-unpicked.
|
|
43
|
+
*
|
|
44
|
+
* The pin is given up, never moved, if the pick turns out to be unplayable: the container is only known once a media
|
|
45
|
+
* playlist resolves, which is after the pick is made, so the selection clears rather than quietly appending bytes
|
|
46
|
+
* nothing can decode.
|
|
47
|
+
*
|
|
48
|
+
* `<mux-background-video>` in html and react is this same Media under a Mux-flavored name — an alias, not a variant.
|
|
49
|
+
* Nothing about the surface changes with the name.
|
|
50
|
+
*
|
|
51
|
+
* Everything else the use case fixes rather than exposes: video-only, looping, muted, autoplaying, loading as soon as
|
|
52
|
+
* there is a source. `attach` writes that onto the element and nothing here declares `loop` / `muted` / `autoplay` /
|
|
53
|
+
* `preload` of its own — a host-bound Media inherits all four from the host already, and shadowing them with fixed
|
|
54
|
+
* values would only make reads describe an intention rather than what the element is doing.
|
|
55
|
+
*
|
|
56
|
+
* A new src re-resolves the presentation, tearing down the state, SourceBuffers, and in-flight requests the previous
|
|
57
|
+
* one built before the next begins. The engine instance and the attached media element are both kept, so neither has to
|
|
58
|
+
* be rewired.
|
|
59
|
+
*
|
|
60
|
+
* @example
|
|
61
|
+
* class HlsBackgroundVideoAdapter extends HlsBackgroundVideoMixin(BackgroundVideoHost) {}
|
|
62
|
+
*
|
|
63
|
+
* const media = new HlsBackgroundVideoAdapter();
|
|
64
|
+
* media.attach(document.querySelector('video'));
|
|
65
|
+
* media.src = 'https://stream.mux.com/PLAYBACK_ID.m3u8?max_resolution=720p';
|
|
66
|
+
* media.play();
|
|
67
|
+
*
|
|
68
|
+
* @fires error - Fired when a fatal condition is reported. Read `error` for it.
|
|
69
|
+
*/
|
|
70
|
+
function HlsBackgroundVideoMixin(BaseClass) {
|
|
71
|
+
class HlsBackgroundVideoImpl extends BaseClass {
|
|
72
|
+
static defaultProps = { src: "" };
|
|
73
|
+
#engine;
|
|
74
|
+
#config;
|
|
75
|
+
#signals;
|
|
76
|
+
#error = null;
|
|
77
|
+
/**
|
|
78
|
+
* The _reported_ condition currently surfaced, which is what the re-fire latch keys on. Not `#error.code`: that's
|
|
79
|
+
* the code this adapter chose to surface, and the substitution below can make the two differ.
|
|
80
|
+
*/
|
|
81
|
+
#reportedCode = null;
|
|
82
|
+
#stopErrorSync;
|
|
83
|
+
/** Pending loadstart listener from a deferred play() retry, if any. */
|
|
84
|
+
#loadstartListener = null;
|
|
85
|
+
constructor(...args) {
|
|
86
|
+
super(...args);
|
|
87
|
+
const { config } = args?.[0] ?? {};
|
|
88
|
+
this.#config = config;
|
|
89
|
+
this.#engine = this.#createEngine();
|
|
90
|
+
this.#stopErrorSync = effect(() => {
|
|
91
|
+
const errors = this.#signals.state.errors.get();
|
|
92
|
+
this.#setError(firstFatal(errors, FATAL_SVTA_CODES), errors);
|
|
93
|
+
});
|
|
94
|
+
}
|
|
95
|
+
get engine() {
|
|
96
|
+
return this.#engine;
|
|
97
|
+
}
|
|
98
|
+
/**
|
|
99
|
+
* The current fatal condition, or `null`. Only _fatal_ ones appear here — the engine reports non-fatal ones too
|
|
100
|
+
* (they stay in `engine.state.errors`), and promoting them would say playback had failed when it hadn't. Which ones
|
|
101
|
+
* are fatal is wider here than on the video and audio Medias; see {@link FATAL_SVTA_CODES}. Resets per source.
|
|
102
|
+
* Fires `'error'` when set.
|
|
103
|
+
*
|
|
104
|
+
* Mapped the same way theirs are: a sequence holding an unimplemented-capability cause surfaces as
|
|
105
|
+
* {@link SVTA_UNSUPPORTED_PLAYBACK_FEATURE} (99001) with the specifics logged, because "this player can't play this
|
|
106
|
+
* source" is what a consumer can act on, where a raw container or DRM code only says what to go and look up.
|
|
107
|
+
*/
|
|
108
|
+
get error() {
|
|
109
|
+
return this.#error;
|
|
110
|
+
}
|
|
111
|
+
#setError(reported, errors) {
|
|
112
|
+
if (!reported) {
|
|
113
|
+
this.#error = null;
|
|
114
|
+
this.#reportedCode = null;
|
|
115
|
+
return;
|
|
116
|
+
}
|
|
117
|
+
if (this.#reportedCode === reported.code) return;
|
|
118
|
+
this.#reportedCode = reported.code;
|
|
119
|
+
console.error(UNPLAYABLE_SOURCE_MESSAGE, { conditions: errors });
|
|
120
|
+
this.#error = {
|
|
121
|
+
code: hasUnsupportedFeatureCause(errors) ? SVTA_UNSUPPORTED_PLAYBACK_FEATURE : reported.code,
|
|
122
|
+
message: reported.message ?? "",
|
|
123
|
+
...reported.data === void 0 ? {} : { data: reported.data }
|
|
124
|
+
};
|
|
125
|
+
this.dispatchEvent?.(new Event("error"));
|
|
126
|
+
}
|
|
127
|
+
attach(mediaElement) {
|
|
128
|
+
super.attach?.(mediaElement);
|
|
129
|
+
mediaElement.loop = true;
|
|
130
|
+
mediaElement.muted = true;
|
|
131
|
+
mediaElement.autoplay = true;
|
|
132
|
+
mediaElement.preload = "auto";
|
|
133
|
+
this.#signals.context.mediaElement.set(mediaElement);
|
|
134
|
+
}
|
|
135
|
+
detach() {
|
|
136
|
+
this.#cancelPendingPlay();
|
|
137
|
+
this.#signals.context.mediaElement.set(void 0);
|
|
138
|
+
super.detach?.();
|
|
139
|
+
}
|
|
140
|
+
destroy() {
|
|
141
|
+
this.#cancelPendingPlay();
|
|
142
|
+
this.#stopErrorSync();
|
|
143
|
+
this.#engine.destroy();
|
|
144
|
+
}
|
|
145
|
+
get src() {
|
|
146
|
+
return this.#signals.state.presentation.get()?.url ?? "";
|
|
147
|
+
}
|
|
148
|
+
set src(value) {
|
|
149
|
+
if (value === this.src) return;
|
|
150
|
+
this.#cancelPendingPlay();
|
|
151
|
+
this.#signals.state.presentation.set(value ? { url: value } : void 0);
|
|
152
|
+
}
|
|
153
|
+
async play() {
|
|
154
|
+
const mediaElement = this.#signals.context.mediaElement.get();
|
|
155
|
+
if (!mediaElement) return Promise.reject(/* @__PURE__ */ new Error("HlsBackgroundVideoAdapterCore: no media element attached"));
|
|
156
|
+
try {
|
|
157
|
+
return await mediaElement.play();
|
|
158
|
+
} catch (err) {
|
|
159
|
+
if (this.src) return new Promise((resolve, reject) => {
|
|
160
|
+
const listener = () => {
|
|
161
|
+
this.#loadstartListener = null;
|
|
162
|
+
mediaElement.play().then(resolve, reject);
|
|
163
|
+
};
|
|
164
|
+
this.#loadstartListener = listener;
|
|
165
|
+
mediaElement.addEventListener("loadstart", listener, { once: true });
|
|
166
|
+
});
|
|
167
|
+
throw err;
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
#createEngine() {
|
|
171
|
+
return createBackgroundVideoEngine({
|
|
172
|
+
...this.#config,
|
|
173
|
+
onSignalsReady: (signals) => {
|
|
174
|
+
this.#signals = signals;
|
|
175
|
+
}
|
|
176
|
+
});
|
|
177
|
+
}
|
|
178
|
+
#cancelPendingPlay() {
|
|
179
|
+
if (!this.#loadstartListener) return;
|
|
180
|
+
this.#signals.context.mediaElement.get()?.removeEventListener("loadstart", this.#loadstartListener);
|
|
181
|
+
this.#loadstartListener = null;
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
return HlsBackgroundVideoImpl;
|
|
185
|
+
}
|
|
186
|
+
/** Standalone SPF background-video adapter with no base class. */
|
|
187
|
+
var HlsBackgroundVideoAdapterCore = class extends HlsBackgroundVideoMixin(class {}) {};
|
|
188
|
+
//#endregion
|
|
189
|
+
export { HlsBackgroundVideoAdapterCore, HlsBackgroundVideoMixin };
|
|
190
|
+
|
|
191
|
+
//# sourceMappingURL=mixin.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mixin.js","names":["#config","#engine","#createEngine","#stopErrorSync","#signals","#setError","#error","#reportedCode","#cancelPendingPlay","#loadstartListener"],"sources":["../../../../../src/playback/adapters/hls-background-video/mixin.ts"],"sourcesContent":["import type { Constructor, MixinReturn } from '@videojs/utils/types';\n\nimport type { Composition } from '../../../core/composition/create-composition';\nimport { effect } from '../../../core/signals/effect';\nimport {\n SVTA_NO_SUPPORTED_VIDEO_TRACK,\n SVTA_UNSUPPORTED_DRM_SYSTEM,\n SVTA_UNSUPPORTED_PLAYBACK_FEATURE,\n SVTA_UNSUPPORTED_VIDEO_FORMAT,\n type SvtaError,\n} from '../../../media/errors';\nimport {\n type BackgroundVideoEngineConfig,\n type BackgroundVideoEngineContext,\n type BackgroundVideoEngineSignals,\n type BackgroundVideoEngineState,\n createBackgroundVideoEngine,\n} from '../../engines/hls/engine-background-video';\nimport { UNPLAYABLE_SOURCE_MESSAGE } from '../../primitives/error-messages';\nimport { firstFatal, type HlsVideoMediaError, hasUnsupportedFeatureCause } from '../hls-video/error-surface';\n\n// The same error shape the video and audio Medias expose, under the name they\n// publish it as — one type for all three surfaces rather than a background-flavored\n// copy of it.\nexport type { HlsVideoMediaError } from '../hls-video/error-surface';\n\nexport interface HlsBackgroundVideoAdapterProps {\n src: string;\n}\n\nexport interface HlsBackgroundVideoAdapterAPI extends HlsBackgroundVideoAdapterProps {\n readonly engine: Composition<BackgroundVideoEngineState, BackgroundVideoEngineContext>;\n readonly error: HlsVideoMediaError | null;\n attach(mediaElement: HTMLMediaElement): void;\n detach(): void;\n destroy(): void;\n play(): Promise<void>;\n}\n\n/**\n * Which reported conditions this composition treats as **fatal** — the ones that reach `error` and fire `'error'`.\n * Severity isn't part of an SVTA code (§Approach: \"impact varies with player implementation\"), so it's decided at this\n * boundary rather than by the reporter.\n *\n * **Causes are fatal here, unlike on the other two adapters.** There, a cause is context — one unplayable rendition\n * doesn't fail a source whose others still play, and a verdict follows if the type empties. In the pinned variant a\n * cause _is_ the verdict: only the pinned rendition's playlist is ever resolved, so a cause can only be about the pick\n * itself, and dropping that pick is final — nothing here re-picks (that is what `switchVideoTrack` exists for, and this\n * engine doesn't compose it). Measured on Chromium: an MPEG-TS source reports 1004 and an encrypted one 4008, each with\n * no verdict behind it, and the element then sits at `readyState 0` with `error` null forever.\n *\n * The verdict is still listed, for the shapes that report nothing else: no video renditions at all, or a ladder pruned\n * before anything resolves — both of which `reportAbsentTrackType` covers from the tail of the constraint chain.\n *\n * First-fatal-wins then surfaces the cause rather than the verdict when both are present, which is the more specific of\n * the two.\n */\nconst FATAL_SVTA_CODES: ReadonlySet<number> = new Set<number>([\n SVTA_NO_SUPPORTED_VIDEO_TRACK,\n SVTA_UNSUPPORTED_VIDEO_FORMAT,\n SVTA_UNSUPPORTED_DRM_SYSTEM,\n]);\n\n/**\n * Mixin that adds the background-video SPF playback engine to any base class, for an HLS URL.\n *\n * `src` is the whole input surface, and `error` is the one output: nothing about an unplayable source reaches the media\n * element on its own here — an unsupported container, encryption with no EME, and an undecodable codec all leave\n * `HTMLMediaElement.error` null with the element stalled at `readyState 0` (measured on Chromium and WebKit) — so a\n * consumer that watched only the `<video>` would see a source that never appears and never says why. The engine reports\n * each condition onto `engine.state.errors` and logs it; this adapter promotes the first fatal one, mapping it the same\n * way the video and audio Medias map theirs. See `internal/design/spf/features/errors.md`.\n *\n * Selection pins the largest rendition that _fits the screen_, and holds it for the session. The manifest is still the\n * better place to narrow further: a delivery param — `?max_resolution=720p` on a Mux stream URL, for one — keeps the\n * renditions it excludes out of the manifest entirely, rather than fetched-then-unpicked.\n *\n * The pin is given up, never moved, if the pick turns out to be unplayable: the container is only known once a media\n * playlist resolves, which is after the pick is made, so the selection clears rather than quietly appending bytes\n * nothing can decode.\n *\n * `<mux-background-video>` in html and react is this same Media under a Mux-flavored name — an alias, not a variant.\n * Nothing about the surface changes with the name.\n *\n * Everything else the use case fixes rather than exposes: video-only, looping, muted, autoplaying, loading as soon as\n * there is a source. `attach` writes that onto the element and nothing here declares `loop` / `muted` / `autoplay` /\n * `preload` of its own — a host-bound Media inherits all four from the host already, and shadowing them with fixed\n * values would only make reads describe an intention rather than what the element is doing.\n *\n * A new src re-resolves the presentation, tearing down the state, SourceBuffers, and in-flight requests the previous\n * one built before the next begins. The engine instance and the attached media element are both kept, so neither has to\n * be rewired.\n *\n * @example\n * class HlsBackgroundVideoAdapter extends HlsBackgroundVideoMixin(BackgroundVideoHost) {}\n *\n * const media = new HlsBackgroundVideoAdapter();\n * media.attach(document.querySelector('video'));\n * media.src = 'https://stream.mux.com/PLAYBACK_ID.m3u8?max_resolution=720p';\n * media.play();\n *\n * @fires error - Fired when a fatal condition is reported. Read `error` for it.\n */\nexport function HlsBackgroundVideoMixin<Base extends Constructor<any>>(BaseClass: Base) {\n class HlsBackgroundVideoImpl extends BaseClass {\n static readonly defaultProps: HlsBackgroundVideoAdapterProps = {\n src: '',\n };\n\n #engine: Composition<BackgroundVideoEngineState, BackgroundVideoEngineContext>;\n #config: BackgroundVideoEngineConfig;\n #signals!: BackgroundVideoEngineSignals;\n #error: HlsVideoMediaError | null = null;\n /**\n * The _reported_ condition currently surfaced, which is what the re-fire latch keys on. Not `#error.code`: that's\n * the code this adapter chose to surface, and the substitution below can make the two differ.\n */\n #reportedCode: number | null = null;\n #stopErrorSync: () => void;\n\n /** Pending loadstart listener from a deferred play() retry, if any. */\n #loadstartListener: (() => void) | null = null;\n\n constructor(...args: any[]) {\n super(...args);\n\n const { config } = args?.[0] ?? {};\n\n this.#config = config;\n this.#engine = this.#createEngine();\n\n // Promote the first fatal condition out of the engine's reported sequence\n // onto this surface. Clearing rides the same signal: `collectErrors` resets\n // the slot per source, so a new source starts with no error without this\n // needing its own source-change hook.\n this.#stopErrorSync = effect(() => {\n const errors = this.#signals.state.errors.get();\n\n this.#setError(firstFatal(errors, FATAL_SVTA_CODES), errors);\n });\n }\n\n get engine(): Composition<BackgroundVideoEngineState, BackgroundVideoEngineContext> {\n return this.#engine;\n }\n\n /**\n * The current fatal condition, or `null`. Only _fatal_ ones appear here — the engine reports non-fatal ones too\n * (they stay in `engine.state.errors`), and promoting them would say playback had failed when it hadn't. Which ones\n * are fatal is wider here than on the video and audio Medias; see {@link FATAL_SVTA_CODES}. Resets per source.\n * Fires `'error'` when set.\n *\n * Mapped the same way theirs are: a sequence holding an unimplemented-capability cause surfaces as\n * {@link SVTA_UNSUPPORTED_PLAYBACK_FEATURE} (99001) with the specifics logged, because \"this player can't play this\n * source\" is what a consumer can act on, where a raw container or DRM code only says what to go and look up.\n */\n get error(): HlsVideoMediaError | null {\n return this.#error;\n }\n\n #setError(reported: SvtaError | undefined, errors: readonly SvtaError[] | undefined): void {\n if (!reported) {\n // Cleared (new source). No event: `'error'` announces a failure, and\n // consumers reset their own copy on source change.\n this.#error = null;\n this.#reportedCode = null;\n return;\n }\n\n // Keyed on the code, not the object: a later append re-runs this effect\n // with an equal-but-new array, and re-firing `'error'` for a condition\n // already surfaced would look like a second failure.\n if (this.#reportedCode === reported.code) return;\n\n this.#reportedCode = reported.code;\n\n // Logged for every fatal condition, not just the substituted ones: a source\n // with no video renditions is as dead as an unplayable container, and it\n // would otherwise reach a developer as a bare code. One generic sentence\n // rather than one per case — the conditions beside it carry the specifics.\n //\n // Prose stays here rather than on `error.message`, matching the other two:\n // viewer-facing copy is the consumer's to localize, and a background video\n // has no chrome to put it in anyway.\n console.error(UNPLAYABLE_SOURCE_MESSAGE, { conditions: errors });\n\n this.#error = {\n code: hasUnsupportedFeatureCause(errors) ? SVTA_UNSUPPORTED_PLAYBACK_FEATURE : reported.code,\n message: reported.message ?? '',\n ...(reported.data === undefined ? {} : { data: reported.data }),\n };\n // Optional-chained: with an EventTarget-less base (`HlsBackgroundVideoAdapterCore`\n // standalone) there's nowhere to dispatch.\n this.dispatchEvent?.(new Event('error'));\n }\n\n // -------------------------------------------------------------------------\n // Media element lifecycle\n // -------------------------------------------------------------------------\n\n attach(mediaElement: HTMLMediaElement): void {\n super.attach?.(mediaElement);\n // The one place the fixed behavior is stated. Muted and autoplay are what\n // let it start without a gesture, loop is the defining behavior, and\n // `preload` says out loud what the engine does regardless — it subtracts\n // preload monitoring and loads from the moment it has a source.\n mediaElement.loop = true;\n mediaElement.muted = true;\n mediaElement.autoplay = true;\n mediaElement.preload = 'auto';\n\n this.#signals.context.mediaElement.set(mediaElement);\n }\n\n detach(): void {\n this.#cancelPendingPlay();\n this.#signals.context.mediaElement.set(undefined);\n super.detach?.();\n }\n\n destroy(): void {\n this.#cancelPendingPlay();\n this.#stopErrorSync();\n this.#engine.destroy();\n }\n\n // -------------------------------------------------------------------------\n // src — synchronous IDL attribute (WHATWG §4.8.11.2)\n // -------------------------------------------------------------------------\n\n get src(): string {\n return this.#signals.state.presentation.get()?.url ?? '';\n }\n\n set src(value: string) {\n // Same line the HLS Medias draw: the presentation is set from a fresh\n // object every time, so re-resolving a URL already playing would restart\n // it for no reason.\n if (value === this.src) return;\n\n this.#cancelPendingPlay();\n this.#signals.state.presentation.set(value ? { url: value } : undefined);\n }\n\n // -------------------------------------------------------------------------\n // play() — WHATWG §4.8.11.8\n // Delegates to the attached media element's native play().\n // -------------------------------------------------------------------------\n\n async play(): Promise<void> {\n const mediaElement = this.#signals.context.mediaElement.get();\n if (!mediaElement) return Promise.reject(new Error('HlsBackgroundVideoAdapterCore: no media element attached'));\n\n try {\n return await mediaElement.play();\n } catch (err) {\n // If we have a pending HLS source, the rejection may be because MSE\n // hasn't attached a blob URL yet. Wait for loadstart (src assigned by\n // MSE setup) and retry once.\n if (this.src) {\n return new Promise<void>((resolve, reject) => {\n const listener = () => {\n this.#loadstartListener = null;\n mediaElement.play().then(resolve, reject);\n };\n\n this.#loadstartListener = listener;\n mediaElement.addEventListener('loadstart', listener, { once: true });\n });\n }\n\n throw err;\n }\n }\n\n // -------------------------------------------------------------------------\n // Private\n // -------------------------------------------------------------------------\n\n #createEngine(): Composition<BackgroundVideoEngineState, BackgroundVideoEngineContext> {\n // No selection config of its own: the engine's default rule chain already\n // narrows to the largest rendition that fits the screen, which is exactly\n // what this adapter used to hand over as a bespoke picker.\n return createBackgroundVideoEngine({\n ...this.#config,\n onSignalsReady: (signals) => {\n this.#signals = signals;\n },\n });\n }\n\n #cancelPendingPlay(): void {\n if (!this.#loadstartListener) return;\n\n const mediaElement = this.#signals.context.mediaElement.get();\n\n mediaElement?.removeEventListener('loadstart', this.#loadstartListener);\n this.#loadstartListener = null;\n }\n }\n\n return HlsBackgroundVideoImpl as unknown as MixinReturn<Base, HlsBackgroundVideoAdapterAPI> & {\n readonly defaultProps: HlsBackgroundVideoAdapterProps;\n };\n}\n\n/** Standalone SPF background-video adapter with no base class. */\nexport class HlsBackgroundVideoAdapterCore extends HlsBackgroundVideoMixin(class {}) {}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;AAyDA,MAAM,mCAAwC,IAAI,IAAY;CAC5D;CACA;CACA;AACF,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA0CD,SAAgB,wBAAuD,WAAiB;CACtF,MAAM,+BAA+B,UAAU;EAC7C,OAAgB,eAA+C,EAC7D,KAAK,GACP;EAEA;EACA;EACA;EACA,SAAoC;;;;;EAKpC,gBAA+B;EAC/B;;EAGA,qBAA0C;EAE1C,YAAY,GAAG,MAAa;GAC1B,MAAM,GAAG,IAAI;GAEb,MAAM,EAAE,WAAW,OAAO,MAAM,CAAC;GAEjC,KAAKA,UAAU;GACf,KAAKC,UAAU,KAAKC,cAAc;GAMlC,KAAKC,iBAAiB,aAAa;IACjC,MAAM,SAAS,KAAKC,SAAS,MAAM,OAAO,IAAI;IAE9C,KAAKC,UAAU,WAAW,QAAQ,gBAAgB,GAAG,MAAM;GAC7D,CAAC;EACH;EAEA,IAAI,SAAgF;GAClF,OAAO,KAAKJ;EACd;;;;;;;;;;;EAYA,IAAI,QAAmC;GACrC,OAAO,KAAKK;EACd;EAEA,UAAU,UAAiC,QAAgD;GACzF,IAAI,CAAC,UAAU;IAGb,KAAKA,SAAS;IACd,KAAKC,gBAAgB;IACrB;GACF;GAKA,IAAI,KAAKA,kBAAkB,SAAS,MAAM;GAE1C,KAAKA,gBAAgB,SAAS;GAU9B,QAAQ,MAAM,2BAA2B,EAAE,YAAY,OAAO,CAAC;GAE/D,KAAKD,SAAS;IACZ,MAAM,2BAA2B,MAAM,IAAI,oCAAoC,SAAS;IACxF,SAAS,SAAS,WAAW;IAC7B,GAAI,SAAS,SAAS,KAAA,IAAY,CAAC,IAAI,EAAE,MAAM,SAAS,KAAK;GAC/D;GAGA,KAAK,gBAAgB,IAAI,MAAM,OAAO,CAAC;EACzC;EAMA,OAAO,cAAsC;GAC3C,MAAM,SAAS,YAAY;GAK3B,aAAa,OAAO;GACpB,aAAa,QAAQ;GACrB,aAAa,WAAW;GACxB,aAAa,UAAU;GAEvB,KAAKF,SAAS,QAAQ,aAAa,IAAI,YAAY;EACrD;EAEA,SAAe;GACb,KAAKI,mBAAmB;GACxB,KAAKJ,SAAS,QAAQ,aAAa,IAAI,KAAA,CAAS;GAChD,MAAM,SAAS;EACjB;EAEA,UAAgB;GACd,KAAKI,mBAAmB;GACxB,KAAKL,eAAe;GACpB,KAAKF,QAAQ,QAAQ;EACvB;EAMA,IAAI,MAAc;GAChB,OAAO,KAAKG,SAAS,MAAM,aAAa,IAAI,CAAC,EAAE,OAAO;EACxD;EAEA,IAAI,IAAI,OAAe;GAIrB,IAAI,UAAU,KAAK,KAAK;GAExB,KAAKI,mBAAmB;GACxB,KAAKJ,SAAS,MAAM,aAAa,IAAI,QAAQ,EAAE,KAAK,MAAM,IAAI,KAAA,CAAS;EACzE;EAOA,MAAM,OAAsB;GAC1B,MAAM,eAAe,KAAKA,SAAS,QAAQ,aAAa,IAAI;GAC5D,IAAI,CAAC,cAAc,OAAO,QAAQ,uBAAO,IAAI,MAAM,0DAA0D,CAAC;GAE9G,IAAI;IACF,OAAO,MAAM,aAAa,KAAK;GACjC,SAAS,KAAK;IAIZ,IAAI,KAAK,KACP,OAAO,IAAI,SAAe,SAAS,WAAW;KAC5C,MAAM,iBAAiB;MACrB,KAAKK,qBAAqB;MAC1B,aAAa,KAAK,CAAC,CAAC,KAAK,SAAS,MAAM;KAC1C;KAEA,KAAKA,qBAAqB;KAC1B,aAAa,iBAAiB,aAAa,UAAU,EAAE,MAAM,KAAK,CAAC;IACrE,CAAC;IAGH,MAAM;GACR;EACF;EAMA,gBAAuF;GAIrF,OAAO,4BAA4B;IACjC,GAAG,KAAKT;IACR,iBAAiB,YAAY;KAC3B,KAAKI,WAAW;IAClB;GACF,CAAC;EACH;EAEA,qBAA2B;GACzB,IAAI,CAAC,KAAKK,oBAAoB;GAI9B,KAF0BL,SAAS,QAAQ,aAAa,IAE7C,CAAC,EAAE,oBAAoB,aAAa,KAAKK,kBAAkB;GACtE,KAAKA,qBAAqB;EAC5B;CACF;CAEA,OAAO;AAGT;;AAGA,IAAa,gCAAb,cAAmD,wBAAwB,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { HlsVideoAdapterAPI, HlsVideoAdapterProps } from "./mixin.js";
|
|
2
|
+
import { HTMLVideoAdapter } from "@videojs/media/dom";
|
|
3
|
+
//#region src/playback/adapters/hls-video/adapter.d.ts
|
|
4
|
+
declare const HlsVideoAdapterBase: import("@videojs/media/media-tracks").WithMediaTracks<import("@videojs/utils/types").Constructor<HTMLVideoAdapter & HlsVideoAdapterAPI, any[]> & Omit<typeof HTMLVideoAdapter, "prototype"> & {
|
|
5
|
+
readonly alternativeMediaSuggestion: string | undefined;
|
|
6
|
+
readonly defaultProps: HlsVideoAdapterProps;
|
|
7
|
+
}>;
|
|
8
|
+
declare class HlsVideoAdapter extends HlsVideoAdapterBase {}
|
|
9
|
+
//#endregion
|
|
10
|
+
export { HlsVideoAdapter };
|
|
11
|
+
//# sourceMappingURL=adapter.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"adapter.d.ts","names":[],"sources":["../../../../../src/playback/adapters/hls-video/adapter.ts"],"mappings":";;;cAMM,2DAAmB,+CAAA,YAAA,mBAAA,6BAAA,YAAA;;yBAAA;;cAEZ,wBAAwB"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { HlsVideoMixin } from "./mixin.js";
|
|
2
|
+
import { HlsVideoMediaTracksMixin } from "./media-tracks.js";
|
|
3
|
+
import { HTMLVideoAdapter } from "@videojs/media/dom";
|
|
4
|
+
import { MediaTracksMixin } from "@videojs/media/media-tracks";
|
|
5
|
+
//#region src/playback/adapters/hls-video/adapter.ts
|
|
6
|
+
const HlsVideoAdapterBase = HlsVideoMediaTracksMixin(MediaTracksMixin(HlsVideoMixin(HTMLVideoAdapter)));
|
|
7
|
+
var HlsVideoAdapter = class extends HlsVideoAdapterBase {};
|
|
8
|
+
//#endregion
|
|
9
|
+
export { HlsVideoAdapter };
|
|
10
|
+
|
|
11
|
+
//# sourceMappingURL=adapter.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"adapter.js","names":[],"sources":["../../../../../src/playback/adapters/hls-video/adapter.ts"],"sourcesContent":["import { HTMLVideoAdapter } from '@videojs/media/dom';\nimport { MediaTracksMixin } from '@videojs/media/media-tracks';\n\nimport { HlsVideoMediaTracksMixin } from './media-tracks';\nimport { HlsVideoMixin } from './mixin';\n\nconst HlsVideoAdapterBase = HlsVideoMediaTracksMixin(MediaTracksMixin(HlsVideoMixin(HTMLVideoAdapter)));\n\nexport class HlsVideoAdapter extends HlsVideoAdapterBase {}\n"],"mappings":";;;;;AAMA,MAAM,sBAAsB,yBAAyB,iBAAiB,cAAc,gBAAgB,CAAC,CAAC;AAEtG,IAAa,kBAAb,cAAqC,oBAAoB,CAAC"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { ErrorLike } from "@videojs/media";
|
|
2
|
+
//#region src/playback/adapters/hls-video/error-surface.d.ts
|
|
3
|
+
/**
|
|
4
|
+
* The error shape a media surface exposes: `@videojs/media`'s {@link ErrorLike} plus the reporter context the engine
|
|
5
|
+
* carries alongside a condition.
|
|
6
|
+
*
|
|
7
|
+
* `code` is the **SVTA code**, not a `MediaError.MEDIA_ERR_*` value. Consumers that map codes to copy currently only
|
|
8
|
+
* know 1–5, so an SVTA code falls through to showing `message`; an extensible code lookup above the engine is the
|
|
9
|
+
* follow-up that fixes it.
|
|
10
|
+
*/
|
|
11
|
+
interface HlsVideoMediaError extends ErrorLike {
|
|
12
|
+
/** Reporter context (which selection emptied, which track, …). */
|
|
13
|
+
readonly data?: unknown;
|
|
14
|
+
}
|
|
15
|
+
//#endregion
|
|
16
|
+
export { HlsVideoMediaError };
|
|
17
|
+
//# sourceMappingURL=error-surface.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"error-surface.d.ts","names":[],"sources":["../../../../../src/playback/adapters/hls-video/error-surface.ts"],"mappings":";;;;;;;;;;UA8BiB,2BAA2B;;WAEjC"}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { SVTA_UNSUPPORTED_AUDIO_FORMAT, SVTA_UNSUPPORTED_DRM_SYSTEM, SVTA_UNSUPPORTED_VIDEO_FORMAT } from "../../../media/errors.js";
|
|
2
|
+
//#region src/playback/adapters/hls-video/error-surface.ts
|
|
3
|
+
/**
|
|
4
|
+
* `message`, plus the alternative-Media sentence when `media`'s class names one.
|
|
5
|
+
*
|
|
6
|
+
* Read off the class rather than passed in so a subclass can point at a better-equipped sibling — the SPF Mux Medias
|
|
7
|
+
* name the hls.js-backed one, which plays the MPEG-TS and DRM sources SPF doesn't — without either adapter knowing that
|
|
8
|
+
* sibling exists.
|
|
9
|
+
*/
|
|
10
|
+
function withAlternativeMediaSuggestion(message, media) {
|
|
11
|
+
const { alternativeMediaSuggestion } = media.constructor;
|
|
12
|
+
const suggestion = alternativeMediaSuggestion?.trim();
|
|
13
|
+
return suggestion ? `${message} ${suggestion}` : message;
|
|
14
|
+
}
|
|
15
|
+
/** The first condition `fatalCodes` covers — the root cause, not its consequences. */
|
|
16
|
+
function firstFatal(errors, fatalCodes) {
|
|
17
|
+
return errors?.find((error) => fatalCodes.has(error.code));
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* The causes that mean the engine has no pipeline for what the source delivers — a container it can't append, or
|
|
21
|
+
* encryption it can't decrypt.
|
|
22
|
+
*
|
|
23
|
+
* What these have in common is that no retry, no other CDN, and no other rendition of the same source fixes them: the
|
|
24
|
+
* source needs a capability this engine doesn't have. That's the distinction the surfaced code exists to draw, and it's
|
|
25
|
+
* why the set is these three rather than "every cause".
|
|
26
|
+
*/
|
|
27
|
+
const UNSUPPORTED_FEATURE_CAUSES = /* @__PURE__ */ new Set([
|
|
28
|
+
SVTA_UNSUPPORTED_VIDEO_FORMAT,
|
|
29
|
+
SVTA_UNSUPPORTED_AUDIO_FORMAT,
|
|
30
|
+
SVTA_UNSUPPORTED_DRM_SYSTEM
|
|
31
|
+
]);
|
|
32
|
+
/**
|
|
33
|
+
* Whether anything in the sequence is a cause of the "we don't implement this" kind.
|
|
34
|
+
*
|
|
35
|
+
* Deliberately `some` over the whole sequence rather than a per-type match against the verdict. A verdict means one
|
|
36
|
+
* type's candidates emptied, but the _reason_ the source is unplayable can sit on another type — an audio-only source
|
|
37
|
+
* whose sole rendition is encrypted empties the audio candidates, and a video source with encrypted video empties the
|
|
38
|
+
* video ones. Both are the same answer to the viewer, so both get the same code.
|
|
39
|
+
*/
|
|
40
|
+
function hasUnsupportedFeatureCause(errors) {
|
|
41
|
+
return errors?.some((error) => UNSUPPORTED_FEATURE_CAUSES.has(error.code)) ?? false;
|
|
42
|
+
}
|
|
43
|
+
//#endregion
|
|
44
|
+
export { firstFatal, hasUnsupportedFeatureCause, withAlternativeMediaSuggestion };
|
|
45
|
+
|
|
46
|
+
//# sourceMappingURL=error-surface.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"error-surface.js","names":[],"sources":["../../../../../src/playback/adapters/hls-video/error-surface.ts"],"sourcesContent":["/**\n * The shared half of promoting reported conditions onto a media surface.\n *\n * Every adapter that has one does the same things: pick the first condition it treats as fatal, latch it so a later\n * append doesn't re-fire, and name a better-equipped Media when its own class points at one. Only the _policy_ differs\n * — which codes are fatal, which the video, audio-only, and background adapters each answer differently — so that stays\n * with each adapter and everything else lives here.\n *\n * `firstFatal` is the part all three share. The `ErrorLike` mapping below it is for the two that feed a store and a\n * dialog; the background adapter surfaces the reported condition unmapped, so it takes the picker and nothing else.\n *\n * See `internal/design/spf/features/errors.md` for the causes-vs-verdicts split this rests on.\n */\nimport type { ErrorLike } from '@videojs/media';\n\nimport {\n SVTA_UNSUPPORTED_AUDIO_FORMAT,\n SVTA_UNSUPPORTED_DRM_SYSTEM,\n SVTA_UNSUPPORTED_VIDEO_FORMAT,\n type SvtaError,\n} from '../../../media/errors';\n\n/**\n * The error shape a media surface exposes: `@videojs/media`'s {@link ErrorLike} plus the reporter context the engine\n * carries alongside a condition.\n *\n * `code` is the **SVTA code**, not a `MediaError.MEDIA_ERR_*` value. Consumers that map codes to copy currently only\n * know 1–5, so an SVTA code falls through to showing `message`; an extensible code lookup above the engine is the\n * follow-up that fixes it.\n */\nexport interface HlsVideoMediaError extends ErrorLike {\n /** Reporter context (which selection emptied, which track, …). */\n readonly data?: unknown;\n}\n\n/**\n * `message`, plus the alternative-Media sentence when `media`'s class names one.\n *\n * Read off the class rather than passed in so a subclass can point at a better-equipped sibling — the SPF Mux Medias\n * name the hls.js-backed one, which plays the MPEG-TS and DRM sources SPF doesn't — without either adapter knowing that\n * sibling exists.\n */\nexport function withAlternativeMediaSuggestion(message: string, media: object): string {\n const { alternativeMediaSuggestion } = media.constructor as { alternativeMediaSuggestion?: string };\n const suggestion = alternativeMediaSuggestion?.trim();\n\n return suggestion ? `${message} ${suggestion}` : message;\n}\n\n/** The first condition `fatalCodes` covers — the root cause, not its consequences. */\nexport function firstFatal(\n errors: readonly SvtaError[] | undefined,\n fatalCodes: ReadonlySet<number>\n): SvtaError | undefined {\n return errors?.find((error) => fatalCodes.has(error.code));\n}\n\n/**\n * The causes that mean the engine has no pipeline for what the source delivers — a container it can't append, or\n * encryption it can't decrypt.\n *\n * What these have in common is that no retry, no other CDN, and no other rendition of the same source fixes them: the\n * source needs a capability this engine doesn't have. That's the distinction the surfaced code exists to draw, and it's\n * why the set is these three rather than \"every cause\".\n */\nconst UNSUPPORTED_FEATURE_CAUSES: ReadonlySet<number> = new Set<number>([\n SVTA_UNSUPPORTED_VIDEO_FORMAT,\n SVTA_UNSUPPORTED_AUDIO_FORMAT,\n SVTA_UNSUPPORTED_DRM_SYSTEM,\n]);\n\n/**\n * Whether anything in the sequence is a cause of the \"we don't implement this\" kind.\n *\n * Deliberately `some` over the whole sequence rather than a per-type match against the verdict. A verdict means one\n * type's candidates emptied, but the _reason_ the source is unplayable can sit on another type — an audio-only source\n * whose sole rendition is encrypted empties the audio candidates, and a video source with encrypted video empties the\n * video ones. Both are the same answer to the viewer, so both get the same code.\n */\nexport function hasUnsupportedFeatureCause(errors: readonly SvtaError[] | undefined): boolean {\n return errors?.some((error) => UNSUPPORTED_FEATURE_CAUSES.has(error.code)) ?? false;\n}\n"],"mappings":";;;;;;;;;AA0CA,SAAgB,+BAA+B,SAAiB,OAAuB;CACrF,MAAM,EAAE,+BAA+B,MAAM;CAC7C,MAAM,aAAa,4BAA4B,KAAK;CAEpD,OAAO,aAAa,GAAG,QAAQ,GAAG,eAAe;AACnD;;AAGA,SAAgB,WACd,QACA,YACuB;CACvB,OAAO,QAAQ,MAAM,UAAU,WAAW,IAAI,MAAM,IAAI,CAAC;AAC3D;;;;;;;;;AAUA,MAAM,6CAAkD,IAAI,IAAY;CACtE;CACA;CACA;AACF,CAAC;;;;;;;;;AAUD,SAAgB,2BAA2B,QAAmD;CAC5F,OAAO,QAAQ,MAAM,UAAU,2BAA2B,IAAI,MAAM,IAAI,CAAC,KAAK;AAChF"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { Composition } from "../../../core/composition/create-composition.js";
|
|
2
|
+
import { HlsVideoEngineContext, HlsVideoEngineState } from "../../engines/hls/engine.js";
|
|
3
|
+
import { MediaAudioTrackCapability, MediaVideoRenditionCapability, MediaVideoTrackCapability } from "@videojs/media";
|
|
4
|
+
import { Constructor } from "@videojs/utils/types";
|
|
5
|
+
//#region src/playback/adapters/hls-video/media-tracks.d.ts
|
|
6
|
+
type HlsVideoEngineHost = {
|
|
7
|
+
readonly engine: Composition<HlsVideoEngineState, HlsVideoEngineContext>;
|
|
8
|
+
destroy?(): void;
|
|
9
|
+
};
|
|
10
|
+
type MediaTracksHost = HlsVideoEngineHost & MediaVideoTrackCapability & MediaAudioTrackCapability & MediaVideoRenditionCapability;
|
|
11
|
+
/**
|
|
12
|
+
* Projects the SPF engine's presentation onto the media element's `videoRenditions` / `audioTracks` lists, and wires
|
|
13
|
+
* user selection back to the engine's `userVideoTrackSelection` / `userAudioTrackSelection` signals.
|
|
14
|
+
*
|
|
15
|
+
* Requires the media-tracks mixin (track-list infrastructure) earlier in the chain so the host exposes `addVideoTrack`,
|
|
16
|
+
* `videoRenditions`, and friends.
|
|
17
|
+
*/
|
|
18
|
+
declare function HlsVideoMediaTracksMixin<Base extends Constructor<MediaTracksHost>>(BaseClass: Base): Base;
|
|
19
|
+
//#endregion
|
|
20
|
+
export { HlsVideoMediaTracksMixin };
|
|
21
|
+
//# sourceMappingURL=media-tracks.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"media-tracks.d.ts","names":[],"sources":["../../../../../src/playback/adapters/hls-video/media-tracks.ts"],"mappings":";;;;;KAoCK;WACM,QAAQ,YAAY,qBAAqB;EAClD;;KAGG,kBAAkB,qBACrB,4BACA,4BACA;;;;;;;;iBAac,yBAAyB,aAAa,YAAY,kBAAkB,WAAW,OAiLpD"}
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
import { computed, untrack } from "../../../core/signals/primitives.js";
|
|
2
|
+
import { effect } from "../../../core/signals/effect.js";
|
|
3
|
+
import { dedupedAudioTracks, dedupedVideoTracks, findAudioTrackById, findVideoTrackById, frameRateToNumber, isSameAudioTrack, isSameVideoTrack, toUserAudioTrackSelection, toUserVideoTrackSelection } from "../../../media/media-tracks/media-tracks.js";
|
|
4
|
+
//#region src/playback/adapters/hls-video/media-tracks.ts
|
|
5
|
+
const toVideoKey = (rendition) => ({
|
|
6
|
+
width: rendition.width,
|
|
7
|
+
height: rendition.height,
|
|
8
|
+
bandwidth: rendition.bitrate
|
|
9
|
+
});
|
|
10
|
+
const toAudioKey = (track) => ({
|
|
11
|
+
language: track.language,
|
|
12
|
+
name: track.label
|
|
13
|
+
});
|
|
14
|
+
/** Two track lists carry the same set when their id sequences match. */
|
|
15
|
+
const sameIds = (a, b) => a.length === b.length && a.every((item, i) => item.id === b[i].id);
|
|
16
|
+
/**
|
|
17
|
+
* Projects the SPF engine's presentation onto the media element's `videoRenditions` / `audioTracks` lists, and wires
|
|
18
|
+
* user selection back to the engine's `userVideoTrackSelection` / `userAudioTrackSelection` signals.
|
|
19
|
+
*
|
|
20
|
+
* Requires the media-tracks mixin (track-list infrastructure) earlier in the chain so the host exposes `addVideoTrack`,
|
|
21
|
+
* `videoRenditions`, and friends.
|
|
22
|
+
*/
|
|
23
|
+
function HlsVideoMediaTracksMixin(BaseClass) {
|
|
24
|
+
class HlsVideoMediaTracks extends BaseClass {
|
|
25
|
+
#abort = new AbortController();
|
|
26
|
+
#destroyed = false;
|
|
27
|
+
#renditions = [];
|
|
28
|
+
#audioTracks = [];
|
|
29
|
+
constructor(...args) {
|
|
30
|
+
super(...args);
|
|
31
|
+
const { state } = this.engine;
|
|
32
|
+
const { signal } = this.#abort;
|
|
33
|
+
const renditionsSignal = computed(() => dedupedVideoTracks(state.presentation.get()), { equals: sameIds });
|
|
34
|
+
const audioTracksSignal = computed(() => dedupedAudioTracks(state.presentation.get()), { equals: sameIds });
|
|
35
|
+
const reflectRenditions = () => {
|
|
36
|
+
const renditions = renditionsSignal.get();
|
|
37
|
+
this.#renditions = renditions;
|
|
38
|
+
this.#removeVideoTracks();
|
|
39
|
+
if (!renditions.length) return;
|
|
40
|
+
const videoTrack = this.addVideoTrack("main");
|
|
41
|
+
videoTrack.selected = true;
|
|
42
|
+
const resolved = untrack(() => findVideoTrackById(state.presentation.get(), state.selectedVideoTrackId.get()));
|
|
43
|
+
for (const rendition of renditions) {
|
|
44
|
+
const domRendition = videoTrack.addRendition("", rendition.width, rendition.height, rendition.codecs.join(","), rendition.bandwidth, rendition.frameRate ? frameRateToNumber(rendition.frameRate) : void 0);
|
|
45
|
+
domRendition.id = rendition.id;
|
|
46
|
+
domRendition.active = isSameVideoTrack(toVideoKey(domRendition), resolved);
|
|
47
|
+
}
|
|
48
|
+
};
|
|
49
|
+
const reflectSelectedVideo = () => {
|
|
50
|
+
const resolved = findVideoTrackById(state.presentation.get(), state.selectedVideoTrackId.get());
|
|
51
|
+
for (const rendition of this.videoRenditions) rendition.active = isSameVideoTrack(toVideoKey(rendition), resolved);
|
|
52
|
+
};
|
|
53
|
+
const reflectAudioTracks = () => {
|
|
54
|
+
const tracks = audioTracksSignal.get();
|
|
55
|
+
this.#audioTracks = tracks;
|
|
56
|
+
this.#removeAudioTracks();
|
|
57
|
+
if (!tracks.length) return;
|
|
58
|
+
const resolved = untrack(() => findAudioTrackById(state.presentation.get(), state.selectedAudioTrackId.get()));
|
|
59
|
+
for (const track of tracks) {
|
|
60
|
+
const domTrack = this.addAudioTrack(track.default ? "main" : "alternative", track.name, track.language ?? "");
|
|
61
|
+
domTrack.id = track.id;
|
|
62
|
+
domTrack.enabled = isSameAudioTrack(toAudioKey(domTrack), resolved);
|
|
63
|
+
}
|
|
64
|
+
};
|
|
65
|
+
const reflectSelectedAudio = () => {
|
|
66
|
+
const resolved = findAudioTrackById(state.presentation.get(), state.selectedAudioTrackId.get());
|
|
67
|
+
for (const track of this.audioTracks) track.enabled = isSameAudioTrack(toAudioKey(track), resolved);
|
|
68
|
+
};
|
|
69
|
+
const sourceUrl = computed(() => state.presentation.get()?.url);
|
|
70
|
+
const resetSelectionOnSourceChange = () => {
|
|
71
|
+
sourceUrl.get();
|
|
72
|
+
state.userVideoTrackSelection.set(void 0);
|
|
73
|
+
state.userAudioTrackSelection.set(void 0);
|
|
74
|
+
};
|
|
75
|
+
const effectCleanups = [
|
|
76
|
+
effect(reflectRenditions),
|
|
77
|
+
effect(reflectSelectedVideo),
|
|
78
|
+
effect(reflectAudioTracks),
|
|
79
|
+
effect(reflectSelectedAudio),
|
|
80
|
+
effect(resetSelectionOnSourceChange)
|
|
81
|
+
];
|
|
82
|
+
this.videoRenditions.addEventListener("change", this.#selectRendition, { signal });
|
|
83
|
+
this.audioTracks.addEventListener("change", this.#selectAudio, { signal });
|
|
84
|
+
signal.addEventListener("abort", () => effectCleanups.forEach((cleanup) => cleanup()), { once: true });
|
|
85
|
+
}
|
|
86
|
+
destroy() {
|
|
87
|
+
if (this.#destroyed) return;
|
|
88
|
+
this.#destroyed = true;
|
|
89
|
+
this.#abort.abort();
|
|
90
|
+
this.#removeVideoTracks();
|
|
91
|
+
this.#removeAudioTracks();
|
|
92
|
+
super.destroy?.();
|
|
93
|
+
}
|
|
94
|
+
#selectRendition = () => {
|
|
95
|
+
const { userVideoTrackSelection } = this.engine.state;
|
|
96
|
+
const index = this.videoRenditions.selectedIndex;
|
|
97
|
+
const domRendition = index < 0 ? void 0 : this.videoRenditions[index];
|
|
98
|
+
const rendition = this.#renditions.find((candidate) => candidate.id === domRendition?.id);
|
|
99
|
+
userVideoTrackSelection.set(toUserVideoTrackSelection(rendition));
|
|
100
|
+
};
|
|
101
|
+
#selectAudio = () => {
|
|
102
|
+
const { presentation, selectedAudioTrackId, userAudioTrackSelection } = this.engine.state;
|
|
103
|
+
const resolved = findAudioTrackById(presentation.get(), selectedAudioTrackId.get());
|
|
104
|
+
const current = [...this.audioTracks].find((track) => isSameAudioTrack(toAudioKey(track), resolved));
|
|
105
|
+
const enabled = [...this.audioTracks].filter((track) => track.enabled);
|
|
106
|
+
const target = enabled.find((track) => track !== current) ?? enabled[0];
|
|
107
|
+
if (!target) return;
|
|
108
|
+
for (const track of enabled) if (track !== target) track.enabled = false;
|
|
109
|
+
if (target === current) return;
|
|
110
|
+
const audioTrack = this.#audioTracks.find((candidate) => candidate.id === target.id);
|
|
111
|
+
userAudioTrackSelection.set(toUserAudioTrackSelection(audioTrack));
|
|
112
|
+
};
|
|
113
|
+
#removeVideoTracks() {
|
|
114
|
+
for (const videoTrack of [...this.videoTracks]) this.removeVideoTrack(videoTrack);
|
|
115
|
+
}
|
|
116
|
+
#removeAudioTracks() {
|
|
117
|
+
for (const audioTrack of [...this.audioTracks]) this.removeAudioTrack(audioTrack);
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
return HlsVideoMediaTracks;
|
|
121
|
+
}
|
|
122
|
+
//#endregion
|
|
123
|
+
export { HlsVideoMediaTracksMixin };
|
|
124
|
+
|
|
125
|
+
//# sourceMappingURL=media-tracks.js.map
|