@videojs/spf 10.0.0-beta.30 → 10.0.0-beta.32
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/dist/default/core/actors/create-machine-actor.js +23 -25
- package/dist/default/core/actors/create-machine-actor.js.map +1 -1
- package/dist/default/core/actors/create-transition-actor.js +7 -9
- package/dist/default/core/actors/create-transition-actor.js.map +1 -1
- package/dist/default/core/composition/create-composition.js +26 -29
- package/dist/default/core/composition/create-composition.js.map +1 -1
- package/dist/default/core/composition/share-signals.js +12 -17
- package/dist/default/core/composition/share-signals.js.map +1 -1
- package/dist/default/core/machine.js +3 -4
- package/dist/default/core/machine.js.map +1 -1
- package/dist/default/core/reactors/create-machine-reactor.js +20 -19
- package/dist/default/core/reactors/create-machine-reactor.js.map +1 -1
- package/dist/default/core/signals/effect.js +24 -4
- package/dist/default/core/signals/effect.js.map +1 -1
- package/dist/default/core/signals/primitives.js +10 -14
- package/dist/default/core/signals/primitives.js.map +1 -1
- package/dist/default/core/signals/when.js +6 -8
- package/dist/default/core/signals/when.js.map +1 -1
- package/dist/default/core/tasks/delayed-reschedule.js +7 -11
- package/dist/default/core/tasks/delayed-reschedule.js.map +1 -1
- package/dist/default/core/tasks/task.js +59 -82
- package/dist/default/core/tasks/task.js.map +1 -1
- package/dist/default/hls.js +3 -1
- package/dist/default/index.js +2 -3
- package/dist/default/index.js.map +1 -1
- package/dist/default/media/abr/quality-selection.js +3 -7
- package/dist/default/media/abr/quality-selection.js.map +1 -1
- package/dist/default/media/buffer/back-buffer.js +15 -19
- package/dist/default/media/buffer/back-buffer.js.map +1 -1
- package/dist/default/media/buffer/forward-buffer.js +32 -41
- package/dist/default/media/buffer/forward-buffer.js.map +1 -1
- package/dist/default/media/dom/capabilities.js +26 -37
- package/dist/default/media/dom/capabilities.js.map +1 -1
- package/dist/default/media/dom/mse/append-segment.js +3 -5
- package/dist/default/media/dom/mse/append-segment.js.map +1 -1
- package/dist/default/media/dom/mse/buffer-flusher.js +5 -5
- package/dist/default/media/dom/mse/buffer-flusher.js.map +1 -1
- package/dist/default/media/dom/mse/duration.js +23 -31
- package/dist/default/media/dom/mse/duration.js.map +1 -1
- package/dist/default/media/dom/mse/end-of-stream.js +3 -6
- package/dist/default/media/dom/mse/end-of-stream.js.map +1 -1
- package/dist/default/media/dom/mse/mediasource-setup.js +65 -81
- package/dist/default/media/dom/mse/mediasource-setup.js.map +1 -1
- package/dist/default/media/dom/screen.js +37 -54
- package/dist/default/media/dom/screen.js.map +1 -1
- package/dist/default/media/dom/text/resolve-vtt-segment.js.map +1 -1
- package/dist/default/media/dom/text/text-track-slots.js +15 -23
- package/dist/default/media/dom/text/text-track-slots.js.map +1 -1
- package/dist/default/media/errors.js +25 -34
- package/dist/default/media/errors.js.map +1 -1
- package/dist/default/media/hls/parse-attributes.js +9 -26
- package/dist/default/media/hls/parse-attributes.js.map +1 -1
- package/dist/default/media/hls/parse-media-playlist.js +25 -33
- package/dist/default/media/hls/parse-media-playlist.js.map +1 -1
- package/dist/default/media/hls/parse-multivariant.js +3 -3
- package/dist/default/media/hls/parse-multivariant.js.map +1 -1
- package/dist/default/media/hls/reload-policy.js +19 -27
- package/dist/default/media/hls/reload-policy.js.map +1 -1
- package/dist/default/media/hls/resolve-url.js +1 -3
- package/dist/default/media/hls/resolve-url.js.map +1 -1
- package/dist/default/media/live-window.js +9 -13
- package/dist/default/media/live-window.js.map +1 -1
- package/dist/default/media/media-tracks/media-tracks.js +12 -17
- package/dist/default/media/media-tracks/media-tracks.js.map +1 -1
- package/dist/default/media/mp4/box.js +4 -5
- package/dist/default/media/mp4/box.js.map +1 -1
- package/dist/default/media/mp4/timestamp-origin.js +30 -42
- package/dist/default/media/mp4/timestamp-origin.js.map +1 -1
- package/dist/default/media/primitives/resolution.js +5 -8
- package/dist/default/media/primitives/resolution.js.map +1 -1
- package/dist/default/media/primitives/select-tracks.js +24 -34
- package/dist/default/media/primitives/select-tracks.js.map +1 -1
- package/dist/default/media/text/parse-vtt-timestamp-map.js +6 -8
- package/dist/default/media/text/parse-vtt-timestamp-map.js.map +1 -1
- package/dist/default/media/text/resolve-vtt-metadata.js +8 -9
- package/dist/default/media/text/resolve-vtt-metadata.js.map +1 -1
- package/dist/default/media/types/index.js +10 -18
- package/dist/default/media/types/index.js.map +1 -1
- package/dist/default/media/utils/cdn.js +10 -16
- package/dist/default/media/utils/cdn.js.map +1 -1
- package/dist/default/media/utils/preload.js +4 -6
- package/dist/default/media/utils/preload.js.map +1 -1
- package/dist/default/media/utils/track-selection.js +10 -14
- package/dist/default/media/utils/track-selection.js.map +1 -1
- package/dist/default/media/utils/tracks.js +56 -54
- package/dist/default/media/utils/tracks.js.map +1 -1
- package/dist/default/network/bandwidth-estimator.js +18 -19
- package/dist/default/network/bandwidth-estimator.js.map +1 -1
- package/dist/default/network/chunked-stream-iterable.js +4 -6
- package/dist/default/network/chunked-stream-iterable.js.map +1 -1
- package/dist/default/network/ewma.js +22 -25
- package/dist/default/network/ewma.js.map +1 -1
- package/dist/default/network/fetch.js +30 -37
- package/dist/default/network/fetch.js.map +1 -1
- package/dist/default/playback/actors/dom/segment-loader.js +28 -44
- package/dist/default/playback/actors/dom/segment-loader.js.map +1 -1
- package/dist/default/playback/actors/dom/source-buffer.js.map +1 -1
- package/dist/default/playback/actors/dom/text-tracks.js.map +1 -1
- package/dist/default/playback/actors/text-track-segment-loader.js +24 -35
- package/dist/default/playback/actors/text-track-segment-loader.js.map +1 -1
- package/dist/default/playback/adapters/hls-audio/adapter.js +23 -31
- package/dist/default/playback/adapters/hls-audio/adapter.js.map +1 -1
- package/dist/default/playback/adapters/hls-audio/media.js.map +1 -1
- package/dist/default/playback/adapters/hls-background-video/adapter.js +50 -70
- package/dist/default/playback/adapters/hls-background-video/adapter.js.map +1 -1
- package/dist/default/playback/adapters/hls-background-video/host.js +12 -16
- package/dist/default/playback/adapters/hls-background-video/host.js.map +1 -1
- package/dist/default/playback/adapters/hls-background-video/media.js +5 -8
- package/dist/default/playback/adapters/hls-background-video/media.js.map +1 -1
- package/dist/default/playback/adapters/hls-video/adapter.js +43 -60
- package/dist/default/playback/adapters/hls-video/adapter.js.map +1 -1
- package/dist/default/playback/adapters/hls-video/error-surface.js +13 -18
- package/dist/default/playback/adapters/hls-video/error-surface.js.map +1 -1
- package/dist/default/playback/adapters/hls-video/media-tracks.js +4 -5
- package/dist/default/playback/adapters/hls-video/media-tracks.js.map +1 -1
- package/dist/default/playback/adapters/hls-video/media.js.map +1 -1
- package/dist/default/playback/adapters/mux-audio/media.js +8 -12
- package/dist/default/playback/adapters/mux-audio/media.js.map +1 -1
- package/dist/default/playback/adapters/mux-video/adapter.js +25 -33
- package/dist/default/playback/adapters/mux-video/adapter.js.map +1 -1
- package/dist/default/playback/adapters/mux-video/media.js +7 -9
- package/dist/default/playback/adapters/mux-video/media.js.map +1 -1
- package/dist/default/playback/behaviors/calculate-presentation-duration.js +5 -8
- package/dist/default/playback/behaviors/calculate-presentation-duration.js.map +1 -1
- package/dist/default/playback/behaviors/collect-errors.js +39 -52
- package/dist/default/playback/behaviors/collect-errors.js.map +1 -1
- package/dist/default/playback/behaviors/derive-cdn-priority.js +16 -23
- package/dist/default/playback/behaviors/derive-cdn-priority.js.map +1 -1
- package/dist/default/playback/behaviors/dom/airplay.js +38 -61
- package/dist/default/playback/behaviors/dom/airplay.js.map +1 -1
- package/dist/default/playback/behaviors/dom/apply-start-position.js +23 -35
- package/dist/default/playback/behaviors/dom/apply-start-position.js.map +1 -1
- package/dist/default/playback/behaviors/dom/end-of-stream.js +11 -16
- package/dist/default/playback/behaviors/dom/end-of-stream.js.map +1 -1
- package/dist/default/playback/behaviors/dom/load-segments.js +27 -39
- package/dist/default/playback/behaviors/dom/load-segments.js.map +1 -1
- package/dist/default/playback/behaviors/dom/recover-end-stall.js +21 -26
- package/dist/default/playback/behaviors/dom/recover-end-stall.js.map +1 -1
- package/dist/default/playback/behaviors/dom/seek-to-live-edge.js +41 -60
- package/dist/default/playback/behaviors/dom/seek-to-live-edge.js.map +1 -1
- package/dist/default/playback/behaviors/dom/setup-buffer-actors.js +50 -74
- package/dist/default/playback/behaviors/dom/setup-buffer-actors.js.map +1 -1
- package/dist/default/playback/behaviors/dom/setup-mediasource.js +29 -43
- package/dist/default/playback/behaviors/dom/setup-mediasource.js.map +1 -1
- package/dist/default/playback/behaviors/dom/setup-text-track-actors.js.map +1 -1
- package/dist/default/playback/behaviors/dom/sync-live-seekable-range.js +3 -4
- package/dist/default/playback/behaviors/dom/sync-live-seekable-range.js.map +1 -1
- package/dist/default/playback/behaviors/dom/sync-text-tracks.js +30 -45
- package/dist/default/playback/behaviors/dom/sync-text-tracks.js.map +1 -1
- package/dist/default/playback/behaviors/dom/track-current-time.js +9 -11
- package/dist/default/playback/behaviors/dom/track-current-time.js.map +1 -1
- package/dist/default/playback/behaviors/dom/track-load-triggers.js +24 -32
- package/dist/default/playback/behaviors/dom/track-load-triggers.js.map +1 -1
- package/dist/default/playback/behaviors/dom/track-playback-rate.js +6 -8
- package/dist/default/playback/behaviors/dom/track-playback-rate.js.map +1 -1
- package/dist/default/playback/behaviors/dom/track-player-resolution.js +10 -14
- package/dist/default/playback/behaviors/dom/track-player-resolution.js.map +1 -1
- package/dist/default/playback/behaviors/dom/track-screen-resolution.js +8 -9
- package/dist/default/playback/behaviors/dom/track-screen-resolution.js.map +1 -1
- package/dist/default/playback/behaviors/dom/update-mediasource-duration.js +28 -43
- package/dist/default/playback/behaviors/dom/update-mediasource-duration.js.map +1 -1
- package/dist/default/playback/behaviors/establish-start-media-time.js +32 -42
- package/dist/default/playback/behaviors/establish-start-media-time.js.map +1 -1
- package/dist/default/playback/behaviors/resolve-presentation.js +13 -22
- package/dist/default/playback/behaviors/resolve-presentation.js.map +1 -1
- package/dist/default/playback/behaviors/resolve-track.js +5 -12
- package/dist/default/playback/behaviors/resolve-track.js.map +1 -1
- package/dist/default/playback/behaviors/select-tracks.js +77 -104
- package/dist/default/playback/behaviors/select-tracks.js.map +1 -1
- package/dist/default/playback/behaviors/setup-failover-monitor.js +11 -16
- package/dist/default/playback/behaviors/setup-failover-monitor.js.map +1 -1
- package/dist/default/playback/behaviors/sync-preload.js +9 -13
- package/dist/default/playback/behaviors/sync-preload.js.map +1 -1
- package/dist/default/playback/behaviors/track-switching.js +189 -173
- package/dist/default/playback/behaviors/track-switching.js.map +1 -1
- package/dist/default/playback/engines/hls/engine-audio-only.js +20 -24
- package/dist/default/playback/engines/hls/engine-audio-only.js.map +1 -1
- package/dist/default/playback/engines/hls/engine-background-video.js +22 -27
- package/dist/default/playback/engines/hls/engine-background-video.js.map +1 -1
- package/dist/default/playback/engines/hls/engine.js +22 -25
- package/dist/default/playback/engines/hls/engine.js.map +1 -1
- package/dist/default/playback/primitives/error-messages.js +16 -25
- package/dist/default/playback/primitives/error-messages.js.map +1 -1
- package/dist/default/playback/primitives/failover-fetch.js +9 -14
- package/dist/default/playback/primitives/failover-fetch.js.map +1 -1
- package/dist/default/playback/primitives/head-peek.js +7 -10
- package/dist/default/playback/primitives/head-peek.js.map +1 -1
- package/dist/default/playback/primitives/live-window.js +12 -15
- package/dist/default/playback/primitives/live-window.js.map +1 -1
- package/dist/default/playback/primitives/relocation-pipelines.js +34 -46
- package/dist/default/playback/primitives/relocation-pipelines.js.map +1 -1
- package/dist/default/playback/primitives/report-track-conditions.js +26 -38
- package/dist/default/playback/primitives/report-track-conditions.js.map +1 -1
- package/dist/default/playback/primitives/segment-load-pipeline.js +15 -15
- package/dist/default/playback/primitives/segment-load-pipeline.js.map +1 -1
- package/dist/default/playback/primitives/selection-rules.js +65 -36
- package/dist/default/playback/primitives/selection-rules.js.map +1 -1
- package/dist/default/playback/primitives/text-segment-load-pipeline.js +4 -5
- package/dist/default/playback/primitives/text-segment-load-pipeline.js.map +1 -1
- package/dist/default/playback/primitives/track-types.js +10 -18
- package/dist/default/playback/primitives/track-types.js.map +1 -1
- package/dist/dev/core/actors/actor.d.ts +4 -4
- package/dist/dev/core/actors/actor.d.ts.map +1 -1
- package/dist/dev/core/actors/create-machine-actor.d.ts +38 -47
- package/dist/dev/core/actors/create-machine-actor.d.ts.map +1 -1
- package/dist/dev/core/actors/create-machine-actor.js +23 -25
- package/dist/dev/core/actors/create-machine-actor.js.map +1 -1
- package/dist/dev/core/actors/create-transition-actor.d.ts +11 -15
- package/dist/dev/core/actors/create-transition-actor.d.ts.map +1 -1
- package/dist/dev/core/actors/create-transition-actor.js +7 -9
- package/dist/dev/core/actors/create-transition-actor.js.map +1 -1
- package/dist/dev/core/composition/create-composition.d.ts +70 -102
- package/dist/dev/core/composition/create-composition.d.ts.map +1 -1
- package/dist/dev/core/composition/create-composition.js +26 -29
- package/dist/dev/core/composition/create-composition.js.map +1 -1
- package/dist/dev/core/composition/share-signals.d.ts +17 -24
- package/dist/dev/core/composition/share-signals.d.ts.map +1 -1
- package/dist/dev/core/composition/share-signals.js +12 -17
- package/dist/dev/core/composition/share-signals.js.map +1 -1
- package/dist/dev/core/machine.d.ts +4 -4
- package/dist/dev/core/machine.js +3 -4
- package/dist/dev/core/machine.js.map +1 -1
- package/dist/dev/core/reactors/create-machine-reactor.d.ts +33 -39
- package/dist/dev/core/reactors/create-machine-reactor.d.ts.map +1 -1
- package/dist/dev/core/reactors/create-machine-reactor.js +20 -19
- package/dist/dev/core/reactors/create-machine-reactor.js.map +1 -1
- package/dist/dev/core/signals/effect.d.ts +3 -4
- package/dist/dev/core/signals/effect.d.ts.map +1 -1
- package/dist/dev/core/signals/effect.js +24 -4
- package/dist/dev/core/signals/effect.js.map +1 -1
- package/dist/dev/core/signals/primitives.d.ts +10 -12
- package/dist/dev/core/signals/primitives.d.ts.map +1 -1
- package/dist/dev/core/signals/primitives.js +10 -14
- package/dist/dev/core/signals/primitives.js.map +1 -1
- package/dist/dev/core/signals/when.js +6 -8
- package/dist/dev/core/signals/when.js.map +1 -1
- package/dist/dev/core/tasks/delayed-reschedule.js +7 -11
- package/dist/dev/core/tasks/delayed-reschedule.js.map +1 -1
- package/dist/dev/core/tasks/task.d.ts +51 -73
- package/dist/dev/core/tasks/task.d.ts.map +1 -1
- package/dist/dev/core/tasks/task.js +59 -82
- package/dist/dev/core/tasks/task.js.map +1 -1
- package/dist/dev/hls.d.ts +3 -1
- package/dist/dev/hls.js +3 -1
- package/dist/dev/index.d.ts +2 -3
- package/dist/dev/index.d.ts.map +1 -1
- package/dist/dev/index.js +2 -3
- package/dist/dev/index.js.map +1 -1
- package/dist/dev/media/abr/quality-selection.d.ts +7 -10
- package/dist/dev/media/abr/quality-selection.d.ts.map +1 -1
- package/dist/dev/media/abr/quality-selection.js +3 -7
- package/dist/dev/media/abr/quality-selection.js.map +1 -1
- package/dist/dev/media/buffer/back-buffer.d.ts +2 -7
- package/dist/dev/media/buffer/back-buffer.d.ts.map +1 -1
- package/dist/dev/media/buffer/back-buffer.js +15 -19
- package/dist/dev/media/buffer/back-buffer.js.map +1 -1
- package/dist/dev/media/buffer/forward-buffer.d.ts +2 -7
- package/dist/dev/media/buffer/forward-buffer.d.ts.map +1 -1
- package/dist/dev/media/buffer/forward-buffer.js +32 -41
- package/dist/dev/media/buffer/forward-buffer.js.map +1 -1
- package/dist/dev/media/dom/capabilities.js +26 -37
- package/dist/dev/media/dom/capabilities.js.map +1 -1
- package/dist/dev/media/dom/mse/append-segment.d.ts +3 -5
- package/dist/dev/media/dom/mse/append-segment.d.ts.map +1 -1
- package/dist/dev/media/dom/mse/append-segment.js +3 -5
- package/dist/dev/media/dom/mse/append-segment.js.map +1 -1
- package/dist/dev/media/dom/mse/buffer-flusher.d.ts +5 -5
- package/dist/dev/media/dom/mse/buffer-flusher.js +5 -5
- package/dist/dev/media/dom/mse/buffer-flusher.js.map +1 -1
- package/dist/dev/media/dom/mse/duration.js +23 -31
- package/dist/dev/media/dom/mse/duration.js.map +1 -1
- package/dist/dev/media/dom/mse/end-of-stream.js +3 -6
- package/dist/dev/media/dom/mse/end-of-stream.js.map +1 -1
- package/dist/dev/media/dom/mse/mediasource-setup.js +65 -81
- package/dist/dev/media/dom/mse/mediasource-setup.js.map +1 -1
- package/dist/dev/media/dom/screen.d.ts.map +1 -1
- package/dist/dev/media/dom/screen.js +37 -54
- package/dist/dev/media/dom/screen.js.map +1 -1
- package/dist/dev/media/dom/text/resolve-vtt-segment.d.ts.map +1 -1
- package/dist/dev/media/dom/text/resolve-vtt-segment.js.map +1 -1
- package/dist/dev/media/dom/text/text-track-slots.d.ts +10 -16
- package/dist/dev/media/dom/text/text-track-slots.d.ts.map +1 -1
- package/dist/dev/media/dom/text/text-track-slots.js +15 -23
- package/dist/dev/media/dom/text/text-track-slots.js.map +1 -1
- package/dist/dev/media/errors.d.ts +32 -46
- package/dist/dev/media/errors.d.ts.map +1 -1
- package/dist/dev/media/errors.js +25 -34
- package/dist/dev/media/errors.js.map +1 -1
- package/dist/dev/media/hls/parse-attributes.js +9 -26
- package/dist/dev/media/hls/parse-attributes.js.map +1 -1
- package/dist/dev/media/hls/parse-media-playlist.js +25 -33
- package/dist/dev/media/hls/parse-media-playlist.js.map +1 -1
- package/dist/dev/media/hls/parse-multivariant.js +3 -3
- package/dist/dev/media/hls/parse-multivariant.js.map +1 -1
- package/dist/dev/media/hls/reload-policy.js +19 -27
- package/dist/dev/media/hls/reload-policy.js.map +1 -1
- package/dist/dev/media/hls/resolve-url.js +1 -3
- package/dist/dev/media/hls/resolve-url.js.map +1 -1
- package/dist/dev/media/live-window.js +9 -13
- package/dist/dev/media/live-window.js.map +1 -1
- package/dist/dev/media/media-tracks/media-tracks.d.ts +8 -13
- package/dist/dev/media/media-tracks/media-tracks.d.ts.map +1 -1
- package/dist/dev/media/media-tracks/media-tracks.js +12 -17
- package/dist/dev/media/media-tracks/media-tracks.js.map +1 -1
- package/dist/dev/media/mp4/box.js +4 -5
- package/dist/dev/media/mp4/box.js.map +1 -1
- package/dist/dev/media/mp4/timestamp-origin.js +30 -42
- package/dist/dev/media/mp4/timestamp-origin.js.map +1 -1
- package/dist/dev/media/primitives/resolution.d.ts +6 -8
- package/dist/dev/media/primitives/resolution.d.ts.map +1 -1
- package/dist/dev/media/primitives/resolution.js +5 -8
- package/dist/dev/media/primitives/resolution.js.map +1 -1
- package/dist/dev/media/primitives/select-tracks.js +24 -34
- package/dist/dev/media/primitives/select-tracks.js.map +1 -1
- package/dist/dev/media/text/parse-vtt-timestamp-map.js +6 -8
- package/dist/dev/media/text/parse-vtt-timestamp-map.js.map +1 -1
- package/dist/dev/media/text/resolve-vtt-metadata.js +8 -9
- package/dist/dev/media/text/resolve-vtt-metadata.js.map +1 -1
- package/dist/dev/media/types/index.d.ts +106 -177
- package/dist/dev/media/types/index.d.ts.map +1 -1
- package/dist/dev/media/types/index.js +10 -18
- package/dist/dev/media/types/index.js.map +1 -1
- package/dist/dev/media/utils/cdn.d.ts +4 -6
- package/dist/dev/media/utils/cdn.d.ts.map +1 -1
- package/dist/dev/media/utils/cdn.js +10 -16
- package/dist/dev/media/utils/cdn.js.map +1 -1
- package/dist/dev/media/utils/preload.js +4 -6
- package/dist/dev/media/utils/preload.js.map +1 -1
- package/dist/dev/media/utils/track-selection.js +10 -14
- package/dist/dev/media/utils/track-selection.js.map +1 -1
- package/dist/dev/media/utils/tracks.js +56 -54
- package/dist/dev/media/utils/tracks.js.map +1 -1
- package/dist/dev/network/bandwidth-estimator.d.ts +7 -9
- package/dist/dev/network/bandwidth-estimator.d.ts.map +1 -1
- package/dist/dev/network/bandwidth-estimator.js +18 -19
- package/dist/dev/network/bandwidth-estimator.js.map +1 -1
- package/dist/dev/network/chunked-stream-iterable.js +4 -6
- package/dist/dev/network/chunked-stream-iterable.js.map +1 -1
- package/dist/dev/network/ewma.js +22 -25
- package/dist/dev/network/ewma.js.map +1 -1
- package/dist/dev/network/fetch.js +30 -37
- package/dist/dev/network/fetch.js.map +1 -1
- package/dist/dev/playback/actors/dom/segment-loader.d.ts +7 -11
- package/dist/dev/playback/actors/dom/segment-loader.d.ts.map +1 -1
- package/dist/dev/playback/actors/dom/segment-loader.js +28 -44
- package/dist/dev/playback/actors/dom/segment-loader.js.map +1 -1
- package/dist/dev/playback/actors/dom/source-buffer.d.ts +5 -7
- package/dist/dev/playback/actors/dom/source-buffer.d.ts.map +1 -1
- package/dist/dev/playback/actors/dom/source-buffer.js.map +1 -1
- package/dist/dev/playback/actors/dom/text-tracks.js.map +1 -1
- package/dist/dev/playback/actors/text-track-segment-loader.d.ts +10 -16
- package/dist/dev/playback/actors/text-track-segment-loader.d.ts.map +1 -1
- package/dist/dev/playback/actors/text-track-segment-loader.js +24 -35
- package/dist/dev/playback/actors/text-track-segment-loader.js.map +1 -1
- package/dist/dev/playback/actors/text-tracks.d.ts +5 -8
- package/dist/dev/playback/actors/text-tracks.d.ts.map +1 -1
- package/dist/dev/playback/adapters/hls-audio/adapter.d.ts +11 -14
- package/dist/dev/playback/adapters/hls-audio/adapter.d.ts.map +1 -1
- package/dist/dev/playback/adapters/hls-audio/adapter.js +23 -31
- package/dist/dev/playback/adapters/hls-audio/adapter.js.map +1 -1
- package/dist/dev/playback/adapters/hls-audio/media.d.ts.map +1 -1
- package/dist/dev/playback/adapters/hls-audio/media.js.map +1 -1
- package/dist/dev/playback/adapters/hls-background-video/adapter.d.ts +28 -39
- package/dist/dev/playback/adapters/hls-background-video/adapter.d.ts.map +1 -1
- package/dist/dev/playback/adapters/hls-background-video/adapter.js +50 -70
- package/dist/dev/playback/adapters/hls-background-video/adapter.js.map +1 -1
- package/dist/dev/playback/adapters/hls-background-video/host.d.ts +12 -16
- package/dist/dev/playback/adapters/hls-background-video/host.d.ts.map +1 -1
- package/dist/dev/playback/adapters/hls-background-video/host.js +12 -16
- package/dist/dev/playback/adapters/hls-background-video/host.js.map +1 -1
- package/dist/dev/playback/adapters/hls-background-video/media.d.ts +5 -8
- package/dist/dev/playback/adapters/hls-background-video/media.d.ts.map +1 -1
- package/dist/dev/playback/adapters/hls-background-video/media.js +5 -8
- package/dist/dev/playback/adapters/hls-background-video/media.js.map +1 -1
- package/dist/dev/playback/adapters/hls-video/adapter.d.ts +12 -14
- package/dist/dev/playback/adapters/hls-video/adapter.d.ts.map +1 -1
- package/dist/dev/playback/adapters/hls-video/adapter.js +43 -60
- package/dist/dev/playback/adapters/hls-video/adapter.js.map +1 -1
- package/dist/dev/playback/adapters/hls-video/error-surface.d.ts +4 -5
- package/dist/dev/playback/adapters/hls-video/error-surface.d.ts.map +1 -1
- package/dist/dev/playback/adapters/hls-video/error-surface.js +13 -18
- package/dist/dev/playback/adapters/hls-video/error-surface.js.map +1 -1
- package/dist/dev/playback/adapters/hls-video/media-tracks.d.ts +4 -5
- package/dist/dev/playback/adapters/hls-video/media-tracks.d.ts.map +1 -1
- package/dist/dev/playback/adapters/hls-video/media-tracks.js +4 -5
- package/dist/dev/playback/adapters/hls-video/media-tracks.js.map +1 -1
- package/dist/dev/playback/adapters/hls-video/media.d.ts.map +1 -1
- package/dist/dev/playback/adapters/hls-video/media.js.map +1 -1
- package/dist/dev/playback/adapters/mux-audio/media.d.ts +8 -12
- package/dist/dev/playback/adapters/mux-audio/media.d.ts.map +1 -1
- package/dist/dev/playback/adapters/mux-audio/media.js +8 -12
- package/dist/dev/playback/adapters/mux-audio/media.js.map +1 -1
- package/dist/dev/playback/adapters/mux-video/adapter.d.ts +9 -11
- package/dist/dev/playback/adapters/mux-video/adapter.d.ts.map +1 -1
- package/dist/dev/playback/adapters/mux-video/adapter.js +25 -33
- package/dist/dev/playback/adapters/mux-video/adapter.js.map +1 -1
- package/dist/dev/playback/adapters/mux-video/media.d.ts +7 -9
- package/dist/dev/playback/adapters/mux-video/media.d.ts.map +1 -1
- package/dist/dev/playback/adapters/mux-video/media.js +7 -9
- package/dist/dev/playback/adapters/mux-video/media.js.map +1 -1
- package/dist/dev/playback/behaviors/calculate-presentation-duration.d.ts +5 -8
- package/dist/dev/playback/behaviors/calculate-presentation-duration.d.ts.map +1 -1
- package/dist/dev/playback/behaviors/calculate-presentation-duration.js +5 -8
- package/dist/dev/playback/behaviors/calculate-presentation-duration.js.map +1 -1
- package/dist/dev/playback/behaviors/collect-errors.d.ts +2 -0
- package/dist/dev/playback/behaviors/collect-errors.js +39 -52
- package/dist/dev/playback/behaviors/collect-errors.js.map +1 -1
- package/dist/dev/playback/behaviors/derive-cdn-priority.js +16 -23
- package/dist/dev/playback/behaviors/derive-cdn-priority.js.map +1 -1
- package/dist/dev/playback/behaviors/dom/airplay.js +38 -61
- package/dist/dev/playback/behaviors/dom/airplay.js.map +1 -1
- package/dist/dev/playback/behaviors/dom/apply-start-position.js +23 -35
- package/dist/dev/playback/behaviors/dom/apply-start-position.js.map +1 -1
- package/dist/dev/playback/behaviors/dom/end-of-stream.js +11 -16
- package/dist/dev/playback/behaviors/dom/end-of-stream.js.map +1 -1
- package/dist/dev/playback/behaviors/dom/load-segments.d.ts +5 -8
- package/dist/dev/playback/behaviors/dom/load-segments.d.ts.map +1 -1
- package/dist/dev/playback/behaviors/dom/load-segments.js +27 -39
- package/dist/dev/playback/behaviors/dom/load-segments.js.map +1 -1
- package/dist/dev/playback/behaviors/dom/recover-end-stall.js +21 -26
- package/dist/dev/playback/behaviors/dom/recover-end-stall.js.map +1 -1
- package/dist/dev/playback/behaviors/dom/seek-to-live-edge.js +41 -60
- package/dist/dev/playback/behaviors/dom/seek-to-live-edge.js.map +1 -1
- package/dist/dev/playback/behaviors/dom/setup-buffer-actors.js +50 -74
- package/dist/dev/playback/behaviors/dom/setup-buffer-actors.js.map +1 -1
- package/dist/dev/playback/behaviors/dom/setup-mediasource.js +29 -43
- package/dist/dev/playback/behaviors/dom/setup-mediasource.js.map +1 -1
- package/dist/dev/playback/behaviors/dom/setup-text-track-actors.d.ts +3 -3
- package/dist/dev/playback/behaviors/dom/setup-text-track-actors.d.ts.map +1 -1
- package/dist/dev/playback/behaviors/dom/setup-text-track-actors.js.map +1 -1
- package/dist/dev/playback/behaviors/dom/sync-live-seekable-range.js +3 -4
- package/dist/dev/playback/behaviors/dom/sync-live-seekable-range.js.map +1 -1
- package/dist/dev/playback/behaviors/dom/sync-text-tracks.js +30 -45
- package/dist/dev/playback/behaviors/dom/sync-text-tracks.js.map +1 -1
- package/dist/dev/playback/behaviors/dom/track-current-time.d.ts +2 -2
- package/dist/dev/playback/behaviors/dom/track-current-time.d.ts.map +1 -1
- package/dist/dev/playback/behaviors/dom/track-current-time.js +9 -11
- package/dist/dev/playback/behaviors/dom/track-current-time.js.map +1 -1
- package/dist/dev/playback/behaviors/dom/track-load-triggers.d.ts +6 -12
- package/dist/dev/playback/behaviors/dom/track-load-triggers.d.ts.map +1 -1
- package/dist/dev/playback/behaviors/dom/track-load-triggers.js +24 -32
- package/dist/dev/playback/behaviors/dom/track-load-triggers.js.map +1 -1
- package/dist/dev/playback/behaviors/dom/track-playback-rate.d.ts +2 -2
- package/dist/dev/playback/behaviors/dom/track-playback-rate.d.ts.map +1 -1
- package/dist/dev/playback/behaviors/dom/track-playback-rate.js +6 -8
- package/dist/dev/playback/behaviors/dom/track-playback-rate.js.map +1 -1
- package/dist/dev/playback/behaviors/dom/track-player-resolution.d.ts.map +1 -1
- package/dist/dev/playback/behaviors/dom/track-player-resolution.js +10 -14
- package/dist/dev/playback/behaviors/dom/track-player-resolution.js.map +1 -1
- package/dist/dev/playback/behaviors/dom/track-screen-resolution.js +8 -9
- package/dist/dev/playback/behaviors/dom/track-screen-resolution.js.map +1 -1
- package/dist/dev/playback/behaviors/dom/update-mediasource-duration.js +28 -43
- package/dist/dev/playback/behaviors/dom/update-mediasource-duration.js.map +1 -1
- package/dist/dev/playback/behaviors/establish-start-media-time.d.ts +15 -19
- package/dist/dev/playback/behaviors/establish-start-media-time.d.ts.map +1 -1
- package/dist/dev/playback/behaviors/establish-start-media-time.js +32 -42
- package/dist/dev/playback/behaviors/establish-start-media-time.js.map +1 -1
- package/dist/dev/playback/behaviors/resolve-presentation.d.ts.map +1 -1
- package/dist/dev/playback/behaviors/resolve-presentation.js +13 -22
- package/dist/dev/playback/behaviors/resolve-presentation.js.map +1 -1
- package/dist/dev/playback/behaviors/resolve-track.js +5 -12
- package/dist/dev/playback/behaviors/resolve-track.js.map +1 -1
- package/dist/dev/playback/behaviors/select-tracks.d.ts +28 -39
- package/dist/dev/playback/behaviors/select-tracks.d.ts.map +1 -1
- package/dist/dev/playback/behaviors/select-tracks.js +77 -104
- package/dist/dev/playback/behaviors/select-tracks.js.map +1 -1
- package/dist/dev/playback/behaviors/setup-failover-monitor.d.ts +1 -4
- package/dist/dev/playback/behaviors/setup-failover-monitor.d.ts.map +1 -1
- package/dist/dev/playback/behaviors/setup-failover-monitor.js +11 -16
- package/dist/dev/playback/behaviors/setup-failover-monitor.js.map +1 -1
- package/dist/dev/playback/behaviors/sync-preload.js +9 -13
- package/dist/dev/playback/behaviors/sync-preload.js.map +1 -1
- package/dist/dev/playback/behaviors/track-switching.d.ts +110 -0
- package/dist/dev/playback/behaviors/track-switching.d.ts.map +1 -0
- package/dist/dev/playback/behaviors/track-switching.js +189 -173
- package/dist/dev/playback/behaviors/track-switching.js.map +1 -1
- package/dist/dev/playback/engines/hls/engine-audio-only.d.ts +59 -72
- package/dist/dev/playback/engines/hls/engine-audio-only.d.ts.map +1 -1
- package/dist/dev/playback/engines/hls/engine-audio-only.js +20 -24
- package/dist/dev/playback/engines/hls/engine-audio-only.js.map +1 -1
- package/dist/dev/playback/engines/hls/engine-background-video.d.ts +51 -78
- package/dist/dev/playback/engines/hls/engine-background-video.d.ts.map +1 -1
- package/dist/dev/playback/engines/hls/engine-background-video.js +22 -27
- package/dist/dev/playback/engines/hls/engine-background-video.js.map +1 -1
- package/dist/dev/playback/engines/hls/engine.d.ts +115 -155
- package/dist/dev/playback/engines/hls/engine.d.ts.map +1 -1
- package/dist/dev/playback/engines/hls/engine.js +22 -25
- package/dist/dev/playback/engines/hls/engine.js.map +1 -1
- package/dist/dev/playback/primitives/derive-start-media-time.d.ts +3 -3
- package/dist/dev/playback/primitives/derive-start-media-time.d.ts.map +1 -1
- package/dist/dev/playback/primitives/error-messages.js +16 -25
- package/dist/dev/playback/primitives/error-messages.js.map +1 -1
- package/dist/dev/playback/primitives/failover-fetch.js +9 -14
- package/dist/dev/playback/primitives/failover-fetch.js.map +1 -1
- package/dist/dev/playback/primitives/head-peek.js +7 -10
- package/dist/dev/playback/primitives/head-peek.js.map +1 -1
- package/dist/dev/playback/primitives/live-window.js +12 -15
- package/dist/dev/playback/primitives/live-window.js.map +1 -1
- package/dist/dev/playback/primitives/relocation-pipelines.js +34 -46
- package/dist/dev/playback/primitives/relocation-pipelines.js.map +1 -1
- package/dist/dev/playback/primitives/report-track-conditions.d.ts +1 -4
- package/dist/dev/playback/primitives/report-track-conditions.d.ts.map +1 -1
- package/dist/dev/playback/primitives/report-track-conditions.js +26 -38
- package/dist/dev/playback/primitives/report-track-conditions.js.map +1 -1
- package/dist/dev/playback/primitives/segment-load-pipeline.js +15 -15
- package/dist/dev/playback/primitives/segment-load-pipeline.js.map +1 -1
- package/dist/dev/playback/primitives/selection-rules.d.ts +45 -17
- package/dist/dev/playback/primitives/selection-rules.d.ts.map +1 -1
- package/dist/dev/playback/primitives/selection-rules.js +65 -36
- package/dist/dev/playback/primitives/selection-rules.js.map +1 -1
- package/dist/dev/playback/primitives/source-buffer-messages.d.ts +6 -9
- package/dist/dev/playback/primitives/source-buffer-messages.d.ts.map +1 -1
- package/dist/dev/playback/primitives/text-segment-load-pipeline.d.ts +20 -29
- package/dist/dev/playback/primitives/text-segment-load-pipeline.d.ts.map +1 -1
- package/dist/dev/playback/primitives/text-segment-load-pipeline.js +4 -5
- package/dist/dev/playback/primitives/text-segment-load-pipeline.js.map +1 -1
- package/dist/dev/playback/primitives/text-track-messages.d.ts.map +1 -1
- package/dist/dev/playback/primitives/track-types.js +10 -18
- package/dist/dev/playback/primitives/track-types.js.map +1 -1
- package/package.json +25 -28
|
@@ -8,8 +8,8 @@ interface PlaybackRateContext {
|
|
|
8
8
|
}
|
|
9
9
|
interface TrackPlaybackRateConfig {
|
|
10
10
|
/**
|
|
11
|
-
* Value written to `state.playbackRate` when no media element is attached.
|
|
12
|
-
*
|
|
11
|
+
* Value written to `state.playbackRate` when no media element is attached. Defaults to `1` — the HTMLMediaElement
|
|
12
|
+
* spec default.
|
|
13
13
|
*/
|
|
14
14
|
defaultPlaybackRate?: number;
|
|
15
15
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"track-playback-rate.d.ts","names":[],"sources":["../../../../../src/playback/behaviors/dom/track-playback-rate.ts"],"mappings":";;
|
|
1
|
+
{"version":3,"file":"track-playback-rate.d.ts","names":[],"sources":["../../../../../src/playback/behaviors/dom/track-playback-rate.ts"],"mappings":";;UAeiB;EACf;;UAGe;EACf,eAAe;;UAGA;;;;;EAKf;;cA8BW;;;;;MAtBY,cAAA,OAAO;;;;MACL,cAAA,eAAe"}
|
|
@@ -3,15 +3,13 @@ import { effect } from "../../../core/signals/effect.js";
|
|
|
3
3
|
import { listen } from "@videojs/utils/dom";
|
|
4
4
|
//#region src/playback/behaviors/dom/track-playback-rate.ts
|
|
5
5
|
/**
|
|
6
|
-
* Mirror `mediaElement.playbackRate` into reactive state. On each `ratechange`
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
* event.
|
|
6
|
+
* Mirror `mediaElement.playbackRate` into reactive state. On each `ratechange` event, write the new value to
|
|
7
|
+
* `state.playbackRate`. Also syncs immediately when a media element becomes available so consumers don't wait for the
|
|
8
|
+
* first event.
|
|
10
9
|
*
|
|
11
|
-
* When no media element is attached, writes `config.defaultPlaybackRate`
|
|
12
|
-
*
|
|
13
|
-
*
|
|
14
|
-
* does not push `state.playbackRate` back to the element.
|
|
10
|
+
* When no media element is attached, writes `config.defaultPlaybackRate` (default-default `1`, matching the
|
|
11
|
+
* HTMLMediaElement spec) so consumers always see the rate a freshly attached element would have. Read-only mirror; does
|
|
12
|
+
* not push `state.playbackRate` back to the element.
|
|
15
13
|
*/
|
|
16
14
|
function trackPlaybackRateSetup({ state, context, config }) {
|
|
17
15
|
const defaultPlaybackRate = config?.defaultPlaybackRate ?? 1;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"track-playback-rate.js","names":[],"sources":["../../../../../src/playback/behaviors/dom/track-playback-rate.ts"],"sourcesContent":["/**\n * Mirror `mediaElement.playbackRate` into reactive state. On each `ratechange
|
|
1
|
+
{"version":3,"file":"track-playback-rate.js","names":[],"sources":["../../../../../src/playback/behaviors/dom/track-playback-rate.ts"],"sourcesContent":["/**\n * Mirror `mediaElement.playbackRate` into reactive state. On each `ratechange` event, write the new value to\n * `state.playbackRate`. Also syncs immediately when a media element becomes available so consumers don't wait for the\n * first event.\n *\n * When no media element is attached, writes `config.defaultPlaybackRate` (default-default `1`, matching the\n * HTMLMediaElement spec) so consumers always see the rate a freshly attached element would have. Read-only mirror; does\n * not push `state.playbackRate` back to the element.\n */\nimport { listen } from '@videojs/utils/dom';\n\nimport { defineBehavior } from '../../../core/composition/create-composition';\nimport { effect } from '../../../core/signals/effect';\nimport type { ReadonlySignal, Signal } from '../../../core/signals/primitives';\n\nexport interface PlaybackRateState {\n playbackRate?: number;\n}\n\nexport interface PlaybackRateContext {\n mediaElement?: HTMLMediaElement | undefined;\n}\n\nexport interface TrackPlaybackRateConfig {\n /**\n * Value written to `state.playbackRate` when no media element is attached. Defaults to `1` — the HTMLMediaElement\n * spec default.\n */\n defaultPlaybackRate?: number;\n}\n\nfunction trackPlaybackRateSetup({\n state,\n context,\n config,\n}: {\n state: { playbackRate: Signal<PlaybackRateState['playbackRate']> };\n context: { mediaElement: ReadonlySignal<PlaybackRateContext['mediaElement']> };\n config?: TrackPlaybackRateConfig;\n}): () => void {\n const defaultPlaybackRate = config?.defaultPlaybackRate ?? 1;\n\n return effect(() => {\n const mediaElement = context.mediaElement.get();\n\n if (!mediaElement) {\n state.playbackRate.set(defaultPlaybackRate);\n return;\n }\n\n const sync = () => state.playbackRate.set(mediaElement.playbackRate);\n\n sync();\n\n return listen(mediaElement, 'ratechange', sync);\n });\n}\n\nexport const trackPlaybackRate = defineBehavior({\n stateKeys: ['playbackRate'],\n contextKeys: ['mediaElement'],\n setup: trackPlaybackRateSetup,\n});\n"],"mappings":";;;;;;;;;;;;;AA+BA,SAAS,uBAAuB,EAC9B,OACA,SACA,UAKa;CACb,MAAM,sBAAsB,QAAQ,uBAAuB;CAE3D,OAAO,aAAa;EAClB,MAAM,eAAe,QAAQ,aAAa,IAAI;EAE9C,IAAI,CAAC,cAAc;GACjB,MAAM,aAAa,IAAI,mBAAmB;GAC1C;EACF;EAEA,MAAM,aAAa,MAAM,aAAa,IAAI,aAAa,YAAY;EAEnE,KAAK;EAEL,OAAO,OAAO,cAAc,cAAc,IAAI;CAChD,CAAC;AACH;AAEA,MAAa,oBAAoB,eAAe;CAC9C,WAAW,CAAC,cAAc;CAC1B,aAAa,CAAC,cAAc;CAC5B,OAAO;AACT,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"track-player-resolution.d.ts","names":[],"sources":["../../../../../src/playback/behaviors/dom/track-player-resolution.ts"],"mappings":";;;;
|
|
1
|
+
{"version":3,"file":"track-player-resolution.d.ts","names":[],"sources":["../../../../../src/playback/behaviors/dom/track-player-resolution.ts"],"mappings":";;;;KA0BY,mBAAmB"}
|
|
@@ -5,24 +5,20 @@ import { observeElementSize, observeRenderedSize } from "@videojs/utils/dom";
|
|
|
5
5
|
import { shallowEqual } from "@videojs/utils/object";
|
|
6
6
|
//#region src/playback/behaviors/dom/track-player-resolution.ts
|
|
7
7
|
/**
|
|
8
|
-
* Mirror the player element's rendered pixel dimensions into reactive state, so
|
|
9
|
-
*
|
|
10
|
-
* without reading the DOM at pick time — which would make the picker impure, and
|
|
8
|
+
* Mirror the player element's rendered pixel dimensions into reactive state, so a rendition cap can narrow candidates
|
|
9
|
+
* to what the element can actually show without reading the DOM at pick time — which would make the picker impure, and
|
|
11
10
|
* would never re-pick when the element resized.
|
|
12
11
|
*
|
|
13
|
-
* The player-element half of the caps in
|
|
14
|
-
*
|
|
15
|
-
*
|
|
16
|
-
* the screen behind it (`trackScreenResolution`).
|
|
12
|
+
* The player-element half of the caps in `internal/design/spf/features/rendition-selection-caps.md`, and the tighter
|
|
13
|
+
* half: a small embed on a large display is capped by its own box rather than by the screen behind it
|
|
14
|
+
* (`trackScreenResolution`).
|
|
17
15
|
*
|
|
18
|
-
* Reported as a width and a height in device pixels — the same units, and for the
|
|
19
|
-
*
|
|
20
|
-
* track dimensions, and a `"720p"`-style tier only describes a track once you
|
|
16
|
+
* Reported as a width and a height in device pixels — the same units, and for the same reason, as `media/dom/screen`'s
|
|
17
|
+
* reading: the cap compares against real track dimensions, and a `"720p"`-style tier only describes a track once you
|
|
21
18
|
* assume its aspect ratio.
|
|
22
19
|
*
|
|
23
|
-
* `undefined` where there is nothing to measure — no element attached, or one
|
|
24
|
-
*
|
|
25
|
-
* is the value the cap reads as "don't cap".
|
|
20
|
+
* `undefined` where there is nothing to measure — no element attached, or one that isn't being rendered (detached,
|
|
21
|
+
* `display: none`, not yet laid out) — which is the value the cap reads as "don't cap".
|
|
26
22
|
*/
|
|
27
23
|
function trackPlayerResolutionSetup({ state, context, config = {} }) {
|
|
28
24
|
const { capRenditionToPlayerSize = true, useDevicePixelRatio = true } = config;
|
|
@@ -44,7 +40,7 @@ function trackPlayerResolutionSetup({ state, context, config = {} }) {
|
|
|
44
40
|
* Track the player element's rendered resolution in `state.playerResolution`.
|
|
45
41
|
*
|
|
46
42
|
* @example
|
|
47
|
-
*
|
|
43
|
+
* const cleanup = trackPlayerResolution.setup({ state, context });
|
|
48
44
|
*/
|
|
49
45
|
const trackPlayerResolution = defineBehavior({
|
|
50
46
|
stateKeys: ["playerResolution"],
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"track-player-resolution.js","names":[],"sources":["../../../../../src/playback/behaviors/dom/track-player-resolution.ts"],"sourcesContent":["/**\n * Mirror the player element's rendered pixel dimensions into reactive state, so
|
|
1
|
+
{"version":3,"file":"track-player-resolution.js","names":[],"sources":["../../../../../src/playback/behaviors/dom/track-player-resolution.ts"],"sourcesContent":["/**\n * Mirror the player element's rendered pixel dimensions into reactive state, so a rendition cap can narrow candidates\n * to what the element can actually show without reading the DOM at pick time — which would make the picker impure, and\n * would never re-pick when the element resized.\n *\n * The player-element half of the caps in `internal/design/spf/features/rendition-selection-caps.md`, and the tighter\n * half: a small embed on a large display is capped by its own box rather than by the screen behind it\n * (`trackScreenResolution`).\n *\n * Reported as a width and a height in device pixels — the same units, and for the same reason, as `media/dom/screen`'s\n * reading: the cap compares against real track dimensions, and a `\"720p\"`-style tier only describes a track once you\n * assume its aspect ratio.\n *\n * `undefined` where there is nothing to measure — no element attached, or one that isn't being rendered (detached,\n * `display: none`, not yet laid out) — which is the value the cap reads as \"don't cap\".\n */\n\nimport { type ElementSize, observeElementSize, observeRenderedSize } from '@videojs/utils/dom';\nimport { shallowEqual } from '@videojs/utils/object';\n\nimport { defineBehavior } from '../../../core/composition/create-composition';\nimport { effect } from '../../../core/signals/effect';\nimport type { ReadonlySignal, Signal } from '../../../core/signals/primitives';\nimport { type Resolution, scaleResolution } from '../../../media/primitives/resolution';\n\n/** A player element's rendered pixel dimensions. */\nexport type PlayerResolution = Resolution;\n\nexport interface PlayerResolutionState {\n playerResolution?: PlayerResolution;\n}\n\nexport interface PlayerResolutionContext {\n mediaElement?: HTMLMediaElement | undefined;\n}\n\nexport interface TrackPlayerResolutionConfig {\n /**\n * Whether to cap renditions to the player's rendered size at all. `false` measures nothing, which leaves\n * `state.playerResolution` unset and the cap inert. Defaults to `true`.\n *\n * Named for the policy rather than the measurement because it is the public switch for the feature — the same one\n * hls.js spells `capLevelToPlayerSize` and the Mux Video element spells `cap-rendition-to-player-size`.\n */\n capRenditionToPlayerSize?: boolean;\n /**\n * Whether the reading is scaled into device pixels. Defaults to `true` — see\n * `ScreenResolutionOptions.useDevicePixelRatio` in `media/dom/screen.ts`, including its note on page zoom being\n * folded into the ratio outside WebKit.\n */\n useDevicePixelRatio?: boolean;\n}\n\nfunction trackPlayerResolutionSetup({\n state,\n context,\n config = {},\n}: {\n state: { playerResolution: Signal<PlayerResolutionState['playerResolution']> };\n context: { mediaElement: ReadonlySignal<PlayerResolutionContext['mediaElement']> };\n config?: TrackPlayerResolutionConfig;\n}): () => void {\n const { capRenditionToPlayerSize = true, useDevicePixelRatio = true } = config;\n\n return effect(() => {\n const mediaElement = context.mediaElement.get();\n // Clear before (re-)observing so the previous element's measurement can't\n // stand while the new one's first observation is in flight.\n let current: PlayerResolution | undefined;\n\n state.playerResolution.set(current);\n\n if (!capRenditionToPlayerSize || !mediaElement) return;\n\n // Compared rather than written straight through, since the slot holds an\n // object and would otherwise notify on identity alone: a resize that rounds\n // to the same device pixels is not a change worth re-running selection for.\n // Same reason `watchScreenResolution` compares its readings.\n const write = (size: ElementSize & { scale?: number }) => {\n const next = scaleResolution(size, size.scale);\n if (shallowEqual(current, next)) return;\n\n current = next;\n state.playerResolution.set(next);\n };\n\n return useDevicePixelRatio ? observeRenderedSize(mediaElement, write) : observeElementSize(mediaElement, write);\n });\n}\n\n/**\n * Track the player element's rendered resolution in `state.playerResolution`.\n *\n * @example\n * const cleanup = trackPlayerResolution.setup({ state, context });\n */\nexport const trackPlayerResolution = defineBehavior({\n stateKeys: ['playerResolution'],\n contextKeys: ['mediaElement'],\n setup: trackPlayerResolutionSetup,\n});\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;AAqDA,SAAS,2BAA2B,EAClC,OACA,SACA,SAAS,CAAC,KAKG;CACb,MAAM,EAAE,2BAA2B,MAAM,sBAAsB,SAAS;CAExE,OAAO,aAAa;EAClB,MAAM,eAAe,QAAQ,aAAa,IAAI;EAG9C,IAAI;EAEJ,MAAM,iBAAiB,IAAI,OAAO;EAElC,IAAI,CAAC,4BAA4B,CAAC,cAAc;EAMhD,MAAM,SAAS,SAA2C;GACxD,MAAM,OAAO,gBAAgB,MAAM,KAAK,KAAK;GAC7C,IAAI,aAAa,SAAS,IAAI,GAAG;GAEjC,UAAU;GACV,MAAM,iBAAiB,IAAI,IAAI;EACjC;EAEA,OAAO,sBAAsB,oBAAoB,cAAc,KAAK,IAAI,mBAAmB,cAAc,KAAK;CAChH,CAAC;AACH;;;;;;;AAQA,MAAa,wBAAwB,eAAe;CAClD,WAAW,CAAC,kBAAkB;CAC9B,aAAa,CAAC,cAAc;CAC5B,OAAO;AACT,CAAC"}
|
|
@@ -2,21 +2,20 @@ import { defineBehavior } from "../../../core/composition/create-composition.js"
|
|
|
2
2
|
import { watchScreenResolution } from "../../../media/dom/screen.js";
|
|
3
3
|
//#region src/playback/behaviors/dom/track-screen-resolution.ts
|
|
4
4
|
/**
|
|
5
|
-
* Mirror the screen's pixel dimensions into reactive state, so a rendition cap
|
|
6
|
-
* can
|
|
7
|
-
* environment at pick time — which would make the picker impure, and would never
|
|
5
|
+
* Mirror the screen's pixel dimensions into reactive state, so a rendition cap can narrow candidates to what the screen
|
|
6
|
+
* can actually show without reading the environment at pick time — which would make the picker impure, and would never
|
|
8
7
|
* re-pick when the screen changed.
|
|
9
8
|
*
|
|
10
|
-
* Populated at setup rather than on the first change: `watchScreenResolution`
|
|
11
|
-
*
|
|
12
|
-
* never move. `undefined` where there is no screen to read, which is the value a
|
|
9
|
+
* Populated at setup rather than on the first change: `watchScreenResolution` reports its starting value, so nothing
|
|
10
|
+
* downstream waits on a screen that may never move. `undefined` where there is no screen to read, which is the value a
|
|
13
11
|
* cap reads as "no cap" — see `getScreenResolution` on why that beats a zero.
|
|
14
12
|
*
|
|
15
|
-
* Reads no other slot, and has no source-identity reset: the screen is
|
|
16
|
-
*
|
|
13
|
+
* Reads no other slot, and has no source-identity reset: the screen is independent of the presentation, so a new `src`
|
|
14
|
+
* doesn't invalidate the reading.
|
|
17
15
|
*/
|
|
18
16
|
function trackScreenResolutionSetup({ state, config }) {
|
|
19
|
-
|
|
17
|
+
const useDevicePixelRatio = config?.useDevicePixelRatio ?? true;
|
|
18
|
+
return watchScreenResolution((resolution) => state.screenResolution.set(resolution), { useDevicePixelRatio });
|
|
20
19
|
}
|
|
21
20
|
const trackScreenResolution = defineBehavior({
|
|
22
21
|
stateKeys: ["screenResolution"],
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"track-screen-resolution.js","names":[],"sources":["../../../../../src/playback/behaviors/dom/track-screen-resolution.ts"],"sourcesContent":["/**\n * Mirror the screen's pixel dimensions into reactive state, so a rendition cap
|
|
1
|
+
{"version":3,"file":"track-screen-resolution.js","names":[],"sources":["../../../../../src/playback/behaviors/dom/track-screen-resolution.ts"],"sourcesContent":["/**\n * Mirror the screen's pixel dimensions into reactive state, so a rendition cap can narrow candidates to what the screen\n * can actually show without reading the environment at pick time — which would make the picker impure, and would never\n * re-pick when the screen changed.\n *\n * Populated at setup rather than on the first change: `watchScreenResolution` reports its starting value, so nothing\n * downstream waits on a screen that may never move. `undefined` where there is no screen to read, which is the value a\n * cap reads as \"no cap\" — see `getScreenResolution` on why that beats a zero.\n *\n * Reads no other slot, and has no source-identity reset: the screen is independent of the presentation, so a new `src`\n * doesn't invalidate the reading.\n */\nimport { defineBehavior } from '../../../core/composition/create-composition';\nimport type { Signal } from '../../../core/signals/primitives';\nimport { type ScreenResolution, watchScreenResolution } from '../../../media/dom/screen';\n\nexport interface ScreenResolutionState {\n screenResolution?: ScreenResolution;\n}\n\nexport interface TrackScreenResolutionConfig {\n /**\n * Whether the reading is scaled into device pixels. Defaults to `true` — see\n * `ScreenResolutionOptions.useDevicePixelRatio`, including its note on page zoom being folded into the ratio outside\n * WebKit.\n */\n useDevicePixelRatio?: boolean;\n}\n\nfunction trackScreenResolutionSetup({\n state,\n config,\n}: {\n state: { screenResolution: Signal<ScreenResolutionState['screenResolution']> };\n config?: TrackScreenResolutionConfig;\n}): () => void {\n const useDevicePixelRatio = config?.useDevicePixelRatio ?? true;\n\n // No `effect` wrapper, unlike its `track*` siblings: they re-subscribe when\n // `context.mediaElement` changes, and this behavior has no reactive dependency\n // to re-run on. The watcher's own teardown is the whole cleanup.\n return watchScreenResolution((resolution) => state.screenResolution.set(resolution), { useDevicePixelRatio });\n}\n\nexport const trackScreenResolution = defineBehavior({\n stateKeys: ['screenResolution'],\n contextKeys: [],\n setup: trackScreenResolutionSetup,\n});\n"],"mappings":";;;;;;;;;;;;;;;AA6BA,SAAS,2BAA2B,EAClC,OACA,UAIa;CACb,MAAM,sBAAsB,QAAQ,uBAAuB;CAK3D,OAAO,uBAAuB,eAAe,MAAM,iBAAiB,IAAI,UAAU,GAAG,EAAE,oBAAoB,CAAC;AAC9G;AAEA,MAAa,wBAAwB,eAAe;CAClD,WAAW,CAAC,kBAAkB;CAC9B,aAAa,CAAC;CACd,OAAO;AACT,CAAC"}
|
|
@@ -5,58 +5,43 @@ import { waitForMediaSourceOpen } from "../../../media/dom/mse/mediasource-setup
|
|
|
5
5
|
import { getMaxBufferedEnd, shouldUpdateDuration, waitForSourceBuffersReady } from "../../../media/dom/mse/duration.js";
|
|
6
6
|
//#region src/playback/behaviors/dom/update-mediasource-duration.ts
|
|
7
7
|
/**
|
|
8
|
-
* **Propagate `presentation.duration` to `mediaSource.duration` — exactly
|
|
9
|
-
* once per MediaSource.**
|
|
8
|
+
* **Propagate `presentation.duration` to `mediaSource.duration` — exactly once per MediaSource.**
|
|
10
9
|
*
|
|
11
10
|
* Two paths, by whether the presentation is live:
|
|
12
11
|
*
|
|
13
|
-
* - **Live** (`presentation.duration === Infinity`): write `Infinity` once the
|
|
14
|
-
*
|
|
15
|
-
*
|
|
16
|
-
*
|
|
17
|
-
*
|
|
18
|
-
*
|
|
19
|
-
*
|
|
20
|
-
*
|
|
21
|
-
*
|
|
22
|
-
* -
|
|
23
|
-
* all SourceBuffers are idle, clamped to be ≥ the highest buffered range (MSE
|
|
24
|
-
* spec). Written only while `mediaSource.duration` is still `NaN`; once any
|
|
25
|
-
* non-NaN value is present (us on a prior entry, or `endOfStream` from the
|
|
26
|
-
* buffered end), the property is left alone — re-syncing would race
|
|
27
|
-
* concurrent `appendBuffer()` calls.
|
|
12
|
+
* - **Live** (`presentation.duration === Infinity`): write `Infinity` once the MediaSource is open and no SourceBuffer is
|
|
13
|
+
* mid-append. No buffered clamp is needed (`Infinity` ≥ any range) and — unlike the finite case — it needn't precede
|
|
14
|
+
* the first append: `Infinity` overrides whatever finite live-edge value an append may have pinned (a finite duration
|
|
15
|
+
* would otherwise stall the stream once the window slides past it). The wait-for-idle is required because the MSE
|
|
16
|
+
* spec forbids setting `duration` while a buffer is `updating`; both waits resolve immediately when already open /
|
|
17
|
+
* idle.
|
|
18
|
+
* - **VoD** (finite): the value is written once, after `mediaSource` is open and all SourceBuffers are idle, clamped to
|
|
19
|
+
* be ≥ the highest buffered range (MSE spec). Written only while `mediaSource.duration` is still `NaN`; once any
|
|
20
|
+
* non-NaN value is present (us on a prior entry, or `endOfStream` from the buffered end), the property is left alone
|
|
21
|
+
* — re-syncing would race concurrent `appendBuffer()` calls.
|
|
28
22
|
*
|
|
29
23
|
* The entry resolves three async preconditions in order before writing:
|
|
30
24
|
*
|
|
31
|
-
* 1. **MediaSource open** — `waitForMediaSourceOpen` defers until the first
|
|
32
|
-
*
|
|
33
|
-
*
|
|
34
|
-
*
|
|
35
|
-
*
|
|
36
|
-
* `
|
|
37
|
-
* 3. **Buffered-range clamp** — `getMaxBufferedEnd` ensures the written
|
|
38
|
-
* duration is at least the highest buffered end (MSE spec disallows
|
|
39
|
-
* a smaller `duration` than any buffered range).
|
|
25
|
+
* 1. **MediaSource open** — `waitForMediaSourceOpen` defers until the first `sourceopen` event (or any readyState
|
|
26
|
+
* transition, since `'ended'` / `'closed'` mean we've missed the window and should bail).
|
|
27
|
+
* 2. **All SourceBuffers idle** — `waitForSourceBuffersReady` defers per the MSE-spec rule that `duration` cannot be set
|
|
28
|
+
* while any buffer has `updating === true`.
|
|
29
|
+
* 3. **Buffered-range clamp** — `getMaxBufferedEnd` ensures the written duration is at least the highest buffered end (MSE
|
|
30
|
+
* spec disallows a smaller `duration` than any buffered range).
|
|
40
31
|
*
|
|
41
|
-
* The buffer-set helpers operate across `mediaSource.sourceBuffers` (the
|
|
42
|
-
*
|
|
43
|
-
* audio-only, video-only, and mixed configurations.
|
|
32
|
+
* The buffer-set helpers operate across `mediaSource.sourceBuffers` (the canonical aggregate), so the behavior composes
|
|
33
|
+
* uniformly across audio-only, video-only, and mixed configurations.
|
|
44
34
|
*
|
|
45
|
-
* Single-positive-state reactor (`'preconditions-unmet'` ↔ `'duration-writable'`):
|
|
46
|
-
*
|
|
47
|
-
*
|
|
48
|
-
* the
|
|
49
|
-
*
|
|
50
|
-
*
|
|
51
|
-
*
|
|
52
|
-
* 'open'` covers the narrow race where `endOfStream()` synchronously
|
|
53
|
-
* transitions readyState to `'ended'` between our `waitForMediaSourceOpen`
|
|
54
|
-
* resolution and the `mediaSource.duration` write.
|
|
35
|
+
* Single-positive-state reactor (`'preconditions-unmet'` ↔ `'duration-writable'`): state derivation is purely
|
|
36
|
+
* signal-driven (presentation validity + mediaSource existence). MediaSource lifecycle state (`readyState`) and the
|
|
37
|
+
* `duration` itself are non-signal DOM properties resolved inside the entry's async sequence. The state-exit cleanup
|
|
38
|
+
* aborts the in-flight wait, so source resets and behavior destroy structurally cancel the pending write. A post-await
|
|
39
|
+
* re-check of `mediaSource.readyState === 'open'` covers the narrow race where `endOfStream()` synchronously
|
|
40
|
+
* transitions readyState to `'ended'` between our `waitForMediaSourceOpen` resolution and the `mediaSource.duration`
|
|
41
|
+
* write.
|
|
55
42
|
*
|
|
56
|
-
* Downstream of `calculatePresentationDuration` (which writes
|
|
57
|
-
* `
|
|
58
|
-
* write `mediaSource.duration` — the "exactly once" contract keeps us out
|
|
59
|
-
* of that path).
|
|
43
|
+
* Downstream of `calculatePresentationDuration` (which writes `presentation.duration`); concurrent with `endOfStream`
|
|
44
|
+
* (which may later write `mediaSource.duration` — the "exactly once" contract keeps us out of that path).
|
|
60
45
|
*/
|
|
61
46
|
function deriveState(presentation, mediaSource) {
|
|
62
47
|
return shouldUpdateDuration(presentation, mediaSource) ? "duration-writable" : "preconditions-unmet";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"update-mediasource-duration.js","names":[],"sources":["../../../../../src/playback/behaviors/dom/update-mediasource-duration.ts"],"sourcesContent":["/**\n * **Propagate `presentation.duration` to `mediaSource.duration` — exactly\n * once per MediaSource.**\n *\n * Two paths, by whether the presentation is live:\n *\n * - **Live** (`presentation.duration === Infinity`): write `Infinity` once the\n * MediaSource is open and no SourceBuffer is mid-append. No buffered clamp is\n * needed (`Infinity` ≥ any range) and — unlike the finite case — it needn't\n * precede the first append: `Infinity` overrides whatever finite live-edge\n * value an append may have pinned (a finite duration would otherwise stall\n * the stream once the window slides past it). The wait-for-idle is required\n * because the MSE spec forbids setting `duration` while a buffer is\n * `updating`; both waits resolve immediately when already open / idle.\n *\n * - **VoD** (finite): the value is written once, after `mediaSource` is open and\n * all SourceBuffers are idle, clamped to be ≥ the highest buffered range (MSE\n * spec). Written only while `mediaSource.duration` is still `NaN`; once any\n * non-NaN value is present (us on a prior entry, or `endOfStream` from the\n * buffered end), the property is left alone — re-syncing would race\n * concurrent `appendBuffer()` calls.\n *\n * The entry resolves three async preconditions in order before writing:\n *\n * 1. **MediaSource open** — `waitForMediaSourceOpen` defers until the first\n * `sourceopen` event (or any readyState transition, since `'ended'` /\n * `'closed'` mean we've missed the window and should bail).\n * 2. **All SourceBuffers idle** — `waitForSourceBuffersReady` defers per\n * the MSE-spec rule that `duration` cannot be set while any buffer has\n * `updating === true`.\n * 3. **Buffered-range clamp** — `getMaxBufferedEnd` ensures the written\n * duration is at least the highest buffered end (MSE spec disallows\n * a smaller `duration` than any buffered range).\n *\n * The buffer-set helpers operate across `mediaSource.sourceBuffers` (the\n * canonical aggregate), so the behavior composes uniformly across\n * audio-only, video-only, and mixed configurations.\n *\n * Single-positive-state reactor (`'preconditions-unmet'` ↔ `'duration-writable'`):\n * state derivation is purely signal-driven (presentation validity +\n * mediaSource existence). MediaSource lifecycle state (`readyState`) and\n * the `duration` itself are non-signal DOM properties resolved inside the\n * entry's async sequence. The state-exit cleanup aborts the in-flight\n * wait, so source resets and behavior destroy structurally cancel the\n * pending write. A post-await re-check of `mediaSource.readyState ===\n * 'open'` covers the narrow race where `endOfStream()` synchronously\n * transitions readyState to `'ended'` between our `waitForMediaSourceOpen`\n * resolution and the `mediaSource.duration` write.\n *\n * Downstream of `calculatePresentationDuration` (which writes\n * `presentation.duration`); concurrent with `endOfStream` (which may later\n * write `mediaSource.duration` — the \"exactly once\" contract keeps us out\n * of that path).\n */\nimport { defineBehavior } from '../../../core/composition/create-composition';\nimport type { Reactor } from '../../../core/reactors/create-machine-reactor';\nimport { createMachineReactor } from '../../../core/reactors/create-machine-reactor';\nimport { computed, type ReadonlySignal } from '../../../core/signals/primitives';\nimport { getMaxBufferedEnd, shouldUpdateDuration, waitForSourceBuffersReady } from '../../../media/dom/mse/duration';\nimport { waitForMediaSourceOpen } from '../../../media/dom/mse/mediasource-setup';\nimport type { MaybeResolvedPresentation } from '../../../media/types';\n\ntype DurationFsmState = 'preconditions-unmet' | 'duration-writable';\n\nfunction deriveState(\n presentation: MaybeResolvedPresentation | undefined,\n mediaSource: MediaSource | undefined\n): DurationFsmState {\n return shouldUpdateDuration(presentation, mediaSource) ? 'duration-writable' : 'preconditions-unmet';\n}\n\nfunction updateMediaSourceDurationSetup({\n state,\n context,\n}: {\n state: { presentation: ReadonlySignal<MaybeResolvedPresentation | undefined> };\n context: { mediaSource: ReadonlySignal<MediaSource | undefined> };\n}): Reactor<DurationFsmState | 'destroying' | 'destroyed'> {\n // Purely signal-driven derivation: only `presentation` validity and\n // `mediaSource` existence. MediaSource lifecycle (`readyState`),\n // its attached `sourceBuffers`, and `mediaSource.duration` itself are\n // non-signal DOM properties consumed inside the entry — none of them\n // sneak into `computed(...)`.\n const derivedStateSignal = computed(() => deriveState(state.presentation.get(), context.mediaSource.get()));\n\n return createMachineReactor<DurationFsmState>({\n initial: 'preconditions-unmet',\n monitor: () => derivedStateSignal.get(),\n states: {\n 'preconditions-unmet': {},\n\n 'duration-writable': {\n // entry body is auto-untracked. The state machine handles source\n // resets via deriveState; this entry resolves the MediaSource\n // lifecycle preconditions in sequence and binds its cleanup\n // (abort) to state exit + destroy.\n entry: () => {\n const presentation = state.presentation.get()!;\n const mediaSource = context.mediaSource.get()!;\n\n // Live: write Infinity once the MediaSource is open and no buffer is\n // mid-append (the MSE spec forbids setting `duration` while a\n // SourceBuffer is `updating`, and racing an in-flight append throws).\n // No `NaN` guard, unlike the VoD path below — Infinity must override\n // whatever finite live-edge value an append may have pinned.\n if (presentation.duration === Number.POSITIVE_INFINITY) {\n if (mediaSource.duration === Number.POSITIVE_INFINITY) return;\n const controller = new AbortController();\n void (async () => {\n await waitForMediaSourceOpen(mediaSource, controller.signal);\n if (controller.signal.aborted || mediaSource.readyState !== 'open') return;\n await waitForSourceBuffersReady(mediaSource.sourceBuffers, controller.signal);\n if (controller.signal.aborted || mediaSource.readyState !== 'open') return;\n if (mediaSource.duration !== Number.POSITIVE_INFINITY) {\n mediaSource.duration = Number.POSITIVE_INFINITY;\n }\n })();\n return () => controller.abort();\n }\n\n // VoD idempotency: someone (us on a prior entry, or concurrent\n // `endOfStream`) has already written. No-op and leave the state\n // alone — the next source-reset transition will produce a fresh\n // entry against the new MediaSource (whose `duration` starts at\n // `NaN` again).\n if (!Number.isNaN(mediaSource.duration)) return;\n\n const controller = new AbortController();\n\n const writeWhenReady = async () => {\n await waitForMediaSourceOpen(mediaSource, controller.signal);\n if (controller.signal.aborted) return;\n // `waitForMediaSourceOpen` resolves on any readyState transition\n // out of 'closed'; if we landed in 'ended' / 'closed' instead of\n // 'open', the write window is gone.\n if (mediaSource.readyState !== 'open') return;\n\n await waitForSourceBuffersReady(mediaSource.sourceBuffers, controller.signal);\n if (controller.signal.aborted) return;\n\n // Narrow race: `endOfStream()` synchronously transitions\n // readyState to 'ended' AND writes `mediaSource.duration`\n // between our `waitForMediaSourceOpen` resolution and here.\n // Re-read the DOM property to catch this window.\n if (mediaSource.readyState !== 'open') return;\n\n // MSE spec: duration cannot be less than any buffered range.\n // Re-read sourceBuffers after the await so any buffer added\n // during the wait is included in the clamp.\n const maxBufferedEnd = getMaxBufferedEnd(mediaSource.sourceBuffers);\n const duration = maxBufferedEnd > presentation.duration! ? maxBufferedEnd : presentation.duration!;\n mediaSource.duration = duration;\n };\n\n writeWhenReady();\n\n return () => controller.abort();\n },\n },\n },\n });\n}\n\nexport const updateMediaSourceDuration = defineBehavior({\n stateKeys: ['presentation'],\n contextKeys: ['mediaSource'],\n setup: updateMediaSourceDurationSetup,\n});\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAgEA,SAAS,YACP,cACA,aACkB;CAClB,OAAO,qBAAqB,cAAc,WAAW,IAAI,sBAAsB;AACjF;AAEA,SAAS,+BAA+B,EACtC,OACA,WAIyD;CAMzD,MAAM,qBAAqB,eAAe,YAAY,MAAM,aAAa,IAAI,GAAG,QAAQ,YAAY,IAAI,CAAC,CAAC;CAE1G,OAAO,qBAAuC;EAC5C,SAAS;EACT,eAAe,mBAAmB,IAAI;EACtC,QAAQ;GACN,uBAAuB,CAAC;GAExB,qBAAqB,EAKnB,aAAa;IACX,MAAM,eAAe,MAAM,aAAa,IAAI;IAC5C,MAAM,cAAc,QAAQ,YAAY,IAAI;IAO5C,IAAI,aAAa,aAAa,OAAO,mBAAmB;KACtD,IAAI,YAAY,aAAa,OAAO,mBAAmB;KACvD,MAAM,aAAa,IAAI,gBAAgB;KACvC,CAAM,YAAY;MAChB,MAAM,uBAAuB,aAAa,WAAW,MAAM;MAC3D,IAAI,WAAW,OAAO,WAAW,YAAY,eAAe,QAAQ;MACpE,MAAM,0BAA0B,YAAY,eAAe,WAAW,MAAM;MAC5E,IAAI,WAAW,OAAO,WAAW,YAAY,eAAe,QAAQ;MACpE,IAAI,YAAY,aAAa,OAAO,mBAClC,YAAY,WAAW,OAAO;KAElC,EAAA,CAAG;KACH,aAAa,WAAW,MAAM;IAChC;IAOA,IAAI,CAAC,OAAO,MAAM,YAAY,QAAQ,GAAG;IAEzC,MAAM,aAAa,IAAI,gBAAgB;IAEvC,MAAM,iBAAiB,YAAY;KACjC,MAAM,uBAAuB,aAAa,WAAW,MAAM;KAC3D,IAAI,WAAW,OAAO,SAAS;KAI/B,IAAI,YAAY,eAAe,QAAQ;KAEvC,MAAM,0BAA0B,YAAY,eAAe,WAAW,MAAM;KAC5E,IAAI,WAAW,OAAO,SAAS;KAM/B,IAAI,YAAY,eAAe,QAAQ;KAKvC,MAAM,iBAAiB,kBAAkB,YAAY,aAAa;KAClE,MAAM,WAAW,iBAAiB,aAAa,WAAY,iBAAiB,aAAa;KACzF,YAAY,WAAW;IACzB;IAEA,eAAe;IAEf,aAAa,WAAW,MAAM;GAChC,EACF;EACF;CACF,CAAC;AACH;AAEA,MAAa,4BAA4B,eAAe;CACtD,WAAW,CAAC,cAAc;CAC1B,aAAa,CAAC,aAAa;CAC3B,OAAO;AACT,CAAC"}
|
|
1
|
+
{"version":3,"file":"update-mediasource-duration.js","names":[],"sources":["../../../../../src/playback/behaviors/dom/update-mediasource-duration.ts"],"sourcesContent":["/**\n * **Propagate `presentation.duration` to `mediaSource.duration` — exactly once per MediaSource.**\n *\n * Two paths, by whether the presentation is live:\n *\n * - **Live** (`presentation.duration === Infinity`): write `Infinity` once the MediaSource is open and no SourceBuffer is\n * mid-append. No buffered clamp is needed (`Infinity` ≥ any range) and — unlike the finite case — it needn't precede\n * the first append: `Infinity` overrides whatever finite live-edge value an append may have pinned (a finite duration\n * would otherwise stall the stream once the window slides past it). The wait-for-idle is required because the MSE\n * spec forbids setting `duration` while a buffer is `updating`; both waits resolve immediately when already open /\n * idle.\n * - **VoD** (finite): the value is written once, after `mediaSource` is open and all SourceBuffers are idle, clamped to\n * be ≥ the highest buffered range (MSE spec). Written only while `mediaSource.duration` is still `NaN`; once any\n * non-NaN value is present (us on a prior entry, or `endOfStream` from the buffered end), the property is left alone\n * — re-syncing would race concurrent `appendBuffer()` calls.\n *\n * The entry resolves three async preconditions in order before writing:\n *\n * 1. **MediaSource open** — `waitForMediaSourceOpen` defers until the first `sourceopen` event (or any readyState\n * transition, since `'ended'` / `'closed'` mean we've missed the window and should bail).\n * 2. **All SourceBuffers idle** — `waitForSourceBuffersReady` defers per the MSE-spec rule that `duration` cannot be set\n * while any buffer has `updating === true`.\n * 3. **Buffered-range clamp** — `getMaxBufferedEnd` ensures the written duration is at least the highest buffered end (MSE\n * spec disallows a smaller `duration` than any buffered range).\n *\n * The buffer-set helpers operate across `mediaSource.sourceBuffers` (the canonical aggregate), so the behavior composes\n * uniformly across audio-only, video-only, and mixed configurations.\n *\n * Single-positive-state reactor (`'preconditions-unmet'` ↔ `'duration-writable'`): state derivation is purely\n * signal-driven (presentation validity + mediaSource existence). MediaSource lifecycle state (`readyState`) and the\n * `duration` itself are non-signal DOM properties resolved inside the entry's async sequence. The state-exit cleanup\n * aborts the in-flight wait, so source resets and behavior destroy structurally cancel the pending write. A post-await\n * re-check of `mediaSource.readyState === 'open'` covers the narrow race where `endOfStream()` synchronously\n * transitions readyState to `'ended'` between our `waitForMediaSourceOpen` resolution and the `mediaSource.duration`\n * write.\n *\n * Downstream of `calculatePresentationDuration` (which writes `presentation.duration`); concurrent with `endOfStream`\n * (which may later write `mediaSource.duration` — the \"exactly once\" contract keeps us out of that path).\n */\nimport { defineBehavior } from '../../../core/composition/create-composition';\nimport type { Reactor } from '../../../core/reactors/create-machine-reactor';\nimport { createMachineReactor } from '../../../core/reactors/create-machine-reactor';\nimport { computed, type ReadonlySignal } from '../../../core/signals/primitives';\nimport { getMaxBufferedEnd, shouldUpdateDuration, waitForSourceBuffersReady } from '../../../media/dom/mse/duration';\nimport { waitForMediaSourceOpen } from '../../../media/dom/mse/mediasource-setup';\nimport type { MaybeResolvedPresentation } from '../../../media/types';\n\ntype DurationFsmState = 'preconditions-unmet' | 'duration-writable';\n\nfunction deriveState(\n presentation: MaybeResolvedPresentation | undefined,\n mediaSource: MediaSource | undefined\n): DurationFsmState {\n return shouldUpdateDuration(presentation, mediaSource) ? 'duration-writable' : 'preconditions-unmet';\n}\n\nfunction updateMediaSourceDurationSetup({\n state,\n context,\n}: {\n state: { presentation: ReadonlySignal<MaybeResolvedPresentation | undefined> };\n context: { mediaSource: ReadonlySignal<MediaSource | undefined> };\n}): Reactor<DurationFsmState | 'destroying' | 'destroyed'> {\n // Purely signal-driven derivation: only `presentation` validity and\n // `mediaSource` existence. MediaSource lifecycle (`readyState`),\n // its attached `sourceBuffers`, and `mediaSource.duration` itself are\n // non-signal DOM properties consumed inside the entry — none of them\n // sneak into `computed(...)`.\n const derivedStateSignal = computed(() => deriveState(state.presentation.get(), context.mediaSource.get()));\n\n return createMachineReactor<DurationFsmState>({\n initial: 'preconditions-unmet',\n monitor: () => derivedStateSignal.get(),\n states: {\n 'preconditions-unmet': {},\n\n 'duration-writable': {\n // entry body is auto-untracked. The state machine handles source\n // resets via deriveState; this entry resolves the MediaSource\n // lifecycle preconditions in sequence and binds its cleanup\n // (abort) to state exit + destroy.\n entry: () => {\n const presentation = state.presentation.get()!;\n const mediaSource = context.mediaSource.get()!;\n\n // Live: write Infinity once the MediaSource is open and no buffer is\n // mid-append (the MSE spec forbids setting `duration` while a\n // SourceBuffer is `updating`, and racing an in-flight append throws).\n // No `NaN` guard, unlike the VoD path below — Infinity must override\n // whatever finite live-edge value an append may have pinned.\n if (presentation.duration === Number.POSITIVE_INFINITY) {\n if (mediaSource.duration === Number.POSITIVE_INFINITY) return;\n\n const controller = new AbortController();\n\n void (async () => {\n await waitForMediaSourceOpen(mediaSource, controller.signal);\n\n if (controller.signal.aborted || mediaSource.readyState !== 'open') return;\n\n await waitForSourceBuffersReady(mediaSource.sourceBuffers, controller.signal);\n\n if (controller.signal.aborted || mediaSource.readyState !== 'open') return;\n\n if (mediaSource.duration !== Number.POSITIVE_INFINITY) {\n mediaSource.duration = Number.POSITIVE_INFINITY;\n }\n })();\n return () => controller.abort();\n }\n\n // VoD idempotency: someone (us on a prior entry, or concurrent\n // `endOfStream`) has already written. No-op and leave the state\n // alone — the next source-reset transition will produce a fresh\n // entry against the new MediaSource (whose `duration` starts at\n // `NaN` again).\n if (!Number.isNaN(mediaSource.duration)) return;\n\n const controller = new AbortController();\n\n const writeWhenReady = async () => {\n await waitForMediaSourceOpen(mediaSource, controller.signal);\n\n if (controller.signal.aborted) return;\n\n // `waitForMediaSourceOpen` resolves on any readyState transition\n // out of 'closed'; if we landed in 'ended' / 'closed' instead of\n // 'open', the write window is gone.\n if (mediaSource.readyState !== 'open') return;\n\n await waitForSourceBuffersReady(mediaSource.sourceBuffers, controller.signal);\n\n if (controller.signal.aborted) return;\n\n // Narrow race: `endOfStream()` synchronously transitions\n // readyState to 'ended' AND writes `mediaSource.duration`\n // between our `waitForMediaSourceOpen` resolution and here.\n // Re-read the DOM property to catch this window.\n if (mediaSource.readyState !== 'open') return;\n\n // MSE spec: duration cannot be less than any buffered range.\n // Re-read sourceBuffers after the await so any buffer added\n // during the wait is included in the clamp.\n const maxBufferedEnd = getMaxBufferedEnd(mediaSource.sourceBuffers);\n const duration = maxBufferedEnd > presentation.duration! ? maxBufferedEnd : presentation.duration!;\n\n mediaSource.duration = duration;\n };\n\n writeWhenReady();\n\n return () => controller.abort();\n },\n },\n },\n });\n}\n\nexport const updateMediaSourceDuration = defineBehavior({\n stateKeys: ['presentation'],\n contextKeys: ['mediaSource'],\n setup: updateMediaSourceDurationSetup,\n});\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAiDA,SAAS,YACP,cACA,aACkB;CAClB,OAAO,qBAAqB,cAAc,WAAW,IAAI,sBAAsB;AACjF;AAEA,SAAS,+BAA+B,EACtC,OACA,WAIyD;CAMzD,MAAM,qBAAqB,eAAe,YAAY,MAAM,aAAa,IAAI,GAAG,QAAQ,YAAY,IAAI,CAAC,CAAC;CAE1G,OAAO,qBAAuC;EAC5C,SAAS;EACT,eAAe,mBAAmB,IAAI;EACtC,QAAQ;GACN,uBAAuB,CAAC;GAExB,qBAAqB,EAKnB,aAAa;IACX,MAAM,eAAe,MAAM,aAAa,IAAI;IAC5C,MAAM,cAAc,QAAQ,YAAY,IAAI;IAO5C,IAAI,aAAa,aAAa,OAAO,mBAAmB;KACtD,IAAI,YAAY,aAAa,OAAO,mBAAmB;KAEvD,MAAM,aAAa,IAAI,gBAAgB;KAEvC,CAAM,YAAY;MAChB,MAAM,uBAAuB,aAAa,WAAW,MAAM;MAE3D,IAAI,WAAW,OAAO,WAAW,YAAY,eAAe,QAAQ;MAEpE,MAAM,0BAA0B,YAAY,eAAe,WAAW,MAAM;MAE5E,IAAI,WAAW,OAAO,WAAW,YAAY,eAAe,QAAQ;MAEpE,IAAI,YAAY,aAAa,OAAO,mBAClC,YAAY,WAAW,OAAO;KAElC,EAAA,CAAG;KACH,aAAa,WAAW,MAAM;IAChC;IAOA,IAAI,CAAC,OAAO,MAAM,YAAY,QAAQ,GAAG;IAEzC,MAAM,aAAa,IAAI,gBAAgB;IAEvC,MAAM,iBAAiB,YAAY;KACjC,MAAM,uBAAuB,aAAa,WAAW,MAAM;KAE3D,IAAI,WAAW,OAAO,SAAS;KAK/B,IAAI,YAAY,eAAe,QAAQ;KAEvC,MAAM,0BAA0B,YAAY,eAAe,WAAW,MAAM;KAE5E,IAAI,WAAW,OAAO,SAAS;KAM/B,IAAI,YAAY,eAAe,QAAQ;KAKvC,MAAM,iBAAiB,kBAAkB,YAAY,aAAa;KAClE,MAAM,WAAW,iBAAiB,aAAa,WAAY,iBAAiB,aAAa;KAEzF,YAAY,WAAW;IACzB;IAEA,eAAe;IAEf,aAAa,WAAW,MAAM;GAChC,EACF;EACF;CACF,CAAC;AACH;AAEA,MAAa,4BAA4B,eAAe;CACtD,WAAW,CAAC,cAAc;CAC1B,aAAa,CAAC,aAAa;CAC3B,OAAO;AACT,CAAC"}
|
|
@@ -3,32 +3,28 @@ import "../../core/composition/create-composition.js";
|
|
|
3
3
|
import { DeriveStartMediaTime, DeriveStartMediaTimeContext } from "../primitives/derive-start-media-time.js";
|
|
4
4
|
//#region src/playback/behaviors/establish-start-media-time.d.ts
|
|
5
5
|
/**
|
|
6
|
-
* The **default** — relocate the whole presentation by one shared origin: the `min`
|
|
7
|
-
*
|
|
8
|
-
*
|
|
6
|
+
* The **default** — relocate the whole presentation by one shared origin: the `min` across the _selected_ A/V tracks'
|
|
7
|
+
* own origins, denormalized onto every type. This single reduce subsumes the "per-type" and "shared" tiers:
|
|
8
|
+
*
|
|
9
9
|
* - **aligned A/V** — `min` equals each origin (they're equal), so it matches per-type;
|
|
10
|
-
* - **skewed A/V** (e.g. Apple's 44ms audio-lead) — `min` keeps every track's earliest
|
|
11
|
-
*
|
|
12
|
-
* the real skew (per-type would flatten it, desyncing A/V);
|
|
10
|
+
* - **skewed A/V** (e.g. Apple's 44ms audio-lead) — `min` keeps every track's earliest DTS ≥ 0 (relocating by ≤ each own
|
|
11
|
+
* origin never drives one negative) _and_ preserves the real skew (per-type would flatten it, desyncing A/V);
|
|
13
12
|
* - **single type / muxed** — `min` of the one origin is that origin.
|
|
14
13
|
*
|
|
15
|
-
* Returns `undefined` for every type until all
|
|
16
|
-
*
|
|
17
|
-
*
|
|
18
|
-
*
|
|
19
|
-
* (native — ordinary ~0-PTS VOD isn't relocated).
|
|
14
|
+
* Returns `undefined` for every type until all _selected_ types have a complete origin (the shared-`min` barrier).
|
|
15
|
+
* Which types must contribute is read from `ctx` (the selected v/a ids); with no selection context it coordinates
|
|
16
|
+
* across whatever types have data. A shared origin below {@link NEAR_ZERO_ORIGIN_THRESHOLD} is returned as `0` (native
|
|
17
|
+
* — ordinary ~0-PTS VOD isn't relocated).
|
|
20
18
|
*/
|
|
21
19
|
declare const deriveSharedMinStartMediaTime: DeriveStartMediaTime;
|
|
22
20
|
/**
|
|
23
|
-
* Coordination-axis
|
|
24
|
-
*
|
|
25
|
-
*
|
|
26
|
-
* the shared-`min` barrier (each type stamps as soon as its own origin is discovered).
|
|
21
|
+
* Coordination-axis _off_ — each type relocates by its own origin, independently. Not the default: it flattens real A/V
|
|
22
|
+
* skew (see {@link deriveSharedMinStartMediaTime}). Kept as an opt-in for compositions that know their A/V is aligned
|
|
23
|
+
* and want to skip the shared-`min` barrier (each type stamps as soon as its own origin is discovered).
|
|
27
24
|
*
|
|
28
|
-
* Caution: {@link NEAR_ZERO_ORIGIN_THRESHOLD} applies independently per type here — if
|
|
29
|
-
*
|
|
30
|
-
*
|
|
31
|
-
* `internal/design/spf/live-presentation-timeline-model.md` (collision 5).
|
|
25
|
+
* Caution: {@link NEAR_ZERO_ORIGIN_THRESHOLD} applies independently per type here — if two types' origins straddle it,
|
|
26
|
+
* one snaps to `0` and the other doesn't, injecting up to a threshold's worth of A/V offset. Safe for the intended
|
|
27
|
+
* aligned-A/V opt-in; see `internal/design/spf/live-presentation-timeline-model.md` (collision 5).
|
|
32
28
|
*/
|
|
33
29
|
declare const derivePerTypeStartMediaTime: DeriveStartMediaTime;
|
|
34
30
|
//#endregion
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"establish-start-media-time.d.ts","names":[],"sources":["../../../../src/playback/behaviors/establish-start-media-time.ts"],"mappings":"
|
|
1
|
+
{"version":3,"file":"establish-start-media-time.d.ts","names":[],"sources":["../../../../src/playback/behaviors/establish-start-media-time.ts"],"mappings":";;;;;;;;;;;;;;;;;;cAmGa,+BAA+B;;;;;;;;;;cA8B/B,6BAA6B"}
|
|
@@ -4,10 +4,9 @@ import { isResolvedPresentation, isResolvedTrack } from "../../media/types/index
|
|
|
4
4
|
import { findTrackById } from "../../media/utils/tracks.js";
|
|
5
5
|
//#region src/playback/behaviors/establish-start-media-time.ts
|
|
6
6
|
/**
|
|
7
|
-
* A single type's own media-timeline origin:
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
* `undefined` until timescale + baseMediaDecodeTime + segmentStartTime are all present.
|
|
7
|
+
* A single type's own media-timeline origin: `baseMediaDecodeTime/timescale − segmentStartTime` (the `segmentStartTime`
|
|
8
|
+
* term makes it the stream origin even when the first loaded segment isn't the 0th). `undefined` until timescale +
|
|
9
|
+
* baseMediaDecodeTime + segmentStartTime are all present.
|
|
11
10
|
*/
|
|
12
11
|
function ownOrigin(data) {
|
|
13
12
|
const { timescale, baseMediaDecodeTime, segmentStartTime } = data ?? {};
|
|
@@ -18,20 +17,18 @@ function thresholdOrigin(origin) {
|
|
|
18
17
|
return origin < 1 ? 0 : origin;
|
|
19
18
|
}
|
|
20
19
|
/**
|
|
21
|
-
* The **default** — relocate the whole presentation by one shared origin: the `min`
|
|
22
|
-
*
|
|
23
|
-
*
|
|
20
|
+
* The **default** — relocate the whole presentation by one shared origin: the `min` across the _selected_ A/V tracks'
|
|
21
|
+
* own origins, denormalized onto every type. This single reduce subsumes the "per-type" and "shared" tiers:
|
|
22
|
+
*
|
|
24
23
|
* - **aligned A/V** — `min` equals each origin (they're equal), so it matches per-type;
|
|
25
|
-
* - **skewed A/V** (e.g. Apple's 44ms audio-lead) — `min` keeps every track's earliest
|
|
26
|
-
*
|
|
27
|
-
* the real skew (per-type would flatten it, desyncing A/V);
|
|
24
|
+
* - **skewed A/V** (e.g. Apple's 44ms audio-lead) — `min` keeps every track's earliest DTS ≥ 0 (relocating by ≤ each own
|
|
25
|
+
* origin never drives one negative) _and_ preserves the real skew (per-type would flatten it, desyncing A/V);
|
|
28
26
|
* - **single type / muxed** — `min` of the one origin is that origin.
|
|
29
27
|
*
|
|
30
|
-
* Returns `undefined` for every type until all
|
|
31
|
-
*
|
|
32
|
-
*
|
|
33
|
-
*
|
|
34
|
-
* (native — ordinary ~0-PTS VOD isn't relocated).
|
|
28
|
+
* Returns `undefined` for every type until all _selected_ types have a complete origin (the shared-`min` barrier).
|
|
29
|
+
* Which types must contribute is read from `ctx` (the selected v/a ids); with no selection context it coordinates
|
|
30
|
+
* across whatever types have data. A shared origin below {@link NEAR_ZERO_ORIGIN_THRESHOLD} is returned as `0` (native
|
|
31
|
+
* — ordinary ~0-PTS VOD isn't relocated).
|
|
35
32
|
*/
|
|
36
33
|
const deriveSharedMinStartMediaTime = (containerData, ctx) => {
|
|
37
34
|
const contributingTypes = [];
|
|
@@ -45,15 +42,13 @@ const deriveSharedMinStartMediaTime = (containerData, ctx) => {
|
|
|
45
42
|
return out;
|
|
46
43
|
};
|
|
47
44
|
/**
|
|
48
|
-
* Coordination-axis
|
|
49
|
-
*
|
|
50
|
-
*
|
|
51
|
-
* the shared-`min` barrier (each type stamps as soon as its own origin is discovered).
|
|
45
|
+
* Coordination-axis _off_ — each type relocates by its own origin, independently. Not the default: it flattens real A/V
|
|
46
|
+
* skew (see {@link deriveSharedMinStartMediaTime}). Kept as an opt-in for compositions that know their A/V is aligned
|
|
47
|
+
* and want to skip the shared-`min` barrier (each type stamps as soon as its own origin is discovered).
|
|
52
48
|
*
|
|
53
|
-
* Caution: {@link NEAR_ZERO_ORIGIN_THRESHOLD} applies independently per type here — if
|
|
54
|
-
*
|
|
55
|
-
*
|
|
56
|
-
* `internal/design/spf/live-presentation-timeline-model.md` (collision 5).
|
|
49
|
+
* Caution: {@link NEAR_ZERO_ORIGIN_THRESHOLD} applies independently per type here — if two types' origins straddle it,
|
|
50
|
+
* one snaps to `0` and the other doesn't, injecting up to a threshold's worth of A/V offset. Safe for the intended
|
|
51
|
+
* aligned-A/V opt-in; see `internal/design/spf/live-presentation-timeline-model.md` (collision 5).
|
|
57
52
|
*/
|
|
58
53
|
const derivePerTypeStartMediaTime = (containerData) => {
|
|
59
54
|
const out = {};
|
|
@@ -64,25 +59,22 @@ const derivePerTypeStartMediaTime = (containerData) => {
|
|
|
64
59
|
return out;
|
|
65
60
|
};
|
|
66
61
|
/**
|
|
67
|
-
* The anchor-source track: the selected video track, falling back to audio
|
|
68
|
-
*
|
|
69
|
-
* under concurrent resolves.
|
|
62
|
+
* The anchor-source track: the selected video track, falling back to audio (audio-only). Deterministic — never "first
|
|
63
|
+
* resolved", which is race-dependent under concurrent resolves.
|
|
70
64
|
*/
|
|
71
65
|
function referenceTrackId(ctx) {
|
|
72
66
|
return ctx.selectedVideoTrackId ?? ctx.selectedAudioTrackId;
|
|
73
67
|
}
|
|
74
68
|
/**
|
|
75
|
-
* The live-anchor first-parse gate (the "parses align" step of the establishment
|
|
76
|
-
*
|
|
77
|
-
* the
|
|
78
|
-
*
|
|
79
|
-
*
|
|
80
|
-
*
|
|
81
|
-
* `placeOnAnchor` path. Establishment is sticky-once, so an unanchored first
|
|
82
|
-
* parse would be permanently misaligned — that's the race this gate closes.
|
|
69
|
+
* The live-anchor first-parse gate (the "parses align" step of the establishment order). Open for the reference track
|
|
70
|
+
* itself — its local-from-0 placement _is_ the presentation timeline (presentation-0 = the join point). Every other
|
|
71
|
+
* track holds until the reference's first parse settles the anchor question: no PDT → local placement is already
|
|
72
|
+
* correct, proceed; PDT anchor → hold until the establishment reactor stamps it onto this track, so the parse takes the
|
|
73
|
+
* `placeOnAnchor` path. Establishment is sticky-once, so an unanchored first parse would be permanently misaligned —
|
|
74
|
+
* that's the race this gate closes.
|
|
83
75
|
*
|
|
84
|
-
* Pairs with the {@link establishStartMediaTime} reactor (the stamp that opens
|
|
85
|
-
*
|
|
76
|
+
* Pairs with the {@link establishStartMediaTime} reactor (the stamp that opens the anchored branch); wire both or
|
|
77
|
+
* neither.
|
|
86
78
|
*/
|
|
87
79
|
const gateFirstParseOnAnchor = (presentation, ctx, trackId) => {
|
|
88
80
|
const referenceId = referenceTrackId(ctx);
|
|
@@ -95,12 +87,10 @@ const gateFirstParseOnAnchor = (presentation, ctx, trackId) => {
|
|
|
95
87
|
return findTrackById(presentation, trackId)?.startDate !== void 0;
|
|
96
88
|
};
|
|
97
89
|
/**
|
|
98
|
-
* Stamp the frozen wall-clock anchor as `startDate` onto every track that lacks
|
|
99
|
-
*
|
|
100
|
-
*
|
|
101
|
-
*
|
|
102
|
-
* — resolves already anchored. The reference track's own parser-computed
|
|
103
|
-
* `startDate` reads back as the anchor, so it's naturally left untouched.
|
|
90
|
+
* Stamp the frozen wall-clock anchor as `startDate` onto every track that lacks one (idempotent — same reference when
|
|
91
|
+
* nothing moved). Unresolved shells pick it up as the `placeOnAnchor` preset; covering _all_ tracks in one pass means
|
|
92
|
+
* any track selected later — an ABR rung, another audio language, late captions — resolves already anchored. The
|
|
93
|
+
* reference track's own parser-computed `startDate` reads back as the anchor, so it's naturally left untouched.
|
|
104
94
|
*/
|
|
105
95
|
function stampStartDates(presentation, anchor) {
|
|
106
96
|
let changed = false;
|