prismcast 1.6.0 → 1.7.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.
Files changed (194) hide show
  1. package/dist/browser/cdp.js +1 -1
  2. package/dist/browser/cdp.js.map +1 -1
  3. package/dist/browser/channelSelection.d.ts +10 -34
  4. package/dist/browser/channelSelection.js +19 -96
  5. package/dist/browser/channelSelection.js.map +1 -1
  6. package/dist/browser/display.d.ts +19 -0
  7. package/dist/browser/display.js +16 -11
  8. package/dist/browser/display.js.map +1 -1
  9. package/dist/browser/index.d.ts +9 -46
  10. package/dist/browser/index.js +136 -191
  11. package/dist/browser/index.js.map +1 -1
  12. package/dist/browser/login.d.ts +65 -0
  13. package/dist/browser/login.js +193 -0
  14. package/dist/browser/login.js.map +1 -0
  15. package/dist/browser/precaching.js +12 -0
  16. package/dist/browser/precaching.js.map +1 -1
  17. package/dist/browser/tuning/comcastPolymer.d.ts +23 -0
  18. package/dist/browser/tuning/comcastPolymer.js +655 -0
  19. package/dist/browser/tuning/comcastPolymer.js.map +1 -0
  20. package/dist/browser/tuning/cox.d.ts +2 -0
  21. package/dist/browser/tuning/cox.js +14 -0
  22. package/dist/browser/tuning/cox.js.map +1 -0
  23. package/dist/browser/tuning/directv.js +1 -1
  24. package/dist/browser/tuning/directv.js.map +1 -1
  25. package/dist/browser/tuning/fox.js +2 -2
  26. package/dist/browser/tuning/fox.js.map +1 -1
  27. package/dist/browser/tuning/hbo.js +1 -1
  28. package/dist/browser/tuning/hbo.js.map +1 -1
  29. package/dist/browser/tuning/hulu.js +1 -1
  30. package/dist/browser/tuning/hulu.js.map +1 -1
  31. package/dist/browser/tuning/shared.d.ts +46 -0
  32. package/dist/browser/tuning/shared.js +100 -0
  33. package/dist/browser/tuning/shared.js.map +1 -0
  34. package/dist/browser/tuning/sling.js +1 -1
  35. package/dist/browser/tuning/sling.js.map +1 -1
  36. package/dist/browser/tuning/spectrum.js +1 -1
  37. package/dist/browser/tuning/spectrum.js.map +1 -1
  38. package/dist/browser/tuning/thumbnailRow.js +1 -1
  39. package/dist/browser/tuning/thumbnailRow.js.map +1 -1
  40. package/dist/browser/tuning/tileClick.js +1 -1
  41. package/dist/browser/tuning/tileClick.js.map +1 -1
  42. package/dist/browser/tuning/xfinity.js +10 -603
  43. package/dist/browser/tuning/xfinity.js.map +1 -1
  44. package/dist/browser/tuning/youtubeTv.js +1 -1
  45. package/dist/browser/tuning/youtubeTv.js.map +1 -1
  46. package/dist/browser/video.d.ts +18 -0
  47. package/dist/browser/video.js +69 -107
  48. package/dist/browser/video.js.map +1 -1
  49. package/dist/channels/index.d.ts +2 -2
  50. package/dist/channels/index.js +2075 -800
  51. package/dist/channels/index.js.map +1 -1
  52. package/dist/config/health.js +20 -2
  53. package/dist/config/health.js.map +1 -1
  54. package/dist/config/index.js +29 -64
  55. package/dist/config/index.js.map +1 -1
  56. package/dist/config/providerPacks.js +4 -1
  57. package/dist/config/providerPacks.js.map +1 -1
  58. package/dist/config/providers.d.ts +12 -5
  59. package/dist/config/providers.js +110 -94
  60. package/dist/config/providers.js.map +1 -1
  61. package/dist/config/sites.js +15 -9
  62. package/dist/config/sites.js.map +1 -1
  63. package/dist/config/userChannels.d.ts +50 -2
  64. package/dist/config/userChannels.js +212 -10
  65. package/dist/config/userChannels.js.map +1 -1
  66. package/dist/config/userConfig.d.ts +1 -1
  67. package/dist/config/userConfig.js +2 -15
  68. package/dist/config/userConfig.js.map +1 -1
  69. package/dist/hdhr/channelMap.d.ts +1 -1
  70. package/dist/hdhr/channelMap.js +4 -4
  71. package/dist/hdhr/channelMap.js.map +1 -1
  72. package/dist/index.js +9 -15
  73. package/dist/index.js.map +1 -1
  74. package/dist/native/index.d.ts +3 -0
  75. package/dist/native/index.js +2 -1
  76. package/dist/native/index.js.map +1 -1
  77. package/dist/native/probe.d.ts +4 -3
  78. package/dist/native/probe.js +36 -12
  79. package/dist/native/probe.js.map +1 -1
  80. package/dist/native/proxy.d.ts +2 -0
  81. package/dist/native/proxy.js +369 -326
  82. package/dist/native/proxy.js.map +1 -1
  83. package/dist/routes/components.d.ts +43 -0
  84. package/dist/routes/components.js +122 -0
  85. package/dist/routes/components.js.map +1 -1
  86. package/dist/routes/config/channels/index.d.ts +2 -2
  87. package/dist/routes/config/channels/index.js +1 -1
  88. package/dist/routes/config/channels/index.js.map +1 -1
  89. package/dist/routes/config/channels/routes.js +443 -65
  90. package/dist/routes/config/channels/routes.js.map +1 -1
  91. package/dist/routes/config/channels/table.d.ts +76 -0
  92. package/dist/routes/config/channels/table.js +352 -66
  93. package/dist/routes/config/channels/table.js.map +1 -1
  94. package/dist/routes/config/index.d.ts +1 -1
  95. package/dist/routes/config/index.js +1 -1
  96. package/dist/routes/config/index.js.map +1 -1
  97. package/dist/routes/config/providers.d.ts +6 -6
  98. package/dist/routes/config/providers.js +69 -95
  99. package/dist/routes/config/providers.js.map +1 -1
  100. package/dist/routes/index.d.ts +0 -16
  101. package/dist/routes/index.js +0 -17
  102. package/dist/routes/index.js.map +1 -1
  103. package/dist/routes/providers.js +106 -3
  104. package/dist/routes/providers.js.map +1 -1
  105. package/dist/routes/root/content.js +55 -38
  106. package/dist/routes/root/content.js.map +1 -1
  107. package/dist/routes/root/index.js +2 -1
  108. package/dist/routes/root/index.js.map +1 -1
  109. package/dist/routes/root/scripts/channels.js +772 -312
  110. package/dist/routes/root/scripts/channels.js.map +1 -1
  111. package/dist/routes/root/scripts/config.js +596 -544
  112. package/dist/routes/root/scripts/config.js.map +1 -1
  113. package/dist/routes/root/scripts/index.d.ts +1 -0
  114. package/dist/routes/root/scripts/index.js +1 -0
  115. package/dist/routes/root/scripts/index.js.map +1 -1
  116. package/dist/routes/root/scripts/shared.d.ts +6 -0
  117. package/dist/routes/root/scripts/shared.js +391 -0
  118. package/dist/routes/root/scripts/shared.js.map +1 -0
  119. package/dist/routes/root/scripts/status.js +36 -21
  120. package/dist/routes/root/scripts/status.js.map +1 -1
  121. package/dist/routes/root/styles.js +113 -8
  122. package/dist/routes/root/styles.js.map +1 -1
  123. package/dist/service/commands.js +2 -1
  124. package/dist/service/commands.js.map +1 -1
  125. package/dist/streaming/fmp4Segmenter.d.ts +2 -0
  126. package/dist/streaming/fmp4Segmenter.js +7 -4
  127. package/dist/streaming/fmp4Segmenter.js.map +1 -1
  128. package/dist/streaming/hls.js +269 -188
  129. package/dist/streaming/hls.js.map +1 -1
  130. package/dist/streaming/hlsResume.d.ts +9 -3
  131. package/dist/streaming/hlsResume.js +13 -6
  132. package/dist/streaming/hlsResume.js.map +1 -1
  133. package/dist/streaming/hlsSegments.d.ts +1 -2
  134. package/dist/streaming/hlsSegments.js +48 -46
  135. package/dist/streaming/hlsSegments.js.map +1 -1
  136. package/dist/streaming/lifecycle.js +8 -12
  137. package/dist/streaming/lifecycle.js.map +1 -1
  138. package/dist/streaming/monitor.js +625 -585
  139. package/dist/streaming/monitor.js.map +1 -1
  140. package/dist/streaming/mpegts.js +1 -1
  141. package/dist/streaming/mpegts.js.map +1 -1
  142. package/dist/streaming/preroll.d.ts +40 -20
  143. package/dist/streaming/preroll.js +147 -86
  144. package/dist/streaming/preroll.js.map +1 -1
  145. package/dist/streaming/recovery.d.ts +0 -6
  146. package/dist/streaming/recovery.js +0 -8
  147. package/dist/streaming/recovery.js.map +1 -1
  148. package/dist/streaming/registry.d.ts +36 -9
  149. package/dist/streaming/registry.js +6 -9
  150. package/dist/streaming/registry.js.map +1 -1
  151. package/dist/streaming/setup.d.ts +1 -1
  152. package/dist/streaming/setup.js +44 -21
  153. package/dist/streaming/setup.js.map +1 -1
  154. package/dist/streaming/showInfo.d.ts +7 -6
  155. package/dist/streaming/showInfo.js +156 -36
  156. package/dist/streaming/showInfo.js.map +1 -1
  157. package/dist/streaming/statusEmitter.d.ts +14 -2
  158. package/dist/streaming/statusEmitter.js +22 -4
  159. package/dist/streaming/statusEmitter.js.map +1 -1
  160. package/dist/types/channels.d.ts +31 -0
  161. package/dist/types/config.d.ts +2 -2
  162. package/dist/types/index.d.ts +1 -1
  163. package/dist/types/index.js.map +1 -1
  164. package/dist/types/profiles.d.ts +8 -3
  165. package/dist/types/selection.d.ts +1 -0
  166. package/dist/types/shared.d.ts +1 -1
  167. package/dist/utils/debugFilter.d.ts +0 -5
  168. package/dist/utils/debugFilter.js +5 -11
  169. package/dist/utils/debugFilter.js.map +1 -1
  170. package/dist/utils/delay.d.ts +12 -0
  171. package/dist/utils/delay.js +20 -0
  172. package/dist/utils/delay.js.map +1 -1
  173. package/dist/utils/evaluate.js +6 -11
  174. package/dist/utils/evaluate.js.map +1 -1
  175. package/dist/utils/ffmpeg.d.ts +13 -5
  176. package/dist/utils/ffmpeg.js +32 -11
  177. package/dist/utils/ffmpeg.js.map +1 -1
  178. package/dist/utils/format.d.ts +6 -0
  179. package/dist/utils/format.js +8 -0
  180. package/dist/utils/format.js.map +1 -1
  181. package/dist/utils/index.d.ts +1 -0
  182. package/dist/utils/index.js +1 -0
  183. package/dist/utils/index.js.map +1 -1
  184. package/dist/utils/logEmitter.js +1 -1
  185. package/dist/utils/logEmitter.js.map +1 -1
  186. package/dist/utils/retry.d.ts +15 -9
  187. package/dist/utils/retry.js +7 -23
  188. package/dist/utils/retry.js.map +1 -1
  189. package/dist/utils/timing.d.ts +5 -0
  190. package/dist/utils/timing.js +13 -0
  191. package/dist/utils/timing.js.map +1 -0
  192. package/dist/utils/version.js +2 -2
  193. package/dist/utils/version.js.map +1 -1
  194. package/package.json +5 -5
