@videojs/spf 10.0.0-beta.3 → 10.0.0-beta.30
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 +91 -0
- package/dist/default/core/actors/create-machine-actor.js.map +1 -0
- package/dist/default/core/actors/create-transition-actor.js +46 -0
- package/dist/default/core/actors/create-transition-actor.js.map +1 -0
- package/dist/default/core/composition/create-composition.js +85 -0
- package/dist/default/core/composition/create-composition.js.map +1 -0
- package/dist/default/core/composition/share-signals.js +39 -0
- package/dist/default/core/composition/share-signals.js.map +1 -0
- package/dist/default/core/machine.js +26 -0
- package/dist/default/core/machine.js.map +1 -0
- package/dist/default/core/reactors/create-machine-reactor.js +83 -0
- package/dist/default/core/reactors/create-machine-reactor.js.map +1 -0
- package/dist/default/core/signals/effect.js +41 -0
- package/dist/default/core/signals/effect.js.map +1 -0
- package/dist/default/core/signals/primitives.js +54 -0
- package/dist/default/core/signals/primitives.js.map +1 -0
- package/dist/default/core/signals/when.js +38 -0
- package/dist/default/core/signals/when.js.map +1 -0
- package/dist/default/core/tasks/delayed-reschedule.js +31 -0
- package/dist/default/core/tasks/delayed-reschedule.js.map +1 -0
- package/dist/default/core/tasks/task.js +321 -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 +8 -0
- package/dist/default/index.js +23 -0
- package/dist/default/index.js.map +1 -0
- package/dist/default/media/abr/quality-selection.js +21 -0
- package/dist/default/media/abr/quality-selection.js.map +1 -0
- package/dist/default/media/buffer/back-buffer.js +46 -0
- package/dist/default/media/buffer/back-buffer.js.map +1 -0
- package/dist/default/media/buffer/forward-buffer.js +119 -0
- package/dist/default/media/buffer/forward-buffer.js.map +1 -0
- package/dist/default/media/dom/capabilities.js +72 -0
- package/dist/default/media/dom/capabilities.js.map +1 -0
- package/dist/default/media/dom/mse/append-segment.js +60 -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 +95 -0
- package/dist/default/media/dom/mse/duration.js.map +1 -0
- package/dist/default/media/dom/mse/end-of-stream.js +20 -0
- package/dist/default/media/dom/mse/end-of-stream.js.map +1 -0
- package/dist/default/media/dom/mse/mediasource-setup.js +242 -0
- package/dist/default/media/dom/mse/mediasource-setup.js.map +1 -0
- package/dist/default/media/dom/screen.js +112 -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 +69 -0
- package/dist/default/media/dom/text/text-track-slots.js.map +1 -0
- package/dist/default/media/errors.js +69 -0
- package/dist/default/media/errors.js.map +1 -0
- package/dist/default/media/hls/parse-attributes.js +148 -0
- package/dist/default/media/hls/parse-attributes.js.map +1 -0
- package/dist/default/media/hls/parse-media-playlist.js +261 -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 +71 -0
- package/dist/default/media/hls/reload-policy.js.map +1 -0
- package/dist/default/media/hls/resolve-url.js +11 -0
- package/dist/default/media/hls/resolve-url.js.map +1 -0
- package/dist/default/media/live-window.js +36 -0
- package/dist/default/media/live-window.js.map +1 -0
- package/dist/default/media/media-tracks/media-tracks.js +101 -0
- package/dist/default/media/media-tracks/media-tracks.js.map +1 -0
- package/dist/default/media/mp4/box.js +58 -0
- package/dist/default/media/mp4/box.js.map +1 -0
- package/dist/default/media/mp4/timestamp-origin.js +107 -0
- package/dist/default/media/mp4/timestamp-origin.js.map +1 -0
- package/dist/default/media/primitives/resolution.js +29 -0
- package/dist/default/media/primitives/resolution.js.map +1 -0
- package/dist/default/media/primitives/select-tracks.js +107 -0
- package/dist/default/media/primitives/select-tracks.js.map +1 -0
- package/dist/default/media/text/parse-vtt-timestamp-map.js +42 -0
- package/dist/default/media/text/parse-vtt-timestamp-map.js.map +1 -0
- package/dist/default/media/text/resolve-vtt-metadata.js +23 -0
- package/dist/default/media/text/resolve-vtt-metadata.js.map +1 -0
- package/dist/default/media/types/index.js +50 -0
- package/dist/default/media/types/index.js.map +1 -0
- package/dist/default/media/utils/cdn.js +56 -0
- package/dist/default/media/utils/cdn.js.map +1 -0
- package/dist/default/media/utils/preload.js +22 -0
- package/dist/default/media/utils/preload.js.map +1 -0
- package/dist/default/media/utils/track-selection.js +47 -0
- package/dist/default/media/utils/track-selection.js.map +1 -0
- package/dist/default/media/utils/tracks.js +144 -0
- package/dist/default/media/utils/tracks.js.map +1 -0
- package/dist/default/media-tracks.js +2 -0
- package/dist/default/mux-audio.js +3 -0
- package/dist/default/mux-background-video.js +3 -0
- package/dist/default/mux-video.js +3 -0
- package/dist/default/network/bandwidth-estimator.js +96 -0
- package/dist/default/network/bandwidth-estimator.js.map +1 -0
- package/dist/default/network/chunked-stream-iterable.js +49 -0
- package/dist/default/network/chunked-stream-iterable.js.map +1 -0
- package/dist/default/network/ewma.js +71 -0
- package/dist/default/network/ewma.js.map +1 -0
- package/dist/default/network/fetch.js +115 -0
- package/dist/default/network/fetch.js.map +1 -0
- package/dist/default/playback/actors/dom/segment-loader.js +249 -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 +149 -0
- package/dist/default/playback/actors/text-track-segment-loader.js.map +1 -0
- package/dist/default/playback/adapters/hls-audio/adapter.js +186 -0
- package/dist/default/playback/adapters/hls-audio/adapter.js.map +1 -0
- package/dist/default/playback/adapters/hls-audio/media.js +9 -0
- package/dist/default/playback/adapters/hls-audio/media.js.map +1 -0
- package/dist/default/playback/adapters/hls-background-video/adapter.js +211 -0
- package/dist/default/playback/adapters/hls-background-video/adapter.js.map +1 -0
- package/dist/default/playback/adapters/hls-background-video/host.js +60 -0
- package/dist/default/playback/adapters/hls-background-video/host.js.map +1 -0
- package/dist/default/playback/adapters/hls-background-video/media.js +21 -0
- package/dist/default/playback/adapters/hls-background-video/media.js.map +1 -0
- package/dist/default/playback/adapters/hls-video/adapter.js +316 -0
- package/dist/default/playback/adapters/hls-video/adapter.js.map +1 -0
- package/dist/default/playback/adapters/hls-video/error-surface.js +51 -0
- package/dist/default/playback/adapters/hls-video/error-surface.js.map +1 -0
- package/dist/default/playback/adapters/hls-video/media-tracks.js +126 -0
- package/dist/default/playback/adapters/hls-video/media-tracks.js.map +1 -0
- package/dist/default/playback/adapters/hls-video/media.js +11 -0
- package/dist/default/playback/adapters/hls-video/media.js.map +1 -0
- package/dist/default/playback/adapters/mux-audio/media.js +26 -0
- package/dist/default/playback/adapters/mux-audio/media.js.map +1 -0
- package/dist/default/playback/adapters/mux-video/adapter.js +105 -0
- package/dist/default/playback/adapters/mux-video/adapter.js.map +1 -0
- package/dist/default/playback/adapters/mux-video/media.js +23 -0
- package/dist/default/playback/adapters/mux-video/media.js.map +1 -0
- package/dist/default/playback/behaviors/calculate-presentation-duration.js +36 -0
- package/dist/default/playback/behaviors/calculate-presentation-duration.js.map +1 -0
- package/dist/default/playback/behaviors/collect-errors.js +111 -0
- package/dist/default/playback/behaviors/collect-errors.js.map +1 -0
- package/dist/default/playback/behaviors/derive-cdn-priority.js +68 -0
- package/dist/default/playback/behaviors/derive-cdn-priority.js.map +1 -0
- package/dist/default/playback/behaviors/dom/airplay.js +211 -0
- package/dist/default/playback/behaviors/dom/airplay.js.map +1 -0
- package/dist/default/playback/behaviors/dom/apply-start-position.js +93 -0
- package/dist/default/playback/behaviors/dom/apply-start-position.js.map +1 -0
- package/dist/default/playback/behaviors/dom/end-of-stream.js +102 -0
- package/dist/default/playback/behaviors/dom/end-of-stream.js.map +1 -0
- package/dist/default/playback/behaviors/dom/load-segments.js +181 -0
- package/dist/default/playback/behaviors/dom/load-segments.js.map +1 -0
- package/dist/default/playback/behaviors/dom/recover-end-stall.js +77 -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 +132 -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 +205 -0
- package/dist/default/playback/behaviors/dom/setup-buffer-actors.js.map +1 -0
- package/dist/default/playback/behaviors/dom/setup-mediasource.js +114 -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 +26 -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 +124 -0
- package/dist/default/playback/behaviors/dom/sync-text-tracks.js.map +1 -0
- package/dist/default/playback/behaviors/dom/track-current-time.js +52 -0
- package/dist/default/playback/behaviors/dom/track-current-time.js.map +1 -0
- package/dist/default/playback/behaviors/dom/track-load-triggers.js +94 -0
- package/dist/default/playback/behaviors/dom/track-load-triggers.js.map +1 -0
- package/dist/default/playback/behaviors/dom/track-playback-rate.js +37 -0
- package/dist/default/playback/behaviors/dom/track-playback-rate.js.map +1 -0
- package/dist/default/playback/behaviors/dom/track-player-resolution.js +57 -0
- package/dist/default/playback/behaviors/dom/track-player-resolution.js.map +1 -0
- package/dist/default/playback/behaviors/dom/track-screen-resolution.js +29 -0
- package/dist/default/playback/behaviors/dom/track-screen-resolution.js.map +1 -0
- package/dist/default/playback/behaviors/dom/update-mediasource-duration.js +113 -0
- package/dist/default/playback/behaviors/dom/update-mediasource-duration.js.map +1 -0
- package/dist/default/playback/behaviors/establish-start-media-time.js +197 -0
- package/dist/default/playback/behaviors/establish-start-media-time.js.map +1 -0
- package/dist/default/playback/behaviors/resolve-presentation.js +85 -0
- package/dist/default/playback/behaviors/resolve-presentation.js.map +1 -0
- package/dist/default/playback/behaviors/resolve-track.js +141 -0
- package/dist/default/playback/behaviors/resolve-track.js.map +1 -0
- package/dist/default/playback/behaviors/select-tracks.js +216 -0
- package/dist/default/playback/behaviors/select-tracks.js.map +1 -0
- package/dist/default/playback/behaviors/setup-failover-monitor.js +66 -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 +391 -0
- package/dist/default/playback/behaviors/track-switching.js.map +1 -0
- package/dist/default/playback/engines/hls/engine-audio-only.js +98 -0
- package/dist/default/playback/engines/hls/engine-audio-only.js.map +1 -0
- package/dist/default/playback/engines/hls/engine-background-video.js +92 -0
- package/dist/default/playback/engines/hls/engine-background-video.js.map +1 -0
- package/dist/default/playback/engines/hls/engine.js +147 -0
- package/dist/default/playback/engines/hls/engine.js.map +1 -0
- package/dist/default/playback/primitives/error-messages.js +51 -0
- package/dist/default/playback/primitives/error-messages.js.map +1 -0
- package/dist/default/playback/primitives/failover-fetch.js +42 -0
- package/dist/default/playback/primitives/failover-fetch.js.map +1 -0
- package/dist/default/playback/primitives/head-peek.js +44 -0
- package/dist/default/playback/primitives/head-peek.js.map +1 -0
- package/dist/default/playback/primitives/live-window.js +66 -0
- package/dist/default/playback/primitives/live-window.js.map +1 -0
- package/dist/default/playback/primitives/relocation-pipelines.js +203 -0
- package/dist/default/playback/primitives/relocation-pipelines.js.map +1 -0
- package/dist/default/playback/primitives/report-track-conditions.js +86 -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 +86 -0
- package/dist/default/playback/primitives/selection-rules.js.map +1 -0
- package/dist/default/playback/primitives/text-segment-load-pipeline.js +37 -0
- package/dist/default/playback/primitives/text-segment-load-pipeline.js.map +1 -0
- package/dist/default/playback/primitives/track-types.js +61 -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 +128 -0
- package/dist/dev/core/actors/create-machine-actor.d.ts.map +1 -0
- package/dist/dev/core/actors/create-machine-actor.js +91 -0
- package/dist/dev/core/actors/create-machine-actor.js.map +1 -0
- package/dist/dev/core/actors/create-transition-actor.d.ts +41 -0
- package/dist/dev/core/actors/create-transition-actor.d.ts.map +1 -0
- package/dist/dev/core/actors/create-transition-actor.js +46 -0
- package/dist/dev/core/actors/create-transition-actor.js.map +1 -0
- package/dist/dev/core/composition/create-composition.d.ts +273 -0
- package/dist/dev/core/composition/create-composition.d.ts.map +1 -0
- package/dist/dev/core/composition/create-composition.js +85 -0
- package/dist/dev/core/composition/create-composition.js.map +1 -0
- package/dist/dev/core/composition/share-signals.d.ts +46 -0
- package/dist/dev/core/composition/share-signals.d.ts.map +1 -0
- package/dist/dev/core/composition/share-signals.js +39 -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 +26 -0
- package/dist/dev/core/machine.js.map +1 -0
- package/dist/dev/core/reactors/create-machine-reactor.d.ts +93 -0
- package/dist/dev/core/reactors/create-machine-reactor.d.ts.map +1 -0
- package/dist/dev/core/reactors/create-machine-reactor.js +83 -0
- package/dist/dev/core/reactors/create-machine-reactor.js.map +1 -0
- package/dist/dev/core/signals/effect.d.ts +15 -0
- package/dist/dev/core/signals/effect.d.ts.map +1 -0
- package/dist/dev/core/signals/effect.js +41 -0
- package/dist/dev/core/signals/effect.js.map +1 -0
- package/dist/dev/core/signals/primitives.d.ts +46 -0
- package/dist/dev/core/signals/primitives.d.ts.map +1 -0
- package/dist/dev/core/signals/primitives.js +54 -0
- package/dist/dev/core/signals/primitives.js.map +1 -0
- package/dist/dev/core/signals/when.js +38 -0
- package/dist/dev/core/signals/when.js.map +1 -0
- package/dist/dev/core/tasks/delayed-reschedule.js +31 -0
- package/dist/dev/core/tasks/delayed-reschedule.js.map +1 -0
- package/dist/dev/core/tasks/task.d.ts +166 -0
- package/dist/dev/core/tasks/task.d.ts.map +1 -0
- package/dist/dev/core/tasks/task.js +321 -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 +9 -0
- package/dist/dev/hls.js +8 -0
- package/dist/dev/index.d.ts +24 -0
- package/dist/dev/index.d.ts.map +1 -0
- package/dist/dev/index.js +23 -0
- package/dist/dev/index.js.map +1 -0
- package/dist/dev/media/abr/quality-selection.d.ts +22 -0
- package/dist/dev/media/abr/quality-selection.d.ts.map +1 -0
- package/dist/dev/media/abr/quality-selection.js +21 -0
- package/dist/dev/media/abr/quality-selection.js.map +1 -0
- package/dist/dev/media/buffer/back-buffer.d.ts +14 -0
- package/dist/dev/media/buffer/back-buffer.d.ts.map +1 -0
- package/dist/dev/media/buffer/back-buffer.js +46 -0
- package/dist/dev/media/buffer/back-buffer.js.map +1 -0
- package/dist/dev/media/buffer/forward-buffer.d.ts +14 -0
- package/dist/dev/media/buffer/forward-buffer.d.ts.map +1 -0
- package/dist/dev/media/buffer/forward-buffer.js +119 -0
- package/dist/dev/media/buffer/forward-buffer.js.map +1 -0
- package/dist/dev/media/dom/capabilities.js +72 -0
- package/dist/dev/media/dom/capabilities.js.map +1 -0
- package/dist/dev/media/dom/mse/append-segment.d.ts +18 -0
- package/dist/dev/media/dom/mse/append-segment.d.ts.map +1 -0
- package/dist/dev/media/dom/mse/append-segment.js +60 -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 +95 -0
- package/dist/dev/media/dom/mse/duration.js.map +1 -0
- package/dist/dev/media/dom/mse/end-of-stream.js +20 -0
- package/dist/dev/media/dom/mse/end-of-stream.js.map +1 -0
- package/dist/dev/media/dom/mse/mediasource-setup.js +242 -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 +112 -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 +30 -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 +69 -0
- package/dist/dev/media/dom/text/text-track-slots.js.map +1 -0
- package/dist/dev/media/errors.d.ts +82 -0
- package/dist/dev/media/errors.d.ts.map +1 -0
- package/dist/dev/media/errors.js +69 -0
- package/dist/dev/media/errors.js.map +1 -0
- package/dist/dev/media/hls/parse-attributes.js +148 -0
- package/dist/dev/media/hls/parse-attributes.js.map +1 -0
- package/dist/dev/media/hls/parse-media-playlist.js +261 -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 +71 -0
- package/dist/dev/media/hls/reload-policy.js.map +1 -0
- package/dist/dev/media/hls/resolve-url.js +11 -0
- package/dist/dev/media/hls/resolve-url.js.map +1 -0
- package/dist/dev/media/live-window.js +36 -0
- package/dist/dev/media/live-window.js.map +1 -0
- package/dist/dev/media/media-tracks/media-tracks.d.ts +51 -0
- package/dist/dev/media/media-tracks/media-tracks.d.ts.map +1 -0
- package/dist/dev/media/media-tracks/media-tracks.js +101 -0
- package/dist/dev/media/media-tracks/media-tracks.js.map +1 -0
- package/dist/dev/media/mp4/box.js +58 -0
- package/dist/dev/media/mp4/box.js.map +1 -0
- package/dist/dev/media/mp4/timestamp-origin.js +107 -0
- package/dist/dev/media/mp4/timestamp-origin.js.map +1 -0
- package/dist/dev/media/primitives/resolution.d.ts +24 -0
- package/dist/dev/media/primitives/resolution.d.ts.map +1 -0
- package/dist/dev/media/primitives/resolution.js +29 -0
- package/dist/dev/media/primitives/resolution.js.map +1 -0
- package/dist/dev/media/primitives/select-tracks.js +107 -0
- package/dist/dev/media/primitives/select-tracks.js.map +1 -0
- package/dist/dev/media/text/parse-vtt-timestamp-map.js +42 -0
- package/dist/dev/media/text/parse-vtt-timestamp-map.js.map +1 -0
- package/dist/dev/media/text/resolve-vtt-metadata.js +23 -0
- package/dist/dev/media/text/resolve-vtt-metadata.js.map +1 -0
- package/dist/dev/media/types/index.d.ts +377 -0
- package/dist/dev/media/types/index.d.ts.map +1 -0
- package/dist/dev/media/types/index.js +50 -0
- package/dist/dev/media/types/index.js.map +1 -0
- package/dist/dev/media/utils/cdn.d.ts +13 -0
- package/dist/dev/media/utils/cdn.d.ts.map +1 -0
- package/dist/dev/media/utils/cdn.js +56 -0
- package/dist/dev/media/utils/cdn.js.map +1 -0
- package/dist/dev/media/utils/preload.js +22 -0
- package/dist/dev/media/utils/preload.js.map +1 -0
- package/dist/dev/media/utils/track-selection.js +47 -0
- package/dist/dev/media/utils/track-selection.js.map +1 -0
- package/dist/dev/media/utils/tracks.js +144 -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/mux-audio.d.ts +4 -0
- package/dist/dev/mux-audio.js +3 -0
- package/dist/dev/mux-background-video.d.ts +4 -0
- package/dist/dev/mux-background-video.js +3 -0
- package/dist/dev/mux-video.d.ts +4 -0
- package/dist/dev/mux-video.js +3 -0
- package/dist/dev/network/bandwidth-estimator.d.ts +50 -0
- package/dist/dev/network/bandwidth-estimator.d.ts.map +1 -0
- package/dist/dev/network/bandwidth-estimator.js +96 -0
- package/dist/dev/network/bandwidth-estimator.js.map +1 -0
- package/dist/dev/network/chunked-stream-iterable.js +49 -0
- package/dist/dev/network/chunked-stream-iterable.js.map +1 -0
- package/dist/dev/network/ewma.js +71 -0
- package/dist/dev/network/ewma.js.map +1 -0
- package/dist/dev/network/fetch.js +115 -0
- package/dist/dev/network/fetch.js.map +1 -0
- package/dist/dev/playback/actors/dom/segment-loader.d.ts +48 -0
- package/dist/dev/playback/actors/dom/segment-loader.d.ts.map +1 -0
- package/dist/dev/playback/actors/dom/segment-loader.js +249 -0
- package/dist/dev/playback/actors/dom/segment-loader.js.map +1 -0
- package/dist/dev/playback/actors/dom/source-buffer.d.ts +47 -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 +54 -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 +149 -0
- package/dist/dev/playback/actors/text-track-segment-loader.js.map +1 -0
- package/dist/dev/playback/actors/text-tracks.d.ts +33 -0
- package/dist/dev/playback/actors/text-tracks.d.ts.map +1 -0
- package/dist/dev/playback/adapters/hls-audio/adapter.d.ts +54 -0
- package/dist/dev/playback/adapters/hls-audio/adapter.d.ts.map +1 -0
- package/dist/dev/playback/adapters/hls-audio/adapter.js +186 -0
- package/dist/dev/playback/adapters/hls-audio/adapter.js.map +1 -0
- package/dist/dev/playback/adapters/hls-audio/media.d.ts +10 -0
- package/dist/dev/playback/adapters/hls-audio/media.d.ts.map +1 -0
- package/dist/dev/playback/adapters/hls-audio/media.js +9 -0
- package/dist/dev/playback/adapters/hls-audio/media.js.map +1 -0
- package/dist/dev/playback/adapters/hls-background-video/adapter.d.ts +77 -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 +211 -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 +38 -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 +60 -0
- package/dist/dev/playback/adapters/hls-background-video/host.js.map +1 -0
- package/dist/dev/playback/adapters/hls-background-video/media.d.ts +20 -0
- package/dist/dev/playback/adapters/hls-background-video/media.d.ts.map +1 -0
- package/dist/dev/playback/adapters/hls-background-video/media.js +21 -0
- package/dist/dev/playback/adapters/hls-background-video/media.js.map +1 -0
- package/dist/dev/playback/adapters/hls-video/adapter.d.ts +63 -0
- package/dist/dev/playback/adapters/hls-video/adapter.d.ts.map +1 -0
- package/dist/dev/playback/adapters/hls-video/adapter.js +316 -0
- package/dist/dev/playback/adapters/hls-video/adapter.js.map +1 -0
- package/dist/dev/playback/adapters/hls-video/error-surface.d.ts +18 -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 +51 -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 +22 -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 +126 -0
- package/dist/dev/playback/adapters/hls-video/media-tracks.js.map +1 -0
- package/dist/dev/playback/adapters/hls-video/media.d.ts +10 -0
- package/dist/dev/playback/adapters/hls-video/media.d.ts.map +1 -0
- package/dist/dev/playback/adapters/hls-video/media.js +11 -0
- package/dist/dev/playback/adapters/hls-video/media.js.map +1 -0
- package/dist/dev/playback/adapters/mux-audio/media.d.ts +28 -0
- package/dist/dev/playback/adapters/mux-audio/media.d.ts.map +1 -0
- package/dist/dev/playback/adapters/mux-audio/media.js +26 -0
- package/dist/dev/playback/adapters/mux-audio/media.js.map +1 -0
- package/dist/dev/playback/adapters/mux-video/adapter.d.ts +34 -0
- package/dist/dev/playback/adapters/mux-video/adapter.d.ts.map +1 -0
- package/dist/dev/playback/adapters/mux-video/adapter.js +105 -0
- package/dist/dev/playback/adapters/mux-video/adapter.js.map +1 -0
- package/dist/dev/playback/adapters/mux-video/media.d.ts +24 -0
- package/dist/dev/playback/adapters/mux-video/media.d.ts.map +1 -0
- package/dist/dev/playback/adapters/mux-video/media.js +23 -0
- package/dist/dev/playback/adapters/mux-video/media.js.map +1 -0
- package/dist/dev/playback/behaviors/calculate-presentation-duration.d.ts +26 -0
- package/dist/dev/playback/behaviors/calculate-presentation-duration.d.ts.map +1 -0
- package/dist/dev/playback/behaviors/calculate-presentation-duration.js +36 -0
- package/dist/dev/playback/behaviors/calculate-presentation-duration.js.map +1 -0
- package/dist/dev/playback/behaviors/collect-errors.js +111 -0
- package/dist/dev/playback/behaviors/collect-errors.js.map +1 -0
- package/dist/dev/playback/behaviors/derive-cdn-priority.js +68 -0
- package/dist/dev/playback/behaviors/derive-cdn-priority.js.map +1 -0
- package/dist/dev/playback/behaviors/dom/airplay.js +211 -0
- package/dist/dev/playback/behaviors/dom/airplay.js.map +1 -0
- package/dist/dev/playback/behaviors/dom/apply-start-position.js +93 -0
- package/dist/dev/playback/behaviors/dom/apply-start-position.js.map +1 -0
- package/dist/dev/playback/behaviors/dom/end-of-stream.js +102 -0
- package/dist/dev/playback/behaviors/dom/end-of-stream.js.map +1 -0
- package/dist/dev/playback/behaviors/dom/load-segments.d.ts +72 -0
- package/dist/dev/playback/behaviors/dom/load-segments.d.ts.map +1 -0
- package/dist/dev/playback/behaviors/dom/load-segments.js +181 -0
- package/dist/dev/playback/behaviors/dom/load-segments.js.map +1 -0
- package/dist/dev/playback/behaviors/dom/recover-end-stall.js +77 -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 +132 -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 +205 -0
- package/dist/dev/playback/behaviors/dom/setup-buffer-actors.js.map +1 -0
- package/dist/dev/playback/behaviors/dom/setup-mediasource.js +114 -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 +26 -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 +124 -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 +52 -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 +47 -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 +94 -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 +37 -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 +57 -0
- package/dist/dev/playback/behaviors/dom/track-player-resolution.js.map +1 -0
- package/dist/dev/playback/behaviors/dom/track-screen-resolution.js +29 -0
- package/dist/dev/playback/behaviors/dom/track-screen-resolution.js.map +1 -0
- package/dist/dev/playback/behaviors/dom/update-mediasource-duration.js +113 -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 +36 -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 +197 -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 +85 -0
- package/dist/dev/playback/behaviors/resolve-presentation.js.map +1 -0
- package/dist/dev/playback/behaviors/resolve-track.js +141 -0
- package/dist/dev/playback/behaviors/resolve-track.js.map +1 -0
- package/dist/dev/playback/behaviors/select-tracks.d.ts +72 -0
- package/dist/dev/playback/behaviors/select-tracks.d.ts.map +1 -0
- package/dist/dev/playback/behaviors/select-tracks.js +216 -0
- package/dist/dev/playback/behaviors/select-tracks.js.map +1 -0
- package/dist/dev/playback/behaviors/setup-failover-monitor.d.ts +14 -0
- package/dist/dev/playback/behaviors/setup-failover-monitor.d.ts.map +1 -0
- package/dist/dev/playback/behaviors/setup-failover-monitor.js +66 -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.js +391 -0
- package/dist/dev/playback/behaviors/track-switching.js.map +1 -0
- package/dist/dev/playback/engines/hls/engine-audio-only.d.ts +173 -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 +98 -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 +158 -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 +92 -0
- package/dist/dev/playback/engines/hls/engine-background-video.js.map +1 -0
- package/dist/dev/playback/engines/hls/engine.d.ts +329 -0
- package/dist/dev/playback/engines/hls/engine.d.ts.map +1 -0
- package/dist/dev/playback/engines/hls/engine.js +147 -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 +51 -0
- package/dist/dev/playback/primitives/error-messages.js.map +1 -0
- package/dist/dev/playback/primitives/failover-fetch.js +42 -0
- package/dist/dev/playback/primitives/failover-fetch.js.map +1 -0
- package/dist/dev/playback/primitives/head-peek.js +44 -0
- package/dist/dev/playback/primitives/head-peek.js.map +1 -0
- package/dist/dev/playback/primitives/live-window.js +66 -0
- package/dist/dev/playback/primitives/live-window.js.map +1 -0
- package/dist/dev/playback/primitives/relocation-pipelines.js +203 -0
- package/dist/dev/playback/primitives/relocation-pipelines.js.map +1 -0
- package/dist/dev/playback/primitives/report-track-conditions.d.ts +11 -0
- package/dist/dev/playback/primitives/report-track-conditions.d.ts.map +1 -0
- package/dist/dev/playback/primitives/report-track-conditions.js +86 -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 +38 -0
- package/dist/dev/playback/primitives/selection-rules.d.ts.map +1 -0
- package/dist/dev/playback/primitives/selection-rules.js +86 -0
- package/dist/dev/playback/primitives/selection-rules.js.map +1 -0
- package/dist/dev/playback/primitives/source-buffer-messages.d.ts +43 -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 +65 -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 +37 -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 +61 -0
- package/dist/dev/playback/primitives/track-types.js.map +1 -0
- package/package.json +63 -26
- package/dist/adapter-CMw-rvbk.js +0 -3512
- package/dist/adapter-CMw-rvbk.js.map +0 -1
- package/dist/adapter-l8iJN_GI.d.ts +0 -689
- package/dist/adapter-l8iJN_GI.d.ts.map +0 -1
- package/dist/dom/index.d.ts +0 -243
- 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,377 @@
|
|
|
1
|
+
//#region src/media/types/index.d.ts
|
|
2
|
+
/**
|
|
3
|
+
* Core SPF Types
|
|
4
|
+
*
|
|
5
|
+
* Based on CMAF-HAM (Common Media Application Format - Hypothetical Application Model)
|
|
6
|
+
* Protocol-agnostic representation of streaming media content.
|
|
7
|
+
*
|
|
8
|
+
* @see https://github.com/streaming-video-technology-alliance/common-media-library
|
|
9
|
+
*/
|
|
10
|
+
/**
|
|
11
|
+
* Base identifier type for all HAM objects.
|
|
12
|
+
*/
|
|
13
|
+
interface Ham {
|
|
14
|
+
id: string;
|
|
15
|
+
/**
|
|
16
|
+
* Format-/protocol-specific values that aren't part of the generic CMAF-HAM
|
|
17
|
+
* model — kept in an open bag so the model stays format-neutral (mirrors how
|
|
18
|
+
* CMAF-HAM itself stashes protocol extras rather than growing the model).
|
|
19
|
+
* Typed reads go through dedicated accessors (e.g. `getMediaPlaylistMetadata`).
|
|
20
|
+
*/
|
|
21
|
+
metadata?: Record<string, unknown>;
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Addressable resource with optional byte range.
|
|
25
|
+
*/
|
|
26
|
+
interface AddressableObject {
|
|
27
|
+
url: string;
|
|
28
|
+
byteRange?: {
|
|
29
|
+
start: number;
|
|
30
|
+
end: number;
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Time span with start time and duration.
|
|
35
|
+
* Used for segments and other timed ranges.
|
|
36
|
+
*/
|
|
37
|
+
interface TimeSpan {
|
|
38
|
+
startTime: number;
|
|
39
|
+
duration: number;
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Track content type.
|
|
43
|
+
*/
|
|
44
|
+
type TrackType = 'video' | 'audio' | 'text';
|
|
45
|
+
/**
|
|
46
|
+
* Video frame rate expressed as numerator/denominator.
|
|
47
|
+
*
|
|
48
|
+
* Examples:
|
|
49
|
+
* - 30 fps: { frameRateNumerator: 30 }
|
|
50
|
+
* - 29.97 fps: { frameRateNumerator: 30000, frameRateDenominator: 1001 }
|
|
51
|
+
*/
|
|
52
|
+
interface FrameRate {
|
|
53
|
+
frameRateNumerator: number;
|
|
54
|
+
frameRateDenominator?: number;
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Generic type for partially resolved tracks.
|
|
58
|
+
* Removes fields that come from media playlist parsing.
|
|
59
|
+
*
|
|
60
|
+
* @param T - Track type to make partially resolved (must extend Track)
|
|
61
|
+
*/
|
|
62
|
+
type PartiallyResolved<T extends Track = Track> = Omit<T, 'segments' | 'initialization' | keyof TimeSpan> & {
|
|
63
|
+
segments?: never;
|
|
64
|
+
duration?: never;
|
|
65
|
+
startTime?: never;
|
|
66
|
+
initialization?: never;
|
|
67
|
+
};
|
|
68
|
+
/**
|
|
69
|
+
* Base track type containing common properties for all resolved tracks.
|
|
70
|
+
* A resolved track has segments, duration, and initialization data.
|
|
71
|
+
* All URLs are fully qualified (parsers resolve relative URLs).
|
|
72
|
+
*/
|
|
73
|
+
/**
|
|
74
|
+
* Track startTime is always 0 — the presentation-timeline origin (and future
|
|
75
|
+
* multi-period base). The live sliding-window edge is `segments[0].startTime`,
|
|
76
|
+
* derived — never stored here.
|
|
77
|
+
*/
|
|
78
|
+
type Track = Ham & AddressableObject & TimeSpan & {
|
|
79
|
+
type: TrackType;
|
|
80
|
+
codecs?: string[];
|
|
81
|
+
mimeType: string;
|
|
82
|
+
language?: string | undefined;
|
|
83
|
+
bandwidth: number;
|
|
84
|
+
initialization?: AddressableObject;
|
|
85
|
+
segments: Segment[];
|
|
86
|
+
/**
|
|
87
|
+
* Media-timeline (decode/encode) coordinate of the track's timeline origin
|
|
88
|
+
* (presentation-0) — the media-time base value of the coordinate model, peer
|
|
89
|
+
* to `startTime` (presentation). Derived from the container
|
|
90
|
+
* (`tfdt.baseMediaDecodeTime ÷ mdhd.timescale`); the relocation offset is
|
|
91
|
+
* `−startMediaTime` (targets presentation-0 — `Track.startTime` plays no
|
|
92
|
+
* part), never stored.
|
|
93
|
+
*
|
|
94
|
+
* Optional: `undefined` means not yet established, or never establishable
|
|
95
|
+
* (e.g. text tracks carry no container origin); a near-zero/native origin is
|
|
96
|
+
* established as `0` (no relocation). Established once per source by the
|
|
97
|
+
* `establishStartMediaTime` reactor. See
|
|
98
|
+
* `internal/design/spf/presentation-timeline-model.md`.
|
|
99
|
+
*/
|
|
100
|
+
startMediaTime?: number;
|
|
101
|
+
/**
|
|
102
|
+
* Wall-clock time (epoch seconds) at the track's timeline origin
|
|
103
|
+
* (presentation-0) — pure playlist arithmetic over any PDT-bearing segment:
|
|
104
|
+
* `segment.startDate − segment.startTime`, invariant along a linear
|
|
105
|
+
* timeline. Optional: absent when no segment carries `startDate`.
|
|
106
|
+
*
|
|
107
|
+
* The wall-clock member of the coordinate triple (peer to `startTime` and
|
|
108
|
+
* `startMediaTime`). For live it is the anchor segments are PDT-placed
|
|
109
|
+
* against on every parse; equal `startDate` across tracks marks the same
|
|
110
|
+
* presentation instant. See
|
|
111
|
+
* `internal/design/spf/live-presentation-timeline-model.md`.
|
|
112
|
+
*/
|
|
113
|
+
startDate?: number;
|
|
114
|
+
};
|
|
115
|
+
/**
|
|
116
|
+
* Per-track-type origin-establishment data, accumulated across appends (the media
|
|
117
|
+
* track's `track_id` + `mdhd` timescale from the init, `tfdt` baseMediaDecodeTime of
|
|
118
|
+
* that same track from the first media segment) — hence optional. The transient input
|
|
119
|
+
* the `establishStartMediaTime` reactor reduces into `Track.startMediaTime`.
|
|
120
|
+
*
|
|
121
|
+
* `trackId` is the ISO-BMFF `track_ID` of the buffered media track (`vide`/`soun`),
|
|
122
|
+
* read from the init's `tkhd`; it ties the timescale to the *same* track's
|
|
123
|
+
* `baseMediaDecodeTime` (matched via `tfhd.track_id`) so a muxed segment carrying a
|
|
124
|
+
* second track (e.g. `clcp` captions) reads the right `tfdt` rather than the first one.
|
|
125
|
+
*
|
|
126
|
+
* `segmentStartTime` is the 0-based presentation start of the segment
|
|
127
|
+
* `baseMediaDecodeTime` was read from — *not* a container value (it's the playlist
|
|
128
|
+
* position), but co-located because the origin is `baseMediaDecodeTime/timescale −
|
|
129
|
+
* segmentStartTime`: the first *loaded* segment isn't necessarily the 0th (a
|
|
130
|
+
* non-zero initial `currentTime`, or live/DVR), so the decode time alone isn't the
|
|
131
|
+
* stream origin.
|
|
132
|
+
*/
|
|
133
|
+
interface MediaContainerData {
|
|
134
|
+
trackId?: number;
|
|
135
|
+
timescale?: number;
|
|
136
|
+
baseMediaDecodeTime?: number;
|
|
137
|
+
segmentStartTime?: number;
|
|
138
|
+
}
|
|
139
|
+
/**
|
|
140
|
+
* Raw media-segment bytes — a complete buffer or a byte stream. The transport-neutral
|
|
141
|
+
* payload the loader pipeline carries; `AppendData` (the MSE `SourceBuffer` append
|
|
142
|
+
* input in `media/dom/mse`) is an alias of this at the DOM boundary.
|
|
143
|
+
*/
|
|
144
|
+
type SegmentData = ArrayBuffer | AsyncIterable<Uint8Array>;
|
|
145
|
+
/**
|
|
146
|
+
* Resolved video track with segments.
|
|
147
|
+
*/
|
|
148
|
+
type VideoTrack = Track & Required<Pick<Track, 'initialization' | 'codecs'>> & {
|
|
149
|
+
type: 'video';
|
|
150
|
+
width?: number;
|
|
151
|
+
height?: number;
|
|
152
|
+
frameRate?: FrameRate;
|
|
153
|
+
/**
|
|
154
|
+
* Audio groups (`EXT-X-STREAM-INF:AUDIO`) this video rendition can pair
|
|
155
|
+
* with. A list because one rendition is typically listed across multiple
|
|
156
|
+
* `EXT-X-STREAM-INF` entries — one per audio group (the HLS cross-product) —
|
|
157
|
+
* which the parser collapses into a single track carrying every group it
|
|
158
|
+
* advertised.
|
|
159
|
+
*/
|
|
160
|
+
audioGroupIds?: string[];
|
|
161
|
+
};
|
|
162
|
+
/**
|
|
163
|
+
* Resolved audio track with segments.
|
|
164
|
+
*/
|
|
165
|
+
type AudioTrack = Track & Required<Pick<Track, 'initialization' | 'codecs'>> & {
|
|
166
|
+
type: 'audio';
|
|
167
|
+
groupId: string;
|
|
168
|
+
name: string;
|
|
169
|
+
sampleRate: number;
|
|
170
|
+
channels: number;
|
|
171
|
+
default?: boolean;
|
|
172
|
+
autoselect?: boolean;
|
|
173
|
+
};
|
|
174
|
+
/**
|
|
175
|
+
* Resolved text track with segments.
|
|
176
|
+
*/
|
|
177
|
+
type TextTrack = Track & {
|
|
178
|
+
type: 'text';
|
|
179
|
+
groupId: string;
|
|
180
|
+
label: string;
|
|
181
|
+
kind: 'subtitles' | 'captions';
|
|
182
|
+
default?: boolean;
|
|
183
|
+
autoselect?: boolean;
|
|
184
|
+
forced?: boolean;
|
|
185
|
+
};
|
|
186
|
+
/**
|
|
187
|
+
* Predicate that answers "can this environment decode this track?" — the
|
|
188
|
+
* capability-probing surface, read by the track-switching hard-constraint
|
|
189
|
+
* pre-pass (`excludeUnplayableTracks`) to drop undecodable renditions before
|
|
190
|
+
* selection. Kept DOM-free here (a plain function type over a minimal track
|
|
191
|
+
* shape) so DOM-free behaviors can consume it; the DOM implementation
|
|
192
|
+
* (`canPlayTrack` in `media/dom/capabilities.ts`) wraps
|
|
193
|
+
* `MediaSource.isTypeSupported`.
|
|
194
|
+
*
|
|
195
|
+
* Takes the minimal codec-bearing shape both video and audio candidates
|
|
196
|
+
* carry. `mimeType` is optional so unprobeable candidates (no MIME) can be
|
|
197
|
+
* passed straight through as playable rather than dropped.
|
|
198
|
+
*/
|
|
199
|
+
type CanPlayTrack = (track: {
|
|
200
|
+
mimeType?: string;
|
|
201
|
+
codecs?: string[];
|
|
202
|
+
metadata?: Record<string, unknown>;
|
|
203
|
+
}) => boolean;
|
|
204
|
+
/**
|
|
205
|
+
* Minimal text-track cue shape — start time, end time, and display text.
|
|
206
|
+
*
|
|
207
|
+
* Host-agnostic representation. `VTTCue` structurally satisfies this
|
|
208
|
+
* interface, so DOM consumers pass `VTTCue` values directly. Non-DOM
|
|
209
|
+
* hosts (workers, test fakes, non-browser engines) can satisfy the same
|
|
210
|
+
* shape without pulling in DOM types.
|
|
211
|
+
*/
|
|
212
|
+
interface Cue {
|
|
213
|
+
startTime: number;
|
|
214
|
+
endTime: number;
|
|
215
|
+
text: string;
|
|
216
|
+
}
|
|
217
|
+
/**
|
|
218
|
+
* Partially resolved text track from multivariant playlist.
|
|
219
|
+
* Has metadata but no segments or initialization yet (media playlist not fetched).
|
|
220
|
+
*/
|
|
221
|
+
type PartiallyResolvedTextTrack = PartiallyResolved<TextTrack>;
|
|
222
|
+
/**
|
|
223
|
+
* Union of all resolved track types.
|
|
224
|
+
*/
|
|
225
|
+
type ResolvedTrack = VideoTrack | AudioTrack | TextTrack;
|
|
226
|
+
/**
|
|
227
|
+
* Generic switching set type.
|
|
228
|
+
* A group of tracks that can be switched between seamlessly.
|
|
229
|
+
*
|
|
230
|
+
* @param T - Track type (VideoTrack, AudioTrack, or TextTrack)
|
|
231
|
+
*/
|
|
232
|
+
type SwitchingSetOf<T extends Track = Track> = Ham & {
|
|
233
|
+
type: T['type'];
|
|
234
|
+
tracks: (PartiallyResolved<T> | T)[];
|
|
235
|
+
};
|
|
236
|
+
/**
|
|
237
|
+
* Generic selection set type.
|
|
238
|
+
* Groups switching sets by track type.
|
|
239
|
+
*
|
|
240
|
+
* @param T - Track type (VideoTrack, AudioTrack, or TextTrack)
|
|
241
|
+
*/
|
|
242
|
+
type SelectionSetOf<T extends Track = Track> = Ham & {
|
|
243
|
+
type: T['type'];
|
|
244
|
+
switchingSets: SwitchingSetOf<T>[];
|
|
245
|
+
};
|
|
246
|
+
/**
|
|
247
|
+
* Video selection set - contains only video switching sets.
|
|
248
|
+
*/
|
|
249
|
+
type VideoSelectionSet = SelectionSetOf<VideoTrack>;
|
|
250
|
+
/**
|
|
251
|
+
* Audio selection set - contains only audio switching sets.
|
|
252
|
+
*/
|
|
253
|
+
type AudioSelectionSet = SelectionSetOf<AudioTrack>;
|
|
254
|
+
/**
|
|
255
|
+
* Text selection set - contains only text switching sets.
|
|
256
|
+
*/
|
|
257
|
+
type TextSelectionSet = SelectionSetOf<TextTrack>;
|
|
258
|
+
/**
|
|
259
|
+
* Selection set - groups switching sets by track type.
|
|
260
|
+
* Discriminated union ensures type-safe track access.
|
|
261
|
+
*/
|
|
262
|
+
type SelectionSet = VideoSelectionSet | AudioSelectionSet | TextSelectionSet;
|
|
263
|
+
/**
|
|
264
|
+
* Media segment with timing information.
|
|
265
|
+
* Follows CMAF-HAM composition pattern.
|
|
266
|
+
*
|
|
267
|
+
* `startDate` is the absolute wall-clock time of the segment's first
|
|
268
|
+
* sample, in **epoch seconds** (unit-consistent with `startTime`/`duration`),
|
|
269
|
+
* derived from `#EXT-X-PROGRAM-DATE-TIME` (explicit or interpolated forward via
|
|
270
|
+
* `EXTINF`). Unlike the per-track-relative `startTime`, it is comparable across
|
|
271
|
+
* tracks, so it is the cross-track sync anchor for demuxed audio/video and the
|
|
272
|
+
* exact recovery value on a full live-window turnover. Optional: absent when the
|
|
273
|
+
* source carries no PDT (allowed by RFC 8216, required by Apple's HLS authoring
|
|
274
|
+
* spec — so present on conformant content).
|
|
275
|
+
*/
|
|
276
|
+
type Segment = Ham & AddressableObject & TimeSpan & {
|
|
277
|
+
startDate?: number;
|
|
278
|
+
};
|
|
279
|
+
/**
|
|
280
|
+
* Playlist-level metadata surfaced from a parsed media playlist. HLS delivery
|
|
281
|
+
* specifics — not part of the generic CMAF-HAM model — so they live under
|
|
282
|
+
* `Ham.metadata` (read via `getMediaPlaylistMetadata`) rather than as
|
|
283
|
+
* first-class `Track` fields:
|
|
284
|
+
*
|
|
285
|
+
* - `targetDuration` (`#EXT-X-TARGETDURATION`) — reload-cadence basis.
|
|
286
|
+
* - `mediaSequence` (`#EXT-X-MEDIA-SEQUENCE`, default 0) — sequence number of
|
|
287
|
+
* `segments[0]`; the join key for merging successive reload snapshots.
|
|
288
|
+
* - `playlistType` (`#EXT-X-PLAYLIST-TYPE`) — `VOD` / `EVENT` / undefined.
|
|
289
|
+
* - `endList` (`#EXT-X-ENDLIST`) — playlist is complete; stop reloading.
|
|
290
|
+
*/
|
|
291
|
+
interface MediaPlaylistMetadata {
|
|
292
|
+
targetDuration: number;
|
|
293
|
+
mediaSequence: number;
|
|
294
|
+
playlistType?: 'VOD' | 'EVENT';
|
|
295
|
+
endList: boolean;
|
|
296
|
+
/**
|
|
297
|
+
* Whether this rendition carries encrypted segments — any `#EXT-X-KEY` whose
|
|
298
|
+
* `METHOD` isn't `NONE`. Detection only: enough to tell that playback needs
|
|
299
|
+
* decryption support, not enough to perform it.
|
|
300
|
+
*
|
|
301
|
+
* Deliberately *not* a model-level `protection` shape. CMAF-HAM puts
|
|
302
|
+
* `protection` on `SwitchingSet`, but that can't express two real cases: a
|
|
303
|
+
* clear lead (`METHOD=NONE` segments followed by encrypted ones — protection
|
|
304
|
+
* varies along the timeline within one rendition) or key rotation (its single
|
|
305
|
+
* `defaultKid` can't represent a key changing over time). Modeling it properly
|
|
306
|
+
* belongs to DRM support; until then this records the one fact a playlist
|
|
307
|
+
* reliably gives us. Per-rendition because that's HLS's granularity —
|
|
308
|
+
* `EXT-X-KEY` is a media-playlist tag.
|
|
309
|
+
*
|
|
310
|
+
* Conservative for a clear lead: a rendition whose opening segments are clear
|
|
311
|
+
* still reads as encrypted, so it's judged unplayable rather than played until
|
|
312
|
+
* it breaks.
|
|
313
|
+
*/
|
|
314
|
+
encrypted?: boolean;
|
|
315
|
+
/**
|
|
316
|
+
* `EXT-X-SERVER-CONTROL` `HOLD-BACK` (seconds) — the server's declared distance
|
|
317
|
+
* from the live edge for clients playing *complete* segments. Absent when the
|
|
318
|
+
* server doesn't advertise it, in which case the spec default (3 × target
|
|
319
|
+
* duration) applies. Deliberately HLS vocabulary living in the playlist
|
|
320
|
+
* metadata rather than on `Track`: whether a wall-clock holdback generalizes
|
|
321
|
+
* across delivery formats is unresolved.
|
|
322
|
+
*
|
|
323
|
+
* `PART-HOLD-BACK` is **not** captured — it only applies to clients playing
|
|
324
|
+
* partial segments, and using it while fetching whole segments would put the
|
|
325
|
+
* playhead ahead of the last complete segment. Add it with LL-HLS support.
|
|
326
|
+
*/
|
|
327
|
+
holdBack?: number;
|
|
328
|
+
/**
|
|
329
|
+
* Whether the server is delivering this rendition as Low-Latency HLS — any of
|
|
330
|
+
* `#EXT-X-PART`, `#EXT-X-PART-INF`, or `EXT-X-SERVER-CONTROL`'s
|
|
331
|
+
* `PART-HOLD-BACK`.
|
|
332
|
+
*
|
|
333
|
+
* Detection only, and deliberately so: partial segments are ignored by the
|
|
334
|
+
* parser and the loader fetches whole segments, so an LL-HLS playlist plays as
|
|
335
|
+
* standard live at standard latency. Recording the fact is what lets a
|
|
336
|
+
* composition *say* that rather than silently under-delivering the latency the
|
|
337
|
+
* publisher configured.
|
|
338
|
+
*/
|
|
339
|
+
lowLatency?: boolean;
|
|
340
|
+
}
|
|
341
|
+
/** Typed read of the media-playlist metadata stashed in `ham.metadata`. */
|
|
342
|
+
declare function getMediaPlaylistMetadata(ham: Pick<Ham, 'metadata'>): MediaPlaylistMetadata | undefined;
|
|
343
|
+
/**
|
|
344
|
+
* The source's semantic nature — live vs on-demand. A model concept
|
|
345
|
+
* (consumer-facing), distinct from completeness / duration: a live stream that
|
|
346
|
+
* has *ended* is still `'live'`.
|
|
347
|
+
*/
|
|
348
|
+
type StreamType = 'live' | 'on-demand';
|
|
349
|
+
/**
|
|
350
|
+
* Presentation - a single playable period of content.
|
|
351
|
+
* Uses TimeSpan fields (startTime always 0, duration optional until track resolved).
|
|
352
|
+
*
|
|
353
|
+
* Extends AddressableObject so `url` contains the original manifest URL.
|
|
354
|
+
* All URLs are fully qualified (parsers resolve relative URLs).
|
|
355
|
+
*/
|
|
356
|
+
type Presentation = Ham & AddressableObject & Partial<TimeSpan> & {
|
|
357
|
+
selectionSets: SelectionSet[];
|
|
358
|
+
/**
|
|
359
|
+
* Live vs on-demand — the source's semantic nature. Populated once a media
|
|
360
|
+
* playlist is parsed (derived from `#EXT-X-PLAYLIST-TYPE` via
|
|
361
|
+
* `deriveStreamType`); orthogonal to duration / completeness.
|
|
362
|
+
*/
|
|
363
|
+
streamType?: StreamType;
|
|
364
|
+
};
|
|
365
|
+
/**
|
|
366
|
+
* State-shaped presentation that may or may not be resolved yet.
|
|
367
|
+
*
|
|
368
|
+
* The lifecycle is a single value: a caller writes `{ url }`, and the
|
|
369
|
+
* resolver populates the rest in place. `url` is always present; resolved
|
|
370
|
+
* fields (`id`, `selectionSets`, duration) appear once parsing succeeds.
|
|
371
|
+
*
|
|
372
|
+
* Use `isResolvedPresentation` to narrow to `Presentation`.
|
|
373
|
+
*/
|
|
374
|
+
type MaybeResolvedPresentation = AddressableObject & Partial<Omit<Presentation, keyof AddressableObject>>;
|
|
375
|
+
//#endregion
|
|
376
|
+
export { AddressableObject, AudioSelectionSet, AudioTrack, CanPlayTrack, Cue, FrameRate, Ham, MaybeResolvedPresentation, MediaContainerData, MediaPlaylistMetadata, PartiallyResolved, PartiallyResolvedTextTrack, Presentation, ResolvedTrack, Segment, SegmentData, SelectionSet, SelectionSetOf, StreamType, SwitchingSetOf, TextSelectionSet, TextTrack, TimeSpan, Track, TrackType, VideoSelectionSet, VideoTrack, getMediaPlaylistMetadata };
|
|
377
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","names":[],"sources":["../../../../src/media/types/index.ts"],"mappings":";;;;;;;;;;;;UAgBiB;EACf;;;;;;;EAOA,WAAW;;;;;UAMI;EACf;EACA;IACE;IACA;;;;;;;UAyBa;EACf;EACA;;;;;KAUU;;;;;;;;UAaK;EACf;EACA;;;;;;;;KAaU,kBAAkB,UAAU,QAAQ,SAAS,KAAK,yCAAyC;EACrG;EACA;EACA;EACA;;;;;;;;;;;;KA6BU,QAAQ,MAClB,oBACA;EACE,MAAM;EACN;EACA;EACA;EACA;EACA,iBAAiB;EACjB,UAAU;;;;;;;;;;;;;;;EAeV;;;;;;;;;;;;;EAaA;;;;;;;;;;;;;;;;;;;;UAqBa;EACf;EACA;EACA;EACA;;;;;;;KAQU,cAAc,cAAc,cAAc;;;;KAK1C,aAAa,QACvB,SAAS,KAAK;EACZ;EAGA;EACA;EACA,YAAY;;;;;;;;EAQZ;;;;;KAMQ,aAAa,QACvB,SAAS,KAAK;EACZ;EACA;EACA;EACA;EACA;EACA;EACA;;;;;KAMQ,YAAY;EACtB;EACA;EACA;EACA;EACA;EACA;EACA;;;;;;;;;;;;;;;KAgBU,gBAAgB;EAC1B;EACA;EACA,WAAW;;;;;;;;;;UAWI;EACf;EACA;EACA;;;;;;KAmBU,6BAA6B,kBAAkB;;;;KAK/C,gBAAgB,aAAa,aAAa;;;;;;;KAoB1C,eAAe,UAAU,QAAQ,SAAS;EACpD,MAAM;EACN,SAAS,kBAAkB,KAAK;;;;;;;;KA8BtB,eAAe,UAAU,QAAQ,SAAS;EACpD,MAAM;EACN,eAAe,eAAe;;;;;KAMpB,oBAAoB,eAAe;;;;KAKnC,oBAAoB,eAAe;;;;KAKnC,mBAAmB,eAAe;;;;;KAMlC,eAAe,oBAAoB,oBAAoB;;;;;;;;;;;;;;KAmBvD,UAAU,MAAM,oBAAoB;EAAa;;;;;;;;;;;;;;UA4B5C;EACf;EACA;EACA;EACA;;;;;;;;;;;;;;;;;;;EAmBA;;;;;;;;;;;;;EAaA;;;;;;;;;;;;EAYA;;;iBAOc,yBAAyB,KAAK,KAAK,mBAAmB;;;;;;KAa1D;;;;;;;;KAwCA,eAAe,MACzB,oBACA,QAAQ;EACN,eAAe;;;;;;EAMf,aAAa;;;;;;;;;;;KAYL,4BAA4B,oBAAoB,QAAQ,KAAK,oBAAoB"}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
//#region src/media/types/index.ts
|
|
2
|
+
/**
|
|
3
|
+
* Floating-point tolerance for matching segments by `startTime`. Two
|
|
4
|
+
* segments are considered the same position when
|
|
5
|
+
* `Math.abs(a.startTime - b.startTime) < SEGMENT_TIME_EPSILON`. Used by
|
|
6
|
+
* the source-buffer dedup and segment-loader quality-aware filter to
|
|
7
|
+
* tolerate sub-millisecond drift in segment timestamps across multiple
|
|
8
|
+
* playlists / quality levels.
|
|
9
|
+
*/
|
|
10
|
+
const SEGMENT_TIME_EPSILON = 1e-4;
|
|
11
|
+
/** Key under `Ham.metadata` where {@link MediaPlaylistMetadata} is stored. */
|
|
12
|
+
const MEDIA_PLAYLIST_METADATA_KEY = "mediaPlaylist";
|
|
13
|
+
/** Typed read of the media-playlist metadata stashed in `ham.metadata`. */
|
|
14
|
+
function getMediaPlaylistMetadata(ham) {
|
|
15
|
+
return ham.metadata?.[MEDIA_PLAYLIST_METADATA_KEY];
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Derive {@link StreamType} from a media playlist's metadata. Per the model,
|
|
19
|
+
* only `#EXT-X-PLAYLIST-TYPE:VOD` marks on-demand; everything else (EVENT, or
|
|
20
|
+
* the tag absent) is live — completeness (`endList`) never factors in.
|
|
21
|
+
*/
|
|
22
|
+
function deriveStreamType(metadata) {
|
|
23
|
+
return metadata?.playlistType === "VOD" ? "on-demand" : "live";
|
|
24
|
+
}
|
|
25
|
+
function isResolvedTrack(track) {
|
|
26
|
+
return "segments" in track;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Check if a presentation has duration (at least one track resolved).
|
|
30
|
+
* Narrows type to include required duration.
|
|
31
|
+
*/
|
|
32
|
+
function hasPresentationDuration(presentation) {
|
|
33
|
+
return presentation.duration !== void 0;
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Narrows a `MaybeResolvedPresentation` to a fully resolved `Presentation`.
|
|
37
|
+
*
|
|
38
|
+
* A presentation is resolved once `resolvePresentation` has parsed the
|
|
39
|
+
* manifest and populated both `id` and `selectionSets`. Both must be
|
|
40
|
+
* present — a partial value with only one of them isn't usable, and
|
|
41
|
+
* letting it through would have downstream behaviors crash when they
|
|
42
|
+
* access `selectionSets`.
|
|
43
|
+
*/
|
|
44
|
+
function isResolvedPresentation(presentation) {
|
|
45
|
+
return presentation !== void 0 && presentation.id !== void 0 && presentation.selectionSets !== void 0;
|
|
46
|
+
}
|
|
47
|
+
//#endregion
|
|
48
|
+
export { MEDIA_PLAYLIST_METADATA_KEY, SEGMENT_TIME_EPSILON, deriveStreamType, getMediaPlaylistMetadata, hasPresentationDuration, isResolvedPresentation, isResolvedTrack };
|
|
49
|
+
|
|
50
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","names":[],"sources":["../../../../src/media/types/index.ts"],"sourcesContent":["/**\n * Core SPF Types\n *\n * Based on CMAF-HAM (Common Media Application Format - Hypothetical Application Model)\n * Protocol-agnostic representation of streaming media content.\n *\n * @see https://github.com/streaming-video-technology-alliance/common-media-library\n */\n\n// =============================================================================\n// Base Types\n// =============================================================================\n\n/**\n * Base identifier type for all HAM objects.\n */\nexport interface Ham {\n id: string;\n /**\n * Format-/protocol-specific values that aren't part of the generic CMAF-HAM\n * model — kept in an open bag so the model stays format-neutral (mirrors how\n * CMAF-HAM itself stashes protocol extras rather than growing the model).\n * Typed reads go through dedicated accessors (e.g. `getMediaPlaylistMetadata`).\n */\n metadata?: Record<string, unknown>;\n}\n\n/**\n * Addressable resource with optional byte range.\n */\nexport interface AddressableObject {\n url: string;\n byteRange?: {\n start: number;\n end: number;\n };\n}\n\n// =============================================================================\n// Platform-agnostic Media Element\n// =============================================================================\n\n/**\n * Platform-agnostic media element interface.\n * Captures minimal shape needed for orchestration without DOM dependencies.\n * HTMLMediaElement satisfies this interface.\n */\nexport interface MediaElementLike {\n preload: string;\n}\n\n// =============================================================================\n// Time and Duration\n// =============================================================================\n\n/**\n * Time span with start time and duration.\n * Used for segments and other timed ranges.\n */\nexport interface TimeSpan {\n startTime: number;\n duration: number;\n}\n\n// =============================================================================\n// Enums\n// =============================================================================\n\n/**\n * Track content type.\n */\nexport type TrackType = 'video' | 'audio' | 'text';\n\n// =============================================================================\n// Frame Rate\n// =============================================================================\n\n/**\n * Video frame rate expressed as numerator/denominator.\n *\n * Examples:\n * - 30 fps: { frameRateNumerator: 30 }\n * - 29.97 fps: { frameRateNumerator: 30000, frameRateDenominator: 1001 }\n */\nexport interface FrameRate {\n frameRateNumerator: number;\n frameRateDenominator?: number;\n}\n\n// =============================================================================\n// Partially Resolved Tracks (before media playlist is fetched)\n// =============================================================================\n\n/**\n * Generic type for partially resolved tracks.\n * Removes fields that come from media playlist parsing.\n *\n * @param T - Track type to make partially resolved (must extend Track)\n */\nexport type PartiallyResolved<T extends Track = Track> = Omit<T, 'segments' | 'initialization' | keyof TimeSpan> & {\n segments?: never;\n duration?: never;\n startTime?: never;\n initialization?: never;\n};\n\n/**\n * Partially resolved video track from multivariant playlist.\n * Has metadata but no segments or initialization yet (media playlist not fetched).\n */\nexport type PartiallyResolvedVideoTrack = PartiallyResolved<VideoTrack>;\n\n/**\n * Partially resolved audio track from multivariant playlist.\n * Has metadata but no segments or initialization yet (media playlist not fetched).\n */\nexport type PartiallyResolvedAudioTrack = PartiallyResolved<AudioTrack>;\n\n// =============================================================================\n// Resolved Track Types (with segments from media playlist)\n// =============================================================================\n\n/**\n * Base track type containing common properties for all resolved tracks.\n * A resolved track has segments, duration, and initialization data.\n * All URLs are fully qualified (parsers resolve relative URLs).\n */\n/**\n * Track startTime is always 0 — the presentation-timeline origin (and future\n * multi-period base). The live sliding-window edge is `segments[0].startTime`,\n * derived — never stored here.\n */\nexport type Track = Ham &\n AddressableObject &\n TimeSpan & {\n type: TrackType;\n codecs?: string[]; // Optional per HLS spec\n mimeType: string;\n language?: string | undefined;\n bandwidth: number;\n initialization?: AddressableObject;\n segments: Segment[];\n /**\n * Media-timeline (decode/encode) coordinate of the track's timeline origin\n * (presentation-0) — the media-time base value of the coordinate model, peer\n * to `startTime` (presentation). Derived from the container\n * (`tfdt.baseMediaDecodeTime ÷ mdhd.timescale`); the relocation offset is\n * `−startMediaTime` (targets presentation-0 — `Track.startTime` plays no\n * part), never stored.\n *\n * Optional: `undefined` means not yet established, or never establishable\n * (e.g. text tracks carry no container origin); a near-zero/native origin is\n * established as `0` (no relocation). Established once per source by the\n * `establishStartMediaTime` reactor. See\n * `internal/design/spf/presentation-timeline-model.md`.\n */\n startMediaTime?: number;\n /**\n * Wall-clock time (epoch seconds) at the track's timeline origin\n * (presentation-0) — pure playlist arithmetic over any PDT-bearing segment:\n * `segment.startDate − segment.startTime`, invariant along a linear\n * timeline. Optional: absent when no segment carries `startDate`.\n *\n * The wall-clock member of the coordinate triple (peer to `startTime` and\n * `startMediaTime`). For live it is the anchor segments are PDT-placed\n * against on every parse; equal `startDate` across tracks marks the same\n * presentation instant. See\n * `internal/design/spf/live-presentation-timeline-model.md`.\n */\n startDate?: number;\n };\n\n/**\n * Per-track-type origin-establishment data, accumulated across appends (the media\n * track's `track_id` + `mdhd` timescale from the init, `tfdt` baseMediaDecodeTime of\n * that same track from the first media segment) — hence optional. The transient input\n * the `establishStartMediaTime` reactor reduces into `Track.startMediaTime`.\n *\n * `trackId` is the ISO-BMFF `track_ID` of the buffered media track (`vide`/`soun`),\n * read from the init's `tkhd`; it ties the timescale to the *same* track's\n * `baseMediaDecodeTime` (matched via `tfhd.track_id`) so a muxed segment carrying a\n * second track (e.g. `clcp` captions) reads the right `tfdt` rather than the first one.\n *\n * `segmentStartTime` is the 0-based presentation start of the segment\n * `baseMediaDecodeTime` was read from — *not* a container value (it's the playlist\n * position), but co-located because the origin is `baseMediaDecodeTime/timescale −\n * segmentStartTime`: the first *loaded* segment isn't necessarily the 0th (a\n * non-zero initial `currentTime`, or live/DVR), so the decode time alone isn't the\n * stream origin.\n */\nexport interface MediaContainerData {\n trackId?: number;\n timescale?: number;\n baseMediaDecodeTime?: number;\n segmentStartTime?: number;\n}\n\n/**\n * Raw media-segment bytes — a complete buffer or a byte stream. The transport-neutral\n * payload the loader pipeline carries; `AppendData` (the MSE `SourceBuffer` append\n * input in `media/dom/mse`) is an alias of this at the DOM boundary.\n */\nexport type SegmentData = ArrayBuffer | AsyncIterable<Uint8Array>;\n\n/**\n * Resolved video track with segments.\n */\nexport type VideoTrack = Track &\n Required<Pick<Track, 'initialization' | 'codecs'>> & {\n type: 'video';\n\n // Optional metadata from multivariant (per HLS spec)\n width?: number;\n height?: number;\n frameRate?: FrameRate;\n /**\n * Audio groups (`EXT-X-STREAM-INF:AUDIO`) this video rendition can pair\n * with. A list because one rendition is typically listed across multiple\n * `EXT-X-STREAM-INF` entries — one per audio group (the HLS cross-product) —\n * which the parser collapses into a single track carrying every group it\n * advertised.\n */\n audioGroupIds?: string[];\n };\n\n/**\n * Resolved audio track with segments.\n */\nexport type AudioTrack = Track &\n Required<Pick<Track, 'initialization' | 'codecs'>> & {\n type: 'audio';\n groupId: string;\n name: string;\n sampleRate: number;\n channels: number;\n default?: boolean;\n autoselect?: boolean;\n };\n\n/**\n * Resolved text track with segments.\n */\nexport type TextTrack = Track & {\n type: 'text';\n groupId: string;\n label: string;\n kind: 'subtitles' | 'captions';\n default?: boolean;\n autoselect?: boolean;\n forced?: boolean;\n};\n\n/**\n * Predicate that answers \"can this environment decode this track?\" — the\n * capability-probing surface, read by the track-switching hard-constraint\n * pre-pass (`excludeUnplayableTracks`) to drop undecodable renditions before\n * selection. Kept DOM-free here (a plain function type over a minimal track\n * shape) so DOM-free behaviors can consume it; the DOM implementation\n * (`canPlayTrack` in `media/dom/capabilities.ts`) wraps\n * `MediaSource.isTypeSupported`.\n *\n * Takes the minimal codec-bearing shape both video and audio candidates\n * carry. `mimeType` is optional so unprobeable candidates (no MIME) can be\n * passed straight through as playable rather than dropped.\n */\nexport type CanPlayTrack = (track: {\n mimeType?: string;\n codecs?: string[];\n metadata?: Record<string, unknown>;\n}) => boolean;\n\n/**\n * Minimal text-track cue shape — start time, end time, and display text.\n *\n * Host-agnostic representation. `VTTCue` structurally satisfies this\n * interface, so DOM consumers pass `VTTCue` values directly. Non-DOM\n * hosts (workers, test fakes, non-browser engines) can satisfy the same\n * shape without pulling in DOM types.\n */\nexport interface Cue {\n startTime: number;\n endTime: number;\n text: string;\n}\n\n/**\n * Media element with an iterable text-track list, host-agnostic.\n *\n * Extends `MediaElementLike` with the minimum surface needed to observe\n * which text tracks are currently mounted on the media. `HTMLMediaElement`\n * structurally satisfies this (its `textTracks` is a `TextTrackList`,\n * which is iterable with `{ id }` items).\n */\nexport interface MediaElementWithTextTracks extends MediaElementLike {\n readonly textTracks: Iterable<{ readonly id: string }>;\n}\n\n/**\n * Partially resolved text track from multivariant playlist.\n * Has metadata but no segments or initialization yet (media playlist not fetched).\n */\nexport type PartiallyResolvedTextTrack = PartiallyResolved<TextTrack>;\n\n/**\n * Union of all resolved track types.\n */\nexport type ResolvedTrack = VideoTrack | AudioTrack | TextTrack;\n\n/**\n * Union of all partially resolved track types.\n */\nexport type PartiallyResolvedTrack =\n | PartiallyResolvedVideoTrack\n | PartiallyResolvedAudioTrack\n | PartiallyResolvedTextTrack;\n\n// =============================================================================\n// Switching and Selection Sets\n// =============================================================================\n\n/**\n * Generic switching set type.\n * A group of tracks that can be switched between seamlessly.\n *\n * @param T - Track type (VideoTrack, AudioTrack, or TextTrack)\n */\nexport type SwitchingSetOf<T extends Track = Track> = Ham & {\n type: T['type'];\n tracks: (PartiallyResolved<T> | T)[];\n};\n\n/**\n * Video switching set - contains only video tracks (partially resolved or fully resolved).\n */\nexport type VideoSwitchingSet = SwitchingSetOf<VideoTrack>;\n\n/**\n * Audio switching set - contains only audio tracks (partially resolved or fully resolved).\n */\nexport type AudioSwitchingSet = SwitchingSetOf<AudioTrack>;\n\n/**\n * Text switching set - contains only text tracks (partially resolved or fully resolved).\n */\nexport type TextSwitchingSet = SwitchingSetOf<TextTrack>;\n\n/**\n * Switching set - a group of tracks that can be switched between seamlessly.\n * Discriminated by track type.\n */\nexport type SwitchingSet = VideoSwitchingSet | AudioSwitchingSet | TextSwitchingSet;\n\n/**\n * Generic selection set type.\n * Groups switching sets by track type.\n *\n * @param T - Track type (VideoTrack, AudioTrack, or TextTrack)\n */\nexport type SelectionSetOf<T extends Track = Track> = Ham & {\n type: T['type'];\n switchingSets: SwitchingSetOf<T>[];\n};\n\n/**\n * Video selection set - contains only video switching sets.\n */\nexport type VideoSelectionSet = SelectionSetOf<VideoTrack>;\n\n/**\n * Audio selection set - contains only audio switching sets.\n */\nexport type AudioSelectionSet = SelectionSetOf<AudioTrack>;\n\n/**\n * Text selection set - contains only text switching sets.\n */\nexport type TextSelectionSet = SelectionSetOf<TextTrack>;\n\n/**\n * Selection set - groups switching sets by track type.\n * Discriminated union ensures type-safe track access.\n */\nexport type SelectionSet = VideoSelectionSet | AudioSelectionSet | TextSelectionSet;\n\n// =============================================================================\n// Segment\n// =============================================================================\n\n/**\n * Media segment with timing information.\n * Follows CMAF-HAM composition pattern.\n *\n * `startDate` is the absolute wall-clock time of the segment's first\n * sample, in **epoch seconds** (unit-consistent with `startTime`/`duration`),\n * derived from `#EXT-X-PROGRAM-DATE-TIME` (explicit or interpolated forward via\n * `EXTINF`). Unlike the per-track-relative `startTime`, it is comparable across\n * tracks, so it is the cross-track sync anchor for demuxed audio/video and the\n * exact recovery value on a full live-window turnover. Optional: absent when the\n * source carries no PDT (allowed by RFC 8216, required by Apple's HLS authoring\n * spec — so present on conformant content).\n */\nexport type Segment = Ham & AddressableObject & TimeSpan & { startDate?: number };\n\n/**\n * Floating-point tolerance for matching segments by `startTime`. Two\n * segments are considered the same position when\n * `Math.abs(a.startTime - b.startTime) < SEGMENT_TIME_EPSILON`. Used by\n * the source-buffer dedup and segment-loader quality-aware filter to\n * tolerate sub-millisecond drift in segment timestamps across multiple\n * playlists / quality levels.\n */\nexport const SEGMENT_TIME_EPSILON = 0.0001;\n\n// =============================================================================\n// Media Playlist Metadata\n// =============================================================================\n\n/**\n * Playlist-level metadata surfaced from a parsed media playlist. HLS delivery\n * specifics — not part of the generic CMAF-HAM model — so they live under\n * `Ham.metadata` (read via `getMediaPlaylistMetadata`) rather than as\n * first-class `Track` fields:\n *\n * - `targetDuration` (`#EXT-X-TARGETDURATION`) — reload-cadence basis.\n * - `mediaSequence` (`#EXT-X-MEDIA-SEQUENCE`, default 0) — sequence number of\n * `segments[0]`; the join key for merging successive reload snapshots.\n * - `playlistType` (`#EXT-X-PLAYLIST-TYPE`) — `VOD` / `EVENT` / undefined.\n * - `endList` (`#EXT-X-ENDLIST`) — playlist is complete; stop reloading.\n */\nexport interface MediaPlaylistMetadata {\n targetDuration: number;\n mediaSequence: number;\n playlistType?: 'VOD' | 'EVENT';\n endList: boolean;\n /**\n * Whether this rendition carries encrypted segments — any `#EXT-X-KEY` whose\n * `METHOD` isn't `NONE`. Detection only: enough to tell that playback needs\n * decryption support, not enough to perform it.\n *\n * Deliberately *not* a model-level `protection` shape. CMAF-HAM puts\n * `protection` on `SwitchingSet`, but that can't express two real cases: a\n * clear lead (`METHOD=NONE` segments followed by encrypted ones — protection\n * varies along the timeline within one rendition) or key rotation (its single\n * `defaultKid` can't represent a key changing over time). Modeling it properly\n * belongs to DRM support; until then this records the one fact a playlist\n * reliably gives us. Per-rendition because that's HLS's granularity —\n * `EXT-X-KEY` is a media-playlist tag.\n *\n * Conservative for a clear lead: a rendition whose opening segments are clear\n * still reads as encrypted, so it's judged unplayable rather than played until\n * it breaks.\n */\n encrypted?: boolean;\n /**\n * `EXT-X-SERVER-CONTROL` `HOLD-BACK` (seconds) — the server's declared distance\n * from the live edge for clients playing *complete* segments. Absent when the\n * server doesn't advertise it, in which case the spec default (3 × target\n * duration) applies. Deliberately HLS vocabulary living in the playlist\n * metadata rather than on `Track`: whether a wall-clock holdback generalizes\n * across delivery formats is unresolved.\n *\n * `PART-HOLD-BACK` is **not** captured — it only applies to clients playing\n * partial segments, and using it while fetching whole segments would put the\n * playhead ahead of the last complete segment. Add it with LL-HLS support.\n */\n holdBack?: number;\n /**\n * Whether the server is delivering this rendition as Low-Latency HLS — any of\n * `#EXT-X-PART`, `#EXT-X-PART-INF`, or `EXT-X-SERVER-CONTROL`'s\n * `PART-HOLD-BACK`.\n *\n * Detection only, and deliberately so: partial segments are ignored by the\n * parser and the loader fetches whole segments, so an LL-HLS playlist plays as\n * standard live at standard latency. Recording the fact is what lets a\n * composition *say* that rather than silently under-delivering the latency the\n * publisher configured.\n */\n lowLatency?: boolean;\n}\n\n/** Key under `Ham.metadata` where {@link MediaPlaylistMetadata} is stored. */\nexport const MEDIA_PLAYLIST_METADATA_KEY = 'mediaPlaylist';\n\n/** Typed read of the media-playlist metadata stashed in `ham.metadata`. */\nexport function getMediaPlaylistMetadata(ham: Pick<Ham, 'metadata'>): MediaPlaylistMetadata | undefined {\n return ham.metadata?.[MEDIA_PLAYLIST_METADATA_KEY] as MediaPlaylistMetadata | undefined;\n}\n\n// =============================================================================\n// Stream Type\n// =============================================================================\n\n/**\n * The source's semantic nature — live vs on-demand. A model concept\n * (consumer-facing), distinct from completeness / duration: a live stream that\n * has *ended* is still `'live'`.\n */\nexport type StreamType = 'live' | 'on-demand';\n\n/**\n * Derive {@link StreamType} from a media playlist's metadata. Per the model,\n * only `#EXT-X-PLAYLIST-TYPE:VOD` marks on-demand; everything else (EVENT, or\n * the tag absent) is live — completeness (`endList`) never factors in.\n */\nexport function deriveStreamType(metadata: MediaPlaylistMetadata | undefined): StreamType {\n return metadata?.playlistType === 'VOD' ? 'on-demand' : 'live';\n}\n\n// =============================================================================\n// Media Playlist Info\n// =============================================================================\n\n/**\n * Intermediate representation of a parsed media playlist.\n * Used internally before assembling into full Track structure.\n */\nexport interface MediaPlaylistInfo {\n version: number;\n targetDuration: number;\n playlistType: 'VOD' | 'EVENT' | undefined;\n initSegment: AddressableObject | null;\n segments: Segment[];\n duration: number;\n endList: boolean;\n}\n\n// =============================================================================\n// Presentation\n// =============================================================================\n\n/**\n * Presentation - a single playable period of content.\n * Uses TimeSpan fields (startTime always 0, duration optional until track resolved).\n *\n * Extends AddressableObject so `url` contains the original manifest URL.\n * All URLs are fully qualified (parsers resolve relative URLs).\n */\nexport type Presentation = Ham &\n AddressableObject &\n Partial<TimeSpan> & {\n selectionSets: SelectionSet[];\n /**\n * Live vs on-demand — the source's semantic nature. Populated once a media\n * playlist is parsed (derived from `#EXT-X-PLAYLIST-TYPE` via\n * `deriveStreamType`); orthogonal to duration / completeness.\n */\n streamType?: StreamType;\n };\n\n/**\n * State-shaped presentation that may or may not be resolved yet.\n *\n * The lifecycle is a single value: a caller writes `{ url }`, and the\n * resolver populates the rest in place. `url` is always present; resolved\n * fields (`id`, `selectionSets`, duration) appear once parsing succeeds.\n *\n * Use `isResolvedPresentation` to narrow to `Presentation`.\n */\nexport type MaybeResolvedPresentation = AddressableObject & Partial<Omit<Presentation, keyof AddressableObject>>;\n\n// =============================================================================\n// Type Guards\n// =============================================================================\n\n/**\n * Check if a track is resolved (has segments).\n * Works for all track types with overloaded signatures for type narrowing.\n */\nexport function isResolvedTrack(track: PartiallyResolvedVideoTrack | VideoTrack): track is VideoTrack;\nexport function isResolvedTrack(track: PartiallyResolvedAudioTrack | AudioTrack): track is AudioTrack;\nexport function isResolvedTrack(track: PartiallyResolvedTextTrack | TextTrack): track is TextTrack;\nexport function isResolvedTrack(track: PartiallyResolvedTrack | ResolvedTrack): track is ResolvedTrack;\nexport function isResolvedTrack(track: PartiallyResolvedTrack | ResolvedTrack): track is ResolvedTrack {\n return 'segments' in track;\n}\n\n/**\n * Check if a presentation has duration (at least one track resolved).\n * Narrows type to include required duration.\n */\nexport function hasPresentationDuration(\n presentation: MaybeResolvedPresentation\n): presentation is MaybeResolvedPresentation & { duration: number } {\n return presentation.duration !== undefined;\n}\n\n/**\n * Narrows a `MaybeResolvedPresentation` to a fully resolved `Presentation`.\n *\n * A presentation is resolved once `resolvePresentation` has parsed the\n * manifest and populated both `id` and `selectionSets`. Both must be\n * present — a partial value with only one of them isn't usable, and\n * letting it through would have downstream behaviors crash when they\n * access `selectionSets`.\n */\nexport function isResolvedPresentation(\n presentation: MaybeResolvedPresentation | undefined\n): presentation is Presentation {\n return presentation !== undefined && presentation.id !== undefined && presentation.selectionSets !== undefined;\n}\n"],"mappings":";;;;;;;;;AA2ZA,MAAa,uBAAuB;;AAsEpC,MAAa,8BAA8B;;AAG3C,SAAgB,yBAAyB,KAA+D;CACtG,OAAO,IAAI,WAAW;AACxB;;;;;;AAkBA,SAAgB,iBAAiB,UAAyD;CACxF,OAAO,UAAU,iBAAiB,QAAQ,cAAc;AAC1D;AAkEA,SAAgB,gBAAgB,OAAuE;CACrG,OAAO,cAAc;AACvB;;;;;AAMA,SAAgB,wBACd,cACkE;CAClE,OAAO,aAAa,aAAa,KAAA;AACnC;;;;;;;;;;AAWA,SAAgB,uBACd,cAC8B;CAC9B,OAAO,iBAAiB,KAAA,KAAa,aAAa,OAAO,KAAA,KAAa,aAAa,kBAAkB,KAAA;AACvG"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
//#region src/media/utils/cdn.d.ts
|
|
2
|
+
/**
|
|
3
|
+
* Derive a stable grouping key for the CDN a URL is served from. Synchronous and
|
|
4
|
+
* pure (deliberately not a `resolve*` — no fetch). Consumers override the
|
|
5
|
+
* default via the engine's `getCdnId` config (e.g. to key on Mux's `cdn=` query
|
|
6
|
+
* param instead of the host); every CDN-identity site reads that same function
|
|
7
|
+
* so keys stay comparable across `cdnPriority`, `failedCdns`, and the
|
|
8
|
+
* track-switching constraint + scope.
|
|
9
|
+
*/
|
|
10
|
+
type GetCdnId = (url: string) => string;
|
|
11
|
+
//#endregion
|
|
12
|
+
export { GetCdnId };
|
|
13
|
+
//# sourceMappingURL=cdn.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cdn.d.ts","names":[],"sources":["../../../../src/media/utils/cdn.ts"],"mappings":";;;;;;;;;KAUY,YAAY"}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
//#region src/media/utils/cdn.ts
|
|
2
|
+
/**
|
|
3
|
+
* Default {@link GetCdnId}: the URL's origin (scheme + host + port); falls back
|
|
4
|
+
* to the raw string when the URL can't be parsed, so the return value is always
|
|
5
|
+
* a stable grouping key.
|
|
6
|
+
*/
|
|
7
|
+
function getCdnId(url) {
|
|
8
|
+
try {
|
|
9
|
+
return new URL(url).origin;
|
|
10
|
+
} catch {
|
|
11
|
+
return url;
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
const CDN_TYPE_PRIORITY = {
|
|
15
|
+
video: 0,
|
|
16
|
+
audio: 1,
|
|
17
|
+
text: 2
|
|
18
|
+
};
|
|
19
|
+
/**
|
|
20
|
+
* The distinct CDNs a presentation's tracks are served from, ordered video CDNs
|
|
21
|
+
* first, then audio, then text (manifest order within a type). The head is the
|
|
22
|
+
* primary CDN — the one a sticky pick defaults to — and is always video-derived
|
|
23
|
+
* when the source has video. Returns `[]` for an unresolved presentation with
|
|
24
|
+
* no tracks.
|
|
25
|
+
*
|
|
26
|
+
* Redundant-stream sources list the same content on multiple hosts (e.g. Mux's
|
|
27
|
+
* `?redundant_streams=true`), so each host contributes its own candidate tracks;
|
|
28
|
+
* this collapses them to the set of CDNs across every track type. The CDN-id
|
|
29
|
+
* derivation defaults to {@link getCdnId}; pass a consumer-configured `getId` to
|
|
30
|
+
* key on something other than origin.
|
|
31
|
+
*/
|
|
32
|
+
function getOrderedCdnIds(presentation, getId = getCdnId) {
|
|
33
|
+
const seen = /* @__PURE__ */ new Set();
|
|
34
|
+
const ids = [];
|
|
35
|
+
const selectionSets = [...presentation.selectionSets ?? []].sort((a, b) => CDN_TYPE_PRIORITY[a.type] - CDN_TYPE_PRIORITY[b.type]);
|
|
36
|
+
for (const selectionSet of selectionSets) for (const switchingSet of selectionSet.switchingSets) for (const track of switchingSet.tracks) {
|
|
37
|
+
const id = getId(track.url);
|
|
38
|
+
if (seen.has(id)) continue;
|
|
39
|
+
seen.add(id);
|
|
40
|
+
ids.push(id);
|
|
41
|
+
}
|
|
42
|
+
return ids;
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Add a CDN id to a failed-CDN list, preserving order and ignoring duplicates.
|
|
46
|
+
* Idempotent: re-adding an already-present id returns the same array reference
|
|
47
|
+
* (so a no-op trip doesn't churn the `failedCdns` signal). The failover trip in
|
|
48
|
+
* `resolve-track` and the segment loaders feed this into `failedCdns` via `update`.
|
|
49
|
+
*/
|
|
50
|
+
function addFailedCdn(failed, cdn) {
|
|
51
|
+
return failed?.includes(cdn) ? failed : [...failed ?? [], cdn];
|
|
52
|
+
}
|
|
53
|
+
//#endregion
|
|
54
|
+
export { addFailedCdn, getCdnId, getOrderedCdnIds };
|
|
55
|
+
|
|
56
|
+
//# sourceMappingURL=cdn.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cdn.js","names":[],"sources":["../../../../src/media/utils/cdn.ts"],"sourcesContent":["import type { MaybeResolvedPresentation, TrackType } from '../types';\n\n/**\n * Derive a stable grouping key for the CDN a URL is served from. Synchronous and\n * pure (deliberately not a `resolve*` — no fetch). Consumers override the\n * default via the engine's `getCdnId` config (e.g. to key on Mux's `cdn=` query\n * param instead of the host); every CDN-identity site reads that same function\n * so keys stay comparable across `cdnPriority`, `failedCdns`, and the\n * track-switching constraint + scope.\n */\nexport type GetCdnId = (url: string) => string;\n\n/**\n * Default {@link GetCdnId}: the URL's origin (scheme + host + port); falls back\n * to the raw string when the URL can't be parsed, so the return value is always\n * a stable grouping key.\n */\nexport function getCdnId(url: string): string {\n try {\n return new URL(url).origin;\n } catch {\n return url;\n }\n}\n\n// Track-type priority for CDN ordering: video first, then audio, then text.\n// Selection sets are visited in this order so the head of the returned list is\n// always video-derived. `preferActiveCdn` anchors every track type to the\n// first CDN with surviving tracks (the head), so this makes \"the primary CDN\n// is the video CDN\" a guarantee of `getOrderedCdnIds` rather than a side effect\n// of the order tracks happen to be parsed in.\nconst CDN_TYPE_PRIORITY: Record<TrackType, number> = { video: 0, audio: 1, text: 2 };\n\n/**\n * The distinct CDNs a presentation's tracks are served from, ordered video CDNs\n * first, then audio, then text (manifest order within a type). The head is the\n * primary CDN — the one a sticky pick defaults to — and is always video-derived\n * when the source has video. Returns `[]` for an unresolved presentation with\n * no tracks.\n *\n * Redundant-stream sources list the same content on multiple hosts (e.g. Mux's\n * `?redundant_streams=true`), so each host contributes its own candidate tracks;\n * this collapses them to the set of CDNs across every track type. The CDN-id\n * derivation defaults to {@link getCdnId}; pass a consumer-configured `getId` to\n * key on something other than origin.\n */\nexport function getOrderedCdnIds(presentation: MaybeResolvedPresentation, getId: GetCdnId = getCdnId): string[] {\n const seen = new Set<string>();\n const ids: string[] = [];\n // Stable sort keeps manifest order among same-type selection sets.\n const selectionSets = [...(presentation.selectionSets ?? [])].sort(\n (a, b) => CDN_TYPE_PRIORITY[a.type] - CDN_TYPE_PRIORITY[b.type]\n );\n for (const selectionSet of selectionSets) {\n for (const switchingSet of selectionSet.switchingSets) {\n for (const track of switchingSet.tracks) {\n const id = getId(track.url);\n if (seen.has(id)) continue;\n seen.add(id);\n ids.push(id);\n }\n }\n }\n return ids;\n}\n\n/**\n * Add a CDN id to a failed-CDN list, preserving order and ignoring duplicates.\n * Idempotent: re-adding an already-present id returns the same array reference\n * (so a no-op trip doesn't churn the `failedCdns` signal). The failover trip in\n * `resolve-track` and the segment loaders feed this into `failedCdns` via `update`.\n */\nexport function addFailedCdn(failed: string[] | undefined, cdn: string): string[] {\n return failed?.includes(cdn) ? failed : [...(failed ?? []), cdn];\n}\n"],"mappings":";;;;;;AAiBA,SAAgB,SAAS,KAAqB;CAC5C,IAAI;EACF,OAAO,IAAI,IAAI,GAAG,CAAC,CAAC;CACtB,QAAQ;EACN,OAAO;CACT;AACF;AAQA,MAAM,oBAA+C;CAAE,OAAO;CAAG,OAAO;CAAG,MAAM;AAAE;;;;;;;;;;;;;;AAenF,SAAgB,iBAAiB,cAAyC,QAAkB,UAAoB;CAC9G,MAAM,uBAAO,IAAI,IAAY;CAC7B,MAAM,MAAgB,CAAC;CAEvB,MAAM,gBAAgB,CAAC,GAAI,aAAa,iBAAiB,CAAC,CAAE,CAAC,CAAC,MAC3D,GAAG,MAAM,kBAAkB,EAAE,QAAQ,kBAAkB,EAAE,KAC5D;CACA,KAAK,MAAM,gBAAgB,eACzB,KAAK,MAAM,gBAAgB,aAAa,eACtC,KAAK,MAAM,SAAS,aAAa,QAAQ;EACvC,MAAM,KAAK,MAAM,MAAM,GAAG;EAC1B,IAAI,KAAK,IAAI,EAAE,GAAG;EAClB,KAAK,IAAI,EAAE;EACX,IAAI,KAAK,EAAE;CACb;CAGJ,OAAO;AACT;;;;;;;AAQA,SAAgB,aAAa,QAA8B,KAAuB;CAChF,OAAO,QAAQ,SAAS,GAAG,IAAI,SAAS,CAAC,GAAI,UAAU,CAAC,GAAI,GAAG;AACjE"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
//#region src/media/utils/preload.ts
|
|
2
|
+
function isStandardPreload(value) {
|
|
3
|
+
return value === "auto" || value === "metadata" || value === "none";
|
|
4
|
+
}
|
|
5
|
+
/**
|
|
6
|
+
* Default `preload` value used as the fallback across behaviors
|
|
7
|
+
* (`syncPreload`, `resolvePresentation`, `isBlockingPreload`). Matches the
|
|
8
|
+
* `<video>`/`<audio>` element's implicit default.
|
|
9
|
+
*/
|
|
10
|
+
const DEFAULT_PRELOAD = "metadata";
|
|
11
|
+
/**
|
|
12
|
+
* True when the preload value blocks initial resolution / loading.
|
|
13
|
+
* Falsy values (undefined, empty) fall back to `defaultPreload` (default
|
|
14
|
+
* `DEFAULT_PRELOAD`); the resolved value blocks iff it is `'none'`.
|
|
15
|
+
*/
|
|
16
|
+
function isBlockingPreload(preload, defaultPreload = DEFAULT_PRELOAD) {
|
|
17
|
+
return (preload || defaultPreload) === "none";
|
|
18
|
+
}
|
|
19
|
+
//#endregion
|
|
20
|
+
export { DEFAULT_PRELOAD, isBlockingPreload, isStandardPreload };
|
|
21
|
+
|
|
22
|
+
//# sourceMappingURL=preload.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"preload.js","names":[],"sources":["../../../../src/media/utils/preload.ts"],"sourcesContent":["/**\n * The W3C-standard set of `<video>`/`<audio>` `preload` attribute values.\n * SPF allows extended values (e.g. `'canplay'`) on `state.preload`, which\n * are *not* reflected to the DOM — predicate below is the discriminator.\n */\nexport type StandardPreload = 'auto' | 'metadata' | 'none';\n\nexport function isStandardPreload(value: unknown): value is StandardPreload {\n return value === 'auto' || value === 'metadata' || value === 'none';\n}\n\n/**\n * Default `preload` value used as the fallback across behaviors\n * (`syncPreload`, `resolvePresentation`, `isBlockingPreload`). Matches the\n * `<video>`/`<audio>` element's implicit default.\n */\nexport const DEFAULT_PRELOAD = 'metadata';\n\n/**\n * True when the preload value blocks initial resolution / loading.\n * Falsy values (undefined, empty) fall back to `defaultPreload` (default\n * `DEFAULT_PRELOAD`); the resolved value blocks iff it is `'none'`.\n */\nexport function isBlockingPreload(\n preload: string | undefined,\n defaultPreload: StandardPreload = DEFAULT_PRELOAD\n): boolean {\n return (preload || defaultPreload) === 'none';\n}\n"],"mappings":";AAOA,SAAgB,kBAAkB,OAA0C;CAC1E,OAAO,UAAU,UAAU,UAAU,cAAc,UAAU;AAC/D;;;;;;AAOA,MAAa,kBAAkB;;;;;;AAO/B,SAAgB,kBACd,SACA,iBAAkC,iBACzB;CACT,QAAQ,WAAW,oBAAoB;AACzC"}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { isResolvedTrack } from "../types/index.js";
|
|
2
|
+
//#region src/media/utils/track-selection.ts
|
|
3
|
+
/**
|
|
4
|
+
* Map track type to selected track ID property key in state.
|
|
5
|
+
*/
|
|
6
|
+
const SelectedTrackIdKeyByType = {
|
|
7
|
+
video: "selectedVideoTrackId",
|
|
8
|
+
audio: "selectedAudioTrackId",
|
|
9
|
+
text: "selectedTextTrackId"
|
|
10
|
+
};
|
|
11
|
+
/**
|
|
12
|
+
* Get selected track from state by type.
|
|
13
|
+
* Returns properly typed track (partially or fully resolved) or undefined.
|
|
14
|
+
* Type parameter T is inferred from the type argument.
|
|
15
|
+
*
|
|
16
|
+
* @example
|
|
17
|
+
* const videoTrack = getSelectedTrack(state, 'video');
|
|
18
|
+
* if (videoTrack && isResolvedTrack(videoTrack)) {
|
|
19
|
+
* // videoTrack is VideoTrack
|
|
20
|
+
* }
|
|
21
|
+
*/
|
|
22
|
+
function getSelectedTrack(state, type) {
|
|
23
|
+
const { presentation } = state;
|
|
24
|
+
if (!presentation?.selectionSets) return void 0;
|
|
25
|
+
const trackId = state[SelectedTrackIdKeyByType[type]];
|
|
26
|
+
return presentation.selectionSets.find(({ type: selectionSetType }) => selectionSetType === type)?.switchingSets[0]?.tracks.find(({ id }) => id === trackId);
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Returns the duration of the first resolved selected track, preferring
|
|
30
|
+
* video over audio. A track is "resolved" once its media playlist has been
|
|
31
|
+
* parsed (per {@link isResolvedTrack}). Returns `undefined` if neither
|
|
32
|
+
* selected track is resolved.
|
|
33
|
+
*/
|
|
34
|
+
function getResolvedSelectedTrackDuration(state) {
|
|
35
|
+
if (state.selectedVideoTrackId) {
|
|
36
|
+
const video = getSelectedTrack(state, "video");
|
|
37
|
+
if (video && isResolvedTrack(video)) return video.duration;
|
|
38
|
+
}
|
|
39
|
+
if (state.selectedAudioTrackId) {
|
|
40
|
+
const audio = getSelectedTrack(state, "audio");
|
|
41
|
+
if (audio && isResolvedTrack(audio)) return audio.duration;
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
//#endregion
|
|
45
|
+
export { SelectedTrackIdKeyByType, getResolvedSelectedTrackDuration, getSelectedTrack };
|
|
46
|
+
|
|
47
|
+
//# sourceMappingURL=track-selection.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"track-selection.js","names":[],"sources":["../../../../src/media/utils/track-selection.ts"],"sourcesContent":["import type {\n AudioTrack,\n MaybeResolvedPresentation,\n PartiallyResolvedAudioTrack,\n PartiallyResolvedTextTrack,\n PartiallyResolvedVideoTrack,\n TextTrack,\n TrackType,\n VideoTrack,\n} from '../types';\nimport { isResolvedTrack } from '../types';\n\n/**\n * State shape for track selection.\n * Minimal shape containing presentation and selected track IDs.\n */\nexport interface TrackSelectionState {\n presentation?: MaybeResolvedPresentation;\n selectedVideoTrackId?: string | undefined;\n selectedAudioTrackId?: string | undefined;\n selectedTextTrackId?: string | undefined;\n}\n\n/**\n * Map track type to selected track ID property key in state.\n */\nexport const SelectedTrackIdKeyByType = {\n video: 'selectedVideoTrackId',\n audio: 'selectedAudioTrackId',\n text: 'selectedTextTrackId',\n} as const;\n\n/**\n * Get selected track from state by type.\n * Returns properly typed track (partially or fully resolved) or undefined.\n * Type parameter T is inferred from the type argument.\n *\n * @example\n * const videoTrack = getSelectedTrack(state, 'video');\n * if (videoTrack && isResolvedTrack(videoTrack)) {\n * // videoTrack is VideoTrack\n * }\n */\nexport function getSelectedTrack<T extends TrackType>(\n state: TrackSelectionState,\n type: T\n): T extends 'video'\n ? PartiallyResolvedVideoTrack | VideoTrack | undefined\n : T extends 'audio'\n ? PartiallyResolvedAudioTrack | AudioTrack | undefined\n : T extends 'text'\n ? PartiallyResolvedTextTrack | TextTrack | undefined\n : never {\n const { presentation } = state;\n\n if (!presentation?.selectionSets) return undefined as any;\n\n // Get track ID based on type\n const trackIdKey = SelectedTrackIdKeyByType[type];\n const trackId = state[trackIdKey];\n return presentation.selectionSets\n .find(({ type: selectionSetType }) => selectionSetType === type)\n ?.switchingSets[0]?.tracks.find(({ id }) => id === trackId) as any;\n}\n\n/**\n * Returns the duration of the first resolved selected track, preferring\n * video over audio. A track is \"resolved\" once its media playlist has been\n * parsed (per {@link isResolvedTrack}). Returns `undefined` if neither\n * selected track is resolved.\n */\nexport function getResolvedSelectedTrackDuration(state: TrackSelectionState): number | undefined {\n if (state.selectedVideoTrackId) {\n const video = getSelectedTrack(state, 'video');\n if (video && isResolvedTrack(video)) return video.duration;\n }\n if (state.selectedAudioTrackId) {\n const audio = getSelectedTrack(state, 'audio');\n if (audio && isResolvedTrack(audio)) return audio.duration;\n }\n return undefined;\n}\n"],"mappings":";;;;;AA0BA,MAAa,2BAA2B;CACtC,OAAO;CACP,OAAO;CACP,MAAM;AACR;;;;;;;;;;;;AAaA,SAAgB,iBACd,OACA,MAOY;CACZ,MAAM,EAAE,iBAAiB;CAEzB,IAAI,CAAC,cAAc,eAAe,OAAO,KAAA;CAIzC,MAAM,UAAU,MADG,yBAAyB;CAE5C,OAAO,aAAa,cACjB,MAAM,EAAE,MAAM,uBAAuB,qBAAqB,IAAI,CAAC,EAC9D,cAAc,EAAE,EAAE,OAAO,MAAM,EAAE,SAAS,OAAO,OAAO;AAC9D;;;;;;;AAQA,SAAgB,iCAAiC,OAAgD;CAC/F,IAAI,MAAM,sBAAsB;EAC9B,MAAM,QAAQ,iBAAiB,OAAO,OAAO;EAC7C,IAAI,SAAS,gBAAgB,KAAK,GAAG,OAAO,MAAM;CACpD;CACA,IAAI,MAAM,sBAAsB;EAC9B,MAAM,QAAQ,iBAAiB,OAAO,OAAO;EAC7C,IAAI,SAAS,gBAAgB,KAAK,GAAG,OAAO,MAAM;CACpD;AAEF"}
|