@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,148 @@
|
|
|
1
|
+
//#region src/media/hls/parse-attributes.ts
|
|
2
|
+
/**
|
|
3
|
+
* Parse HLS attribute list from a tag line.
|
|
4
|
+
* Handles both quoted and unquoted values.
|
|
5
|
+
*/
|
|
6
|
+
function parseAttributeList(line) {
|
|
7
|
+
const attributes = /* @__PURE__ */ new Map();
|
|
8
|
+
for (const match of line.matchAll(/([A-Z0-9-]+)=(?:"([^"]*)"|([^,]*))/g)) {
|
|
9
|
+
const key = match[1];
|
|
10
|
+
const value = match[2] ?? match[3] ?? "";
|
|
11
|
+
if (key) attributes.set(key, value);
|
|
12
|
+
}
|
|
13
|
+
return attributes;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Parse RESOLUTION attribute value (WIDTHxHEIGHT).
|
|
17
|
+
*/
|
|
18
|
+
function parseResolution(value) {
|
|
19
|
+
const match = /^(\d+)x(\d+)$/.exec(value);
|
|
20
|
+
if (!match) return null;
|
|
21
|
+
return {
|
|
22
|
+
width: Number.parseInt(match[1], 10),
|
|
23
|
+
height: Number.parseInt(match[2], 10)
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Parse FRAME-RATE attribute to rational frame rate.
|
|
28
|
+
*/
|
|
29
|
+
function parseFrameRate(value) {
|
|
30
|
+
const fps = Number.parseFloat(value);
|
|
31
|
+
if (Number.isNaN(fps) || fps <= 0) return void 0;
|
|
32
|
+
if (Math.abs(fps - 23.976) < .01) return {
|
|
33
|
+
frameRateNumerator: 24e3,
|
|
34
|
+
frameRateDenominator: 1001
|
|
35
|
+
};
|
|
36
|
+
if (Math.abs(fps - 29.97) < .01) return {
|
|
37
|
+
frameRateNumerator: 3e4,
|
|
38
|
+
frameRateDenominator: 1001
|
|
39
|
+
};
|
|
40
|
+
if (Math.abs(fps - 59.94) < .01) return {
|
|
41
|
+
frameRateNumerator: 6e4,
|
|
42
|
+
frameRateDenominator: 1001
|
|
43
|
+
};
|
|
44
|
+
if (fps % 1 === 0) return { frameRateNumerator: Math.round(fps) };
|
|
45
|
+
return { frameRateNumerator: Math.round(fps) };
|
|
46
|
+
}
|
|
47
|
+
const AUDIO_CODEC_PREFIXES = [
|
|
48
|
+
"mp4a.",
|
|
49
|
+
"ac-3",
|
|
50
|
+
"ec-3",
|
|
51
|
+
"ac-4",
|
|
52
|
+
"opus",
|
|
53
|
+
"flac",
|
|
54
|
+
"dts",
|
|
55
|
+
"alac",
|
|
56
|
+
"vorbis"
|
|
57
|
+
];
|
|
58
|
+
/**
|
|
59
|
+
* Parse CODECS attribute into separate video and audio codecs.
|
|
60
|
+
*/
|
|
61
|
+
function parseCodecs(codecs) {
|
|
62
|
+
const parts = codecs.split(",").map((s) => s.trim());
|
|
63
|
+
const result = {};
|
|
64
|
+
for (const codec of parts) {
|
|
65
|
+
const lower = codec.toLowerCase();
|
|
66
|
+
if (codec.startsWith("avc1.") || codec.startsWith("hvc1.") || codec.startsWith("hev1.")) result.video = codec;
|
|
67
|
+
else if (AUDIO_CODEC_PREFIXES.some((prefix) => lower.startsWith(prefix))) result.audio = codec;
|
|
68
|
+
}
|
|
69
|
+
return result;
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* Parse #EXTINF duration value.
|
|
73
|
+
*/
|
|
74
|
+
function parseExtInfDuration(value) {
|
|
75
|
+
const durationPart = value.split(",")[0] ?? value;
|
|
76
|
+
const duration = Number.parseFloat(durationPart);
|
|
77
|
+
return Number.isNaN(duration) ? 0 : duration;
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* Parse BYTERANGE attribute value.
|
|
81
|
+
* Format: "length[@offset]"
|
|
82
|
+
* If offset is omitted, it continues from the previous byte range end.
|
|
83
|
+
*/
|
|
84
|
+
function parseByteRange(value, previousEnd) {
|
|
85
|
+
const match = /^(\d+)(?:@(\d+))?$/.exec(value);
|
|
86
|
+
if (!match) return null;
|
|
87
|
+
const length = Number.parseInt(match[1], 10);
|
|
88
|
+
if (Number.isNaN(length)) return null;
|
|
89
|
+
let start;
|
|
90
|
+
if (match[2] !== void 0) {
|
|
91
|
+
start = Number.parseInt(match[2], 10);
|
|
92
|
+
if (Number.isNaN(start)) return null;
|
|
93
|
+
} else if (previousEnd !== void 0) start = previousEnd;
|
|
94
|
+
else return null;
|
|
95
|
+
return {
|
|
96
|
+
start,
|
|
97
|
+
end: start + length - 1
|
|
98
|
+
};
|
|
99
|
+
}
|
|
100
|
+
/**
|
|
101
|
+
* Create AttributeList from raw attribute string.
|
|
102
|
+
*/
|
|
103
|
+
function createAttributeList(line) {
|
|
104
|
+
const map = parseAttributeList(line);
|
|
105
|
+
return {
|
|
106
|
+
get(key) {
|
|
107
|
+
return map.get(key);
|
|
108
|
+
},
|
|
109
|
+
getInt(key, defaultValue) {
|
|
110
|
+
const value = map.get(key);
|
|
111
|
+
if (value === void 0) return defaultValue;
|
|
112
|
+
const parsed = Number.parseInt(value, 10);
|
|
113
|
+
return Number.isNaN(parsed) ? defaultValue : parsed;
|
|
114
|
+
},
|
|
115
|
+
getFloat(key, defaultValue) {
|
|
116
|
+
const value = map.get(key);
|
|
117
|
+
if (value === void 0) return defaultValue;
|
|
118
|
+
const parsed = Number.parseFloat(value);
|
|
119
|
+
return Number.isNaN(parsed) ? defaultValue : parsed;
|
|
120
|
+
},
|
|
121
|
+
getBool(key) {
|
|
122
|
+
return map.get(key) === "YES";
|
|
123
|
+
},
|
|
124
|
+
getResolution(key) {
|
|
125
|
+
const value = map.get(key);
|
|
126
|
+
if (!value) return void 0;
|
|
127
|
+
return parseResolution(value) ?? void 0;
|
|
128
|
+
},
|
|
129
|
+
getFrameRate(key) {
|
|
130
|
+
const value = map.get(key);
|
|
131
|
+
if (!value) return void 0;
|
|
132
|
+
return parseFrameRate(value);
|
|
133
|
+
}
|
|
134
|
+
};
|
|
135
|
+
}
|
|
136
|
+
/**
|
|
137
|
+
* Match a tag and extract its attributes.
|
|
138
|
+
* Returns null if the line doesn't match the tag.
|
|
139
|
+
*/
|
|
140
|
+
function matchTag(line, tag) {
|
|
141
|
+
const prefix = `#${tag}:`;
|
|
142
|
+
if (!line.startsWith(prefix)) return null;
|
|
143
|
+
return createAttributeList(line.slice(prefix.length));
|
|
144
|
+
}
|
|
145
|
+
//#endregion
|
|
146
|
+
export { createAttributeList, matchTag, parseAttributeList, parseByteRange, parseCodecs, parseExtInfDuration, parseFrameRate, parseResolution };
|
|
147
|
+
|
|
148
|
+
//# sourceMappingURL=parse-attributes.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"parse-attributes.js","names":[],"sources":["../../../../src/media/hls/parse-attributes.ts"],"sourcesContent":["import type { FrameRate } from '../types';\n\n/**\n * Parse HLS attribute list from a tag line.\n * Handles both quoted and unquoted values.\n */\nexport function parseAttributeList(line: string): Map<string, string> {\n const attributes = new Map<string, string>();\n const regex = /([A-Z0-9-]+)=(?:\"([^\"]*)\"|([^,]*))/g;\n\n for (const match of line.matchAll(regex)) {\n const key = match[1];\n const value = match[2] ?? match[3] ?? '';\n if (key) {\n attributes.set(key, value);\n }\n }\n\n return attributes;\n}\n\n/**\n * Parse RESOLUTION attribute value (WIDTHxHEIGHT).\n */\nexport function parseResolution(value: string): { width: number; height: number } | null {\n const match = /^(\\d+)x(\\d+)$/.exec(value);\n if (!match) return null;\n\n const width = Number.parseInt(match[1]!, 10);\n const height = Number.parseInt(match[2]!, 10);\n\n return { width, height };\n}\n\n/**\n * Parse FRAME-RATE attribute to rational frame rate.\n */\nexport function parseFrameRate(value: string): FrameRate | undefined {\n const fps = Number.parseFloat(value);\n if (Number.isNaN(fps) || fps <= 0) return undefined;\n\n // Common frame rates with tolerance for floating point precision\n if (Math.abs(fps - 23.976) < 0.01) {\n return { frameRateNumerator: 24000, frameRateDenominator: 1001 };\n }\n if (Math.abs(fps - 29.97) < 0.01) {\n return { frameRateNumerator: 30000, frameRateDenominator: 1001 };\n }\n if (Math.abs(fps - 59.94) < 0.01) {\n return { frameRateNumerator: 60000, frameRateDenominator: 1001 };\n }\n\n // Integer frame rates\n if (fps % 1 === 0) {\n return { frameRateNumerator: Math.round(fps) };\n }\n\n // Default: use rounded value\n return { frameRateNumerator: Math.round(fps) };\n}\n\n// Audio codec identifiers, matched case-insensitively against each CODECS\n// entry's prefix. Beyond AAC (`mp4a.*`): Dolby (`ac-3`, `ec-3`, `ac-4`), Opus,\n// FLAC (`fLaC`), DTS (`dts*`), ALAC, and Vorbis. Recognizing these is what lets\n// capability probing filter undecodable audio renditions (e.g. an AC-3 5.1\n// track on a browser without AC-3) — an unrecognized codec parses empty and is\n// treated as unprobeable, so it would never be pruned.\nconst AUDIO_CODEC_PREFIXES = ['mp4a.', 'ac-3', 'ec-3', 'ac-4', 'opus', 'flac', 'dts', 'alac', 'vorbis'];\n\n/**\n * Parse CODECS attribute into separate video and audio codecs.\n */\nexport function parseCodecs(codecs: string): { video?: string; audio?: string } {\n const parts = codecs.split(',').map((s) => s.trim());\n const result: { video?: string; audio?: string } = {};\n\n for (const codec of parts) {\n const lower = codec.toLowerCase();\n if (codec.startsWith('avc1.') || codec.startsWith('hvc1.') || codec.startsWith('hev1.')) {\n result.video = codec;\n } else if (AUDIO_CODEC_PREFIXES.some((prefix) => lower.startsWith(prefix))) {\n result.audio = codec;\n }\n }\n\n return result;\n}\n\n/**\n * Parse #EXTINF duration value.\n */\nexport function parseExtInfDuration(value: string): number {\n const durationPart = value.split(',')[0] ?? value;\n const duration = Number.parseFloat(durationPart);\n return Number.isNaN(duration) ? 0 : duration;\n}\n\n/**\n * Parse BYTERANGE attribute value.\n * Format: \"length[@offset]\"\n * If offset is omitted, it continues from the previous byte range end.\n */\nexport function parseByteRange(value: string, previousEnd?: number): { start: number; end: number } | null {\n const match = /^(\\d+)(?:@(\\d+))?$/.exec(value);\n if (!match) return null;\n\n const length = Number.parseInt(match[1]!, 10);\n if (Number.isNaN(length)) return null;\n\n let start: number;\n if (match[2] !== undefined) {\n start = Number.parseInt(match[2], 10);\n if (Number.isNaN(start)) return null;\n } else if (previousEnd !== undefined) {\n start = previousEnd;\n } else {\n return null;\n }\n\n return { start, end: start + length - 1 };\n}\n\n/**\n * AttributeList - Typed attribute access wrapper.\n */\nexport interface AttributeList {\n get: (key: string) => string | undefined;\n getInt: (key: string, defaultValue?: number) => number | undefined;\n getFloat: (key: string, defaultValue?: number) => number | undefined;\n getBool: (key: string) => boolean;\n getResolution: (key: string) => { width: number; height: number } | undefined;\n getFrameRate: (key: string) => FrameRate | undefined;\n}\n\n/**\n * Create AttributeList from raw attribute string.\n */\nexport function createAttributeList(line: string): AttributeList {\n const map = parseAttributeList(line);\n\n return {\n get(key: string): string | undefined {\n return map.get(key);\n },\n\n getInt(key: string, defaultValue?: number): number | undefined {\n const value = map.get(key);\n if (value === undefined) return defaultValue;\n const parsed = Number.parseInt(value, 10);\n return Number.isNaN(parsed) ? defaultValue : parsed;\n },\n\n getFloat(key: string, defaultValue?: number): number | undefined {\n const value = map.get(key);\n if (value === undefined) return defaultValue;\n const parsed = Number.parseFloat(value);\n return Number.isNaN(parsed) ? defaultValue : parsed;\n },\n\n getBool(key: string): boolean {\n return map.get(key) === 'YES';\n },\n\n getResolution(key: string): { width: number; height: number } | undefined {\n const value = map.get(key);\n if (!value) return undefined;\n return parseResolution(value) ?? undefined;\n },\n\n getFrameRate(key: string): FrameRate | undefined {\n const value = map.get(key);\n if (!value) return undefined;\n return parseFrameRate(value);\n },\n };\n}\n\n/**\n * Match a tag and extract its attributes.\n * Returns null if the line doesn't match the tag.\n */\nexport function matchTag(line: string, tag: string): AttributeList | null {\n const prefix = `#${tag}:`;\n if (!line.startsWith(prefix)) return null;\n return createAttributeList(line.slice(prefix.length));\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1,261 @@
|
|
|
1
|
+
import { MEDIA_PLAYLIST_METADATA_KEY, getMediaPlaylistMetadata, isResolvedTrack } from "../types/index.js";
|
|
2
|
+
import { matchTag, parseByteRange, parseExtInfDuration } from "./parse-attributes.js";
|
|
3
|
+
import { resolveUrl } from "./resolve-url.js";
|
|
4
|
+
import { isUndefined } from "@videojs/utils/predicate";
|
|
5
|
+
//#region src/media/hls/parse-media-playlist.ts
|
|
6
|
+
/** MPEG-2 Transport Stream (IANA `video/MP2T`, lowercased for `isTypeSupported`). Video + audio TS — there is no `audio/mp2t`. */
|
|
7
|
+
const MPEG_TS_MIME = "video/mp2t";
|
|
8
|
+
/** Raw ADTS AAC packed-audio (HLS `.aac` segments; IANA `audio/aac`). */
|
|
9
|
+
const RAW_AAC_MIME = "audio/aac";
|
|
10
|
+
const CONTAINER_MIME_BY_EXTENSION = {
|
|
11
|
+
".ts": MPEG_TS_MIME,
|
|
12
|
+
".aac": RAW_AAC_MIME
|
|
13
|
+
};
|
|
14
|
+
/** The non-fMP4 container MIMEs the parser detects — all currently treated as unplayable. */
|
|
15
|
+
const NON_FMP4_CONTAINER_MIMES = new Set(Object.values(CONTAINER_MIME_BY_EXTENSION));
|
|
16
|
+
/**
|
|
17
|
+
* Non-fMP4 container MIME for a (resolved, absolute) segment URL, by file
|
|
18
|
+
* extension, ignoring the query string. `undefined` for fMP4 / unrecognized.
|
|
19
|
+
*/
|
|
20
|
+
function containerMimeFromSegment(url) {
|
|
21
|
+
if (!url) return void 0;
|
|
22
|
+
let path;
|
|
23
|
+
try {
|
|
24
|
+
path = new URL(url).pathname.toLowerCase();
|
|
25
|
+
} catch {
|
|
26
|
+
path = url.toLowerCase().split("?")[0] ?? "";
|
|
27
|
+
}
|
|
28
|
+
const dot = path.lastIndexOf(".");
|
|
29
|
+
return dot === -1 ? void 0 : CONTAINER_MIME_BY_EXTENSION[path.slice(dot)];
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Position a freshly-parsed window (whose segment `startTime`s are snapshot-
|
|
33
|
+
* local, i.e. from 0) onto the timeline established by the previous resolved
|
|
34
|
+
* snapshot. Carries the timeline forward using the media-sequence overlap and
|
|
35
|
+
* the previous window's *actual* segment durations — see
|
|
36
|
+
* `internal/design/spf/live-presentation-timeline-model.md`.
|
|
37
|
+
*
|
|
38
|
+
* - **Overlap** (`0 <= offset < previous.segments.length`): the new window's
|
|
39
|
+
* first segment is the same segment as `previous.segments[offset]`; anchor to
|
|
40
|
+
* its start (URLs checked — a mismatch warns).
|
|
41
|
+
* - **Sequence went backwards** (non-conformant): reset to the local base.
|
|
42
|
+
* - **Full turnover** (no overlap): estimate forward from the previous window's
|
|
43
|
+
* end across the unseen gap. This is the *only* place EXT-X-TARGETDURATION is
|
|
44
|
+
* used for timing — an upper-bound estimate, since the actual rolled-off
|
|
45
|
+
* durations are gone (exact recovery is the deferred PDT decision).
|
|
46
|
+
*
|
|
47
|
+
* Returns the rebased segments (the window edge is `segments[0].startTime`,
|
|
48
|
+
* derived — never stored on the track).
|
|
49
|
+
*/
|
|
50
|
+
function placeOnPreviousTimeline(previous, segments, mediaSequence, targetDuration) {
|
|
51
|
+
const prevSegments = previous.segments;
|
|
52
|
+
const localBase = segments[0]?.startTime ?? 0;
|
|
53
|
+
if (prevSegments.length === 0 || segments.length === 0) return segments;
|
|
54
|
+
const offset = mediaSequence - (getMediaPlaylistMetadata(previous)?.mediaSequence ?? 0);
|
|
55
|
+
let anchor;
|
|
56
|
+
if (offset >= 0 && offset < prevSegments.length) {
|
|
57
|
+
const overlap = prevSegments[offset];
|
|
58
|
+
if (overlap.url !== segments[0].url) console.warn(`[parseMediaPlaylist] media-sequence aligns previous[${offset}] with the new window's first segment, but URLs differ (${overlap.url} vs ${segments[0].url}); sequence numbers may be unreliable.`);
|
|
59
|
+
anchor = overlap.startTime;
|
|
60
|
+
} else if (offset < 0) {
|
|
61
|
+
console.warn(`[parseMediaPlaylist] media-sequence went backwards (offset ${offset}); resetting timeline.`);
|
|
62
|
+
anchor = localBase;
|
|
63
|
+
} else {
|
|
64
|
+
const last = prevSegments[prevSegments.length - 1];
|
|
65
|
+
const newFirst = segments[0];
|
|
66
|
+
if (last.startDate !== void 0 && newFirst.startDate !== void 0) anchor = last.startTime + (newFirst.startDate - last.startDate);
|
|
67
|
+
else {
|
|
68
|
+
anchor = last.startTime + last.duration + (offset - prevSegments.length) * targetDuration;
|
|
69
|
+
console.warn(`[parseMediaPlaylist] full window turnover (offset ${offset} >= ${prevSegments.length}); no PDT to bridge — estimating from previous end.`);
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
const shift = anchor - localBase;
|
|
73
|
+
return shift === 0 ? segments : segments.map((segment) => ({
|
|
74
|
+
...segment,
|
|
75
|
+
startTime: segment.startTime + shift
|
|
76
|
+
}));
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* Place a window on the frozen wall-clock anchor — the track's `startDate`
|
|
80
|
+
* (wall clock at media-time 0). The anchoring PDT-bearing segment lands at
|
|
81
|
+
* `segment.startDate − anchor`, so the window sits on the shared presentation
|
|
82
|
+
* timeline rather than a local-from-zero one (the `startDate` recomputed
|
|
83
|
+
* afterwards then reads back as the anchor — idempotent). This is the **main
|
|
84
|
+
* live path on every parse**: first resolves place against the pre-stamped
|
|
85
|
+
* shell anchor, and reloads re-place from PDT so drift can't accumulate and a
|
|
86
|
+
* long-stall turnover re-places with no overlap bridging (the HLS authoring
|
|
87
|
+
* spec's §8.1 EXTINF-accuracy rule bounds the per-reload correction to ~one
|
|
88
|
+
* video frame). Falls back to the local base when no segment carries PDT —
|
|
89
|
+
* there's nothing to anchor against (callers guard this for reloads, where the
|
|
90
|
+
* local base would reset the timeline).
|
|
91
|
+
*/
|
|
92
|
+
function placeOnAnchor(segments, anchor) {
|
|
93
|
+
const anchorSegment = segments.find((segment) => !isUndefined(segment.startDate));
|
|
94
|
+
if (!anchorSegment || isUndefined(anchorSegment.startDate)) return segments;
|
|
95
|
+
const shift = anchorSegment.startDate - anchor - anchorSegment.startTime;
|
|
96
|
+
if (shift === 0) return segments;
|
|
97
|
+
return segments.map((segment) => ({
|
|
98
|
+
...segment,
|
|
99
|
+
startTime: segment.startTime + shift
|
|
100
|
+
}));
|
|
101
|
+
}
|
|
102
|
+
/**
|
|
103
|
+
* Parse HLS media playlist and resolve track with segments.
|
|
104
|
+
*
|
|
105
|
+
* `previous` is what was known about this track before this parse: the
|
|
106
|
+
* partially-resolved track from the multivariant playlist on the first resolve,
|
|
107
|
+
* or the previously-resolved snapshot on a live reload. Its metadata is carried
|
|
108
|
+
* onto the result either way; when it's already resolved (has segments), its
|
|
109
|
+
* timeline is carried forward so the new window lands on a stable, advancing
|
|
110
|
+
* timeline (see {@link placeOnPreviousTimeline}).
|
|
111
|
+
*
|
|
112
|
+
* @param text - Media playlist text content
|
|
113
|
+
* @param previous - Prior track state (unresolved shell, or previous resolved snapshot)
|
|
114
|
+
* @returns Resolved track with segments (type inferred from input)
|
|
115
|
+
*/
|
|
116
|
+
function parseMediaPlaylist(text, previous) {
|
|
117
|
+
const lines = text.split(/\r?\n/);
|
|
118
|
+
const baseUrl = previous.url;
|
|
119
|
+
const segments = [];
|
|
120
|
+
let initSegmentUrl;
|
|
121
|
+
let initSegmentByteRange;
|
|
122
|
+
let currentDuration = 0;
|
|
123
|
+
let currentByteRange;
|
|
124
|
+
let currentTime = 0;
|
|
125
|
+
let segmentIndex = 0;
|
|
126
|
+
let previousByteRangeEnd;
|
|
127
|
+
let currentStartDate;
|
|
128
|
+
let targetDuration = 0;
|
|
129
|
+
let mediaSequence = 0;
|
|
130
|
+
let playlistType;
|
|
131
|
+
let endList = false;
|
|
132
|
+
let holdBack;
|
|
133
|
+
let lowLatency = false;
|
|
134
|
+
let encrypted = false;
|
|
135
|
+
for (const line of lines) {
|
|
136
|
+
const trimmed = line.trim();
|
|
137
|
+
if (!trimmed || trimmed.startsWith("#") && !trimmed.startsWith("#EXT")) continue;
|
|
138
|
+
if (trimmed.startsWith("#EXT-X-TARGETDURATION:")) {
|
|
139
|
+
targetDuration = Number.parseInt(trimmed.slice(22), 10) || 0;
|
|
140
|
+
continue;
|
|
141
|
+
}
|
|
142
|
+
if (trimmed.startsWith("#EXT-X-MEDIA-SEQUENCE:")) {
|
|
143
|
+
mediaSequence = Number.parseInt(trimmed.slice(22), 10) || 0;
|
|
144
|
+
continue;
|
|
145
|
+
}
|
|
146
|
+
if (trimmed.startsWith("#EXT-X-PROGRAM-DATE-TIME:")) {
|
|
147
|
+
const parsed = Date.parse(trimmed.slice(25).trim());
|
|
148
|
+
currentStartDate = Number.isNaN(parsed) ? currentStartDate : parsed / 1e3;
|
|
149
|
+
continue;
|
|
150
|
+
}
|
|
151
|
+
if (trimmed.startsWith("#EXT-X-PLAYLIST-TYPE:")) {
|
|
152
|
+
const value = trimmed.slice(21).trim();
|
|
153
|
+
playlistType = value === "VOD" || value === "EVENT" ? value : void 0;
|
|
154
|
+
continue;
|
|
155
|
+
}
|
|
156
|
+
const key = matchTag(trimmed, "EXT-X-KEY");
|
|
157
|
+
if (key) {
|
|
158
|
+
const method = key.get("METHOD");
|
|
159
|
+
if (method !== void 0 && method !== "NONE") encrypted = true;
|
|
160
|
+
continue;
|
|
161
|
+
}
|
|
162
|
+
const serverControl = matchTag(trimmed, "EXT-X-SERVER-CONTROL");
|
|
163
|
+
if (serverControl) {
|
|
164
|
+
const value = serverControl.get("HOLD-BACK");
|
|
165
|
+
if (value !== void 0) {
|
|
166
|
+
const parsed = Number.parseFloat(value);
|
|
167
|
+
if (Number.isFinite(parsed) && parsed > 0) holdBack = parsed;
|
|
168
|
+
}
|
|
169
|
+
if (serverControl.get("PART-HOLD-BACK") !== void 0) lowLatency = true;
|
|
170
|
+
continue;
|
|
171
|
+
}
|
|
172
|
+
if (trimmed.startsWith("#EXT-X-PART-INF") || trimmed.startsWith("#EXT-X-PART:")) {
|
|
173
|
+
lowLatency = true;
|
|
174
|
+
continue;
|
|
175
|
+
}
|
|
176
|
+
if (trimmed === "#EXTM3U" || trimmed.startsWith("#EXT-X-VERSION:") || trimmed.startsWith("#EXT-X-INDEPENDENT-SEGMENTS")) continue;
|
|
177
|
+
const mapAttrs = matchTag(trimmed, "EXT-X-MAP");
|
|
178
|
+
if (mapAttrs) {
|
|
179
|
+
const uri = mapAttrs.get("URI");
|
|
180
|
+
if (uri) {
|
|
181
|
+
initSegmentUrl = resolveUrl(uri, baseUrl);
|
|
182
|
+
const byteRangeStr = mapAttrs.get("BYTERANGE");
|
|
183
|
+
if (byteRangeStr) initSegmentByteRange = parseByteRange(byteRangeStr, 0) ?? void 0;
|
|
184
|
+
}
|
|
185
|
+
continue;
|
|
186
|
+
}
|
|
187
|
+
if (trimmed.startsWith("#EXTINF:")) {
|
|
188
|
+
currentDuration = parseExtInfDuration(trimmed.slice(8));
|
|
189
|
+
continue;
|
|
190
|
+
}
|
|
191
|
+
if (trimmed.startsWith("#EXT-X-BYTERANGE:")) {
|
|
192
|
+
currentByteRange = parseByteRange(trimmed.slice(17), previousByteRangeEnd) ?? void 0;
|
|
193
|
+
continue;
|
|
194
|
+
}
|
|
195
|
+
if (trimmed === "#EXT-X-ENDLIST") {
|
|
196
|
+
endList = true;
|
|
197
|
+
continue;
|
|
198
|
+
}
|
|
199
|
+
if (!trimmed.startsWith("#") && currentDuration > 0) {
|
|
200
|
+
const segment = {
|
|
201
|
+
id: `segment-${mediaSequence + segmentIndex}`,
|
|
202
|
+
url: resolveUrl(trimmed, baseUrl),
|
|
203
|
+
duration: currentDuration,
|
|
204
|
+
startTime: currentTime
|
|
205
|
+
};
|
|
206
|
+
if (!isUndefined(currentStartDate)) {
|
|
207
|
+
segment.startDate = currentStartDate;
|
|
208
|
+
currentStartDate += currentDuration;
|
|
209
|
+
}
|
|
210
|
+
if (currentByteRange) {
|
|
211
|
+
segment.byteRange = currentByteRange;
|
|
212
|
+
previousByteRangeEnd = currentByteRange.end + 1;
|
|
213
|
+
} else previousByteRangeEnd = void 0;
|
|
214
|
+
segments.push(segment);
|
|
215
|
+
currentTime += currentDuration;
|
|
216
|
+
segmentIndex++;
|
|
217
|
+
currentDuration = 0;
|
|
218
|
+
currentByteRange = void 0;
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
const complete = endList || playlistType === "VOD";
|
|
222
|
+
const anchor = previous.startDate;
|
|
223
|
+
const hasPdt = segments.some((segment) => !isUndefined(segment.startDate));
|
|
224
|
+
const placed = !isUndefined(anchor) && hasPdt ? placeOnAnchor(segments, anchor) : isResolvedTrack(previous) ? placeOnPreviousTimeline(previous, segments, mediaSequence, targetDuration) : segments;
|
|
225
|
+
const lastPlaced = placed[placed.length - 1];
|
|
226
|
+
const placedEnd = lastPlaced ? lastPlaced.startTime + lastPlaced.duration : 0;
|
|
227
|
+
const trackDuration = complete ? placedEnd : Number.POSITIVE_INFINITY;
|
|
228
|
+
const anchorSegment = placed.find((segment) => !isUndefined(segment.startDate));
|
|
229
|
+
const startDate = anchorSegment && !isUndefined(anchorSegment.startDate) ? anchorSegment.startDate - anchorSegment.startTime : void 0;
|
|
230
|
+
const initialization = previous.type === "text" && !initSegmentUrl ? void 0 : initSegmentUrl ? {
|
|
231
|
+
url: initSegmentUrl,
|
|
232
|
+
...initSegmentByteRange ? { byteRange: initSegmentByteRange } : {}
|
|
233
|
+
} : { url: "" };
|
|
234
|
+
const detectedContainer = initSegmentUrl ? void 0 : containerMimeFromSegment(placed[0]?.url);
|
|
235
|
+
const mimeType = previous.type !== "text" && detectedContainer ? detectedContainer : previous.mimeType;
|
|
236
|
+
return {
|
|
237
|
+
...previous,
|
|
238
|
+
mimeType,
|
|
239
|
+
startTime: 0,
|
|
240
|
+
startDate,
|
|
241
|
+
duration: trackDuration,
|
|
242
|
+
segments: placed,
|
|
243
|
+
initialization,
|
|
244
|
+
metadata: {
|
|
245
|
+
...previous.metadata,
|
|
246
|
+
[MEDIA_PLAYLIST_METADATA_KEY]: {
|
|
247
|
+
targetDuration,
|
|
248
|
+
mediaSequence,
|
|
249
|
+
playlistType,
|
|
250
|
+
lowLatency,
|
|
251
|
+
endList,
|
|
252
|
+
holdBack,
|
|
253
|
+
encrypted
|
|
254
|
+
}
|
|
255
|
+
}
|
|
256
|
+
};
|
|
257
|
+
}
|
|
258
|
+
//#endregion
|
|
259
|
+
export { MPEG_TS_MIME, NON_FMP4_CONTAINER_MIMES, RAW_AAC_MIME, parseMediaPlaylist };
|
|
260
|
+
|
|
261
|
+
//# sourceMappingURL=parse-media-playlist.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"parse-media-playlist.js","names":[],"sources":["../../../../src/media/hls/parse-media-playlist.ts"],"sourcesContent":["import { isUndefined } from '@videojs/utils/predicate';\nimport {\n type AudioTrack,\n getMediaPlaylistMetadata,\n isResolvedTrack,\n MEDIA_PLAYLIST_METADATA_KEY,\n type MediaPlaylistMetadata,\n type PartiallyResolvedAudioTrack,\n type PartiallyResolvedTextTrack,\n type PartiallyResolvedTrack,\n type PartiallyResolvedVideoTrack,\n type ResolvedTrack,\n type Segment,\n type TextTrack,\n type VideoTrack,\n} from '../types';\nimport { matchTag, parseByteRange, parseExtInfDuration } from './parse-attributes';\nimport { resolveUrl } from './resolve-url';\n\n/** MPEG-2 Transport Stream (IANA `video/MP2T`, lowercased for `isTypeSupported`). Video + audio TS — there is no `audio/mp2t`. */\nexport const MPEG_TS_MIME = 'video/mp2t';\n/** Raw ADTS AAC packed-audio (HLS `.aac` segments; IANA `audio/aac`). */\nexport const RAW_AAC_MIME = 'audio/aac';\n\n// Non-fMP4 container MIMEs keyed by segment file extension. fMP4 (the MSE\n// default) always carries an EXT-X-MAP init segment, so a media playlist with\n// no init segment and one of these extensions is a non-fMP4 rendition,\n// relabeled from the fMP4 default. Extend with `.mp3` → 'audio/mpeg' etc.\nconst CONTAINER_MIME_BY_EXTENSION: Record<string, string> = {\n '.ts': MPEG_TS_MIME,\n '.aac': RAW_AAC_MIME,\n};\n\n/** The non-fMP4 container MIMEs the parser detects — all currently treated as unplayable. */\nexport const NON_FMP4_CONTAINER_MIMES = new Set(Object.values(CONTAINER_MIME_BY_EXTENSION));\n\n/**\n * Non-fMP4 container MIME for a (resolved, absolute) segment URL, by file\n * extension, ignoring the query string. `undefined` for fMP4 / unrecognized.\n */\nfunction containerMimeFromSegment(url: string | undefined): string | undefined {\n if (!url) return undefined;\n let path: string;\n try {\n path = new URL(url).pathname.toLowerCase();\n } catch {\n path = url.toLowerCase().split('?')[0] ?? '';\n }\n const dot = path.lastIndexOf('.');\n return dot === -1 ? undefined : CONTAINER_MIME_BY_EXTENSION[path.slice(dot)];\n}\n\n/**\n * Resolve unresolved track type to its resolved equivalent.\n */\ntype ResolveTrack<T> = T extends PartiallyResolvedVideoTrack\n ? VideoTrack\n : T extends PartiallyResolvedAudioTrack\n ? AudioTrack\n : T extends PartiallyResolvedTextTrack\n ? TextTrack\n : never;\n\n/**\n * Position a freshly-parsed window (whose segment `startTime`s are snapshot-\n * local, i.e. from 0) onto the timeline established by the previous resolved\n * snapshot. Carries the timeline forward using the media-sequence overlap and\n * the previous window's *actual* segment durations — see\n * `internal/design/spf/live-presentation-timeline-model.md`.\n *\n * - **Overlap** (`0 <= offset < previous.segments.length`): the new window's\n * first segment is the same segment as `previous.segments[offset]`; anchor to\n * its start (URLs checked — a mismatch warns).\n * - **Sequence went backwards** (non-conformant): reset to the local base.\n * - **Full turnover** (no overlap): estimate forward from the previous window's\n * end across the unseen gap. This is the *only* place EXT-X-TARGETDURATION is\n * used for timing — an upper-bound estimate, since the actual rolled-off\n * durations are gone (exact recovery is the deferred PDT decision).\n *\n * Returns the rebased segments (the window edge is `segments[0].startTime`,\n * derived — never stored on the track).\n */\nfunction placeOnPreviousTimeline(\n previous: ResolvedTrack,\n segments: Segment[],\n mediaSequence: number,\n targetDuration: number\n): Segment[] {\n const prevSegments = previous.segments;\n const localBase = segments[0]?.startTime ?? 0;\n\n if (prevSegments.length === 0 || segments.length === 0) {\n return segments;\n }\n\n const prevMediaSequence = getMediaPlaylistMetadata(previous)?.mediaSequence ?? 0;\n const offset = mediaSequence - prevMediaSequence;\n\n let anchor: number;\n if (offset >= 0 && offset < prevSegments.length) {\n const overlap = prevSegments[offset]!;\n if (overlap.url !== segments[0]!.url) {\n console.warn(\n `[parseMediaPlaylist] media-sequence aligns previous[${offset}] with the new window's first segment, ` +\n `but URLs differ (${overlap.url} vs ${segments[0]!.url}); sequence numbers may be unreliable.`\n );\n }\n anchor = overlap.startTime;\n } else if (offset < 0) {\n console.warn(`[parseMediaPlaylist] media-sequence went backwards (offset ${offset}); resetting timeline.`);\n anchor = localBase;\n } else {\n const last = prevSegments[prevSegments.length - 1]!;\n const newFirst = segments[0]!;\n if (last.startDate !== undefined && newFirst.startDate !== undefined) {\n // PDT bridges the gap exactly — the spec-consistent cross-reload reference,\n // immune to the target-duration over-estimate when actual segment durations\n // differ from the declared ceiling. (`startDate` is intrinsic PDT, unaffected\n // by the new window's local positioning.)\n anchor = last.startTime + (newFirst.startDate - last.startDate);\n } else {\n anchor = last.startTime + last.duration + (offset - prevSegments.length) * targetDuration;\n console.warn(\n `[parseMediaPlaylist] full window turnover (offset ${offset} >= ${prevSegments.length}); ` +\n 'no PDT to bridge — estimating from previous end.'\n );\n }\n }\n\n const shift = anchor - localBase;\n return shift === 0 ? segments : segments.map((segment) => ({ ...segment, startTime: segment.startTime + shift }));\n}\n\n/**\n * Place a window on the frozen wall-clock anchor — the track's `startDate`\n * (wall clock at media-time 0). The anchoring PDT-bearing segment lands at\n * `segment.startDate − anchor`, so the window sits on the shared presentation\n * timeline rather than a local-from-zero one (the `startDate` recomputed\n * afterwards then reads back as the anchor — idempotent). This is the **main\n * live path on every parse**: first resolves place against the pre-stamped\n * shell anchor, and reloads re-place from PDT so drift can't accumulate and a\n * long-stall turnover re-places with no overlap bridging (the HLS authoring\n * spec's §8.1 EXTINF-accuracy rule bounds the per-reload correction to ~one\n * video frame). Falls back to the local base when no segment carries PDT —\n * there's nothing to anchor against (callers guard this for reloads, where the\n * local base would reset the timeline).\n */\nfunction placeOnAnchor(segments: Segment[], anchor: number): Segment[] {\n const anchorSegment = segments.find((segment) => !isUndefined(segment.startDate));\n if (!anchorSegment || isUndefined(anchorSegment.startDate)) {\n return segments;\n }\n\n const shift = anchorSegment.startDate - anchor - anchorSegment.startTime;\n if (shift === 0) {\n return segments;\n }\n\n return segments.map((segment) => ({ ...segment, startTime: segment.startTime + shift }));\n}\n\n/**\n * Parse HLS media playlist and resolve track with segments.\n *\n * `previous` is what was known about this track before this parse: the\n * partially-resolved track from the multivariant playlist on the first resolve,\n * or the previously-resolved snapshot on a live reload. Its metadata is carried\n * onto the result either way; when it's already resolved (has segments), its\n * timeline is carried forward so the new window lands on a stable, advancing\n * timeline (see {@link placeOnPreviousTimeline}).\n *\n * @param text - Media playlist text content\n * @param previous - Prior track state (unresolved shell, or previous resolved snapshot)\n * @returns Resolved track with segments (type inferred from input)\n */\nexport function parseMediaPlaylist<T extends PartiallyResolvedTrack>(\n text: string,\n previous: T | ResolveTrack<T>\n): ResolveTrack<T> {\n const lines = text.split(/\\r?\\n/);\n\n // Segments and resources resolve relative to media playlist URL (per HLS spec)\n const baseUrl = previous.url;\n\n // Parse playlist\n const segments: Segment[] = [];\n let initSegmentUrl: string | undefined;\n let initSegmentByteRange: { start: number; end: number } | undefined;\n\n let currentDuration = 0;\n let currentByteRange: { start: number; end: number } | undefined;\n let currentTime = 0;\n let segmentIndex = 0;\n let previousByteRangeEnd: number | undefined;\n // Absolute wall-clock of the next segment's first sample, in epoch seconds.\n // Seeded by an explicit `#EXT-X-PROGRAM-DATE-TIME` (which re-anchors, e.g.\n // across a discontinuity) and advanced by each segment's duration so segments\n // without their own tag are interpolated forward (per RFC 8216).\n let currentStartDate: number | undefined;\n\n // Playlist-level metadata (surfaced for live reload pacing / merge / termination).\n let targetDuration = 0;\n let mediaSequence = 0;\n let playlistType: 'VOD' | 'EVENT' | undefined;\n let endList = false;\n let holdBack: number | undefined;\n // Low-Latency HLS delivery. Any of the partial-segment tags is enough: the\n // parser ignores parts and the loader fetches whole segments, so this records\n // that the publisher configured LL-HLS, not that we honour it.\n let lowLatency = false;\n // Any EXT-X-KEY with a real METHOD makes the rendition encrypted. Sticky: a\n // clear lead (METHOD=NONE first, a real key later) still counts, since we can\n // only report whether decryption is needed at all.\n let encrypted = false;\n\n for (const line of lines) {\n const trimmed = line.trim();\n\n if (!trimmed || (trimmed.startsWith('#') && !trimmed.startsWith('#EXT'))) {\n continue;\n }\n\n if (trimmed.startsWith('#EXT-X-TARGETDURATION:')) {\n targetDuration = Number.parseInt(trimmed.slice('#EXT-X-TARGETDURATION:'.length), 10) || 0;\n continue;\n }\n\n if (trimmed.startsWith('#EXT-X-MEDIA-SEQUENCE:')) {\n mediaSequence = Number.parseInt(trimmed.slice('#EXT-X-MEDIA-SEQUENCE:'.length), 10) || 0;\n continue;\n }\n\n if (trimmed.startsWith('#EXT-X-PROGRAM-DATE-TIME:')) {\n const parsed = Date.parse(trimmed.slice('#EXT-X-PROGRAM-DATE-TIME:'.length).trim());\n currentStartDate = Number.isNaN(parsed) ? currentStartDate : parsed / 1000;\n continue;\n }\n\n if (trimmed.startsWith('#EXT-X-PLAYLIST-TYPE:')) {\n const value = trimmed.slice('#EXT-X-PLAYLIST-TYPE:'.length).trim();\n playlistType = value === 'VOD' || value === 'EVENT' ? value : undefined;\n continue;\n }\n\n const key = matchTag(trimmed, 'EXT-X-KEY');\n if (key) {\n const method = key.get('METHOD');\n if (method !== undefined && method !== 'NONE') encrypted = true;\n continue;\n }\n\n // #EXT-X-SERVER-CONTROL — HOLD-BACK supplies the latency target. PART-HOLD-BACK\n // is read for its presence only, as an LL-HLS signal; see MediaPlaylistMetadata\n // on why its value stays out of `holdBack` until LL-HLS support lands.\n const serverControl = matchTag(trimmed, 'EXT-X-SERVER-CONTROL');\n if (serverControl) {\n const value = serverControl.get('HOLD-BACK');\n if (value !== undefined) {\n const parsed = Number.parseFloat(value);\n if (Number.isFinite(parsed) && parsed > 0) holdBack = parsed;\n }\n // Advertised for clients playing partial segments — its presence is an\n // LL-HLS signal even though the value stays deliberately unread.\n if (serverControl.get('PART-HOLD-BACK') !== undefined) lowLatency = true;\n continue;\n }\n\n // Partial segments: noted, then skipped. `#EXT-X-PART` lines would otherwise\n // fall through as unrecognized `#EXT` tags, so LL-HLS delivery went unnoticed.\n if (trimmed.startsWith('#EXT-X-PART-INF') || trimmed.startsWith('#EXT-X-PART:')) {\n lowLatency = true;\n continue;\n }\n\n if (\n trimmed === '#EXTM3U' ||\n trimmed.startsWith('#EXT-X-VERSION:') ||\n trimmed.startsWith('#EXT-X-INDEPENDENT-SEGMENTS')\n ) {\n continue;\n }\n\n // #EXT-X-MAP - Init segment\n const mapAttrs = matchTag(trimmed, 'EXT-X-MAP');\n if (mapAttrs) {\n const uri = mapAttrs.get('URI');\n if (uri) {\n initSegmentUrl = resolveUrl(uri, baseUrl);\n const byteRangeStr = mapAttrs.get('BYTERANGE');\n if (byteRangeStr) {\n initSegmentByteRange = parseByteRange(byteRangeStr, 0) ?? undefined;\n }\n }\n continue;\n }\n\n // #EXTINF - Segment duration\n if (trimmed.startsWith('#EXTINF:')) {\n currentDuration = parseExtInfDuration(trimmed.slice(8));\n continue;\n }\n\n // #EXT-X-BYTERANGE - Segment byte range\n if (trimmed.startsWith('#EXT-X-BYTERANGE:')) {\n currentByteRange = parseByteRange(trimmed.slice(17), previousByteRangeEnd) ?? undefined;\n continue;\n }\n\n if (trimmed === '#EXT-X-ENDLIST') {\n endList = true;\n continue;\n }\n\n // Segment URI\n if (!trimmed.startsWith('#') && currentDuration > 0) {\n const segment: Segment = {\n id: `segment-${mediaSequence + segmentIndex}`,\n url: resolveUrl(trimmed, baseUrl),\n duration: currentDuration,\n startTime: currentTime,\n };\n\n if (!isUndefined(currentStartDate)) {\n segment.startDate = currentStartDate;\n // Interpolate forward: the next segment without an explicit tag inherits\n // this anchor plus this segment's duration.\n currentStartDate += currentDuration;\n }\n\n if (currentByteRange) {\n segment.byteRange = currentByteRange;\n previousByteRangeEnd = currentByteRange.end + 1;\n } else {\n previousByteRangeEnd = undefined;\n }\n\n segments.push(segment);\n currentTime += currentDuration;\n segmentIndex++;\n\n currentDuration = 0;\n currentByteRange = undefined;\n }\n }\n\n const complete = endList || playlistType === 'VOD';\n\n // Position this window on the timeline. PDT is primary: whenever the track\n // carries a wall-clock anchor (`startDate` — pre-stamped on the shell for a\n // first resolve, recomputed-and-stable for a reload) and the new window has\n // PDT to place with, place from PDT against that frozen anchor\n // (`placeOnAnchor`) — self-correcting across reloads, history-free across\n // turnovers. Media-sequence/EXTINF carry-forward is the fallback for\n // PDT-less windows; a first resolve with neither anchors at the local base 0.\n const anchor = previous.startDate;\n const hasPdt = segments.some((segment) => !isUndefined(segment.startDate));\n const placed =\n !isUndefined(anchor) && hasPdt\n ? placeOnAnchor(segments, anchor)\n : isResolvedTrack(previous)\n ? placeOnPreviousTimeline(previous, segments, mediaSequence, targetDuration)\n : segments;\n\n // `duration` is the track's duration: Infinity while the playlist can still\n // grow (unended live), finite once complete (VOD / ENDLIST). Paired with\n // `startTime: 0` below, it spans the presentation origin to the last placed\n // segment's end — so it's measured off `placed`, not the local EXTINF sum:\n // for a window that has slid, the sum is the window's length, not its span.\n // Never the target duration.\n const lastPlaced = placed[placed.length - 1];\n const placedEnd = lastPlaced ? lastPlaced.startTime + lastPlaced.duration : 0;\n const trackDuration = complete ? placedEnd : Number.POSITIVE_INFINITY;\n\n // Wall-clock anchor: `startDate − startTime` for the first PDT-bearing\n // segment (constant along a linear timeline). Maps this track's origin to\n // wall clock; recomputed each parse, so it stays stable as the window slides\n // and is comparable across tracks for A/V alignment.\n const anchorSegment = placed.find((segment) => !isUndefined(segment.startDate));\n const startDate =\n anchorSegment && !isUndefined(anchorSegment.startDate)\n ? anchorSegment.startDate - anchorSegment.startTime\n : undefined;\n\n // Build initialization (VTT may not have init segment)\n const initialization =\n previous.type === 'text' && !initSegmentUrl\n ? undefined\n : initSegmentUrl\n ? { url: initSegmentUrl, ...(initSegmentByteRange ? { byteRange: initSegmentByteRange } : {}) }\n : { url: '' };\n\n // Container detection: fMP4 always carries an EXT-X-MAP init segment, so its\n // absence plus a recognized non-fMP4 segment extension (`.ts` → MPEG-TS,\n // `.aac` → raw ADTS AAC) marks a non-fMP4 rendition (high-precision — never\n // trips on fMP4, which mandates the map). Relabel from the fMP4 default\n // `video/mp4` / `audio/mp4` to the container MIME so capability probing prunes\n // it (these containers are currently treated as unplayable; see `canPlayTrack`).\n const detectedContainer = initSegmentUrl ? undefined : containerMimeFromSegment(placed[0]?.url);\n const mimeType = previous.type !== 'text' && detectedContainer ? detectedContainer : previous.mimeType;\n\n // Generic resolution: All type-specific fields already on `previous` track\n // Just add parsed properties (startTime, duration, segments, initialization, metadata)\n return {\n ...previous,\n mimeType,\n startTime: 0,\n startDate,\n duration: trackDuration,\n segments: placed,\n initialization,\n metadata: {\n ...previous.metadata,\n [MEDIA_PLAYLIST_METADATA_KEY]: {\n targetDuration,\n mediaSequence,\n playlistType,\n lowLatency,\n endList,\n holdBack,\n encrypted,\n } satisfies MediaPlaylistMetadata,\n },\n } as unknown as ResolveTrack<T>;\n}\n"],"mappings":"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"}
|