prismcast 1.4.2 → 1.5.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.js +18 -1
- package/dist/app.js.map +1 -1
- package/dist/browser/cdp.d.ts +2 -1
- package/dist/browser/cdp.js +44 -23
- package/dist/browser/cdp.js.map +1 -1
- package/dist/browser/channelSelection.d.ts +45 -1
- package/dist/browser/channelSelection.js +164 -27
- package/dist/browser/channelSelection.js.map +1 -1
- package/dist/browser/display.d.ts +0 -4
- package/dist/browser/display.js +0 -7
- package/dist/browser/display.js.map +1 -1
- package/dist/browser/index.d.ts +5 -0
- package/dist/browser/index.js +14 -0
- package/dist/browser/index.js.map +1 -1
- package/dist/browser/precaching.d.ts +5 -0
- package/dist/browser/precaching.js +112 -0
- package/dist/browser/precaching.js.map +1 -0
- package/dist/browser/tuning/directv.d.ts +2 -0
- package/dist/browser/tuning/directv.js +723 -0
- package/dist/browser/tuning/directv.js.map +1 -0
- package/dist/browser/tuning/fox.d.ts +2 -2
- package/dist/browser/tuning/fox.js +141 -22
- package/dist/browser/tuning/fox.js.map +1 -1
- package/dist/browser/tuning/hbo.d.ts +2 -2
- package/dist/browser/tuning/hbo.js +110 -41
- package/dist/browser/tuning/hbo.js.map +1 -1
- package/dist/browser/tuning/hulu.d.ts +2 -2
- package/dist/browser/tuning/hulu.js +442 -168
- package/dist/browser/tuning/hulu.js.map +1 -1
- package/dist/browser/tuning/sling.d.ts +2 -2
- package/dist/browser/tuning/sling.js +200 -56
- package/dist/browser/tuning/sling.js.map +1 -1
- package/dist/browser/tuning/youtubeTv.d.ts +2 -2
- package/dist/browser/tuning/youtubeTv.js +243 -57
- package/dist/browser/tuning/youtubeTv.js.map +1 -1
- package/dist/browser/video.d.ts +1 -1
- package/dist/browser/video.js +4 -2
- package/dist/browser/video.js.map +1 -1
- package/dist/channels/index.js +280 -34
- package/dist/channels/index.js.map +1 -1
- package/dist/config/health.d.ts +78 -0
- package/dist/config/health.js +202 -0
- package/dist/config/health.js.map +1 -0
- package/dist/config/paths.d.ts +10 -0
- package/dist/config/paths.js +14 -0
- package/dist/config/paths.js.map +1 -1
- package/dist/config/profiles.d.ts +6 -4
- package/dist/config/profiles.js +65 -14
- package/dist/config/profiles.js.map +1 -1
- package/dist/config/providerPacks.d.ts +46 -0
- package/dist/config/providerPacks.js +200 -0
- package/dist/config/providerPacks.js.map +1 -0
- package/dist/config/providers.d.ts +36 -3
- package/dist/config/providers.js +168 -8
- package/dist/config/providers.js.map +1 -1
- package/dist/config/sites.d.ts +1 -12
- package/dist/config/sites.js +38 -5
- package/dist/config/sites.js.map +1 -1
- package/dist/config/userChannels.d.ts +12 -0
- package/dist/config/userChannels.js +81 -14
- package/dist/config/userChannels.js.map +1 -1
- package/dist/config/userConfig.d.ts +5 -1
- package/dist/config/userConfig.js +58 -6
- package/dist/config/userConfig.js.map +1 -1
- package/dist/config/userProfiles.d.ts +81 -0
- package/dist/config/userProfiles.js +424 -0
- package/dist/config/userProfiles.js.map +1 -0
- package/dist/routes/config/channels/index.d.ts +3 -0
- package/dist/routes/config/channels/index.js +3 -0
- package/dist/routes/config/channels/index.js.map +1 -0
- package/dist/routes/config/channels/routes.d.ts +6 -0
- package/dist/routes/config/channels/routes.js +797 -0
- package/dist/routes/config/channels/routes.js.map +1 -0
- package/dist/routes/config/channels/table.d.ts +46 -0
- package/dist/routes/config/channels/table.js +811 -0
- package/dist/routes/config/channels/table.js.map +1 -0
- package/dist/routes/config/index.d.ts +37 -0
- package/dist/routes/config/index.js +81 -0
- package/dist/routes/config/index.js.map +1 -0
- package/dist/routes/config/providers.d.ts +18 -0
- package/dist/routes/config/providers.js +573 -0
- package/dist/routes/config/providers.js.map +1 -0
- package/dist/routes/config/settings.d.ts +39 -0
- package/dist/routes/config/settings.js +820 -0
- package/dist/routes/config/settings.js.map +1 -0
- package/dist/routes/index.d.ts +3 -2
- package/dist/routes/index.js +7 -4
- package/dist/routes/index.js.map +1 -1
- package/dist/routes/playlist.d.ts +5 -1
- package/dist/routes/playlist.js +32 -7
- package/dist/routes/playlist.js.map +1 -1
- package/dist/routes/providers.d.ts +6 -0
- package/dist/routes/providers.js +166 -0
- package/dist/routes/providers.js.map +1 -0
- package/dist/routes/root/content.d.ts +32 -0
- package/dist/routes/root/content.js +857 -0
- package/dist/routes/root/content.js.map +1 -0
- package/dist/routes/root/index.js +197 -0
- package/dist/routes/root/index.js.map +1 -0
- package/dist/routes/root/scripts/channels.d.ts +1 -0
- package/dist/routes/root/scripts/channels.js +745 -0
- package/dist/routes/root/scripts/channels.js.map +1 -0
- package/dist/routes/root/scripts/config.d.ts +1 -0
- package/dist/routes/root/scripts/config.js +1662 -0
- package/dist/routes/root/scripts/config.js.map +1 -0
- package/dist/routes/root/scripts/index.d.ts +3 -0
- package/dist/routes/root/scripts/index.js +8 -0
- package/dist/routes/root/scripts/index.js.map +1 -0
- package/dist/routes/root/scripts/status.d.ts +1 -0
- package/dist/routes/root/scripts/status.js +436 -0
- package/dist/routes/root/scripts/status.js.map +1 -0
- package/dist/routes/root/styles.d.ts +5 -0
- package/dist/routes/root/styles.js +447 -0
- package/dist/routes/root/styles.js.map +1 -0
- package/dist/routes/ui.js +8 -3
- package/dist/routes/ui.js.map +1 -1
- package/dist/service/commands.d.ts +5 -3
- package/dist/service/commands.js +117 -33
- package/dist/service/commands.js.map +1 -1
- package/dist/service/generators.d.ts +27 -0
- package/dist/service/generators.js +97 -6
- package/dist/service/generators.js.map +1 -1
- package/dist/streaming/hls.js +18 -1
- package/dist/streaming/hls.js.map +1 -1
- package/dist/streaming/lifecycle.js +1 -1
- package/dist/streaming/lifecycle.js.map +1 -1
- package/dist/streaming/monitor.d.ts +1 -38
- package/dist/streaming/monitor.js +2 -289
- package/dist/streaming/monitor.js.map +1 -1
- package/dist/streaming/recovery.d.ts +143 -0
- package/dist/streaming/recovery.js +286 -0
- package/dist/streaming/recovery.js.map +1 -0
- package/dist/streaming/registry.d.ts +1 -1
- package/dist/streaming/setup.d.ts +1 -1
- package/dist/streaming/setup.js +3 -1
- package/dist/streaming/setup.js.map +1 -1
- package/dist/streaming/statusEmitter.d.ts +4 -2
- package/dist/streaming/statusEmitter.js +5 -0
- package/dist/streaming/statusEmitter.js.map +1 -1
- package/dist/types/channels.d.ts +68 -0
- package/dist/types/channels.js +2 -0
- package/dist/types/channels.js.map +1 -0
- package/dist/types/config.d.ts +127 -0
- package/dist/types/config.js +2 -0
- package/dist/types/config.js.map +1 -0
- package/dist/types/index.d.ts +7 -429
- package/dist/types/index.js +1 -5
- package/dist/types/index.js.map +1 -1
- package/dist/types/profiles.d.ts +141 -0
- package/dist/types/profiles.js +2 -0
- package/dist/types/profiles.js.map +1 -0
- package/dist/types/selection.d.ts +101 -0
- package/dist/types/selection.js +6 -0
- package/dist/types/selection.js.map +1 -0
- package/dist/types/shared.d.ts +7 -0
- package/dist/types/shared.js +6 -0
- package/dist/types/shared.js.map +1 -0
- package/dist/types/streaming.d.ts +96 -0
- package/dist/types/streaming.js +2 -0
- package/dist/types/streaming.js.map +1 -0
- package/dist/utils/debugFilter.js +3 -1
- package/dist/utils/debugFilter.js.map +1 -1
- package/dist/utils/format.d.ts +7 -0
- package/dist/utils/format.js +22 -0
- package/dist/utils/format.js.map +1 -1
- package/dist/utils/index.d.ts +1 -0
- package/dist/utils/index.js +1 -0
- package/dist/utils/index.js.map +1 -1
- package/dist/utils/sanitize.d.ts +14 -0
- package/dist/utils/sanitize.js +37 -0
- package/dist/utils/sanitize.js.map +1 -0
- package/package.json +5 -3
- package/dist/routes/config.d.ts +0 -76
- package/dist/routes/config.js +0 -2187
- package/dist/routes/config.js.map +0 -1
- package/dist/routes/root.js +0 -3158
- package/dist/routes/root.js.map +0 -1
- /package/dist/routes/{root.d.ts → root/index.d.ts} +0 -0
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import type { Nullable } from "./shared.js";
|
|
2
|
+
/**
|
|
3
|
+
* Channel definition mapping a short name to a streaming URL with optional configuration overrides.
|
|
4
|
+
*/
|
|
5
|
+
export interface Channel {
|
|
6
|
+
channelNumber?: number;
|
|
7
|
+
channelSelector?: string;
|
|
8
|
+
name?: string;
|
|
9
|
+
pacificStationId?: string;
|
|
10
|
+
profile?: string;
|
|
11
|
+
provider?: string;
|
|
12
|
+
scrollSelector?: string;
|
|
13
|
+
scrollTarget?: string;
|
|
14
|
+
scrollToBottom?: boolean;
|
|
15
|
+
stationId?: string;
|
|
16
|
+
tvgShift?: number;
|
|
17
|
+
url: string;
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Enriched channel entry returned by getChannelListing(). Wraps a Channel definition with source classification and enabled status metadata, providing the
|
|
21
|
+
* single source of truth for merged channel data across the codebase.
|
|
22
|
+
*/
|
|
23
|
+
export interface ChannelListingEntry {
|
|
24
|
+
availableByProvider: boolean;
|
|
25
|
+
channel: Channel;
|
|
26
|
+
enabled: boolean;
|
|
27
|
+
key: string;
|
|
28
|
+
source: "override" | "predefined" | "user";
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* A delta override for a predefined channel. All fields are optional because only fields that differ from the predefined definition are stored. String and number
|
|
32
|
+
* fields use Nullable<T> to distinguish "user cleared this field" (null) from "inherit from predefined" (absent). When a field is null, the predefined value is
|
|
33
|
+
* removed in the resolved channel. When a field is absent, the predefined value is inherited.
|
|
34
|
+
*/
|
|
35
|
+
export interface ChannelDelta {
|
|
36
|
+
channelNumber?: Nullable<number>;
|
|
37
|
+
channelSelector?: Nullable<string>;
|
|
38
|
+
name?: Nullable<string>;
|
|
39
|
+
profile?: Nullable<string>;
|
|
40
|
+
stationId?: Nullable<string>;
|
|
41
|
+
tvgShift?: Nullable<number>;
|
|
42
|
+
url?: Nullable<string>;
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* What gets stored in channels.json per key. For user-defined channels (no predefined equivalent), this is a full Channel with a required url. For overrides of
|
|
46
|
+
* predefined channels, this can be a ChannelDelta with only the differing fields. Legacy full-override entries (from before the delta model) are also valid — they
|
|
47
|
+
* are just deltas that happen to override every field.
|
|
48
|
+
*/
|
|
49
|
+
export type StoredChannel = Channel | ChannelDelta;
|
|
50
|
+
/**
|
|
51
|
+
* Map of channel keys to stored channel data (full definitions or deltas). This is the raw type for the channels.json file contents.
|
|
52
|
+
*/
|
|
53
|
+
export type StoredChannelMap = Record<string, StoredChannel>;
|
|
54
|
+
/**
|
|
55
|
+
* Map of channel short names to channel definitions. Channel names must be URL-safe strings (lowercase letters, numbers, hyphens) since they appear in stream
|
|
56
|
+
* request URLs.
|
|
57
|
+
*/
|
|
58
|
+
export type ChannelMap = Record<string, Channel>;
|
|
59
|
+
/**
|
|
60
|
+
* Represents a group of provider variants for the same content. Used by the UI to display provider selection dropdowns for multi-provider channels.
|
|
61
|
+
*/
|
|
62
|
+
export interface ProviderGroup {
|
|
63
|
+
canonicalKey: string;
|
|
64
|
+
variants: {
|
|
65
|
+
key: string;
|
|
66
|
+
label: string;
|
|
67
|
+
}[];
|
|
68
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"channels.js","sourceRoot":"","sources":["../../src/types/channels.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
import type { ChannelSortField, Nullable, SortDirection } from "./shared.js";
|
|
2
|
+
/**
|
|
3
|
+
* Browser-related configuration controlling Chrome launch behavior. Viewport dimensions are derived from the quality preset via getViewport() and are not stored in
|
|
4
|
+
* this configuration object.
|
|
5
|
+
*/
|
|
6
|
+
export interface BrowserConfig {
|
|
7
|
+
executablePath: Nullable<string>;
|
|
8
|
+
initTimeout: number;
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* Filesystem paths for Chrome profile data and extension files.
|
|
12
|
+
*/
|
|
13
|
+
export interface PathsConfig {
|
|
14
|
+
chromeDataDir: Nullable<string>;
|
|
15
|
+
chromeProfileName: string;
|
|
16
|
+
extensionDirName: string;
|
|
17
|
+
logFile: Nullable<string>;
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Playback monitoring and recovery timing configuration. These values control how quickly the system detects playback problems and how aggressively it attempts
|
|
21
|
+
* recovery. The defaults balance responsiveness against false positives from temporary buffering.
|
|
22
|
+
*/
|
|
23
|
+
export interface PlaybackConfig {
|
|
24
|
+
bufferingGracePeriod: number;
|
|
25
|
+
channelSelectorDelay: number;
|
|
26
|
+
channelSwitchDelay: number;
|
|
27
|
+
clickToPlayDelay: number;
|
|
28
|
+
iframeInitDelay: number;
|
|
29
|
+
maxPageReloads: number;
|
|
30
|
+
monitorInterval: number;
|
|
31
|
+
pageReloadWindow: number;
|
|
32
|
+
sourceReloadDelay: number;
|
|
33
|
+
stallCountThreshold: number;
|
|
34
|
+
stallThreshold: number;
|
|
35
|
+
sustainedPlaybackRequired: number;
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Recovery behavior configuration controlling retry logic, backoff timing, and circuit breaker thresholds. These settings determine how the system handles
|
|
39
|
+
* failures and prevents runaway resource consumption from broken streams.
|
|
40
|
+
*/
|
|
41
|
+
export interface RecoveryConfig {
|
|
42
|
+
backoffJitter: number;
|
|
43
|
+
circuitBreakerThreshold: number;
|
|
44
|
+
circuitBreakerWindow: number;
|
|
45
|
+
maxBackoffDelay: number;
|
|
46
|
+
stalePageCleanupInterval: number;
|
|
47
|
+
stalePageGracePeriod: number;
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* HLS streaming configuration controlling segment generation and lifecycle.
|
|
51
|
+
*/
|
|
52
|
+
export interface HLSConfig {
|
|
53
|
+
idleTimeout: number;
|
|
54
|
+
maxSegments: number;
|
|
55
|
+
segmentDuration: number;
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Channels configuration controlling which predefined channels are enabled.
|
|
59
|
+
*/
|
|
60
|
+
export interface ChannelsConfig {
|
|
61
|
+
channelSortDirection: SortDirection;
|
|
62
|
+
channelSortField: ChannelSortField;
|
|
63
|
+
disabledPredefined: string[];
|
|
64
|
+
enabledProviders: string[];
|
|
65
|
+
precacheProviders: string[];
|
|
66
|
+
visibleColumns: string[];
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* HDHomeRun emulation configuration. When enabled, PrismCast runs a separate HTTP server that emulates the HDHomeRun API, allowing Plex to discover and use
|
|
70
|
+
* PrismCast as a virtual tuner for live TV and DVR recording. The emulated device appears in Plex's tuner setup and serves PrismCast's HLS streams directly.
|
|
71
|
+
*/
|
|
72
|
+
export interface HdhrConfig {
|
|
73
|
+
deviceId: string;
|
|
74
|
+
enabled: boolean;
|
|
75
|
+
friendlyName: string;
|
|
76
|
+
port: number;
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* Logging configuration controlling file-based logging behavior.
|
|
80
|
+
*/
|
|
81
|
+
export interface LoggingConfig {
|
|
82
|
+
debugFilter: string;
|
|
83
|
+
httpLogLevel: "all" | "errors" | "filtered" | "none";
|
|
84
|
+
maxSize: number;
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* HTTP server configuration controlling network binding.
|
|
88
|
+
*/
|
|
89
|
+
export interface ServerConfig {
|
|
90
|
+
host: string;
|
|
91
|
+
port: number;
|
|
92
|
+
}
|
|
93
|
+
/**
|
|
94
|
+
* Capture mode for media recording. Determines how video/audio is captured from the browser and processed for HLS output.
|
|
95
|
+
* - "ffmpeg": Captures WebM (H264+Opus) and uses FFmpeg to transcode audio to AAC. More stable for long recordings.
|
|
96
|
+
* - "native": Captures fMP4 (H264+AAC) directly from Chrome. No dependencies but may be unstable with long recordings.
|
|
97
|
+
*/
|
|
98
|
+
export type CaptureMode = "ffmpeg" | "native";
|
|
99
|
+
/**
|
|
100
|
+
* Media streaming configuration controlling video capture quality, timeouts, and concurrency limits.
|
|
101
|
+
*/
|
|
102
|
+
export interface StreamingConfig {
|
|
103
|
+
audioBitsPerSecond: number;
|
|
104
|
+
captureMode: CaptureMode;
|
|
105
|
+
frameRate: number;
|
|
106
|
+
maxConcurrentStreams: number;
|
|
107
|
+
maxNavigationRetries: number;
|
|
108
|
+
navigationTimeout: number;
|
|
109
|
+
qualityPreset: string;
|
|
110
|
+
videoBitsPerSecond: number;
|
|
111
|
+
videoTimeout: number;
|
|
112
|
+
}
|
|
113
|
+
/**
|
|
114
|
+
* Root configuration object containing all application settings organized by functional area.
|
|
115
|
+
*/
|
|
116
|
+
export interface Config {
|
|
117
|
+
browser: BrowserConfig;
|
|
118
|
+
channels: ChannelsConfig;
|
|
119
|
+
hdhr: HdhrConfig;
|
|
120
|
+
hls: HLSConfig;
|
|
121
|
+
logging: LoggingConfig;
|
|
122
|
+
paths: PathsConfig;
|
|
123
|
+
playback: PlaybackConfig;
|
|
124
|
+
recovery: RecoveryConfig;
|
|
125
|
+
server: ServerConfig;
|
|
126
|
+
streaming: StreamingConfig;
|
|
127
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/types/config.ts"],"names":[],"mappings":""}
|
package/dist/types/index.d.ts
CHANGED
|
@@ -1,429 +1,7 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
export
|
|
8
|
-
/**
|
|
9
|
-
* Browser-related configuration controlling Chrome launch behavior. Viewport dimensions are derived from the quality preset via getViewport() and are not stored in
|
|
10
|
-
* this configuration object.
|
|
11
|
-
*/
|
|
12
|
-
export interface BrowserConfig {
|
|
13
|
-
executablePath: Nullable<string>;
|
|
14
|
-
initTimeout: number;
|
|
15
|
-
}
|
|
16
|
-
/**
|
|
17
|
-
* Filesystem paths for Chrome profile data and extension files.
|
|
18
|
-
*/
|
|
19
|
-
export interface PathsConfig {
|
|
20
|
-
chromeDataDir: Nullable<string>;
|
|
21
|
-
chromeProfileName: string;
|
|
22
|
-
extensionDirName: string;
|
|
23
|
-
logFile: Nullable<string>;
|
|
24
|
-
}
|
|
25
|
-
/**
|
|
26
|
-
* Playback monitoring and recovery timing configuration. These values control how quickly the system detects playback problems and how aggressively it attempts
|
|
27
|
-
* recovery. The defaults balance responsiveness against false positives from temporary buffering.
|
|
28
|
-
*/
|
|
29
|
-
export interface PlaybackConfig {
|
|
30
|
-
bufferingGracePeriod: number;
|
|
31
|
-
channelSelectorDelay: number;
|
|
32
|
-
channelSwitchDelay: number;
|
|
33
|
-
clickToPlayDelay: number;
|
|
34
|
-
iframeInitDelay: number;
|
|
35
|
-
maxPageReloads: number;
|
|
36
|
-
monitorInterval: number;
|
|
37
|
-
pageReloadWindow: number;
|
|
38
|
-
sourceReloadDelay: number;
|
|
39
|
-
stallCountThreshold: number;
|
|
40
|
-
stallThreshold: number;
|
|
41
|
-
sustainedPlaybackRequired: number;
|
|
42
|
-
}
|
|
43
|
-
/**
|
|
44
|
-
* Recovery behavior configuration controlling retry logic, backoff timing, and circuit breaker thresholds. These settings determine how the system handles
|
|
45
|
-
* failures and prevents runaway resource consumption from broken streams.
|
|
46
|
-
*/
|
|
47
|
-
export interface RecoveryConfig {
|
|
48
|
-
backoffJitter: number;
|
|
49
|
-
circuitBreakerThreshold: number;
|
|
50
|
-
circuitBreakerWindow: number;
|
|
51
|
-
maxBackoffDelay: number;
|
|
52
|
-
stalePageCleanupInterval: number;
|
|
53
|
-
stalePageGracePeriod: number;
|
|
54
|
-
}
|
|
55
|
-
/**
|
|
56
|
-
* HLS streaming configuration controlling segment generation and lifecycle.
|
|
57
|
-
*/
|
|
58
|
-
export interface HLSConfig {
|
|
59
|
-
idleTimeout: number;
|
|
60
|
-
maxSegments: number;
|
|
61
|
-
segmentDuration: number;
|
|
62
|
-
}
|
|
63
|
-
/**
|
|
64
|
-
* Channels configuration controlling which predefined channels are enabled.
|
|
65
|
-
*/
|
|
66
|
-
export interface ChannelsConfig {
|
|
67
|
-
disabledPredefined: string[];
|
|
68
|
-
enabledProviders: string[];
|
|
69
|
-
}
|
|
70
|
-
/**
|
|
71
|
-
* HDHomeRun emulation configuration. When enabled, PrismCast runs a separate HTTP server that emulates the HDHomeRun API, allowing Plex to discover and use
|
|
72
|
-
* PrismCast as a virtual tuner for live TV and DVR recording. The emulated device appears in Plex's tuner setup and serves PrismCast's HLS streams directly.
|
|
73
|
-
*/
|
|
74
|
-
export interface HdhrConfig {
|
|
75
|
-
deviceId: string;
|
|
76
|
-
enabled: boolean;
|
|
77
|
-
friendlyName: string;
|
|
78
|
-
port: number;
|
|
79
|
-
}
|
|
80
|
-
/**
|
|
81
|
-
* Logging configuration controlling file-based logging behavior.
|
|
82
|
-
*/
|
|
83
|
-
export interface LoggingConfig {
|
|
84
|
-
debugFilter: string;
|
|
85
|
-
httpLogLevel: "all" | "errors" | "filtered" | "none";
|
|
86
|
-
maxSize: number;
|
|
87
|
-
}
|
|
88
|
-
/**
|
|
89
|
-
* HTTP server configuration controlling network binding.
|
|
90
|
-
*/
|
|
91
|
-
export interface ServerConfig {
|
|
92
|
-
host: string;
|
|
93
|
-
port: number;
|
|
94
|
-
}
|
|
95
|
-
/**
|
|
96
|
-
* Capture mode for media recording. Determines how video/audio is captured from the browser and processed for HLS output.
|
|
97
|
-
* - "ffmpeg": Captures WebM (H264+Opus) and uses FFmpeg to transcode audio to AAC. More stable for long recordings.
|
|
98
|
-
* - "native": Captures fMP4 (H264+AAC) directly from Chrome. No dependencies but may be unstable with long recordings.
|
|
99
|
-
*/
|
|
100
|
-
export type CaptureMode = "ffmpeg" | "native";
|
|
101
|
-
/**
|
|
102
|
-
* Media streaming configuration controlling video capture quality, timeouts, and concurrency limits.
|
|
103
|
-
*/
|
|
104
|
-
export interface StreamingConfig {
|
|
105
|
-
audioBitsPerSecond: number;
|
|
106
|
-
captureMode: CaptureMode;
|
|
107
|
-
frameRate: number;
|
|
108
|
-
maxConcurrentStreams: number;
|
|
109
|
-
maxNavigationRetries: number;
|
|
110
|
-
navigationTimeout: number;
|
|
111
|
-
qualityPreset: string;
|
|
112
|
-
videoBitsPerSecond: number;
|
|
113
|
-
videoTimeout: number;
|
|
114
|
-
}
|
|
115
|
-
/**
|
|
116
|
-
* Root configuration object containing all application settings organized by functional area.
|
|
117
|
-
*/
|
|
118
|
-
export interface Config {
|
|
119
|
-
browser: BrowserConfig;
|
|
120
|
-
channels: ChannelsConfig;
|
|
121
|
-
hdhr: HdhrConfig;
|
|
122
|
-
hls: HLSConfig;
|
|
123
|
-
logging: LoggingConfig;
|
|
124
|
-
paths: PathsConfig;
|
|
125
|
-
playback: PlaybackConfig;
|
|
126
|
-
recovery: RecoveryConfig;
|
|
127
|
-
server: ServerConfig;
|
|
128
|
-
streaming: StreamingConfig;
|
|
129
|
-
}
|
|
130
|
-
/**
|
|
131
|
-
* UI category for profile grouping in dropdowns and reference documentation. Profiles are grouped by their fullscreen mechanism and special characteristics.
|
|
132
|
-
* - "api": Profiles using the JavaScript fullscreen API (including embedded iframe and click-to-play variants).
|
|
133
|
-
* - "keyboard": Profiles using keyboard shortcuts (typically the 'f' key) for fullscreen.
|
|
134
|
-
* - "multiChannel": Multi-channel profiles requiring a channel selector for tile or thumbnail-based channel selection.
|
|
135
|
-
* - "special": Special-purpose profiles like static page capture.
|
|
136
|
-
*/
|
|
137
|
-
export type ProfileCategory = "api" | "keyboard" | "multiChannel" | "special";
|
|
138
|
-
/**
|
|
139
|
-
* Site profile definition with optional flags. All flags are optional because profiles can inherit from other profiles, and only the flags that differ from the
|
|
140
|
-
* parent need to be specified. The DEFAULT_SITE_PROFILE provides baseline values for any flags not set through inheritance.
|
|
141
|
-
*/
|
|
142
|
-
export interface SiteProfile {
|
|
143
|
-
category?: ProfileCategory;
|
|
144
|
-
channelSelection?: ChannelSelectionConfig;
|
|
145
|
-
channelSelector?: Nullable<string>;
|
|
146
|
-
clickSelector?: Nullable<string>;
|
|
147
|
-
clickToPlay?: boolean;
|
|
148
|
-
description?: string;
|
|
149
|
-
extends?: string;
|
|
150
|
-
summary?: string;
|
|
151
|
-
fullscreenKey?: Nullable<string>;
|
|
152
|
-
fullscreenSelector?: Nullable<string>;
|
|
153
|
-
hideSelector?: Nullable<string>;
|
|
154
|
-
lockVolumeProperties?: boolean;
|
|
155
|
-
needsIframeHandling?: boolean;
|
|
156
|
-
noVideo?: boolean;
|
|
157
|
-
selectReadyVideo?: boolean;
|
|
158
|
-
useRequestFullscreen?: boolean;
|
|
159
|
-
waitForNetworkIdle?: boolean;
|
|
160
|
-
}
|
|
161
|
-
/**
|
|
162
|
-
* Fully-resolved site profile with all flags having concrete values. After resolving inheritance chains and applying defaults, every flag has a definite boolean
|
|
163
|
-
* or string value. This interface is used by stream handling code that needs to check profile flags without worrying about undefined values.
|
|
164
|
-
*/
|
|
165
|
-
export interface ResolvedSiteProfile {
|
|
166
|
-
channelSelection: ChannelSelectionConfig;
|
|
167
|
-
channelSelector: Nullable<string>;
|
|
168
|
-
clickSelector: Nullable<string>;
|
|
169
|
-
clickToPlay: boolean;
|
|
170
|
-
fullscreenKey: Nullable<string>;
|
|
171
|
-
fullscreenSelector: Nullable<string>;
|
|
172
|
-
hideSelector: Nullable<string>;
|
|
173
|
-
lockVolumeProperties: boolean;
|
|
174
|
-
maxContinuousPlayback: Nullable<number>;
|
|
175
|
-
needsIframeHandling: boolean;
|
|
176
|
-
noVideo: boolean;
|
|
177
|
-
selectReadyVideo: boolean;
|
|
178
|
-
useRequestFullscreen: boolean;
|
|
179
|
-
waitForNetworkIdle: boolean;
|
|
180
|
-
}
|
|
181
|
-
/**
|
|
182
|
-
* Result of resolving a site profile. Includes both the resolved profile configuration and the name of the profile that was matched. The name indicates whether the
|
|
183
|
-
* profile came from a channel hint, domain-based autodetection, or the default fallback.
|
|
184
|
-
*/
|
|
185
|
-
export interface ProfileResolutionResult {
|
|
186
|
-
profile: ResolvedSiteProfile;
|
|
187
|
-
profileName: string;
|
|
188
|
-
}
|
|
189
|
-
/**
|
|
190
|
-
* Channel definition mapping a short name to a streaming URL with optional configuration overrides.
|
|
191
|
-
*/
|
|
192
|
-
export interface Channel {
|
|
193
|
-
channelNumber?: number;
|
|
194
|
-
channelSelector?: string;
|
|
195
|
-
name?: string;
|
|
196
|
-
profile?: string;
|
|
197
|
-
provider?: string;
|
|
198
|
-
stationId?: string;
|
|
199
|
-
url: string;
|
|
200
|
-
}
|
|
201
|
-
/**
|
|
202
|
-
* Enriched channel entry returned by getChannelListing(). Wraps a Channel definition with source classification and enabled status metadata, providing the
|
|
203
|
-
* single source of truth for merged channel data across the codebase.
|
|
204
|
-
*/
|
|
205
|
-
export interface ChannelListingEntry {
|
|
206
|
-
availableByProvider: boolean;
|
|
207
|
-
channel: Channel;
|
|
208
|
-
enabled: boolean;
|
|
209
|
-
key: string;
|
|
210
|
-
source: "override" | "predefined" | "user";
|
|
211
|
-
}
|
|
212
|
-
/**
|
|
213
|
-
* A delta override for a predefined channel. All fields are optional because only fields that differ from the predefined definition are stored. String and number
|
|
214
|
-
* fields use Nullable<T> to distinguish "user cleared this field" (null) from "inherit from predefined" (absent). When a field is null, the predefined value is
|
|
215
|
-
* removed in the resolved channel. When a field is absent, the predefined value is inherited.
|
|
216
|
-
*/
|
|
217
|
-
export interface ChannelDelta {
|
|
218
|
-
channelNumber?: Nullable<number>;
|
|
219
|
-
channelSelector?: Nullable<string>;
|
|
220
|
-
name?: Nullable<string>;
|
|
221
|
-
profile?: Nullable<string>;
|
|
222
|
-
stationId?: Nullable<string>;
|
|
223
|
-
url?: Nullable<string>;
|
|
224
|
-
}
|
|
225
|
-
/**
|
|
226
|
-
* What gets stored in channels.json per key. For user-defined channels (no predefined equivalent), this is a full Channel with a required url. For overrides of
|
|
227
|
-
* predefined channels, this can be a ChannelDelta with only the differing fields. Legacy full-override entries (from before the delta model) are also valid — they
|
|
228
|
-
* are just deltas that happen to override every field.
|
|
229
|
-
*/
|
|
230
|
-
export type StoredChannel = Channel | ChannelDelta;
|
|
231
|
-
/**
|
|
232
|
-
* Map of channel keys to stored channel data (full definitions or deltas). This is the raw type for the channels.json file contents.
|
|
233
|
-
*/
|
|
234
|
-
export type StoredChannelMap = Record<string, StoredChannel>;
|
|
235
|
-
/**
|
|
236
|
-
* Map of channel short names to channel definitions. Channel names must be URL-safe strings (lowercase letters, numbers, hyphens) since they appear in stream
|
|
237
|
-
* request URLs.
|
|
238
|
-
*/
|
|
239
|
-
export type ChannelMap = Record<string, Channel>;
|
|
240
|
-
/**
|
|
241
|
-
* Represents a group of provider variants for the same content. Used by the UI to display provider selection dropdowns for multi-provider channels.
|
|
242
|
-
*/
|
|
243
|
-
export interface ProviderGroup {
|
|
244
|
-
canonicalKey: string;
|
|
245
|
-
variants: {
|
|
246
|
-
key: string;
|
|
247
|
-
label: string;
|
|
248
|
-
}[];
|
|
249
|
-
}
|
|
250
|
-
/**
|
|
251
|
-
* Information about an active streaming session. Created when a stream request is received and deleted when the stream ends.
|
|
252
|
-
*/
|
|
253
|
-
export interface StreamInfo {
|
|
254
|
-
channelName: Nullable<string>;
|
|
255
|
-
id: number;
|
|
256
|
-
page: Page;
|
|
257
|
-
startTime: Date;
|
|
258
|
-
stopMonitor: Nullable<() => RecoveryMetrics>;
|
|
259
|
-
url: string;
|
|
260
|
-
}
|
|
261
|
-
/**
|
|
262
|
-
* Snapshot of a video element's playback state. Collected by the playback health monitor to detect stalls, errors, and other problems.
|
|
263
|
-
*/
|
|
264
|
-
export interface VideoState {
|
|
265
|
-
currentTime: number;
|
|
266
|
-
ended: boolean;
|
|
267
|
-
error: boolean;
|
|
268
|
-
muted: boolean;
|
|
269
|
-
networkState: number;
|
|
270
|
-
paused: boolean;
|
|
271
|
-
readyState: number;
|
|
272
|
-
time: number;
|
|
273
|
-
volume: number;
|
|
274
|
-
}
|
|
275
|
-
/**
|
|
276
|
-
* Strategy for selecting a video element when multiple are present. "selectFirstVideo" takes the first video in DOM order; "selectReadyVideo" finds the video
|
|
277
|
-
* with readyState >= 3, which typically identifies the actively playing main content rather than preloaded ads.
|
|
278
|
-
*/
|
|
279
|
-
export type VideoSelectorType = "selectFirstVideo" | "selectReadyVideo";
|
|
280
|
-
/**
|
|
281
|
-
* Result of URL validation indicating whether the URL is safe to navigate to.
|
|
282
|
-
*/
|
|
283
|
-
export interface UrlValidationResult {
|
|
284
|
-
reason?: string;
|
|
285
|
-
valid: boolean;
|
|
286
|
-
}
|
|
287
|
-
/**
|
|
288
|
-
* Alias for UrlValidationResult maintained for backward compatibility with existing code.
|
|
289
|
-
*/
|
|
290
|
-
export type UrlValidation = UrlValidationResult;
|
|
291
|
-
/**
|
|
292
|
-
* Health check response structure returned by the /health endpoint.
|
|
293
|
-
*/
|
|
294
|
-
export interface HealthStatus {
|
|
295
|
-
browser: {
|
|
296
|
-
connected: boolean;
|
|
297
|
-
pageCount: number;
|
|
298
|
-
};
|
|
299
|
-
captureMode: string;
|
|
300
|
-
chrome: Nullable<string>;
|
|
301
|
-
clients: {
|
|
302
|
-
byType: {
|
|
303
|
-
count: number;
|
|
304
|
-
type: string;
|
|
305
|
-
}[];
|
|
306
|
-
total: number;
|
|
307
|
-
};
|
|
308
|
-
ffmpegAvailable: boolean;
|
|
309
|
-
memory: {
|
|
310
|
-
heapTotal: number;
|
|
311
|
-
heapUsed: number;
|
|
312
|
-
rss: number;
|
|
313
|
-
segmentBuffers: number;
|
|
314
|
-
};
|
|
315
|
-
message?: string;
|
|
316
|
-
status: "degraded" | "healthy" | "unhealthy";
|
|
317
|
-
streams: {
|
|
318
|
-
active: number;
|
|
319
|
-
limit: number;
|
|
320
|
-
};
|
|
321
|
-
timestamp: string;
|
|
322
|
-
uptime: number;
|
|
323
|
-
version: string;
|
|
324
|
-
}
|
|
325
|
-
/**
|
|
326
|
-
* Information about a single active stream as returned by the /streams endpoint.
|
|
327
|
-
*/
|
|
328
|
-
export interface StreamListItem {
|
|
329
|
-
channel: Nullable<string>;
|
|
330
|
-
duration: number;
|
|
331
|
-
id: number;
|
|
332
|
-
startTime: string;
|
|
333
|
-
url: string;
|
|
334
|
-
}
|
|
335
|
-
/**
|
|
336
|
-
* Response structure for the /streams endpoint.
|
|
337
|
-
*/
|
|
338
|
-
export interface StreamListResponse {
|
|
339
|
-
count: number;
|
|
340
|
-
limit: number;
|
|
341
|
-
streams: StreamListItem[];
|
|
342
|
-
}
|
|
343
|
-
/**
|
|
344
|
-
* Available channel selection strategies. Each strategy implements a different approach to finding and selecting channels in a multi-channel player UI.
|
|
345
|
-
*
|
|
346
|
-
* - "foxGrid": Find channel by station code in a non-virtualized guide grid, click the channel logo button via DOM .click(). Used by Fox.com.
|
|
347
|
-
* - "guideGrid": Find channel by exact-matching image alt text, click nearest clickable ancestor. Optionally clicks a tab to reveal the list first. Used by Hulu
|
|
348
|
-
* Live TV.
|
|
349
|
-
* - "hboGrid": Discover the HBO tab page URL from the homepage menu bar, scrape the live channel tile rail for a matching channel name, and navigate to the watch
|
|
350
|
-
* URL. Caches the tab URL across tunes with stale-cache fallback. Used by HBO Max.
|
|
351
|
-
* - "none": No channel selection needed (single-channel sites). This is the default.
|
|
352
|
-
* - "slingGrid": Find channel by data-testid in a virtualized A-Z guide grid, scroll via binary search on .guide-cell scrollTop, click the on-now program
|
|
353
|
-
* cell. Used by Sling TV.
|
|
354
|
-
* - "thumbnailRow": Find channel element using the profile's matchSelector (defaults to image URL matching), click adjacent element on the same row. Used by
|
|
355
|
-
* USA Network.
|
|
356
|
-
* - "tileClick": Find channel element using the profile's matchSelector (defaults to image URL matching), click tile, then optionally click play button if
|
|
357
|
-
* playSelector is configured. Used by Disney+.
|
|
358
|
-
* - "youtubeGrid": Find channel by aria-label in a non-virtualized EPG grid, extract the watch URL, and navigate directly. Used by YouTube TV.
|
|
359
|
-
*/
|
|
360
|
-
export type ChannelSelectionStrategy = "foxGrid" | "guideGrid" | "hboGrid" | "none" | "slingGrid" | "thumbnailRow" | "tileClick" | "youtubeGrid";
|
|
361
|
-
/**
|
|
362
|
-
* Configuration for channel selection behavior within a site profile.
|
|
363
|
-
*/
|
|
364
|
-
export interface ChannelSelectionConfig {
|
|
365
|
-
listSelector?: string;
|
|
366
|
-
matchSelector?: string;
|
|
367
|
-
playSelector?: string;
|
|
368
|
-
strategy: ChannelSelectionStrategy;
|
|
369
|
-
}
|
|
370
|
-
export interface ChannelSelectionProfile extends ResolvedSiteProfile {
|
|
371
|
-
channelSelector: string;
|
|
372
|
-
}
|
|
373
|
-
export declare function isChannelSelectionProfile(profile: ResolvedSiteProfile): profile is ChannelSelectionProfile;
|
|
374
|
-
/**
|
|
375
|
-
* Result of attempting to select a channel from a multi-channel player UI.
|
|
376
|
-
*/
|
|
377
|
-
export interface ChannelSelectorResult {
|
|
378
|
-
reason?: string;
|
|
379
|
-
success: boolean;
|
|
380
|
-
}
|
|
381
|
-
/**
|
|
382
|
-
* The strategy function signature. All strategies take the Puppeteer page and a narrowed profile with guaranteed non-null channelSelector.
|
|
383
|
-
*/
|
|
384
|
-
export type ChannelStrategyHandler = (page: Page, profile: ChannelSelectionProfile) => Promise<ChannelSelectorResult>;
|
|
385
|
-
/**
|
|
386
|
-
* The complete contract for a channel selection strategy. Each provider file exports a single object implementing this interface. The coordinator accesses all
|
|
387
|
-
* provider behavior through these hooks — no strategy-specific imports or hardcoded strategy name checks outside the registry.
|
|
388
|
-
*/
|
|
389
|
-
export interface ChannelStrategyEntry {
|
|
390
|
-
/**
|
|
391
|
-
* Resets all module-level caches (row positions, discovered URLs, watch URLs). Called on browser restart when cached state may be stale.
|
|
392
|
-
*/
|
|
393
|
-
clearCache?: () => void;
|
|
394
|
-
/**
|
|
395
|
-
* Selects the target channel in the provider's guide UI. Receives a Puppeteer page and a profile with a guaranteed non-null channelSelector. Must handle its
|
|
396
|
-
* own retry logic (e.g., overlay dismiss) and return a result indicating success or failure with a diagnostic reason.
|
|
397
|
-
*/
|
|
398
|
-
execute: ChannelStrategyHandler;
|
|
399
|
-
/**
|
|
400
|
-
* Removes a cached watch URL after it failed to produce a working stream. Called by the coordinator when a cached direct navigation fails.
|
|
401
|
-
*/
|
|
402
|
-
invalidateDirectUrl?: (channelSelector: string) => void;
|
|
403
|
-
/**
|
|
404
|
-
* Returns a watch URL for direct navigation, bypassing guide page loading. Implementations may perform async work such as fetching current asset IDs from
|
|
405
|
-
* provider APIs. The page parameter allows setting up response interception or accessing browser context when needed (e.g., cold cache setup).
|
|
406
|
-
*/
|
|
407
|
-
resolveDirectUrl?: (channelSelector: string, page: Page) => Promise<Nullable<string>>;
|
|
408
|
-
}
|
|
409
|
-
/**
|
|
410
|
-
* Coordinates for a click target, used when clicking channel selector elements.
|
|
411
|
-
*/
|
|
412
|
-
export interface ClickTarget {
|
|
413
|
-
x: number;
|
|
414
|
-
y: number;
|
|
415
|
-
}
|
|
416
|
-
/**
|
|
417
|
-
* Result of tuning to a channel, containing the video context needed for monitoring.
|
|
418
|
-
*/
|
|
419
|
-
export interface TuneResult {
|
|
420
|
-
context: Frame | Page;
|
|
421
|
-
}
|
|
422
|
-
/**
|
|
423
|
-
* Browser chrome dimensions (toolbars, borders) calculated by comparing window.outerHeight/Width to window.innerHeight/Width. Used to set window size such that
|
|
424
|
-
* the viewport (content area) matches our target dimensions.
|
|
425
|
-
*/
|
|
426
|
-
export interface UiSize {
|
|
427
|
-
height: number;
|
|
428
|
-
width: number;
|
|
429
|
-
}
|
|
1
|
+
export type { BrowserConfig, CaptureMode, ChannelsConfig, Config, HdhrConfig, HLSConfig, LoggingConfig, PathsConfig, PlaybackConfig, RecoveryConfig, ServerConfig, StreamingConfig } from "./config.js";
|
|
2
|
+
export type { Channel, ChannelDelta, ChannelListingEntry, ChannelMap, ProviderGroup, StoredChannel, StoredChannelMap } from "./channels.js";
|
|
3
|
+
export type { ChannelSelectionConfig, ChannelSelectionStrategy, DomainConfig, ProfileCategory, ProfileResolutionResult, ProfilesValidationResult, ProviderPack, ResolvedSiteProfile, SiteProfile, UserProfilesFile, UserProfilesLoadResult } from "./profiles.js";
|
|
4
|
+
export type { ChannelSelectionProfile, ChannelSelectorResult, ChannelStrategyEntry, ChannelStrategyHandler, ClickTarget, DiscoveredChannel, ProviderModule, TuneResult, UiSize } from "./selection.js";
|
|
5
|
+
export type { ChannelSortField, Nullable, SortDirection } from "./shared.js";
|
|
6
|
+
export type { HealthStatus, StreamInfo, StreamListItem, StreamListResponse, UrlValidation, UrlValidationResult, VideoSelectorType, VideoState } from "./streaming.js";
|
|
7
|
+
export { isChannelSelectionProfile } from "./selection.js";
|
package/dist/types/index.js
CHANGED
|
@@ -1,6 +1,2 @@
|
|
|
1
|
-
|
|
2
|
-
// Used by the coordinator before dispatching to strategy functions.
|
|
3
|
-
export function isChannelSelectionProfile(profile) {
|
|
4
|
-
return (profile.channelSelector !== null) && (profile.channelSelector.length > 0);
|
|
5
|
-
}
|
|
1
|
+
export { isChannelSelectionProfile } from "./selection.js";
|
|
6
2
|
//# sourceMappingURL=index.js.map
|
package/dist/types/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/types/index.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/types/index.ts"],"names":[],"mappings":"AAcA,OAAO,EAAE,yBAAyB,EAAE,MAAM,gBAAgB,CAAC"}
|