@@ -1,31 +1,46 @@
1
1
  /* Copyright(C) 2024-2026, HJD (https://github.com/hjdhjd). All rights reserved.
2
2
  *
3
- * showInfo.ts: Channels DVR API integration for show name lookup.
3
+ * showInfo.ts: Channels DVR API integration for show name and channel logo lookup.
4
4
  */
5
5
  import { LOG, formatError } from "../utils/index.js";
6
+ import { clearChannelLogos, getAllChannels, getChannelListing, getChannelLogo, getChannelStationId, setChannelLogo, setChannelLogos } from "../config/userChannels.js";
6
7
  import { loadUserConfig, saveUserConfig } from "../config/userConfig.js";
7
- import { getAllChannels } from "../config/userChannels.js";
8
+ import { emitChannelUpdate } from "./statusEmitter.js";
8
9
  import { getAllStreams } from "./registry.js";
9
- /* This module integrates with the Channels DVR API to retrieve the names of shows for active streams. Show names are determined from two sources:
10
+ /* This module integrates with the Channels DVR API for two purposes: show name lookup and channel logo population.
10
11
  *
11
- * 1. Active recordings (/dvr/jobs) - If Channels DVR is recording a channel, we get the show name from the recording job
12
- * 2. Program guide (/devices/{id}/guide/now) - For live viewing without recording, we fall back to the current program from the guide
12
+ * Show names are determined from two sources:
13
13
  *
14
- * The polling mechanism uses a two-phase approach — discovery and lookup:
14
+ * 1. Active recordings (/dvr/jobs) - if Channels DVR is recording a channel, we get the show name from the recording job.
15
+ * 2. Program guide (/devices/{id}/guide/now) - for live viewing without recording, we fall back to the current program from the guide.
16
+ *
17
+ * The show name polling mechanism uses a two-phase approach - discovery and lookup:
15
18
  *
16
19
  * 1. Discovery: Every 30 seconds, try each unique client address as a potential Channels DVR server by calling getDeviceMappings(). If a host has matching M3U
17
20
  * devices, cache it as the last known DVR host. Device mappings are cached for 5 minutes, so non-DVR hosts (e.g., Plex IPs) only incur a network timeout on the
18
21
  * first attempt and every 5 minutes thereafter.
19
22
  *
20
- * 2. Lookup: Use the cached DVR host for show name and logo lookups across ALL active streams, regardless of which client initiated them. This enables Plex-initiated
21
- * streams to display show names and logos from the Channels DVR guide, as long as any Channels DVR connection has been seen at some point.
23
+ * 2. Lookup: Use the cached DVR host for show name lookups across ALL active streams, regardless of which client initiated them. This enables Plex-initiated
24
+ * streams to display show names from the Channels DVR guide, as long as any Channels DVR connection has been seen at some point.
25
+ *
26
+ * Channel logos are populated in two tiers when a DVR host is known:
27
+ *
28
+ * 1. Tier 1 (/devices): Logo URLs are extracted from the matched M3U device's channel list during getDeviceMappings(). This covers all channels in the M3U
29
+ * playlist with authoritative, current logo URLs from the DVR.
30
+ *
31
+ * 2. Tier 2 (/tms/stations/{name}): For channels with station IDs not covered by tier 1 (disabled channels, channels without an enabled provider), a TMS station
32
+ * name search finds the best matching logo. Results are matched by station ID when possible, otherwise the first result with a valid logo is used.
33
+ *
34
+ * Logo population runs on DVR host discovery (startup or first stream connection) and refreshes every 24 hours. Individual channel add/edit operations trigger a
35
+ * single-entry TMS search for immediate logo availability.
22
36
  *
23
37
  * Caching strategy:
24
38
  * - Last known DVR host: Persists across poll cycles, resets on shutdown
25
39
  * - Device channel mappings: Cached for 5 minutes per host (rarely change)
26
40
  * - Recording jobs and guide data: Fetched fresh each poll cycle (30 seconds)
41
+ * - Channel logos: Cached by station ID in userChannels.ts, refreshed every 24 hours
27
42
  *
28
- * Failure handling is graceful: if the API is unreachable or returns no match, the show name simply stays empty. This never affects streaming functionality.
43
+ * Failure handling is graceful: if the API is unreachable or returns no match, show names and logos simply stay empty. This never affects streaming functionality.
29
44
  */
