prismcast 1.10.2 → 1.11.0
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/app.d.ts +6 -3
- package/dist/app.d.ts.map +1 -0
- package/dist/app.js +140 -86
- package/dist/app.js.map +1 -1
- package/dist/browser/blockedPage.d.ts +80 -0
- package/dist/browser/blockedPage.d.ts.map +1 -0
- package/dist/browser/blockedPage.js +209 -0
- package/dist/browser/blockedPage.js.map +1 -0
- package/dist/browser/browserSupervisor.d.ts +80 -0
- package/dist/browser/browserSupervisor.d.ts.map +1 -0
- package/dist/browser/browserSupervisor.js +186 -0
- package/dist/browser/browserSupervisor.js.map +1 -0
- package/dist/browser/cdp.d.ts +1 -0
- package/dist/browser/cdp.d.ts.map +1 -0
- package/dist/browser/cdp.js +6 -5
- package/dist/browser/cdp.js.map +1 -1
- package/dist/browser/channelSelection.d.ts +45 -14
- package/dist/browser/channelSelection.d.ts.map +1 -0
- package/dist/browser/channelSelection.js +81 -18
- package/dist/browser/channelSelection.js.map +1 -1
- package/dist/browser/consent.d.ts +152 -0
- package/dist/browser/consent.d.ts.map +1 -0
- package/dist/browser/consent.js +418 -0
- package/dist/browser/consent.js.map +1 -0
- package/dist/browser/display.d.ts +1 -0
- package/dist/browser/display.d.ts.map +1 -0
- package/dist/browser/hlsPlaylistObserver.d.ts +55 -0
- package/dist/browser/hlsPlaylistObserver.d.ts.map +1 -0
- package/dist/browser/hlsPlaylistObserver.js +132 -0
- package/dist/browser/hlsPlaylistObserver.js.map +1 -0
- package/dist/browser/index.d.ts +67 -40
- package/dist/browser/index.d.ts.map +1 -0
- package/dist/browser/index.js +508 -300
- package/dist/browser/index.js.map +1 -1
- package/dist/browser/launchGovernor.d.ts +89 -0
- package/dist/browser/launchGovernor.d.ts.map +1 -0
- package/dist/browser/launchGovernor.js +96 -0
- package/dist/browser/launchGovernor.js.map +1 -0
- package/dist/browser/login.d.ts +10 -2
- package/dist/browser/login.d.ts.map +1 -0
- package/dist/browser/login.js +36 -5
- package/dist/browser/login.js.map +1 -1
- package/dist/browser/manifestInterceptor.d.ts +102 -49
- package/dist/browser/manifestInterceptor.d.ts.map +1 -0
- package/dist/browser/manifestInterceptor.js +219 -237
- package/dist/browser/manifestInterceptor.js.map +1 -1
- package/dist/browser/pageStaleness.d.ts +30 -0
- package/dist/browser/pageStaleness.d.ts.map +1 -0
- package/dist/browser/pageStaleness.js +76 -0
- package/dist/browser/pageStaleness.js.map +1 -0
- package/dist/browser/precaching.d.ts +95 -3
- package/dist/browser/precaching.d.ts.map +1 -0
- package/dist/browser/precaching.js +499 -65
- package/dist/browser/precaching.js.map +1 -1
- package/dist/browser/tabNetworkObserver.d.ts +49 -0
- package/dist/browser/tabNetworkObserver.d.ts.map +1 -0
- package/dist/browser/tabNetworkObserver.js +144 -0
- package/dist/browser/tabNetworkObserver.js.map +1 -0
- package/dist/browser/tuning/cache.d.ts +61 -0
- package/dist/browser/tuning/cache.d.ts.map +1 -0
- package/dist/browser/tuning/cache.js +62 -0
- package/dist/browser/tuning/cache.js.map +1 -0
- package/dist/browser/tuning/comcastPolymer.d.ts +3 -2
- package/dist/browser/tuning/comcastPolymer.d.ts.map +1 -0
- package/dist/browser/tuning/comcastPolymer.js +79 -102
- package/dist/browser/tuning/comcastPolymer.js.map +1 -1
- package/dist/browser/tuning/cox.d.ts +1 -0
- package/dist/browser/tuning/cox.d.ts.map +1 -0
- package/dist/browser/tuning/directv.d.ts +1 -0
- package/dist/browser/tuning/directv.d.ts.map +1 -0
- package/dist/browser/tuning/directv.js +52 -46
- package/dist/browser/tuning/directv.js.map +1 -1
- package/dist/browser/tuning/fox.d.ts +1 -0
- package/dist/browser/tuning/fox.d.ts.map +1 -0
- package/dist/browser/tuning/fox.js +13 -12
- package/dist/browser/tuning/fox.js.map +1 -1
- package/dist/browser/tuning/gridSearch.d.ts +68 -0
- package/dist/browser/tuning/gridSearch.d.ts.map +1 -0
- package/dist/browser/tuning/gridSearch.js +85 -0
- package/dist/browser/tuning/gridSearch.js.map +1 -0
- package/dist/browser/tuning/hbo.d.ts +1 -0
- package/dist/browser/tuning/hbo.d.ts.map +1 -0
- package/dist/browser/tuning/hbo.js +73 -45
- package/dist/browser/tuning/hbo.js.map +1 -1
- package/dist/browser/tuning/hulu.d.ts +1 -0
- package/dist/browser/tuning/hulu.d.ts.map +1 -0
- package/dist/browser/tuning/hulu.js +128 -173
- package/dist/browser/tuning/hulu.js.map +1 -1
- package/dist/browser/tuning/shared.d.ts +75 -5
- package/dist/browser/tuning/shared.d.ts.map +1 -0
- package/dist/browser/tuning/shared.js +216 -6
- package/dist/browser/tuning/shared.js.map +1 -1
- package/dist/browser/tuning/sling.d.ts +1 -0
- package/dist/browser/tuning/sling.d.ts.map +1 -0
- package/dist/browser/tuning/sling.js +105 -126
- package/dist/browser/tuning/sling.js.map +1 -1
- package/dist/browser/tuning/spectrum.d.ts +1 -0
- package/dist/browser/tuning/spectrum.d.ts.map +1 -0
- package/dist/browser/tuning/spectrum.js +80 -125
- package/dist/browser/tuning/spectrum.js.map +1 -1
- package/dist/browser/tuning/thumbnailRow.d.ts +1 -0
- package/dist/browser/tuning/thumbnailRow.d.ts.map +1 -0
- package/dist/browser/tuning/thumbnailRow.js +8 -2
- package/dist/browser/tuning/thumbnailRow.js.map +1 -1
- package/dist/browser/tuning/tileClick.d.ts +1 -0
- package/dist/browser/tuning/tileClick.d.ts.map +1 -0
- package/dist/browser/tuning/tileClick.js +3 -2
- package/dist/browser/tuning/tileClick.js.map +1 -1
- package/dist/browser/tuning/xfinity.d.ts +1 -0
- package/dist/browser/tuning/xfinity.d.ts.map +1 -0
- package/dist/browser/tuning/youtubeTv.d.ts +1 -0
- package/dist/browser/tuning/youtubeTv.d.ts.map +1 -0
- package/dist/browser/tuning/youtubeTv.js +74 -127
- package/dist/browser/tuning/youtubeTv.js.map +1 -1
- package/dist/browser/video.d.ts +54 -14
- package/dist/browser/video.d.ts.map +1 -0
- package/dist/browser/video.js +296 -138
- package/dist/browser/video.js.map +1 -1
- package/dist/channels/index.d.ts +1 -0
- package/dist/channels/index.d.ts.map +1 -0
- package/dist/channels/index.js +12 -9
- package/dist/channels/index.js.map +1 -1
- package/dist/config/channelForm.d.ts +15 -1
- package/dist/config/channelForm.d.ts.map +1 -0
- package/dist/config/channelForm.js +28 -12
- package/dist/config/channelForm.js.map +1 -1
- package/dist/config/consistencyProbe.d.ts +1 -0
- package/dist/config/consistencyProbe.d.ts.map +1 -0
- package/dist/config/consistencyProbe.js +27 -21
- package/dist/config/consistencyProbe.js.map +1 -1
- package/dist/config/health.d.ts +41 -8
- package/dist/config/health.d.ts.map +1 -0
- package/dist/config/health.js +189 -38
- package/dist/config/health.js.map +1 -1
- package/dist/config/index.d.ts +55 -3
- package/dist/config/index.d.ts.map +1 -0
- package/dist/config/index.js +320 -69
- package/dist/config/index.js.map +1 -1
- package/dist/config/paths.d.ts +10 -9
- package/dist/config/paths.d.ts.map +1 -0
- package/dist/config/paths.js +11 -11
- package/dist/config/paths.js.map +1 -1
- package/dist/config/persistence.context.d.ts +1 -0
- package/dist/config/persistence.context.d.ts.map +1 -0
- package/dist/config/persistence.d.ts +13 -10
- package/dist/config/persistence.d.ts.map +1 -0
- package/dist/config/persistence.js +40 -21
- package/dist/config/persistence.js.map +1 -1
- package/dist/config/presets.d.ts +1 -0
- package/dist/config/presets.d.ts.map +1 -0
- package/dist/config/profiles.d.ts +22 -15
- package/dist/config/profiles.d.ts.map +1 -0
- package/dist/config/profiles.js +81 -47
- package/dist/config/profiles.js.map +1 -1
- package/dist/config/providerLineups.d.ts +47 -0
- package/dist/config/providerLineups.d.ts.map +1 -0
- package/dist/config/providerLineups.js +137 -0
- package/dist/config/providerLineups.js.map +1 -0
- package/dist/config/reactivity.d.ts +84 -0
- package/dist/config/reactivity.d.ts.map +1 -0
- package/dist/config/reactivity.js +226 -0
- package/dist/config/reactivity.js.map +1 -0
- package/dist/config/servicePacks.d.ts +18 -2
- package/dist/config/servicePacks.d.ts.map +1 -0
- package/dist/config/servicePacks.js +53 -11
- package/dist/config/servicePacks.js.map +1 -1
- package/dist/config/services.d.ts +21 -15
- package/dist/config/services.d.ts.map +1 -0
- package/dist/config/services.js +35 -24
- package/dist/config/services.js.map +1 -1
- package/dist/config/sites.d.ts +6 -4
- package/dist/config/sites.d.ts.map +1 -0
- package/dist/config/sites.js +15 -11
- package/dist/config/sites.js.map +1 -1
- package/dist/config/userChannels.d.ts +129 -30
- package/dist/config/userChannels.d.ts.map +1 -0
- package/dist/config/userChannels.js +333 -68
- package/dist/config/userChannels.js.map +1 -1
- package/dist/config/userConfig.d.ts +14 -9
- package/dist/config/userConfig.d.ts.map +1 -0
- package/dist/config/userConfig.js +87 -25
- package/dist/config/userConfig.js.map +1 -1
- package/dist/config/userProfiles.d.ts +10 -6
- package/dist/config/userProfiles.d.ts.map +1 -0
- package/dist/config/userProfiles.js +64 -39
- package/dist/config/userProfiles.js.map +1 -1
- package/dist/hdhr/channelMap.d.ts +1 -0
- package/dist/hdhr/channelMap.d.ts.map +1 -0
- package/dist/hdhr/deviceId.d.ts +1 -0
- package/dist/hdhr/deviceId.d.ts.map +1 -0
- package/dist/hdhr/discover.d.ts +1 -0
- package/dist/hdhr/discover.d.ts.map +1 -0
- package/dist/hdhr/discover.js +48 -47
- package/dist/hdhr/discover.js.map +1 -1
- package/dist/hdhr/getHandlers.d.ts +29 -0
- package/dist/hdhr/getHandlers.d.ts.map +1 -0
- package/dist/hdhr/getHandlers.js +196 -0
- package/dist/hdhr/getHandlers.js.map +1 -0
- package/dist/hdhr/identity.d.ts +36 -0
- package/dist/hdhr/identity.d.ts.map +1 -0
- package/dist/hdhr/identity.js +51 -0
- package/dist/hdhr/identity.js.map +1 -0
- package/dist/hdhr/index.d.ts +22 -4
- package/dist/hdhr/index.d.ts.map +1 -0
- package/dist/hdhr/index.js +229 -54
- package/dist/hdhr/index.js.map +1 -1
- package/dist/hdhr/protocol.d.ts +75 -0
- package/dist/hdhr/protocol.d.ts.map +1 -0
- package/dist/hdhr/protocol.js +264 -0
- package/dist/hdhr/protocol.js.map +1 -0
- package/dist/hdhr/tunerState.d.ts +24 -0
- package/dist/hdhr/tunerState.d.ts.map +1 -0
- package/dist/hdhr/tunerState.js +67 -0
- package/dist/hdhr/tunerState.js.map +1 -0
- package/dist/hdhr/udp.d.ts +43 -0
- package/dist/hdhr/udp.d.ts.map +1 -0
- package/dist/hdhr/udp.js +277 -0
- package/dist/hdhr/udp.js.map +1 -0
- package/dist/identity.d.ts +1 -0
- package/dist/identity.d.ts.map +1 -0
- package/dist/identity.js +13 -11
- package/dist/identity.js.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +11 -12
- package/dist/index.js.map +1 -1
- package/dist/native/codecInference.d.ts +1 -0
- package/dist/native/codecInference.d.ts.map +1 -0
- package/dist/native/codecInference.js +50 -5
- package/dist/native/codecInference.js.map +1 -1
- package/dist/native/decrypt.d.ts +6 -2
- package/dist/native/decrypt.d.ts.map +1 -0
- package/dist/native/decrypt.js +15 -8
- package/dist/native/decrypt.js.map +1 -1
- package/dist/native/index.d.ts +40 -17
- package/dist/native/index.d.ts.map +1 -0
- package/dist/native/index.js +281 -120
- package/dist/native/index.js.map +1 -1
- package/dist/native/probe.d.ts +114 -18
- package/dist/native/probe.d.ts.map +1 -0
- package/dist/native/probe.js +452 -115
- package/dist/native/probe.js.map +1 -1
- package/dist/native/proxy.d.ts +57 -5
- package/dist/native/proxy.d.ts.map +1 -0
- package/dist/native/proxy.js +604 -170
- package/dist/native/proxy.js.map +1 -1
- package/dist/native/tokenExpiry.d.ts +1 -0
- package/dist/native/tokenExpiry.d.ts.map +1 -0
- package/dist/native/tokenExpiry.js +1 -1
- package/dist/routes/assets.d.ts +1 -0
- package/dist/routes/assets.d.ts.map +1 -0
- package/dist/routes/assets.js +4 -2
- package/dist/routes/assets.js.map +1 -1
- package/dist/routes/auth.d.ts +1 -0
- package/dist/routes/auth.d.ts.map +1 -0
- package/dist/routes/auth.js +0 -1
- package/dist/routes/auth.js.map +1 -1
- package/dist/routes/cdp.d.ts +5 -5
- package/dist/routes/cdp.d.ts.map +1 -0
- package/dist/routes/cdp.js +59 -20
- package/dist/routes/cdp.js.map +1 -1
- package/dist/routes/channels.d.ts +1 -0
- package/dist/routes/channels.d.ts.map +1 -0
- package/dist/routes/channels.js +2 -1
- package/dist/routes/channels.js.map +1 -1
- package/dist/routes/clientActions.d.ts +98 -0
- package/dist/routes/clientActions.d.ts.map +1 -0
- package/dist/routes/clientActions.js +113 -0
- package/dist/routes/clientActions.js.map +1 -0
- package/dist/routes/components.d.ts +5 -3
- package/dist/routes/components.d.ts.map +1 -0
- package/dist/routes/components.js +36 -39
- package/dist/routes/components.js.map +1 -1
- package/dist/routes/config/channels/endpoints/browse.d.ts +1 -0
- package/dist/routes/config/channels/endpoints/browse.d.ts.map +1 -0
- package/dist/routes/config/channels/endpoints/browse.js +23 -10
- package/dist/routes/config/channels/endpoints/browse.js.map +1 -1
- package/dist/routes/config/channels/endpoints/bulk.d.ts +1 -0
- package/dist/routes/config/channels/endpoints/bulk.d.ts.map +1 -0
- package/dist/routes/config/channels/endpoints/bulk.js +5 -3
- package/dist/routes/config/channels/endpoints/bulk.js.map +1 -1
- package/dist/routes/config/channels/endpoints/crud.d.ts +1 -0
- package/dist/routes/config/channels/endpoints/crud.d.ts.map +1 -0
- package/dist/routes/config/channels/endpoints/crud.js +85 -93
- package/dist/routes/config/channels/endpoints/crud.js.map +1 -1
- package/dist/routes/config/channels/endpoints/importExport.d.ts +1 -0
- package/dist/routes/config/channels/endpoints/importExport.d.ts.map +1 -0
- package/dist/routes/config/channels/endpoints/importExport.js +6 -3
- package/dist/routes/config/channels/endpoints/importExport.js.map +1 -1
- package/dist/routes/config/channels/endpoints/predefined.d.ts +1 -0
- package/dist/routes/config/channels/endpoints/predefined.d.ts.map +1 -0
- package/dist/routes/config/channels/endpoints/prefs.d.ts +1 -0
- package/dist/routes/config/channels/endpoints/prefs.d.ts.map +1 -0
- package/dist/routes/config/channels/endpoints/prefs.js +2 -1
- package/dist/routes/config/channels/endpoints/prefs.js.map +1 -1
- package/dist/routes/config/channels/endpoints/service.d.ts +2 -1
- package/dist/routes/config/channels/endpoints/service.d.ts.map +1 -0
- package/dist/routes/config/channels/endpoints/service.js +3 -1
- package/dist/routes/config/channels/endpoints/service.js.map +1 -1
- package/dist/routes/config/channels/endpoints/tags.d.ts +1 -0
- package/dist/routes/config/channels/endpoints/tags.d.ts.map +1 -0
- package/dist/routes/config/channels/endpoints/tags.js +13 -7
- package/dist/routes/config/channels/endpoints/tags.js.map +1 -1
- package/dist/routes/config/channels/healthBridge.d.ts +24 -0
- package/dist/routes/config/channels/healthBridge.d.ts.map +1 -0
- package/dist/routes/config/channels/healthBridge.js +71 -0
- package/dist/routes/config/channels/healthBridge.js.map +1 -0
- package/dist/routes/config/channels/http/handler.d.ts +1 -0
- package/dist/routes/config/channels/http/handler.d.ts.map +1 -0
- package/dist/routes/config/channels/http/playlistHint.d.ts +2 -1
- package/dist/routes/config/channels/http/playlistHint.d.ts.map +1 -0
- package/dist/routes/config/channels/http/playlistHint.js +16 -2
- package/dist/routes/config/channels/http/playlistHint.js.map +1 -1
- package/dist/routes/config/channels/http/serviceWarning.d.ts +4 -2
- package/dist/routes/config/channels/http/serviceWarning.d.ts.map +1 -0
- package/dist/routes/config/channels/http/serviceWarning.js +3 -2
- package/dist/routes/config/channels/http/serviceWarning.js.map +1 -1
- package/dist/routes/config/channels/index.d.ts +1 -0
- package/dist/routes/config/channels/index.d.ts.map +1 -0
- package/dist/routes/config/channels/setup.d.ts +1 -0
- package/dist/routes/config/channels/setup.d.ts.map +1 -0
- package/dist/routes/config/channels/table.d.ts +3 -3
- package/dist/routes/config/channels/table.d.ts.map +1 -0
- package/dist/routes/config/channels/table.js +148 -107
- package/dist/routes/config/channels/table.js.map +1 -1
- package/dist/routes/config/http/envelope.d.ts +1 -0
- package/dist/routes/config/http/envelope.d.ts.map +1 -0
- package/dist/routes/config/index.d.ts +35 -3
- package/dist/routes/config/index.d.ts.map +1 -0
- package/dist/routes/config/index.js +51 -2
- package/dist/routes/config/index.js.map +1 -1
- package/dist/routes/config/services.d.ts +5 -4
- package/dist/routes/config/services.d.ts.map +1 -0
- package/dist/routes/config/services.js +57 -43
- package/dist/routes/config/services.js.map +1 -1
- package/dist/routes/config/settings.d.ts +1 -0
- package/dist/routes/config/settings.d.ts.map +1 -0
- package/dist/routes/config/settings.js +98 -49
- package/dist/routes/config/settings.js.map +1 -1
- package/dist/routes/debug.d.ts +1 -0
- package/dist/routes/debug.d.ts.map +1 -0
- package/dist/routes/debug.js +277 -139
- package/dist/routes/debug.js.map +1 -1
- package/dist/routes/health.d.ts +39 -1
- package/dist/routes/health.d.ts.map +1 -0
- package/dist/routes/health.js +33 -27
- package/dist/routes/health.js.map +1 -1
- package/dist/routes/hls.d.ts +1 -0
- package/dist/routes/hls.d.ts.map +1 -0
- package/dist/routes/icons.d.ts +1 -0
- package/dist/routes/icons.d.ts.map +1 -0
- package/dist/routes/icons.js +1 -1
- package/dist/routes/index.d.ts +1 -0
- package/dist/routes/index.d.ts.map +1 -0
- package/dist/routes/logs.d.ts +1 -0
- package/dist/routes/logs.d.ts.map +1 -0
- package/dist/routes/logs.js +14 -4
- package/dist/routes/logs.js.map +1 -1
- package/dist/routes/mpegts.d.ts +1 -0
- package/dist/routes/mpegts.d.ts.map +1 -0
- package/dist/routes/play.d.ts +1 -0
- package/dist/routes/play.d.ts.map +1 -0
- package/dist/routes/playlist.d.ts +1 -0
- package/dist/routes/playlist.d.ts.map +1 -0
- package/dist/routes/playlist.js +7 -2
- package/dist/routes/playlist.js.map +1 -1
- package/dist/routes/root/content.d.ts +8 -5
- package/dist/routes/root/content.d.ts.map +1 -0
- package/dist/routes/root/content.js +29 -26
- package/dist/routes/root/content.js.map +1 -1
- package/dist/routes/root/index.d.ts +2 -1
- package/dist/routes/root/index.d.ts.map +1 -0
- package/dist/routes/root/index.js +26 -21
- package/dist/routes/root/index.js.map +1 -1
- package/dist/routes/root/scripts/channels.d.ts +6 -0
- package/dist/routes/root/scripts/channels.d.ts.map +1 -0
- package/dist/routes/root/scripts/channels.js +197 -118
- package/dist/routes/root/scripts/channels.js.map +1 -1
- package/dist/routes/root/scripts/clientEscape.d.ts +22 -0
- package/dist/routes/root/scripts/clientEscape.d.ts.map +1 -0
- package/dist/routes/root/scripts/clientEscape.js +41 -0
- package/dist/routes/root/scripts/clientEscape.js.map +1 -0
- package/dist/routes/root/scripts/clientUrl.d.ts +23 -0
- package/dist/routes/root/scripts/clientUrl.d.ts.map +1 -0
- package/dist/routes/root/scripts/clientUrl.js +44 -0
- package/dist/routes/root/scripts/clientUrl.js.map +1 -0
- package/dist/routes/root/scripts/config.d.ts +6 -0
- package/dist/routes/root/scripts/config.d.ts.map +1 -0
- package/dist/routes/root/scripts/config.js +110 -24
- package/dist/routes/root/scripts/config.js.map +1 -1
- package/dist/routes/root/scripts/index.d.ts +1 -0
- package/dist/routes/root/scripts/index.d.ts.map +1 -0
- package/dist/routes/root/scripts/shared.d.ts +1 -0
- package/dist/routes/root/scripts/shared.d.ts.map +1 -0
- package/dist/routes/root/scripts/shared.js +112 -26
- package/dist/routes/root/scripts/shared.js.map +1 -1
- package/dist/routes/root/scripts/status.d.ts +1 -0
- package/dist/routes/root/scripts/status.d.ts.map +1 -0
- package/dist/routes/root/scripts/status.handlers.d.ts +23 -33
- package/dist/routes/root/scripts/status.handlers.d.ts.map +1 -0
- package/dist/routes/root/scripts/status.handlers.js +46 -92
- package/dist/routes/root/scripts/status.handlers.js.map +1 -1
- package/dist/routes/root/scripts/status.js +21 -8
- package/dist/routes/root/scripts/status.js.map +1 -1
- package/dist/routes/root/styles.d.ts +1 -0
- package/dist/routes/root/styles.d.ts.map +1 -0
- package/dist/routes/root/styles.js +7 -4
- package/dist/routes/root/styles.js.map +1 -1
- package/dist/routes/services.d.ts +13 -1
- package/dist/routes/services.d.ts.map +1 -0
- package/dist/routes/services.js +81 -68
- package/dist/routes/services.js.map +1 -1
- package/dist/routes/sse.d.ts +1 -0
- package/dist/routes/sse.d.ts.map +1 -0
- package/dist/routes/sse.js +1 -1
- package/dist/routes/sse.js.map +1 -1
- package/dist/routes/streams.d.ts +2 -1
- package/dist/routes/streams.d.ts.map +1 -0
- package/dist/routes/streams.js +6 -4
- package/dist/routes/streams.js.map +1 -1
- package/dist/routes/theme.d.ts +3 -2
- package/dist/routes/theme.d.ts.map +1 -0
- package/dist/routes/theme.js +6 -5
- package/dist/routes/theme.js.map +1 -1
- package/dist/routes/ui.d.ts +3 -1
- package/dist/routes/ui.d.ts.map +1 -0
- package/dist/routes/ui.js +16 -4
- package/dist/routes/ui.js.map +1 -1
- package/dist/routes/upgrade.d.ts +1 -0
- package/dist/routes/upgrade.d.ts.map +1 -0
- package/dist/routes/upgrade.js +6 -2
- package/dist/routes/upgrade.js.map +1 -1
- package/dist/service/commands.context.d.ts +1 -0
- package/dist/service/commands.context.d.ts.map +1 -0
- package/dist/service/commands.context.js +4 -3
- package/dist/service/commands.context.js.map +1 -1
- package/dist/service/commands.d.ts +1 -0
- package/dist/service/commands.d.ts.map +1 -0
- package/dist/service/commands.js +10 -13
- package/dist/service/commands.js.map +1 -1
- package/dist/service/generators.context.d.ts +1 -0
- package/dist/service/generators.context.d.ts.map +1 -0
- package/dist/service/generators.context.js +1 -1
- package/dist/service/generators.context.js.map +1 -1
- package/dist/service/generators.d.ts +4 -3
- package/dist/service/generators.d.ts.map +1 -0
- package/dist/service/generators.js +111 -31
- package/dist/service/generators.js.map +1 -1
- package/dist/service/index.d.ts +1 -0
- package/dist/service/index.d.ts.map +1 -0
- package/dist/streaming/captureLock.d.ts +44 -0
- package/dist/streaming/captureLock.d.ts.map +1 -0
- package/dist/streaming/captureLock.js +95 -0
- package/dist/streaming/captureLock.js.map +1 -0
- package/dist/streaming/captureSession.d.ts +31 -0
- package/dist/streaming/captureSession.d.ts.map +1 -0
- package/dist/streaming/captureSession.js +54 -0
- package/dist/streaming/captureSession.js.map +1 -0
- package/dist/streaming/clients.d.ts +1 -0
- package/dist/streaming/clients.d.ts.map +1 -0
- package/dist/streaming/codec.d.ts +1 -0
- package/dist/streaming/codec.d.ts.map +1 -0
- package/dist/streaming/fmp4Segmenter.d.ts +29 -2
- package/dist/streaming/fmp4Segmenter.d.ts.map +1 -0
- package/dist/streaming/fmp4Segmenter.js +79 -26
- package/dist/streaming/fmp4Segmenter.js.map +1 -1
- package/dist/streaming/hls.d.ts +18 -7
- package/dist/streaming/hls.d.ts.map +1 -0
- package/dist/streaming/hls.js +220 -120
- package/dist/streaming/hls.js.map +1 -1
- package/dist/streaming/hlsResume.d.ts +1 -0
- package/dist/streaming/hlsResume.d.ts.map +1 -0
- package/dist/streaming/hlsResume.js +1 -1
- package/dist/streaming/hlsResume.js.map +1 -1
- package/dist/streaming/hlsSegments.d.ts +59 -2
- package/dist/streaming/hlsSegments.d.ts.map +1 -0
- package/dist/streaming/hlsSegments.js +147 -17
- package/dist/streaming/hlsSegments.js.map +1 -1
- package/dist/streaming/lifecycle.d.ts +4 -1
- package/dist/streaming/lifecycle.d.ts.map +1 -0
- package/dist/streaming/lifecycle.js +65 -85
- package/dist/streaming/lifecycle.js.map +1 -1
- package/dist/streaming/monitor.d.ts +6 -4
- package/dist/streaming/monitor.d.ts.map +1 -0
- package/dist/streaming/monitor.js +343 -145
- package/dist/streaming/monitor.js.map +1 -1
- package/dist/streaming/mp4Parser.d.ts +5 -4
- package/dist/streaming/mp4Parser.d.ts.map +1 -0
- package/dist/streaming/mp4Parser.js +36 -13
- package/dist/streaming/mp4Parser.js.map +1 -1
- package/dist/streaming/mpegts.d.ts +16 -0
- package/dist/streaming/mpegts.d.ts.map +1 -0
- package/dist/streaming/mpegts.js +61 -17
- package/dist/streaming/mpegts.js.map +1 -1
- package/dist/streaming/playlistBuilder.d.ts +1 -0
- package/dist/streaming/playlistBuilder.d.ts.map +1 -0
- package/dist/streaming/preroll.d.ts +32 -5
- package/dist/streaming/preroll.d.ts.map +1 -0
- package/dist/streaming/preroll.js +70 -32
- package/dist/streaming/preroll.js.map +1 -1
- package/dist/streaming/pretune.d.ts +26 -1
- package/dist/streaming/pretune.d.ts.map +1 -0
- package/dist/streaming/pretune.js +22 -24
- package/dist/streaming/pretune.js.map +1 -1
- package/dist/streaming/pretuneTimers.d.ts +24 -0
- package/dist/streaming/pretuneTimers.d.ts.map +1 -0
- package/dist/streaming/pretuneTimers.js +56 -0
- package/dist/streaming/pretuneTimers.js.map +1 -0
- package/dist/streaming/recovery.d.ts +139 -5
- package/dist/streaming/recovery.d.ts.map +1 -0
- package/dist/streaming/recovery.js +160 -16
- package/dist/streaming/recovery.js.map +1 -1
- package/dist/streaming/registry.d.ts +27 -9
- package/dist/streaming/registry.d.ts.map +1 -0
- package/dist/streaming/registry.js +21 -3
- package/dist/streaming/registry.js.map +1 -1
- package/dist/streaming/setup.d.ts +157 -29
- package/dist/streaming/setup.d.ts.map +1 -0
- package/dist/streaming/setup.js +1034 -458
- package/dist/streaming/setup.js.map +1 -1
- package/dist/streaming/showInfo.d.ts +21 -1
- package/dist/streaming/showInfo.d.ts.map +1 -0
- package/dist/streaming/showInfo.js +31 -16
- package/dist/streaming/showInfo.js.map +1 -1
- package/dist/streaming/statusEmitter.d.ts +10 -10
- package/dist/streaming/statusEmitter.d.ts.map +1 -0
- package/dist/streaming/statusEmitter.js +5 -8
- package/dist/streaming/statusEmitter.js.map +1 -1
- package/dist/types/channels.d.ts +16 -4
- package/dist/types/channels.d.ts.map +1 -0
- package/dist/types/channels.js +4 -2
- package/dist/types/channels.js.map +1 -1
- package/dist/types/config.d.ts +16 -5
- package/dist/types/config.d.ts.map +1 -0
- package/dist/types/index.d.ts +3 -2
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/profiles.d.ts +6 -4
- package/dist/types/profiles.d.ts.map +1 -0
- package/dist/types/selection.d.ts +31 -3
- package/dist/types/selection.d.ts.map +1 -0
- package/dist/types/selection.js +4 -2
- package/dist/types/selection.js.map +1 -1
- package/dist/types/shared.d.ts +1 -0
- package/dist/types/shared.d.ts.map +1 -0
- package/dist/types/streaming.d.ts +8 -0
- package/dist/types/streaming.d.ts.map +1 -0
- package/dist/upgrade/commands.context.d.ts +1 -0
- package/dist/upgrade/commands.context.d.ts.map +1 -0
- package/dist/upgrade/commands.context.js +14 -10
- package/dist/upgrade/commands.context.js.map +1 -1
- package/dist/upgrade/commands.d.ts +8 -15
- package/dist/upgrade/commands.d.ts.map +1 -0
- package/dist/upgrade/commands.js +27 -28
- package/dist/upgrade/commands.js.map +1 -1
- package/dist/upgrade/detection.context.d.ts +1 -0
- package/dist/upgrade/detection.context.d.ts.map +1 -0
- package/dist/upgrade/detection.context.js +4 -1
- package/dist/upgrade/detection.context.js.map +1 -1
- package/dist/upgrade/detection.d.ts +9 -7
- package/dist/upgrade/detection.d.ts.map +1 -0
- package/dist/upgrade/detection.js +23 -54
- package/dist/upgrade/detection.js.map +1 -1
- package/dist/upgrade/index.d.ts +2 -0
- package/dist/upgrade/index.d.ts.map +1 -0
- package/dist/upgrade/index.js +1 -0
- package/dist/upgrade/index.js.map +1 -1
- package/dist/upgrade/lifecycle.context.d.ts +20 -0
- package/dist/upgrade/lifecycle.context.d.ts.map +1 -0
- package/dist/upgrade/lifecycle.context.js +47 -0
- package/dist/upgrade/lifecycle.context.js.map +1 -0
- package/dist/upgrade/lifecycle.d.ts +72 -0
- package/dist/upgrade/lifecycle.d.ts.map +1 -0
- package/dist/upgrade/lifecycle.js +175 -0
- package/dist/upgrade/lifecycle.js.map +1 -0
- package/dist/upgrade/pathHandle.d.ts +30 -0
- package/dist/upgrade/pathHandle.d.ts.map +1 -0
- package/dist/upgrade/pathHandle.js +102 -0
- package/dist/upgrade/pathHandle.js.map +1 -0
- package/dist/utils/bootSession.context.d.ts +16 -0
- package/dist/utils/bootSession.context.d.ts.map +1 -0
- package/dist/utils/bootSession.context.js +60 -0
- package/dist/utils/bootSession.context.js.map +1 -0
- package/dist/utils/bootSession.d.ts +17 -0
- package/dist/utils/bootSession.d.ts.map +1 -0
- package/dist/utils/bootSession.js +20 -0
- package/dist/utils/bootSession.js.map +1 -0
- package/dist/utils/chromeFetch.d.ts +1 -0
- package/dist/utils/chromeFetch.d.ts.map +1 -0
- package/dist/utils/cliOutput.d.ts +1 -0
- package/dist/utils/cliOutput.d.ts.map +1 -0
- package/dist/utils/clock.d.ts +5 -4
- package/dist/utils/clock.d.ts.map +1 -0
- package/dist/utils/clock.js +19 -16
- package/dist/utils/clock.js.map +1 -1
- package/dist/utils/debugFilter.d.ts +9 -1
- package/dist/utils/debugFilter.d.ts.map +1 -0
- package/dist/utils/debugFilter.js +60 -33
- package/dist/utils/debugFilter.js.map +1 -1
- package/dist/utils/delay.d.ts +48 -15
- package/dist/utils/delay.d.ts.map +1 -0
- package/dist/utils/delay.js +73 -20
- package/dist/utils/delay.js.map +1 -1
- package/dist/utils/errors.d.ts +32 -0
- package/dist/utils/errors.d.ts.map +1 -0
- package/dist/utils/errors.js +45 -4
- package/dist/utils/errors.js.map +1 -1
- package/dist/utils/evaluate.d.ts +1 -0
- package/dist/utils/evaluate.d.ts.map +1 -0
- package/dist/utils/evaluate.js +29 -23
- package/dist/utils/evaluate.js.map +1 -1
- package/dist/utils/ffmpeg.context.d.ts +1 -0
- package/dist/utils/ffmpeg.context.d.ts.map +1 -0
- package/dist/utils/ffmpeg.context.js.map +1 -1
- package/dist/utils/ffmpeg.d.ts +29 -7
- package/dist/utils/ffmpeg.d.ts.map +1 -0
- package/dist/utils/ffmpeg.js +32 -14
- package/dist/utils/ffmpeg.js.map +1 -1
- package/dist/utils/fileLogger.d.ts +3 -1
- package/dist/utils/fileLogger.d.ts.map +1 -0
- package/dist/utils/fileLogger.js +64 -29
- package/dist/utils/fileLogger.js.map +1 -1
- package/dist/utils/format.d.ts +14 -1
- package/dist/utils/format.d.ts.map +1 -0
- package/dist/utils/format.js +19 -5
- package/dist/utils/format.js.map +1 -1
- package/dist/utils/index.d.ts +4 -0
- package/dist/utils/index.d.ts.map +1 -0
- package/dist/utils/index.js +3 -0
- package/dist/utils/index.js.map +1 -1
- package/dist/utils/logEmitter.d.ts +1 -0
- package/dist/utils/logEmitter.d.ts.map +1 -0
- package/dist/utils/logger.d.ts +1 -0
- package/dist/utils/logger.d.ts.map +1 -0
- package/dist/utils/logger.js +10 -6
- package/dist/utils/logger.js.map +1 -1
- package/dist/utils/m3u.d.ts +3 -2
- package/dist/utils/m3u.d.ts.map +1 -0
- package/dist/utils/m3u.js +4 -3
- package/dist/utils/m3u.js.map +1 -1
- package/dist/utils/markup.d.ts +13 -1
- package/dist/utils/markup.d.ts.map +1 -0
- package/dist/utils/markup.js +28 -4
- package/dist/utils/markup.js.map +1 -1
- package/dist/utils/memo.d.ts +3 -2
- package/dist/utils/memo.d.ts.map +1 -0
- package/dist/utils/memo.js +3 -3
- package/dist/utils/morganStream.d.ts +1 -0
- package/dist/utils/morganStream.d.ts.map +1 -0
- package/dist/utils/network.d.ts +1 -0
- package/dist/utils/network.d.ts.map +1 -0
- package/dist/utils/network.js +2 -2
- package/dist/utils/pid.d.ts +3 -25
- package/dist/utils/pid.d.ts.map +1 -0
- package/dist/utils/pid.js +10 -49
- package/dist/utils/pid.js.map +1 -1
- package/dist/utils/platform.d.ts +3 -1
- package/dist/utils/platform.d.ts.map +1 -0
- package/dist/utils/platform.js +2 -1
- package/dist/utils/platform.js.map +1 -1
- package/dist/utils/processInspector.context.d.ts +8 -0
- package/dist/utils/processInspector.context.d.ts.map +1 -0
- package/dist/utils/processInspector.context.js +106 -0
- package/dist/utils/processInspector.context.js.map +1 -0
- package/dist/utils/processInspector.d.ts +55 -0
- package/dist/utils/processInspector.d.ts.map +1 -0
- package/dist/utils/processInspector.js +127 -0
- package/dist/utils/processInspector.js.map +1 -0
- package/dist/utils/retry.d.ts +25 -2
- package/dist/utils/retry.d.ts.map +1 -0
- package/dist/utils/retry.js +33 -6
- package/dist/utils/retry.js.map +1 -1
- package/dist/utils/runtimeIdentity.context.d.ts +7 -0
- package/dist/utils/runtimeIdentity.context.d.ts.map +1 -0
- package/dist/utils/runtimeIdentity.context.js +43 -0
- package/dist/utils/runtimeIdentity.context.js.map +1 -0
- package/dist/utils/runtimeIdentity.d.ts +98 -0
- package/dist/utils/runtimeIdentity.d.ts.map +1 -0
- package/dist/utils/runtimeIdentity.js +181 -0
- package/dist/utils/runtimeIdentity.js.map +1 -0
- package/dist/utils/sanitize.d.ts +1 -0
- package/dist/utils/sanitize.d.ts.map +1 -0
- package/dist/utils/streamContext.d.ts +2 -1
- package/dist/utils/streamContext.d.ts.map +1 -0
- package/dist/utils/streamContext.js +1 -1
- package/dist/utils/timing.d.ts +2 -1
- package/dist/utils/timing.d.ts.map +1 -0
- package/dist/utils/timing.js +0 -5
- package/dist/utils/timing.js.map +1 -1
- package/dist/utils/version.d.ts +1 -0
- package/dist/utils/version.d.ts.map +1 -0
- package/dist/utils/version.js +47 -13
- package/dist/utils/version.js.map +1 -1
- package/package.json +26 -20
|
@@ -1,295 +1,293 @@
|
|
|
1
|
-
import { LOG,
|
|
2
|
-
import {
|
|
3
|
-
/* This module
|
|
4
|
-
*
|
|
1
|
+
import { LOG, extractPathname, startTimer } from "../utils/index.js";
|
|
2
|
+
import { observeHlsPlaylists } from "./hlsPlaylistObserver.js";
|
|
3
|
+
/* This module hosts two consumer-facing state machines built on top of the HLS playlist observer (hlsPlaylistObserver.ts), which in turn rides on the tab-wide
|
|
4
|
+
* network observer (tabNetworkObserver.ts). The layering:
|
|
5
5
|
*
|
|
6
|
-
* -
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
* - Tune verification: confirms that the channel a strategy clicked actually loaded by matching the resulting manifest URL against an expected predicate (e.g.,
|
|
10
|
-
* call sign in the path). See awaitMatchingManifest() and the consumer in src/browser/tuning/fox.ts. This consumer expects master playlists only because tune
|
|
11
|
-
* verification is a multi-channel concept that does not apply to direct-tune media-only sources.
|
|
6
|
+
* tabNetworkObserver -> tab-wide CDP transport (OOPIF-aware via auto-attach + flatten)
|
|
7
|
+
* hlsPlaylistObserver -> HLS filter + body fetch + classify + per-URL dedup + wire-arrival sequencing
|
|
8
|
+
* manifestInterceptor -> selection: the channel-selection epoch, playlist membership, the liveness override, finalize semantics, predicate match
|
|
12
9
|
*
|
|
13
|
-
*
|
|
14
|
-
* forwarded to consumers so each can apply its own kind-specific filter without re-reading the body. Classification lives in exactly one place
|
|
15
|
-
* (src/native/probe.ts) so the master/media decision cannot drift between the interceptor's transport-layer gate and the probe's resolution-layer dispatch.
|
|
16
|
-
* We use a direct fetch rather than CDP's Network.getResponseBody because Chrome's network cache can evict response bodies before we read them, causing
|
|
17
|
-
* spurious "No data found for resource" failures.
|
|
10
|
+
* This module hosts the following consumer-facing state machines built on top of the HLS playlist observer:
|
|
18
11
|
*
|
|
19
|
-
*
|
|
20
|
-
*
|
|
12
|
+
* - installManifestInterceptor(): the long-lived capture used by native HLS setup. Accepts both master and media playlists, tracks the first and latest URL per
|
|
13
|
+
* kind, and resolves with the playlist appropriate for the tune type when finalize() is called. A direct tune (single-channel site navigated by URL) takes the
|
|
14
|
+
* first qualifying capture, master preferred. A guide tune (multi-channel site) judges the captures through three signals - a channel-selection epoch stamped
|
|
15
|
+
* when selection begins, playlist membership of a media playlist within the latest master's declared children, and media liveness - so the tuned channel's
|
|
16
|
+
* playlist is chosen even when a page-load default channel was captured first. See selectInterceptedManifest for the full rule.
|
|
17
|
+
* - awaitMatchingManifest(): the short-lived verification used after a guide-click tune. Accepts master playlists only and resolves with the first URL whose
|
|
18
|
+
* path satisfies a caller-supplied predicate. Media playlists are skipped at the consumer level because tune verification is a multi-channel concept that
|
|
19
|
+
* does not apply to direct-tune media-only sources.
|
|
21
20
|
*
|
|
22
|
-
*
|
|
23
|
-
*
|
|
24
|
-
*
|
|
25
|
-
* injection, etc.) triggers a new manifest fetch for the requested channel. The latest manifest wins.
|
|
26
|
-
*
|
|
27
|
-
* awaitMatchingManifest takes a different approach: it resolves with the first master manifest whose URL satisfies the caller-supplied predicate. The CDP session
|
|
28
|
-
* is torn down automatically on resolution. This is the verification path - the caller has already triggered the tune and now wants confirmation that the
|
|
29
|
-
* resulting manifest belongs to the expected channel.
|
|
21
|
+
* Race safety, URL filtering, body fetching, classification, and wire-arrival sequencing all live below this module - we receive a stream of recognized HLS
|
|
22
|
+
* playlists with their kind, per-kind facts, and arrival ordinal, and apply selection policy. Public callers do not hold CDP session references; the underlying
|
|
23
|
+
* HLS observer disposes its tab network observer deterministically when finalize, timeout, predicate match, or explicit dispose fires.
|
|
30
24
|
*/
|
|
31
|
-
//
|
|
32
|
-
|
|
33
|
-
//
|
|
34
|
-
//
|
|
35
|
-
const FINALIZE_SETTLE_DELAY = 1500;
|
|
25
|
+
// Brief delay after finalize() is called to allow any in-flight manifest response to arrive. Applied for guide-based tunes (directTune=false), where the channel
|
|
26
|
+
// switch may trigger a manifest fetch that arrives milliseconds after the click handler returns, and for direct tunes that have not yet captured a master
|
|
27
|
+
// manifest. A direct tune skips this delay and resolves immediately only once a master manifest has already arrived. Exported so a caller sizing its own
|
|
28
|
+
// interception window (streaming/setup.ts) can include the settle window the window must outlive.
|
|
29
|
+
export const FINALIZE_SETTLE_DELAY = 1500;
|
|
36
30
|
// Default timeout for awaitMatchingManifest. Tune verification is a short-lived check after a click, so the budget is tighter than the native interception path.
|
|
37
31
|
const VERIFICATION_TIMEOUT = 8000;
|
|
38
|
-
// Timeout for the per-response manifest body fetch. The body is fed to classifyHlsPlaylist() to determine whether it is a master playlist; if Chrome's network
|
|
39
|
-
// cache evicts the body or the CDN serves a slow response, we abandon and treat the response as non-master.
|
|
40
|
-
const MANIFEST_BODY_FETCH_TIMEOUT = 5000;
|
|
41
32
|
/**
|
|
42
|
-
*
|
|
43
|
-
*
|
|
44
|
-
* the
|
|
45
|
-
*
|
|
46
|
-
*
|
|
33
|
+
* Reports whether a media playlist is a verified NON-member of a master's declared children, comparing by pathname only. Membership is URL-identity policy, not
|
|
34
|
+
* manifest-format knowledge, which is why it lives here rather than in probe. Pathname-only because post-redirect response URLs diverge from a master's declared
|
|
35
|
+
* child URIs at the host far more often than at the path. The judgment is member-conservative: a media URL that cannot be parsed, an empty declared child list, or
|
|
36
|
+
* an empty effective set after dropping unparseable children all read as MEMBER (the master wins, degrading to the categorical rule, never a new failure). Only a
|
|
37
|
+
* parseable media pathname absent from a non-empty set of parseable child pathnames is a verified non-member.
|
|
47
38
|
*
|
|
48
|
-
* @param
|
|
49
|
-
* @
|
|
39
|
+
* @param mediaUrl - The candidate media playlist URL.
|
|
40
|
+
* @param childUrls - The master's declared child playlist URLs.
|
|
41
|
+
* @returns True only when the media pathname is proven absent from a non-empty effective set of child pathnames.
|
|
50
42
|
*/
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
43
|
+
function isVerifiedNonMemberOfMaster(mediaUrl, childUrls) {
|
|
44
|
+
const mediaPathname = extractPathname(mediaUrl);
|
|
45
|
+
// A media URL we cannot parse cannot be proven foreign, so it reads as a member and the master wins.
|
|
46
|
+
if (mediaPathname === null) {
|
|
47
|
+
return false;
|
|
48
|
+
}
|
|
49
|
+
// Normalize the declared children to pathnames, dropping any that cannot be parsed. An empty declared list or a list that parses to nothing yields an empty
|
|
50
|
+
// effective set: with no children to compare against, membership cannot be disproven, so the master wins.
|
|
51
|
+
const childPathnames = childUrls.map((child) => extractPathname(child)).filter((pathname) => pathname !== null);
|
|
52
|
+
if (childPathnames.length === 0) {
|
|
53
|
+
return false;
|
|
54
54
|
}
|
|
55
|
-
return
|
|
55
|
+
return !childPathnames.includes(mediaPathname);
|
|
56
56
|
}
|
|
57
57
|
/**
|
|
58
|
-
*
|
|
59
|
-
* fetches the body, and asks classifyHlsPlaylist() for the playlist kind; recognized kinds (master, media) fire the callback with the kind label, while
|
|
60
|
-
* unrecognized bodies are skipped. Consumers apply their own kind-specific filtering on top of the callback - installManifestInterceptor accepts both kinds
|
|
61
|
-
* with master priority, while awaitMatchingManifest accepts master only.
|
|
58
|
+
* Selects the playlist appropriate for a given resolution mode from the captured state, reporting the URL together with the kind selection decided.
|
|
62
59
|
*
|
|
63
|
-
*
|
|
64
|
-
*
|
|
65
|
-
*
|
|
66
|
-
*
|
|
67
|
-
*
|
|
60
|
+
* Direct tunes take the earliest qualifying capture (firstMasterUrl before firstMediaUrl), master preferred, with the kind tagged by the slot that supplied the
|
|
61
|
+
* URL. The epoch never participates on the direct branch: a direct tune navigates by URL and its first capture answers.
|
|
62
|
+
*
|
|
63
|
+
* Guide tunes apply a three-signal rule over the latest captures:
|
|
64
|
+
*
|
|
65
|
+
* 1. No master captured: the media fallback (latestMedia's URL) or null. Liveness gates only the override of a master, never the sole available feed, so a VOD
|
|
66
|
+
* media playlist still answers when it is all that arrived.
|
|
67
|
+
* 2. Epoch declared and the master post-epoch (latestMaster.ordinal > markOrdinal): the master, categorically. A master observed after channel selection began
|
|
68
|
+
* answers the click. An absent epoch (mark never called) also leaves the master the winner, because without a click there is no fresher truth to prefer.
|
|
69
|
+
* 3. Override to the media only when every clause holds: an epoch exists (rule 2 falling through means the master is pre-epoch), latestMedia is live, the media
|
|
70
|
+
* is post-epoch (latestMedia.ordinal > markOrdinal - which structurally postdates the pre-epoch master, so no separate ordering clause is needed), and the
|
|
71
|
+
* media is a verified non-member of the master's children. Otherwise the master wins.
|
|
72
|
+
*
|
|
73
|
+
* Membership is member-conservative (see isVerifiedNonMemberOfMaster): anything short of a proven foreign pathname keeps the master, so the override engages only
|
|
74
|
+
* where a media playlist is demonstrably not one of the master's own children. Pure selection policy exported so the rule is testable in isolation from the
|
|
75
|
+
* network plumbing; the closure inside installManifestInterceptor() consumes it through the same shape.
|
|
76
|
+
*
|
|
77
|
+
* @param state - The captured state at resolution time.
|
|
78
|
+
* @returns The selected playlist, or null when no URL matches the resolution mode.
|
|
68
79
|
*/
|
|
69
|
-
|
|
70
|
-
if (
|
|
80
|
+
export function selectInterceptedManifest(state) {
|
|
81
|
+
if (state.directTune) {
|
|
82
|
+
if (state.firstMasterUrl !== null) {
|
|
83
|
+
return { kind: "master", url: state.firstMasterUrl };
|
|
84
|
+
}
|
|
85
|
+
if (state.firstMediaUrl !== null) {
|
|
86
|
+
return { kind: "media", url: state.firstMediaUrl };
|
|
87
|
+
}
|
|
71
88
|
return null;
|
|
72
89
|
}
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
catch (error) {
|
|
78
|
-
LOG.debug(logCategory, "Failed to create CDP session: %s.", String(error));
|
|
79
|
-
return null;
|
|
90
|
+
const { latestMaster, latestMedia, markOrdinal } = state;
|
|
91
|
+
// Rule 1: no master captured. The media fallback answers regardless of liveness.
|
|
92
|
+
if (latestMaster === null) {
|
|
93
|
+
return (latestMedia === null) ? null : { kind: "media", url: latestMedia.url };
|
|
80
94
|
}
|
|
81
|
-
|
|
82
|
-
|
|
95
|
+
// Rule 2: a master observed after channel selection began answers the click categorically; an absent epoch keeps the master too.
|
|
96
|
+
if ((markOrdinal !== null) && (latestMaster.ordinal > markOrdinal)) {
|
|
97
|
+
return { kind: "master", url: latestMaster.url };
|
|
83
98
|
}
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
99
|
+
// Rule 3: override to a live, post-epoch, verified non-member media; otherwise the master wins.
|
|
100
|
+
if ((markOrdinal !== null) && (latestMedia !== null) && latestMedia.live && (latestMedia.ordinal > markOrdinal) &&
|
|
101
|
+
isVerifiedNonMemberOfMaster(latestMedia.url, latestMaster.childUrls)) {
|
|
102
|
+
return { kind: "media", url: latestMedia.url };
|
|
87
103
|
}
|
|
88
|
-
|
|
89
|
-
let disposed = false;
|
|
90
|
-
// Listen for completed responses. We use Network.responseReceived to capture .m3u8 URLs, then fetch the manifest body directly from Node.js to verify it is
|
|
91
|
-
// a master manifest. This avoids CDP's Network.getResponseBody which is unreliable - Chrome's network cache can evict response bodies before we read them.
|
|
92
|
-
const onResponseReceived = async (params) => {
|
|
93
|
-
if (disposed) {
|
|
94
|
-
return;
|
|
95
|
-
}
|
|
96
|
-
const url = params.response.url;
|
|
97
|
-
// Filter for .m3u8 URLs. Strip query parameters before checking the extension.
|
|
98
|
-
const urlPath = url.split("?")[0] ?? "";
|
|
99
|
-
if (!urlPath.endsWith(".m3u8")) {
|
|
100
|
-
return;
|
|
101
|
-
}
|
|
102
|
-
LOG.debug(logCategory, "Observed .m3u8 response: %s.", url.slice(0, 120));
|
|
103
|
-
// Fetch the manifest body directly to inspect whether this is a master manifest. The URL contains embedded CDN auth tokens, so no cookies or special
|
|
104
|
-
// headers are needed beyond the Chrome User-Agent injected by chromeFetch().
|
|
105
|
-
try {
|
|
106
|
-
const response = await chromeFetch(url, { signal: AbortSignal.timeout(MANIFEST_BODY_FETCH_TIMEOUT) });
|
|
107
|
-
if (!response.ok) {
|
|
108
|
-
LOG.debug(logCategory, "Manifest fetch returned HTTP %s for %s.", response.status, url.slice(0, 120));
|
|
109
|
-
return;
|
|
110
|
-
}
|
|
111
|
-
const body = await response.text();
|
|
112
|
-
// Delegate the master/media decision to the canonical classifier. Recognized kinds (master, media) are forwarded to the callback together with the kind
|
|
113
|
-
// label; consumers apply their own filter. Both consumers of onPlaylist maintain their own resolved-flag guard, so a callback that arrives after dispose
|
|
114
|
-
// is harmless - the downstream resolve is idempotent.
|
|
115
|
-
const kind = classifyHlsPlaylist(body);
|
|
116
|
-
if (kind === "unknown") {
|
|
117
|
-
LOG.debug(logCategory, "Skipping .m3u8 classified as unknown (no recognizable HLS directives).");
|
|
118
|
-
return;
|
|
119
|
-
}
|
|
120
|
-
onPlaylist(url, kind);
|
|
121
|
-
}
|
|
122
|
-
catch (error) {
|
|
123
|
-
LOG.debug(logCategory, "Could not fetch .m3u8 body: %s.", String(error));
|
|
124
|
-
}
|
|
125
|
-
};
|
|
126
|
-
// Wrap the async handler to avoid no-misused-promises - EventEmitter.on() does not handle returned promises.
|
|
127
|
-
const wrappedHandler = (...args) => { void onResponseReceived(...args); };
|
|
128
|
-
cdpSession.on("Network.responseReceived", wrappedHandler);
|
|
129
|
-
const dispose = (keepSession) => {
|
|
130
|
-
if (disposed) {
|
|
131
|
-
return;
|
|
132
|
-
}
|
|
133
|
-
disposed = true;
|
|
134
|
-
cdpSession.off("Network.responseReceived", wrappedHandler);
|
|
135
|
-
if (!keepSession) {
|
|
136
|
-
removeManifestInterceptor(cdpSession);
|
|
137
|
-
}
|
|
138
|
-
};
|
|
139
|
-
return { cdpSession, dispose };
|
|
104
|
+
return { kind: "master", url: latestMaster.url };
|
|
140
105
|
}
|
|
141
106
|
/**
|
|
142
|
-
* Installs a long-lived
|
|
143
|
-
*
|
|
144
|
-
*
|
|
145
|
-
*
|
|
146
|
-
*
|
|
107
|
+
* Installs a long-lived HLS playlist observer that tracks observed playlists on the given page. Both master and media playlists are accepted; the first and latest
|
|
108
|
+
* URL per kind are tracked separately, guarded by wire-arrival order, so master-based and media-only sites both work without separate code paths. The returned
|
|
109
|
+
* handle provides a finalize(directTune) callback and a markChannelSelectionStart() epoch stamp; when finalize is called the observer resolves through
|
|
110
|
+
* selectInterceptedManifest with the playlist appropriate for the tune type:
|
|
111
|
+
*
|
|
112
|
+
* - directTune=true: resolves immediately if a master manifest has already arrived (or after the settle delay when only a media-only manifest, or nothing, has
|
|
113
|
+
* arrived so far) with the first manifest captured. Used by sites where the navigated URL itself selects the channel and the player loads its manifest before
|
|
114
|
+
* the click handler returns. Master-first URL preferred over media-first.
|
|
115
|
+
* - directTune=false: resolves after the settle delay through the guide-tune rule (channel-selection epoch, playlist membership, liveness), so the tuned
|
|
116
|
+
* channel's playlist wins over a page-load default channel captured first. Used by guide-based sites where the channel-switch click triggers a new manifest
|
|
117
|
+
* fetch that may arrive milliseconds after the click handler returns.
|
|
147
118
|
*
|
|
148
|
-
*
|
|
149
|
-
*
|
|
150
|
-
*
|
|
151
|
-
* manifest fetch that may arrive milliseconds after the click handler returns. Master-latest URL preferred over media-latest.
|
|
119
|
+
* On timeout (finalize never called), the observer resolves epoch-free through the same guide-tune rule with no epoch declared, so the categorical
|
|
120
|
+
* master-preferred outcome holds and a direct tune the timeout may be guarding is never exposed to the epoch rule. The underlying HLS observer is disposed
|
|
121
|
+
* automatically on resolution; callers do not hold CDP session references.
|
|
152
122
|
*
|
|
153
|
-
*
|
|
154
|
-
*
|
|
155
|
-
*
|
|
156
|
-
* @param
|
|
157
|
-
* @returns The interceptor handle, or null if the
|
|
123
|
+
* @param page - The puppeteer page to monitor.
|
|
124
|
+
* @param timeout - Maximum time in milliseconds to wait for a manifest. Required: every caller sizes its interception window consciously to outlive the phases it
|
|
125
|
+
* observes, so no production caller relies on a shared default. Acts as a safety net if finalize() is never called.
|
|
126
|
+
* @param observeFactory - The HLS playlist observer factory (default observeHlsPlaylists); injectable so the selection state machine can run without a live browser.
|
|
127
|
+
* @returns The interceptor handle, or null if the observer could not be installed.
|
|
158
128
|
*/
|
|
159
|
-
export async function installManifestInterceptor(page, timeout =
|
|
129
|
+
export async function installManifestInterceptor(page, timeout, observeFactory = observeHlsPlaylists) {
|
|
160
130
|
const elapsed = startTimer();
|
|
161
|
-
// Track first
|
|
162
|
-
//
|
|
163
|
-
//
|
|
164
|
-
let
|
|
165
|
-
let
|
|
166
|
-
let
|
|
167
|
-
let
|
|
131
|
+
// Track the first and latest observation per kind, plus the epoch fence. Slot updates are guarded by wire-arrival order, not delivery order: the first slot
|
|
132
|
+
// holds the lowest-ordinal arrival and the latest facts hold the highest, so a body fetch that resolves out of order still records arrival truth. Under
|
|
133
|
+
// in-order delivery this is byte-for-byte the earliest/most-recent behavior. manifestCount stays purely diagnostic for the log lines.
|
|
134
|
+
let firstMaster = null;
|
|
135
|
+
let firstMedia = null;
|
|
136
|
+
let latestMaster = null;
|
|
137
|
+
let latestMedia = null;
|
|
138
|
+
let markOrdinal = null;
|
|
168
139
|
let resolved = false;
|
|
169
140
|
let manifestCount = 0;
|
|
170
141
|
const { promise, resolve } = Promise.withResolvers();
|
|
171
|
-
const observer = await
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
142
|
+
const observer = await observeFactory(page, {
|
|
143
|
+
logCategory: "native:intercept",
|
|
144
|
+
onPlaylist: (playlist) => {
|
|
145
|
+
manifestCount++;
|
|
146
|
+
if (playlist.kind === "master") {
|
|
147
|
+
// First slot: the lowest ordinal wins, so a late delivery of an even-earlier arrival corrects it.
|
|
148
|
+
if ((firstMaster === null) || (playlist.sequence < firstMaster.ordinal)) {
|
|
149
|
+
firstMaster = { ordinal: playlist.sequence, url: playlist.url };
|
|
150
|
+
}
|
|
151
|
+
// Latest slot: the highest ordinal wins, so a late delivery of a lower arrival never displaces it.
|
|
152
|
+
if ((latestMaster === null) || (playlist.sequence > latestMaster.ordinal)) {
|
|
153
|
+
latestMaster = { childUrls: playlist.childUrls, ordinal: playlist.sequence, url: playlist.url };
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
else {
|
|
157
|
+
if ((firstMedia === null) || (playlist.sequence < firstMedia.ordinal)) {
|
|
158
|
+
firstMedia = { ordinal: playlist.sequence, url: playlist.url };
|
|
159
|
+
}
|
|
160
|
+
if ((latestMedia === null) || (playlist.sequence > latestMedia.ordinal)) {
|
|
161
|
+
latestMedia = { live: playlist.live, ordinal: playlist.sequence, url: playlist.url };
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
LOG.debug("native:intercept", "%s playlist captured (#%s, seq %s) in %sms: %s.", playlist.kind, manifestCount, playlist.sequence, elapsed(), playlist.url.slice(0, 120));
|
|
180
165
|
}
|
|
181
|
-
|
|
182
|
-
}, "native:intercept");
|
|
166
|
+
});
|
|
183
167
|
if (!observer) {
|
|
184
168
|
return null;
|
|
185
169
|
}
|
|
186
|
-
//
|
|
187
|
-
//
|
|
188
|
-
const
|
|
170
|
+
// Builds the selection state from the closure locals. epochFree forces markOrdinal to null so the timeout path resolves without the epoch rule, which must
|
|
171
|
+
// never engage on a path a direct tune can reach.
|
|
172
|
+
const buildState = (directTune, epochFree) => ({
|
|
189
173
|
directTune,
|
|
190
|
-
firstMasterUrl,
|
|
191
|
-
firstMediaUrl,
|
|
192
|
-
|
|
193
|
-
|
|
174
|
+
firstMasterUrl: firstMaster?.url ?? null,
|
|
175
|
+
firstMediaUrl: firstMedia?.url ?? null,
|
|
176
|
+
latestMaster,
|
|
177
|
+
latestMedia,
|
|
178
|
+
markOrdinal: epochFree ? null : markOrdinal
|
|
194
179
|
});
|
|
195
|
-
//
|
|
196
|
-
|
|
180
|
+
// Centralized resolution helper. Used by the timeout, finalize, and dispose paths to settle the promise exactly once and tear down the observer regardless of
|
|
181
|
+
// which path won. The selection honors the direct-vs-guide semantics and, for guide tunes, the epoch/membership/liveness rule via selectInterceptedManifest.
|
|
182
|
+
const settle = (options) => {
|
|
183
|
+
const { directTune, epochFree = false, reason } = options;
|
|
197
184
|
if (resolved) {
|
|
198
185
|
return;
|
|
199
186
|
}
|
|
200
187
|
resolved = true;
|
|
201
|
-
|
|
202
|
-
const
|
|
203
|
-
if (
|
|
204
|
-
LOG.debug("native:intercept", "
|
|
205
|
-
observer.dispose(
|
|
206
|
-
resolve({
|
|
188
|
+
clearTimeout(timer);
|
|
189
|
+
const selection = selectInterceptedManifest(buildState(directTune, epochFree));
|
|
190
|
+
if (selection) {
|
|
191
|
+
LOG.debug("native:intercept", "Interception %s in %sms with %s capture(s). Using %s %s: %s.", reason, elapsed(), manifestCount, directTune ? "first" : "latest", selection.kind, selection.url.slice(0, 120));
|
|
192
|
+
observer.dispose();
|
|
193
|
+
resolve({ manifestUrl: selection.url, selectedKind: selection.kind });
|
|
207
194
|
}
|
|
208
195
|
else {
|
|
209
|
-
LOG.debug("native:intercept", "
|
|
210
|
-
observer.dispose(
|
|
196
|
+
LOG.debug("native:intercept", "Interception %s in %sms but no HLS playlist was captured.", reason, elapsed());
|
|
197
|
+
observer.dispose();
|
|
211
198
|
resolve(null);
|
|
212
199
|
}
|
|
213
|
-
}
|
|
200
|
+
};
|
|
201
|
+
// Timeout guard. If finalize() is never called (defensive), settle epoch-free after the timeout: the timeout cannot know the tune kind, and the epoch rule must
|
|
202
|
+
// never engage on a path a direct tune can reach, so it resolves with the categorical master-preferred outcome. With the interception budget sized by the
|
|
203
|
+
// caller to outlive the tune (streaming/setup.ts), this path is last-resort defense rather than a routine finish.
|
|
204
|
+
const timer = setTimeout(() => { settle({ directTune: false, epochFree: true, reason: "timed out" }); }, timeout);
|
|
214
205
|
// Finalize function exposed on the returned handle. Called by the stream setup code after channel selection is complete. The resolution strategy depends on
|
|
215
206
|
// two factors: whether a qualifying manifest has already been captured, and whether the tune is direct or guide-based.
|
|
216
207
|
//
|
|
217
|
-
// -
|
|
208
|
+
// - Master manifest captured + direct tune: settle immediately (A&E, most TVE sites - manifest arrived during page load).
|
|
218
209
|
// - Manifest captured + guide tune: wait FINALIZE_SETTLE_DELAY (Fox guide, Hulu - a newer manifest from the channel switch may still arrive).
|
|
219
210
|
// - No manifest captured + either: wait FINALIZE_SETTLE_DELAY (Fox Sports - manifest fetch starts after video element appears, hasn't arrived yet).
|
|
220
211
|
const finalize = (directTune) => {
|
|
221
212
|
if (resolved) {
|
|
222
213
|
return;
|
|
223
214
|
}
|
|
224
|
-
//
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
}
|
|
229
|
-
resolved = true;
|
|
230
|
-
clearTimeout(timer);
|
|
231
|
-
const selectedUrl = selectUrl(directTune);
|
|
232
|
-
if (selectedUrl) {
|
|
233
|
-
LOG.debug("native:intercept", "Interception finalized in %sms with %s playlist capture(s). Using %s: %s.", elapsed(), manifestCount, directTune ? "first" : "latest", selectedUrl.slice(0, 120));
|
|
234
|
-
observer.dispose(true);
|
|
235
|
-
resolve({ cdpSession: observer.cdpSession, masterManifestUrl: selectedUrl });
|
|
236
|
-
}
|
|
237
|
-
else {
|
|
238
|
-
LOG.debug("native:intercept", "Interception finalized in %sms but no HLS playlist was captured.", elapsed());
|
|
239
|
-
observer.dispose(false);
|
|
240
|
-
resolve(null);
|
|
241
|
-
}
|
|
242
|
-
};
|
|
243
|
-
// For direct tunes, resolve immediately if a master URL has already arrived. We do not short-circuit on a media-only first URL because a master may still
|
|
244
|
-
// be in flight - waiting the settle delay gives master priority a chance to take effect. Once the settle elapses we resolve with whichever URL ranks
|
|
245
|
-
// highest under selectUrl.
|
|
246
|
-
if (directTune && firstMasterUrl) {
|
|
247
|
-
resolveNow();
|
|
215
|
+
// For direct tunes, settle immediately if a master URL has already arrived. We do not short-circuit on a media-only first URL because a master may still
|
|
216
|
+
// be in flight - waiting the settle delay gives the master-first preference a chance to take effect.
|
|
217
|
+
if (directTune && (firstMaster !== null)) {
|
|
218
|
+
settle({ directTune: true, reason: "finalized" });
|
|
248
219
|
}
|
|
249
220
|
else {
|
|
250
|
-
setTimeout(
|
|
221
|
+
setTimeout(() => { settle({ directTune, reason: "finalized" }); }, FINALIZE_SETTLE_DELAY);
|
|
222
|
+
}
|
|
223
|
+
};
|
|
224
|
+
// Stamps the observation epoch at which channel selection begins by fencing the observer's current wire sequence. Observations after the stamp answer the
|
|
225
|
+
// click; guide-tune selection prefers a master observed after this point. Callable again - the latest stamp wins - and a no-op once the interception has
|
|
226
|
+
// resolved, matching the finalize and dispose guard idiom.
|
|
227
|
+
const markChannelSelectionStart = () => {
|
|
228
|
+
if (resolved) {
|
|
229
|
+
return;
|
|
230
|
+
}
|
|
231
|
+
markOrdinal = observer.currentSequence();
|
|
232
|
+
LOG.debug("native:intercept", "Channel selection epoch stamped at wire sequence %s.", markOrdinal);
|
|
233
|
+
};
|
|
234
|
+
// Explicit dispose path for "using" syntax or caller-driven cancellation. Safe to call more than once. Resolves the promise with null if it has not already
|
|
235
|
+
// settled, so callers awaiting the promise are never left hanging on a disposed observer.
|
|
236
|
+
const dispose = () => {
|
|
237
|
+
if (resolved) {
|
|
238
|
+
return;
|
|
251
239
|
}
|
|
240
|
+
resolved = true;
|
|
241
|
+
clearTimeout(timer);
|
|
242
|
+
LOG.debug("native:intercept", "Interception disposed in %sms with %s capture(s) and no resolution selected.", elapsed(), manifestCount);
|
|
243
|
+
observer.dispose();
|
|
244
|
+
resolve(null);
|
|
252
245
|
};
|
|
253
|
-
return { finalize, promise };
|
|
246
|
+
return { dispose, finalize, markChannelSelectionStart, promise, [Symbol.dispose]: dispose };
|
|
254
247
|
}
|
|
255
248
|
/**
|
|
256
|
-
* Awaits the first master HLS manifest
|
|
249
|
+
* Awaits the first master HLS manifest whose URL satisfies the supplied predicate. Used by tune-verification paths where the caller has just clicked or
|
|
257
250
|
* navigated to a target channel and wants to confirm the resulting stream belongs to that channel rather than to whatever default the page was previously
|
|
258
251
|
* showing.
|
|
259
252
|
*
|
|
260
|
-
* Resolves with the matching URL on success. Resolves with null if no matching manifest arrives within the timeout. The
|
|
261
|
-
* in both cases - the verification path does not hand off
|
|
262
|
-
*
|
|
253
|
+
* Resolves with the matching URL on success. Resolves with null if no matching manifest arrives within the timeout. The underlying observer is torn down
|
|
254
|
+
* automatically in both cases - the verification path does not hand off a session to a downstream consumer.
|
|
255
|
+
*
|
|
256
|
+
* @param page - The puppeteer page to monitor.
|
|
263
257
|
* @param predicate - Test applied to each verified master manifest URL. Return true to accept the URL and resolve.
|
|
264
258
|
* @param timeout - Maximum time in milliseconds to wait for a matching manifest.
|
|
259
|
+
* @param observeFactory - The HLS playlist observer factory (default observeHlsPlaylists); injectable so the verification state machine can run without a live browser.
|
|
265
260
|
* @returns The matching URL, or null on timeout.
|
|
266
261
|
*/
|
|
267
|
-
export async function awaitMatchingManifest(page, predicate, timeout = VERIFICATION_TIMEOUT) {
|
|
262
|
+
export async function awaitMatchingManifest(page, predicate, timeout = VERIFICATION_TIMEOUT, observeFactory = observeHlsPlaylists) {
|
|
268
263
|
const elapsed = startTimer();
|
|
269
264
|
let resolved = false;
|
|
270
265
|
const { promise, resolve } = Promise.withResolvers();
|
|
271
266
|
// Tune verification is a multi-channel concept that only applies to master playlists - direct-tune media-only sources do not run a guide-click verification
|
|
272
267
|
// step because the page navigation itself selects the channel. We reject media playlists at the consumer level rather than asking the observer to filter so
|
|
273
268
|
// the observer keeps a single canonical contract (forward all recognized HLS playlists with their kind).
|
|
274
|
-
const observer = await
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
269
|
+
const observer = await observeFactory(page, {
|
|
270
|
+
logCategory: "native:intercept",
|
|
271
|
+
onPlaylist: (playlist) => {
|
|
272
|
+
if (resolved) {
|
|
273
|
+
return;
|
|
274
|
+
}
|
|
275
|
+
if (playlist.kind !== "master") {
|
|
276
|
+
LOG.debug("native:intercept", "Tune verification ignoring non-master playlist (%s).", playlist.kind);
|
|
277
|
+
return;
|
|
278
|
+
}
|
|
279
|
+
if (predicate(playlist.url)) {
|
|
280
|
+
resolved = true;
|
|
281
|
+
LOG.debug("native:intercept", "Matching manifest found in %sms: %s.", elapsed(), playlist.url.slice(0, 120));
|
|
282
|
+
observer?.dispose();
|
|
283
|
+
clearTimeout(timer);
|
|
284
|
+
resolve(playlist.url);
|
|
285
|
+
}
|
|
286
|
+
else {
|
|
287
|
+
LOG.debug("native:intercept", "Master manifest did not match predicate: %s.", playlist.url.slice(0, 120));
|
|
288
|
+
}
|
|
291
289
|
}
|
|
292
|
-
}
|
|
290
|
+
});
|
|
293
291
|
if (!observer) {
|
|
294
292
|
return null;
|
|
295
293
|
}
|
|
@@ -299,25 +297,9 @@ export async function awaitMatchingManifest(page, predicate, timeout = VERIFICAT
|
|
|
299
297
|
}
|
|
300
298
|
resolved = true;
|
|
301
299
|
LOG.debug("native:intercept", "Awaiting matching manifest timed out after %sms.", elapsed());
|
|
302
|
-
observer.dispose(
|
|
300
|
+
observer.dispose();
|
|
303
301
|
resolve(null);
|
|
304
302
|
}, timeout);
|
|
305
303
|
return promise;
|
|
306
304
|
}
|
|
307
|
-
/**
|
|
308
|
-
* Removes the Network domain listener and detaches the CDP session. Safe to call multiple times or on an already-detached session. Public so that native HLS
|
|
309
|
-
* consumers (which receive the CDP session through ManifestInterceptionResult) can clean up after token-refresh handoffs and proxy shutdown.
|
|
310
|
-
* @param cdpSession - The CDP session to clean up.
|
|
311
|
-
*/
|
|
312
|
-
export function removeManifestInterceptor(cdpSession) {
|
|
313
|
-
try {
|
|
314
|
-
cdpSession.removeAllListeners("Network.responseReceived");
|
|
315
|
-
void cdpSession.send("Network.disable").catch(() => { });
|
|
316
|
-
void cdpSession.detach().catch(() => { });
|
|
317
|
-
}
|
|
318
|
-
catch (_error) {
|
|
319
|
-
// Ignore errors during cleanup - the session may already be detached.
|
|
320
|
-
}
|
|
321
|
-
LOG.debug("native:intercept", "CDP manifest interceptor removed.");
|
|
322
|
-
}
|
|
323
305
|
//# sourceMappingURL=manifestInterceptor.js.map
|