30
45
  // Constants.
31
46
  // Default Channels DVR port.
@@ -38,7 +53,9 @@ const MAPPINGS_REFRESH_INTERVAL_MS = 300000;
38
53
  const API_TIMEOUT_MS = 5000;
39
54
  // Debounce delay for triggered updates (2 seconds).
40
55
  const TRIGGER_DEBOUNCE_MS = 2000;
41
- // Logo height in pixels for URL sizing parameter (2x for retina displays).
56
+ // Logo refresh interval (24 hours). Logos change when networks rebrand, which is a handful of times per year.
57
+ const LOGO_REFRESH_INTERVAL_MS = 86400000;
58
+ // Logo image height in pixels for URL normalization (2x for retina displays). Applied to CDN URLs to request smaller images for UI rendering.
42
59
  const LOGO_HEIGHT_PX = 48;
43
60
  // State.
44
61
  // Interval handle for periodic polling.
@@ -47,9 +64,9 @@ let pollInterval = null;
47
64
  const showNameCache = new Map();
48
65
  // Cache of device channel mappings by DVR host.
49
66
  const deviceMappingsByHost = new Map();
50
- // Cache of channel logos by channel key (e.g., "cnn" → "http://...").
51
- const channelLogoCache = new Map();
52
- // Last known Channels DVR host that had matching M3U devices. Used to look up show names and logos for all streams, including those initiated by non-DVR clients
67
+ // Interval handle for 24-hour logo refresh.
68
+ let logoRefreshInterval = null;
69
+ // Last known Channels DVR host that had matching M3U devices. Used to look up show names for all streams, including those initiated by non-DVR clients
53
70
  // (e.g., Plex). Persists across poll cycles but resets on shutdown. Updated whenever getDeviceMappings() finds matching devices on a host.
54
71
  let lastKnownDvrHost = null;
55
72
  // Pending debounced trigger for immediate show name updates.
@@ -72,6 +89,9 @@ export function setDvrHost(host) {
72
89
  }
73
90
  lastKnownDvrHost = host;
74
91
  void persistDvrHost(host);
92
+ // Populate logos whenever the DVR host changes. The early return above (host === lastKnownDvrHost) prevents redundant calls during show name polling's
93
+ // repeated confirmations of the same host. A genuine host change (e.g., DVR migration) triggers a full re-population with the new host's data.
94
+ void populateChannelLogos();
75
95
  }
76
96
  /**
77
97
  * Starts the show info polling interval. Should be called on server startup.
@@ -87,6 +107,10 @@ export function startShowInfoPolling() {
87
107
  pollInterval = setInterval(() => {
88
108
  void updateShowNames();
89
109
  }, POLL_INTERVAL_MS);
110
+ // Start the 24-hour logo refresh. The initial population is triggered by loadPersistedDvrHost() or setDvrHost() when a DVR host becomes known.
111
+ logoRefreshInterval = setInterval(() => {
112
+ void populateChannelLogos();
113
+ }, LOGO_REFRESH_INTERVAL_MS);
90
114
  }
91
115
  /**
92
116
  * Stops the show info polling interval. Should be called on server shutdown.
@@ -96,6 +120,11 @@ export function stopShowInfoPolling() {
96
120
  clearInterval(pollInterval);
97
121
  pollInterval = null;
98
122
  }
123
+ // Clear the logo refresh interval.
124
+ if (logoRefreshInterval) {
125
+ clearInterval(logoRefreshInterval);
126
+ logoRefreshInterval = null;
127
+ }
99
128
  // Clear pending trigger.
100
129
  if (pendingTrigger) {
101
130
  clearTimeout(pendingTrigger);
@@ -104,7 +133,7 @@ export function stopShowInfoPolling() {
104
133
  // Clear caches and cached DVR host on shutdown.
105
134
  showNameCache.clear();
106
135
  deviceMappingsByHost.clear();
107
- channelLogoCache.clear();
136
+ clearChannelLogos();
108
137
  lastKnownDvrHost = null;
109
138
  }
110
139
  /**
@@ -137,18 +166,10 @@ export function getShowName(streamId) {
137
166
  export function clearShowName(streamId) {
138
167
  showNameCache.delete(streamId);
139
168
  }
140
- /**
141
- * Gets the cached logo URL for a channel.
142
- * @param channelKey - The channel key to look up (e.g., "cnn").
143
- * @returns The logo URL if known, undefined otherwise.
144
- */
145
- export function getChannelLogo(channelKey) {
146
- return channelLogoCache.get(channelKey);
147
- }
148
169
  // Internal Functions.
149
170
  /**
150
171
  * Updates show names for all active streams. Discovery phase tries each unique client address as a potential Channels DVR server. Lookup phase uses the cached DVR
151
- * host for all streams, enabling non-DVR clients (e.g., Plex) to display show names and logos.
172
+ * host for all streams, enabling non-DVR clients (e.g., Plex) to display show names.
152
173
  */
153
174
  async function updateShowNames() {
154
175
  const streams = getAllStreams();
@@ -174,7 +195,7 @@ async function updateShowNames() {
174
195
  setDvrHost(host);
175
196
  }
176
197
  }));
177
- // Lookup phase: use the cached DVR host for show name and logo lookups across all streams.
198
+ // Lookup phase: use the cached DVR host for show name lookups across all streams.
178
199
  if (lastKnownDvrHost) {
179
200
  await updateShowNamesForHost(lastKnownDvrHost, allStreamEntries);
180
201
  return;
@@ -282,18 +303,23 @@ export async function getDeviceMappings(host) {
282
303
  continue;
283
304
  }
284
305
  LOG.debug("streaming:showinfo", "Matched M3U device %s as PrismCast source (%d channels, %d%% overlap).", device.DeviceID, device.Channels.length, Math.round(overlapRatio * 100));
285
- // Build guide number → channel ID map for this device and cache logo URLs.
306
+ // Build guide number → channel ID map for this device and extract logo URLs. Logo URLs are cached by station ID (resolved from the channel key via
307
+ // getChannelStationId) so that Pacific channels and provider variants all share the same logo entry.
286
308
  const guideToChannelId = new Map();
309
+ const logos = new Map();
287
310
  for (const channel of device.Channels) {
288
311
  guideToChannelId.set(channel.GuideNumber, channel.ID);
289
- // Cache the logo URL if available.
290
312
  if (channel.Logo) {
291
- const normalizedLogo = normalizeLogoUrl(channel.Logo);
292
- if (normalizedLogo) {
293
- channelLogoCache.set(channel.ID, normalizedLogo);
313
+ const stationId = getChannelStationId(channel.ID);
314
+ if (stationId) {
315
+ logos.set(stationId, normalizeLogoUrl(channel.Logo));
294
316
  }
295
317
  }
296
318
  }
319
+ // Populate the logo cache with URLs from this device (tier 1).
320
+ if (logos.size > 0) {
321
+ setChannelLogos(logos);
322
+ }
297
323
  mappings.set(device.DeviceID, guideToChannelId);
298
324
  deviceIds.push(device.DeviceID);
299
325
  totalChannels += device.Channels.length;
@@ -370,10 +396,12 @@ async function loadPersistedDvrHost() {
370
396
  if (!result.parseError && result.config.dvrHost) {
371
397
  lastKnownDvrHost = result.config.dvrHost;
372
398
  LOG.debug("streaming:showinfo", "Loaded persisted DVR host: %s.", lastKnownDvrHost);
399
+ // Populate logos immediately from the persisted host so they're available on the first page load.
400
+ void populateChannelLogos();
373
401
  }
374
402
  }
375
403
  catch {
376
- // Ignore errors — the host will be discovered from the first stream's client address.
404
+ // Ignore errors - the host will be discovered from the first stream's client address.
377
405
  }
378
406
  }
379
407
  /**
@@ -392,21 +420,113 @@ async function persistDvrHost(host) {
392
420
  LOG.debug("streaming:showinfo", "Failed to persist DVR host: %s.", formatError(error));
393
421
  }
394
422
  }
423
+ // Logo population.
424
+ /**
425
+ * Populates the channel logo cache in two tiers. Tier 1 fetches logo URLs from the DVR's /devices endpoint (covers all channels in the M3U playlist). Tier 2 runs
426
+ * TMS station name searches for any remaining channels with station IDs not covered by tier 1. Called on DVR host discovery (startup or first stream) and every 24
427
+ * hours to pick up network rebrands.
428
+ */
429
+ async function populateChannelLogos() {
430
+ if (!lastKnownDvrHost) {
431
+ return;
432
+ }
433
+ // Tier 1: fetch device data and extract logos. getDeviceMappings() handles the /devices fetch, device matching, and logo extraction into the cache as a side
434
+ // effect. The 5-minute mapping cache means we don't re-fetch if show name polling already called this recently.
435
+ await getDeviceMappings(lastKnownDvrHost);
436
+ // Tier 2: search TMS by channel name for channels with station IDs not covered by tier 1. This covers disabled channels, channels without an enabled provider,
437
+ // and any channels the DVR device didn't include logos for.
438
+ const listing = getChannelListing();
439
+ let cachedCount = 0;
440
+ let tier2Count = 0;
441
+ for (const entry of listing) {
442
+ // Skip channels that already have a logo in the cache (from tier 1 or a previous population cycle).
443
+ if (getChannelLogo(entry.key)) {
444
+ cachedCount++;
445
+ continue;
446
+ }
447
+ const stationId = getChannelStationId(entry.key);
448
+ if (!stationId) {
449
+ continue;
450
+ }
451
+ const channelName = entry.channel.name ?? entry.key;
452
+ // eslint-disable-next-line no-await-in-loop -- Intentional: sequential to avoid flooding the DVR's TMS proxy with concurrent requests.
453
+ const found = await searchTmsStationLogo(lastKnownDvrHost, channelName, stationId);
454
+ if (found) {
455
+ tier2Count++;
456
+ }
457
+ }
458
+ LOG.debug("streaming:logos", "Logo population complete: %d cached, %d from TMS search, %d total.", cachedCount, tier2Count, cachedCount + tier2Count);
459
+ // Emit a channel-update SSE event with all resolved logos so any open channels tab can populate logo images without a page reload.
460
+ const logos = {};
461
+ for (const entry of listing) {
462
+ const logoUrl = getChannelLogo(entry.key);
463
+ if (logoUrl) {
464
+ logos[entry.key] = logoUrl;
465
+ }
466
+ }
467
+ if (Object.keys(logos).length > 0) {
468
+ emitChannelUpdate({ logos });
469
+ }
470
+ }
471
+ /**
472
+ * Searches the TMS stations endpoint for a channel's logo by name. If a result matches the target station ID, uses that logo. Otherwise uses the first result
473
+ * with a valid logo URL (same brand, different regional feed). Caches the result if found.
474
+ * @param host - The DVR server hostname or IP address.
475
+ * @param channelName - The channel display name to search for (e.g., "AMC", "Animal Planet").
476
+ * @param targetStationId - The Gracenote station ID to match against results.
477
+ * @returns True if a logo was found and cached, false otherwise.
478
+ */
479
+ async function searchTmsStationLogo(host, channelName, targetStationId) {
480
+ const results = await fetchFromDvr(host, "/tms/stations/" + encodeURIComponent(channelName));
481
+ if (results.length === 0) {
482
+ return false;
483
+ }
484
+ // Prefer an exact station ID match. If none, use the first result with a valid logo URL (same brand, different regional variant).
485
+ let logoUrl;
486
+ for (const result of results) {
487
+ const uri = result.preferredImage?.uri;
488
+ if (!uri) {
489
+ continue;
490
+ }
491
+ if (result.stationId === targetStationId) {
492
+ logoUrl = uri;
493
+ break;
494
+ }
495
+ logoUrl ??= uri;
496
+ }
497
+ if (!logoUrl) {
498
+ return false;
499
+ }
500
+ setChannelLogo(targetStationId, normalizeLogoUrl(logoUrl));
501
+ LOG.debug("streaming:logos", "TMS search for '%s': found logo for station %s.", channelName, targetStationId);
502
+ return true;
503
+ }
504
+ /**
505
+ * Triggers a single-channel logo lookup via TMS station name search. Called when a channel is added or edited with a station ID. Fire-and-forget - the logo
506
+ * appears on the next page load after the search completes.
507
+ * @param channelName - The channel display name to search for.
508
+ * @param stationId - The Gracenote station ID for the channel.
509
+ */
510
+ export function updateChannelLogo(channelName, stationId) {
511
+ if (!lastKnownDvrHost) {
512
+ return;
513
+ }
514
+ void searchTmsStationLogo(lastKnownDvrHost, channelName, stationId);
515
+ }
395
516
  /**
396
- * Normalizes a logo URL by stripping existing query parameters and adding our sizing parameter.
397
- * @param url - The original logo URL from Channels DVR.
398
- * @returns The normalized URL with height parameter, or undefined if the URL is invalid.
517
+ * Normalizes a logo URL by replacing query parameters with a height-only sizing parameter. The TMS CDN accepts ?h= for image height. This reduces bandwidth by
518
+ * requesting smaller images for UI rendering (48px height for retina) instead of the default 360x270 that the DVR API returns.
519
+ * @param url - The original logo URL from the DVR or TMS API.
520
+ * @returns The URL with query parameters replaced by the height sizing parameter.
399
521
  */
400
522
  function normalizeLogoUrl(url) {
401
523
  try {
402
524
  const parsed = new URL(url);
403
- // Strip existing query parameters and add our sizing.
404
525
  parsed.search = "?h=" + String(LOGO_HEIGHT_PX);
405
526
  return parsed.toString();
406
527
  }
407
528
  catch {
408
- // Invalid URL - return undefined to skip caching.
409
- return undefined;
529
+ return url;
410
530
  }
411
531
  }
412
532
  //# sourceMappingURL=showInfo.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"showInfo.js","sourceRoot":"","sources":["../../src/streaming/showInfo.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"showInfo.js","sourceRoot":"","sources":["../../src/streaming/showInfo.ts"],"names":[],"mappings":"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"}
@@ -10,12 +10,14 @@ export type StreamHealthStatus = "buffering" | "error" | "healthy" | "recovering
10
10
  */
11
11
  export interface StreamStatus {
12
12
  bufferingDuration: Nullable<number>;
13
+ captureCodec: Nullable<string>;
13
14
  channel: Nullable<string>;
14
15
  clientCount: number;
15
16
  clients: ClientTypeCount[];
16
17
  currentTime: number;
17
18
  duration: number;
18
19
  escalationLevel: number;
20
+ hardwareAccelerated: boolean;
19
21
  health: StreamHealthStatus;
20
22
  id: number;
21
23
  lastIssueTime: Nullable<number>;
@@ -23,6 +25,8 @@ export interface StreamStatus {
23
25
  lastRecoveryTime: Nullable<number>;
24
26
  logoUrl: string;
25
27
  memoryBytes: number;
28
+ nativeBandwidth: number;
29
+ nativeResolution: Nullable<string>;
26
30
  networkState: number;
27
31
  pageReloadsInWindow: number;
28
32
  providerName: string;
@@ -62,14 +66,16 @@ export interface StatusSnapshot {
62
66
  /**
63
67
  * Event types emitted by the status emitter.
64
68
  */
65
- export type StatusEventType = "healthChanged" | "snapshot" | "streamAdded" | "streamHealthChanged" | "streamRemoved" | "systemStatusChanged";
69
+ export type StatusEventType = "channelUpdate" | "healthChanged" | "snapshot" | "streamAdded" | "streamHealthChanged" | "streamRemoved" | "systemStatusChanged";
66
70
  /**
67
71
  * Creates the initial StreamStatus object for a new stream. This provides a consistent starting state with all health metrics at their default values.
68
72
  * @param options - The stream initialization options.
69
73
  * @returns The initial stream status.
70
74
  */
71
75
  export declare function createInitialStreamStatus(options: {
76
+ captureCodec?: Nullable<string>;
72
77
  channelName: Nullable<string>;
78
+ hardwareAccelerated?: boolean;
73
79
  numericStreamId: number;
74
80
  providerName: string;
75
81
  startTime: Date;
@@ -119,11 +125,17 @@ export declare function getStreamStatus(streamId: number): StreamStatus | undefi
119
125
  * @param streamId - The ID of the stream to remove.
120
126
  */
121
127
  export declare function removeStreamStatus(streamId: number): void;
128
+ /**
129
+ * Emits a channel table update event. The payload is a partial patch — any combination of rows, counts, scopeCounts, and logos. SSE clients that have the
130
+ * channels tab open apply the patch via applyChannelPatch. Used for server-initiated updates like logo population that have no associated client request.
131
+ * @param patch - The partial channel table patch to emit.
132
+ */
133
+ export declare function emitChannelUpdate(patch: Record<string, unknown>): void;
122
134
  /**
123
135
  * Subscribes a callback to receive all status events. Returns an unsubscribe function.
124
136
  * @param callback - Function to call when a status event is emitted.
125
137
  * @returns A function to unsubscribe the callback.
126
138
  */
127
- export declare function subscribeToStatus(callback: (event: StatusEventType, data: HealthEvent | StreamStatus | SystemStatus | StatusSnapshot | {
139
+ export declare function subscribeToStatus(callback: (event: StatusEventType, data: HealthEvent | Record<string, unknown> | StreamStatus | SystemStatus | StatusSnapshot | {
128
140
  id: number;
129
141
  }) => void): () => void;
@@ -1,5 +1,6 @@
1
1
  import { getHealthSnapshot, subscribeToHealth } from "../config/health.js";
2
- import { EventEmitter } from "events";
2
+ import { CONFIG } from "../config/index.js";
3
+ import { EventEmitter } from "node:events";
3
4
  /* A singleton EventEmitter that broadcasts status updates to all subscribed SSE clients. The emitter maintains current state for all streams, allowing new clients
4
5
  * to receive a snapshot of current status immediately upon connecting.
5
6
  */
@@ -14,12 +15,14 @@ statusEmitter.setMaxListeners(100);
14
15
  export function createInitialStreamStatus(options) {
15
16
  return {
16
17
  bufferingDuration: null,
18
+ captureCodec: options.captureCodec ?? null,
17
19
  channel: options.channelName,
18
20
  clientCount: 0,
19
21
  clients: [],
20
22
  currentTime: 0,
21
23
  duration: 0,
22
24
  escalationLevel: 0,
25
+ hardwareAccelerated: options.hardwareAccelerated ?? false,
23
26
  health: "healthy",
24
27
  id: options.numericStreamId,
25
28
  lastIssueTime: null,
@@ -27,6 +30,8 @@ export function createInitialStreamStatus(options) {
27
30
  lastRecoveryTime: null,
28
31
  logoUrl: "",
29
32
  memoryBytes: 0,
33
+ nativeBandwidth: 0,
34
+ nativeResolution: null,
30
35
  networkState: 0,
31
36
  pageReloadsInWindow: 0,
32
37
  providerName: options.providerName,
@@ -78,9 +83,11 @@ export function emitStreamHealthChanged(status) {
78
83
  * @param status - The updated system status.
79
84
  */
80
85
  export function emitSystemStatusChanged(status) {
81
- // Only emit if something meaningful changed.
86
+ // Only emit if something meaningful changed. The optional chain on the second condition is defensive — TypeScript narrows cachedSystemStatus as non-null after
87
+ // the first comparison, but at runtime the first condition can be truthy with cachedSystemStatus === null (undefined !== true).
82
88
  if ((cachedSystemStatus?.browser.connected !== status.browser.connected) ||
83
- (cachedSystemStatus.streams.active !== status.streams.active)) {
89
+ // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
90
+ (cachedSystemStatus?.streams.active !== status.streams.active)) {
84
91
  cachedSystemStatus = status;
85
92
  statusEmitter.emit("systemStatusChanged", status);
86
93
  }
@@ -103,7 +110,7 @@ export function getStatusSnapshot() {
103
110
  system: cachedSystemStatus ?? {
104
111
  browser: { connected: false, pageCount: 0 },
105
112
  memory: { heapUsed: 0, rss: 0 },
106
- streams: { active: 0, limit: 10 },
113
+ streams: { active: 0, limit: CONFIG.streaming.maxConcurrentStreams },
107
114
  uptime: 0
108
115
  }
109
116
  };
@@ -123,16 +130,26 @@ export function getStreamStatus(streamId) {
123
130
  export function removeStreamStatus(streamId) {
124
131
  streamStatuses.delete(streamId);
125
132
  }
133
+ /**
134
+ * Emits a channel table update event. The payload is a partial patch — any combination of rows, counts, scopeCounts, and logos. SSE clients that have the
135
+ * channels tab open apply the patch via applyChannelPatch. Used for server-initiated updates like logo population that have no associated client request.
136
+ * @param patch - The partial channel table patch to emit.
137
+ */
138
+ export function emitChannelUpdate(patch) {
139
+ statusEmitter.emit("channelUpdate", patch);
140
+ }
126
141
  /**
127
142
  * Subscribes a callback to receive all status events. Returns an unsubscribe function.
128
143
  * @param callback - Function to call when a status event is emitted.
129
144
  * @returns A function to unsubscribe the callback.
130
145
  */
131
146
  export function subscribeToStatus(callback) {
147
+ const channelUpdateHandler = (data) => { callback("channelUpdate", data); };
132
148
  const streamAddedHandler = (data) => { callback("streamAdded", data); };
133
149
  const streamRemovedHandler = (data) => { callback("streamRemoved", data); };
134
150
  const streamHealthChangedHandler = (data) => { callback("streamHealthChanged", data); };
135
151
  const systemStatusChangedHandler = (data) => { callback("systemStatusChanged", data); };
152
+ statusEmitter.on("channelUpdate", channelUpdateHandler);
136
153
  statusEmitter.on("streamAdded", streamAddedHandler);
137
154
  statusEmitter.on("streamRemoved", streamRemovedHandler);
138
155
  statusEmitter.on("streamHealthChanged", streamHealthChangedHandler);
@@ -140,6 +157,7 @@ export function subscribeToStatus(callback) {
140
157
  // Forward health events from the health emitter through the same SSE connection. This avoids a separate SSE endpoint for health updates.
141
158
  const unsubscribeHealth = subscribeToHealth((event) => { callback("healthChanged", event); });
142
159
  return () => {
160
+ statusEmitter.off("channelUpdate", channelUpdateHandler);
143
161
  statusEmitter.off("streamAdded", streamAddedHandler);
144
162
  statusEmitter.off("streamRemoved", streamRemovedHandler);
145
163
  statusEmitter.off("streamHealthChanged", streamHealthChangedHandler);
@@ -1 +1 @@
1
- {"version":3,"file":"statusEmitter.js","sourceRoot":"","sources":["../../src/streaming/statusEmitter.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"statusEmitter.js","sourceRoot":"","sources":["../../src/streaming/statusEmitter.ts"],"names":[],"mappings":"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"}
@@ -1,11 +1,40 @@
1
1
  import type { Nullable } from "./shared.js";
2
+ /**
3
+ * Nested channel definition separating identity from provider affiliation. The authoring format for predefined channels in channels/index.ts. The flattener
4
+ * compiles these into flat Channel entries keyed as "{canonical}" (for the canonical provider) and "{canonical}-{slug}" (for each additional provider).
5
+ */
6
+ export interface ChannelDefinition {
7
+ channelNumber?: number;
8
+ name: string;
9
+ pacificStationId?: string;
10
+ providers: Record<string, ProviderVariant>;
11
+ stationId?: string;
12
+ tvgShift?: number;
13
+ }
14
+ /**
15
+ * A single provider's streaming configuration within a ChannelDefinition. Each provider variant specifies how to reach the channel on that provider's platform.
16
+ * Optional fields override the parent ChannelDefinition's values when this variant is the active provider.
17
+ */
18
+ export interface ProviderVariant {
19
+ channelNumber?: number;
20
+ channelSelector?: string;
21
+ dismissSelector?: string;
22
+ profile?: string;
23
+ provider?: string;
24
+ scrollSelector?: string;
25
+ scrollTarget?: string;
26
+ scrollToBottom?: boolean;
27
+ url: string;
28
+ }
2
29
  /**
3
30
  * Channel definition mapping a short name to a streaming URL with optional configuration overrides.
4
31
  */
5
32
  export interface Channel {
33
+ canonicalKey?: string;
6
34
  channelNumber?: number;
7
35
  channelSelector?: string;
8
36
  dismissSelector?: string;
37
+ hdhrEnabled?: boolean;
9
38
  name?: string;
10
39
  pacificStationId?: string;
11
40
  profile?: string;
@@ -36,6 +65,7 @@ export interface ChannelListingEntry {
36
65
  export interface ChannelDelta {
37
66
  channelNumber?: Nullable<number>;
38
67
  channelSelector?: Nullable<string>;
68
+ hdhrEnabled?: Nullable<boolean>;
39
69
  name?: Nullable<string>;
40
70
  profile?: Nullable<string>;
41
71
  stationId?: Nullable<string>;
@@ -65,5 +95,6 @@ export interface ProviderGroup {
65
95
  variants: {
66
96
  key: string;
67
97
  label: string;
98
+ tag: string;
68
99
  }[];
69
100
  }
@@ -24,7 +24,6 @@ export interface PlaybackConfig {
24
24
  bufferingGracePeriod: number;
25
25
  channelSelectorDelay: number;
26
26
  channelSwitchDelay: number;
27
- clickToPlayDelay: number;
28
27
  iframeInitDelay: number;
29
28
  maxPageReloads: number;
30
29
  monitorInterval: number;
@@ -63,6 +62,7 @@ export interface ChannelsConfig {
63
62
  disabledPredefined: string[];
64
63
  enabledProviders: string[];
65
64
  precacheProviders: string[];
65
+ setupCompleted: boolean;
66
66
  visibleColumns: string[];
67
67
  }
68
68
  /**
@@ -92,7 +92,7 @@ export interface ServerConfig {
92
92
  }
93
93
  /**
94
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.
95
+ * - "ffmpeg": Captures Matroska (H264+Opus) and uses FFmpeg to transcode audio to AAC. More stable for long recordings.
96
96
  * - "native": Captures fMP4 (H264+AAC) directly from Chrome. No dependencies but may be unstable with long recordings.
97
97
  */
98
98
  export type CaptureMode = "ffmpeg" | "native";
@@ -1,5 +1,5 @@
1
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";
2
+ export type { Channel, ChannelDefinition, ChannelDelta, ChannelListingEntry, ChannelMap, ProviderGroup, ProviderVariant, StoredChannel, StoredChannelMap } from "./channels.js";
3
3
  export type { ChannelSelectionConfig, ChannelSelectionStrategy, DomainConfig, ProfileCategory, ProfileResolutionResult, ProfilesValidationResult, ProviderPack, ResolvedSiteProfile, SiteProfile, UserProfilesFile, UserProfilesLoadResult } from "./profiles.js";
4
4
  export type { ChannelSelectionProfile, ChannelSelectorResult, ChannelStrategyEntry, ChannelStrategyHandler, ClickTarget, DiscoveredChannel, ProviderModule, TuneResult, UiSize } from "./selection.js";
5
5
  export type { ChannelSortField, Nullable, SortDirection } from "./shared.js";
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/types/index.ts"],"names":[],"mappings":"AAcA,OAAO,EAAE,yBAAyB,EAAE,MAAM,gBAAgB,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/types/index.ts"],"names":[],"mappings":"AAeA,OAAO,EAAE,yBAAyB,EAAE,MAAM,gBAAgB,CAAC"}