prismcast 1.7.0 → 1.9.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/README.md +6 -6
- package/dist/app.js +24 -13
- package/dist/app.js.map +1 -1
- package/dist/browser/cdp.d.ts +4 -6
- package/dist/browser/cdp.js +13 -17
- package/dist/browser/cdp.js.map +1 -1
- package/dist/browser/index.js +3 -3
- package/dist/browser/index.js.map +1 -1
- package/dist/browser/login.js +11 -8
- package/dist/browser/login.js.map +1 -1
- package/dist/browser/precaching.d.ts +1 -1
- package/dist/browser/precaching.js +23 -23
- package/dist/browser/precaching.js.map +1 -1
- package/dist/browser/tuning/directv.js +4 -7
- package/dist/browser/tuning/directv.js.map +1 -1
- package/dist/browser/tuning/fox.js +1 -1
- package/dist/browser/tuning/fox.js.map +1 -1
- package/dist/browser/tuning/hbo.js +1 -1
- package/dist/browser/tuning/hbo.js.map +1 -1
- package/dist/browser/tuning/hulu.js +3 -3
- package/dist/browser/tuning/hulu.js.map +1 -1
- package/dist/browser/tuning/sling.js +2 -2
- package/dist/browser/tuning/sling.js.map +1 -1
- package/dist/channels/index.d.ts +2 -0
- package/dist/channels/index.js +438 -252
- package/dist/channels/index.js.map +1 -1
- package/dist/config/health.d.ts +3 -3
- package/dist/config/health.js +13 -18
- package/dist/config/health.js.map +1 -1
- package/dist/config/index.js +11 -2
- package/dist/config/index.js.map +1 -1
- package/dist/config/persistence.d.ts +59 -0
- package/dist/config/persistence.js +127 -0
- package/dist/config/persistence.js.map +1 -0
- package/dist/config/profiles.js +10 -10
- package/dist/config/profiles.js.map +1 -1
- package/dist/config/servicePacks.d.ts +46 -0
- package/dist/config/{providerPacks.js → servicePacks.js} +28 -31
- package/dist/config/servicePacks.js.map +1 -0
- package/dist/config/services.d.ts +202 -0
- package/dist/config/services.js +758 -0
- package/dist/config/services.js.map +1 -0
- package/dist/config/sites.js +61 -61
- package/dist/config/sites.js.map +1 -1
- package/dist/config/userChannels.d.ts +89 -27
- package/dist/config/userChannels.js +400 -184
- package/dist/config/userChannels.js.map +1 -1
- package/dist/config/userConfig.d.ts +13 -9
- package/dist/config/userConfig.js +78 -60
- package/dist/config/userConfig.js.map +1 -1
- package/dist/config/userProfiles.d.ts +31 -15
- package/dist/config/userProfiles.js +154 -123
- package/dist/config/userProfiles.js.map +1 -1
- package/dist/hdhr/channelMap.d.ts +1 -1
- package/dist/hdhr/channelMap.js +4 -7
- package/dist/hdhr/channelMap.js.map +1 -1
- package/dist/hdhr/discover.js +7 -15
- package/dist/hdhr/discover.js.map +1 -1
- package/dist/hdhr/index.js +6 -9
- package/dist/hdhr/index.js.map +1 -1
- package/dist/native/index.d.ts +2 -2
- package/dist/native/index.js +17 -27
- package/dist/native/index.js.map +1 -1
- package/dist/native/intercept.js +86 -89
- package/dist/native/intercept.js.map +1 -1
- package/dist/native/probe.js +2 -2
- package/dist/native/probe.js.map +1 -1
- package/dist/native/proxy.d.ts +2 -2
- package/dist/native/proxy.js +4 -4
- package/dist/native/proxy.js.map +1 -1
- package/dist/routes/assets.js +29 -51
- package/dist/routes/assets.js.map +1 -1
- package/dist/routes/auth.js +3 -3
- package/dist/routes/auth.js.map +1 -1
- package/dist/routes/channels.js +5 -11
- package/dist/routes/channels.js.map +1 -1
- package/dist/routes/components.d.ts +0 -8
- package/dist/routes/components.js +0 -19
- package/dist/routes/components.js.map +1 -1
- package/dist/routes/config/channels/index.d.ts +1 -1
- package/dist/routes/config/channels/index.js +1 -1
- package/dist/routes/config/channels/index.js.map +1 -1
- package/dist/routes/config/channels/routes.js +748 -420
- package/dist/routes/config/channels/routes.js.map +1 -1
- package/dist/routes/config/channels/table.d.ts +21 -6
- package/dist/routes/config/channels/table.js +456 -193
- package/dist/routes/config/channels/table.js.map +1 -1
- package/dist/routes/config/index.d.ts +2 -2
- package/dist/routes/config/index.js +3 -3
- package/dist/routes/config/index.js.map +1 -1
- package/dist/routes/config/{providers.js → services.js} +47 -42
- package/dist/routes/config/services.js.map +1 -0
- package/dist/routes/config/settings.js +88 -49
- package/dist/routes/config/settings.js.map +1 -1
- package/dist/routes/debug.js +5 -7
- package/dist/routes/debug.js.map +1 -1
- package/dist/routes/health.js +1 -1
- package/dist/routes/health.js.map +1 -1
- package/dist/routes/icons.d.ts +16 -0
- package/dist/routes/icons.js +44 -0
- package/dist/routes/icons.js.map +1 -0
- package/dist/routes/index.js +2 -2
- package/dist/routes/index.js.map +1 -1
- package/dist/routes/logs.js +4 -4
- package/dist/routes/logs.js.map +1 -1
- package/dist/routes/playlist.d.ts +6 -4
- package/dist/routes/playlist.js +98 -45
- package/dist/routes/playlist.js.map +1 -1
- package/dist/routes/root/content.js +94 -55
- package/dist/routes/root/content.js.map +1 -1
- package/dist/routes/root/scripts/channels.js +620 -478
- package/dist/routes/root/scripts/channels.js.map +1 -1
- package/dist/routes/root/scripts/config.js +884 -964
- package/dist/routes/root/scripts/config.js.map +1 -1
- package/dist/routes/root/scripts/shared.js +468 -188
- package/dist/routes/root/scripts/shared.js.map +1 -1
- package/dist/routes/root/scripts/status.js +252 -207
- package/dist/routes/root/scripts/status.js.map +1 -1
- package/dist/routes/root/styles.js +57 -8
- package/dist/routes/root/styles.js.map +1 -1
- package/dist/routes/services.d.ts +6 -0
- package/dist/routes/{providers.js → services.js} +43 -43
- package/dist/routes/services.js.map +1 -0
- package/dist/routes/ui.d.ts +1 -1
- package/dist/routes/ui.js +3 -1
- package/dist/routes/ui.js.map +1 -1
- package/dist/service/commands.js +8 -43
- package/dist/service/commands.js.map +1 -1
- package/dist/service/generators.d.ts +1 -1
- package/dist/service/generators.js +143 -41
- package/dist/service/generators.js.map +1 -1
- package/dist/streaming/codec.d.ts +20 -0
- package/dist/streaming/codec.js +68 -0
- package/dist/streaming/codec.js.map +1 -0
- package/dist/streaming/fmp4Segmenter.d.ts +2 -2
- package/dist/streaming/fmp4Segmenter.js.map +1 -1
- package/dist/streaming/hls.d.ts +4 -4
- package/dist/streaming/hls.js +35 -29
- package/dist/streaming/hls.js.map +1 -1
- package/dist/streaming/hlsResume.js +3 -3
- package/dist/streaming/hlsResume.js.map +1 -1
- package/dist/streaming/monitor.d.ts +2 -2
- package/dist/streaming/monitor.js +19 -13
- package/dist/streaming/monitor.js.map +1 -1
- package/dist/streaming/preroll.d.ts +15 -14
- package/dist/streaming/preroll.js +32 -12
- package/dist/streaming/preroll.js.map +1 -1
- package/dist/streaming/registry.d.ts +2 -2
- package/dist/streaming/registry.js +4 -8
- package/dist/streaming/registry.js.map +1 -1
- package/dist/streaming/setup.d.ts +4 -4
- package/dist/streaming/setup.js +28 -34
- package/dist/streaming/setup.js.map +1 -1
- package/dist/streaming/showInfo.js +8 -10
- package/dist/streaming/showInfo.js.map +1 -1
- package/dist/streaming/statusEmitter.d.ts +4 -3
- package/dist/streaming/statusEmitter.js +3 -3
- package/dist/streaming/statusEmitter.js.map +1 -1
- package/dist/types/channels.d.ts +18 -11
- package/dist/types/config.d.ts +3 -2
- package/dist/types/index.d.ts +4 -3
- package/dist/types/index.js +1 -0
- package/dist/types/index.js.map +1 -1
- package/dist/types/profiles.d.ts +9 -9
- package/dist/types/selection.d.ts +1 -1
- package/dist/types/shared.d.ts +1 -1
- package/dist/types/streaming.d.ts +8 -16
- package/dist/types/streaming.js +5 -1
- package/dist/types/streaming.js.map +1 -1
- package/dist/upgrade/commands.js +1 -16
- package/dist/upgrade/commands.js.map +1 -1
- package/dist/utils/chromeFetch.js +1 -1
- package/dist/utils/cliOutput.d.ts +10 -0
- package/dist/utils/cliOutput.js +17 -0
- package/dist/utils/cliOutput.js.map +1 -0
- package/dist/utils/debugFilter.js +3 -3
- package/dist/utils/debugFilter.js.map +1 -1
- package/dist/utils/fileLogger.js +4 -3
- package/dist/utils/fileLogger.js.map +1 -1
- package/dist/utils/format.d.ts +21 -4
- package/dist/utils/format.js +45 -7
- 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/logger.js +17 -27
- package/dist/utils/logger.js.map +1 -1
- package/dist/utils/morganStream.js +2 -2
- package/dist/utils/morganStream.js.map +1 -1
- package/dist/utils/platform.js +3 -2
- package/dist/utils/platform.js.map +1 -1
- package/dist/utils/retry.js +2 -4
- package/dist/utils/retry.js.map +1 -1
- package/dist/utils/streamContext.d.ts +7 -0
- package/dist/utils/streamContext.js +10 -1
- package/dist/utils/streamContext.js.map +1 -1
- package/dist/utils/version.js +4 -4
- package/dist/utils/version.js.map +1 -1
- package/package.json +5 -7
- package/dist/config/providerPacks.d.ts +0 -46
- package/dist/config/providerPacks.js.map +0 -1
- package/dist/config/providers.d.ts +0 -175
- package/dist/config/providers.js +0 -678
- package/dist/config/providers.js.map +0 -1
- package/dist/routes/config/providers.js.map +0 -1
- package/dist/routes/providers.d.ts +0 -6
- package/dist/routes/providers.js.map +0 -1
- /package/dist/routes/config/{providers.d.ts → services.d.ts} +0 -0
package/dist/routes/logs.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"logs.js","sourceRoot":"","sources":["../../src/routes/logs.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,gBAAgB,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AACtE,OAAO,EAAE,MAAM,EAAE,MAAM,oBAAoB,CAAC;AAE5C,OAAO,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"logs.js","sourceRoot":"","sources":["../../src/routes/logs.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { ChannelSortField, SortDirection } from "../types/index.js";
|
|
2
2
|
import type { Express, Request } from "express";
|
|
3
|
-
interface
|
|
3
|
+
interface IncludeExcludeFilter {
|
|
4
4
|
readonly exclude: boolean;
|
|
5
5
|
readonly tags: string[];
|
|
6
6
|
}
|
|
@@ -22,14 +22,16 @@ export declare function resolveBaseUrl(req: Request): string;
|
|
|
22
22
|
* Generates the M3U playlist content for display on the landing page or the playlist endpoint. The playlist includes all configured video channels with their
|
|
23
23
|
* stream URLs dynamically constructed from the provided base URL.
|
|
24
24
|
* @param baseUrl - The base URL to use for stream URLs (e.g., "http://localhost:5589").
|
|
25
|
-
* @param
|
|
26
|
-
* a filter tag are included. In exclude mode, channels whose selected
|
|
25
|
+
* @param serviceFilter - Optional service filter based on the currently selected service for each channel. In include mode, only channels whose selected
|
|
26
|
+
* service matches a filter tag are included. In exclude mode, channels whose selected service matches any filter tag are excluded.
|
|
27
|
+
* @param tagFilter - Optional tag filter based on the channel's effective organizational tags. In include mode, only channels with at least one matching tag are
|
|
28
|
+
* included. In exclude mode, channels with any matching tag are excluded. Tag and service filters compose via intersection.
|
|
27
29
|
* @param sort - Optional sort field override. When provided, channels are sorted by this field instead of the user's saved preference. Validated against
|
|
28
30
|
* VALID_SORT_FIELDS before calling.
|
|
29
31
|
* @param direction - Optional sort direction override ("asc" or "desc"). When provided, overrides the user's saved sort direction.
|
|
30
32
|
* @returns The M3U playlist content.
|
|
31
33
|
*/
|
|
32
|
-
export declare function generatePlaylistContent(baseUrl: string,
|
|
34
|
+
export declare function generatePlaylistContent(baseUrl: string, serviceFilter?: IncludeExcludeFilter, tagFilter?: IncludeExcludeFilter, sort?: ChannelSortField, direction?: SortDirection): string;
|
|
33
35
|
/**
|
|
34
36
|
* Creates the playlist endpoint that serves an M3U playlist in Channels DVR format. The playlist lists all configured channels with their stream URLs, allowing
|
|
35
37
|
* Channels DVR to import them as custom channels. The endpoint dynamically constructs URLs using the request host header so the playlist works regardless of how
|
package/dist/routes/playlist.js
CHANGED
|
@@ -1,17 +1,19 @@
|
|
|
1
|
-
import { VALID_SORT_FIELDS, compareChannelSort,
|
|
1
|
+
import { VALID_SORT_FIELDS, compareChannelSort, getAllServiceTags, getServiceTagForChannel, resolveServiceKey } from "../config/services.js";
|
|
2
|
+
import { getActiveTagVocabulary, getAllChannels, getChannelEffectiveTags, tagsMatch } from "../config/userChannels.js";
|
|
2
3
|
import { CONFIG } from "../config/index.js";
|
|
3
|
-
import {
|
|
4
|
-
import { resolveProfile } from "../config/profiles.js";
|
|
4
|
+
import { getProfileForChannel } from "../config/profiles.js";
|
|
5
5
|
/**
|
|
6
|
-
* Parses and validates
|
|
7
|
-
*
|
|
8
|
-
* @param param - The raw query parameter string (e.g., "
|
|
6
|
+
* Parses and validates an include/exclude filter query parameter. The parameter is a comma-separated list of values with optional `-` prefix for exclusion mode.
|
|
7
|
+
* All values must be either include (no prefix) or exclude (`-` prefix) — mixing is not allowed. Values are case-insensitive and validated against a known set.
|
|
8
|
+
* @param param - The raw query parameter string (e.g., "sports,news" or "-kids").
|
|
9
|
+
* @param entityName - Human-readable name for error messages (e.g., "service tag", "tag").
|
|
10
|
+
* @param knownValues - Array of valid values to validate against.
|
|
9
11
|
* @returns An object with `filter` on success, or `error` with a descriptive message and `validTags` list on failure.
|
|
10
12
|
*/
|
|
11
|
-
function
|
|
13
|
+
function parseIncludeExcludeFilter(param, entityName, knownValues) {
|
|
12
14
|
const tokens = param.split(",").map((t) => t.trim().toLowerCase()).filter((t) => t.length > 0);
|
|
13
15
|
if (tokens.length === 0) {
|
|
14
|
-
return { error: "Empty
|
|
16
|
+
return { error: "Empty " + entityName + " filter.", validTags: [] };
|
|
15
17
|
}
|
|
16
18
|
// Classify tokens as include or exclude based on the `-` prefix.
|
|
17
19
|
const excludeTokens = [];
|
|
@@ -26,18 +28,33 @@ function parseProviderFilter(param) {
|
|
|
26
28
|
}
|
|
27
29
|
// Reject mixed mode — all tokens must be either include or exclude.
|
|
28
30
|
if ((excludeTokens.length > 0) && (includeTokens.length > 0)) {
|
|
29
|
-
return { error: "Cannot mix include and exclude filters. Use either \"
|
|
31
|
+
return { error: "Cannot mix include and exclude " + entityName + " filters. Use either \"a,b\" (include) or \"-a,-b\" (exclude).", validTags: [] };
|
|
30
32
|
}
|
|
31
33
|
const isExclude = excludeTokens.length > 0;
|
|
32
|
-
const
|
|
33
|
-
// Validate all
|
|
34
|
-
const
|
|
35
|
-
const
|
|
36
|
-
const unknownTags = tags.filter((tag) => !knownTags.has(tag));
|
|
34
|
+
const filterTags = isExclude ? excludeTokens : includeTokens;
|
|
35
|
+
// Validate all values against the known set. Tokens are already lowercased, so normalize known values for case-insensitive comparison.
|
|
36
|
+
const knownSet = new Set(knownValues.map((v) => v.toLowerCase()));
|
|
37
|
+
const unknownTags = filterTags.filter((tag) => !knownSet.has(tag));
|
|
37
38
|
if (unknownTags.length > 0) {
|
|
38
|
-
return { error: "Unknown
|
|
39
|
+
return { error: "Unknown " + entityName + "(s): " + unknownTags.join(", ") + ".", validTags: knownValues.sort() };
|
|
39
40
|
}
|
|
40
|
-
return { filter: { exclude: isExclude, tags } };
|
|
41
|
+
return { filter: { exclude: isExclude, tags: filterTags } };
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Parses a service filter by validating against known service tags.
|
|
45
|
+
* @param param - The raw query parameter string (e.g., "yttv,sling" or "-hulu,-sling").
|
|
46
|
+
* @returns An object with `filter` on success, or `error` with a descriptive message and `validTags` list on failure.
|
|
47
|
+
*/
|
|
48
|
+
function parseServiceFilter(param) {
|
|
49
|
+
return parseIncludeExcludeFilter(param, "service tag", getAllServiceTags().map((p) => p.tag));
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Parses a tag filter by validating against the active tag vocabulary.
|
|
53
|
+
* @param param - The raw query parameter string (e.g., "sports,news" or "-kids").
|
|
54
|
+
* @returns An object with `filter` on success, or `error` with a descriptive message and `validTags` list on failure.
|
|
55
|
+
*/
|
|
56
|
+
function parseTagFilter(param) {
|
|
57
|
+
return parseIncludeExcludeFilter(param, "tag", getActiveTagVocabulary());
|
|
41
58
|
}
|
|
42
59
|
/**
|
|
43
60
|
* Resolves the base URL from an incoming request by examining headers in priority order. This ensures that playlist URLs and other generated links use the same
|
|
@@ -67,14 +84,16 @@ export function resolveBaseUrl(req) {
|
|
|
67
84
|
* Generates the M3U playlist content for display on the landing page or the playlist endpoint. The playlist includes all configured video channels with their
|
|
68
85
|
* stream URLs dynamically constructed from the provided base URL.
|
|
69
86
|
* @param baseUrl - The base URL to use for stream URLs (e.g., "http://localhost:5589").
|
|
70
|
-
* @param
|
|
71
|
-
* a filter tag are included. In exclude mode, channels whose selected
|
|
87
|
+
* @param serviceFilter - Optional service filter based on the currently selected service for each channel. In include mode, only channels whose selected
|
|
88
|
+
* service matches a filter tag are included. In exclude mode, channels whose selected service matches any filter tag are excluded.
|
|
89
|
+
* @param tagFilter - Optional tag filter based on the channel's effective organizational tags. In include mode, only channels with at least one matching tag are
|
|
90
|
+
* included. In exclude mode, channels with any matching tag are excluded. Tag and service filters compose via intersection.
|
|
72
91
|
* @param sort - Optional sort field override. When provided, channels are sorted by this field instead of the user's saved preference. Validated against
|
|
73
92
|
* VALID_SORT_FIELDS before calling.
|
|
74
93
|
* @param direction - Optional sort direction override ("asc" or "desc"). When provided, overrides the user's saved sort direction.
|
|
75
94
|
* @returns The M3U playlist content.
|
|
76
95
|
*/
|
|
77
|
-
export function generatePlaylistContent(baseUrl,
|
|
96
|
+
export function generatePlaylistContent(baseUrl, serviceFilter, tagFilter, sort, direction) {
|
|
78
97
|
const channels = getAllChannels();
|
|
79
98
|
const lines = ["#EXTM3U", ""];
|
|
80
99
|
const sortField = sort ?? CONFIG.channels.channelSortField;
|
|
@@ -82,31 +101,54 @@ export function generatePlaylistContent(baseUrl, filter, sort, direction) {
|
|
|
82
101
|
// Sort channel keys using the specified (or saved) sort field and direction. Default is name ascending.
|
|
83
102
|
const channelNames = Object.keys(channels).sort((a, b) => compareChannelSort(channels[a], a, channels[b], b, sortField, sortDir));
|
|
84
103
|
for (const name of channelNames) {
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
const
|
|
89
|
-
const
|
|
90
|
-
|
|
91
|
-
|
|
104
|
+
const channel = channels[name];
|
|
105
|
+
// Apply the service filter if specified.
|
|
106
|
+
if (serviceFilter) {
|
|
107
|
+
const selectedKey = resolveServiceKey(name);
|
|
108
|
+
const selectedTag = getServiceTagForChannel(selectedKey);
|
|
109
|
+
const hasMatch = serviceFilter.tags.includes(selectedTag);
|
|
110
|
+
// In include mode, skip channels whose selected service doesn't match any filter tag. In exclude mode, skip channels whose selected service matches.
|
|
111
|
+
if (serviceFilter.exclude ? hasMatch : !hasMatch) {
|
|
92
112
|
continue;
|
|
93
113
|
}
|
|
94
114
|
}
|
|
95
|
-
|
|
96
|
-
//
|
|
97
|
-
const
|
|
98
|
-
if (
|
|
99
|
-
|
|
115
|
+
// Compute effective tags once per channel — used for both the tag filter check and M3U attribute generation. Tags are intersected with the active vocabulary
|
|
116
|
+
// so deleted tags are invisible.
|
|
117
|
+
const effectiveTags = getChannelEffectiveTags(channel);
|
|
118
|
+
// Apply the tag filter if specified. Filter tags are lowercase (normalized by parseIncludeExcludeFilter), so compare case-insensitively.
|
|
119
|
+
if (tagFilter) {
|
|
120
|
+
const hasMatch = tagFilter.tags.some((filterTag) => effectiveTags.some((t) => tagsMatch(t, filterTag)));
|
|
121
|
+
// In include mode, skip channels that don't have any matching tag. In exclude mode, skip channels that have a matching tag.
|
|
122
|
+
if (tagFilter.exclude ? hasMatch : !hasMatch) {
|
|
123
|
+
continue;
|
|
124
|
+
}
|
|
100
125
|
}
|
|
101
|
-
// We use the channel key as the channel-id and the
|
|
102
|
-
const displayName = channel.name ?? name;
|
|
126
|
+
// We use the channel key as the channel-id and the guide title (falling back to channel name) for display. HLS URLs are used for Channels DVR compatibility.
|
|
127
|
+
const displayName = channel.guideTitle ?? channel.name ?? name;
|
|
103
128
|
const streamUrl = baseUrl + "/hls/" + name + "/stream.m3u8";
|
|
104
129
|
// Build the EXTINF line with required channel-id attribute and tvg-name for the friendly display name. Include channel-number when the user has specified one,
|
|
105
|
-
// tvc-guide-stationid for Gracenote guide data when a stationId is defined,
|
|
130
|
+
// tvc-guide-stationid for Gracenote guide data when a stationId is defined, tvg-shift for EPG time offset, tvg-logo for custom channel logos, and group-title
|
|
131
|
+
// for organizational tags (semicolon-delimited for IPTV middleware compatibility).
|
|
106
132
|
const channelNumberAttr = channel.channelNumber ? " channel-number=\"" + String(channel.channelNumber) + "\"" : "";
|
|
133
|
+
const groupTitleAttr = (effectiveTags.length > 0) ? " group-title=\"" + effectiveTags.join(";") + "\"" : "";
|
|
134
|
+
const logoAttr = channel.logoUrl ? " tvg-logo=\"" + channel.logoUrl + "\"" : "";
|
|
107
135
|
const stationIdAttr = channel.stationId ? " tvc-guide-stationid=\"" + channel.stationId + "\"" : "";
|
|
108
136
|
const tvgShiftAttr = (channel.tvgShift !== undefined) ? " tvg-shift=\"" + String(channel.tvgShift) + "\"" : "";
|
|
109
|
-
|
|
137
|
+
// For channels without EPG data, emit tvc-guide-tags so Channels DVR's Automatic Channels can filter on them. Static page channels also get
|
|
138
|
+
// tvc-guide-placeholders to provide a 24-hour guide block since they display persistent content without time-based programming.
|
|
139
|
+
let tvcTagsAttr = "";
|
|
140
|
+
let tvcPlaceholdersAttr = "";
|
|
141
|
+
if (!channel.stationId) {
|
|
142
|
+
if (effectiveTags.length > 0) {
|
|
143
|
+
tvcTagsAttr = " tvc-guide-tags=\"" + effectiveTags.join(", ") + "\"";
|
|
144
|
+
}
|
|
145
|
+
const { profile } = getProfileForChannel(channel);
|
|
146
|
+
if (profile.staticCapture) {
|
|
147
|
+
tvcPlaceholdersAttr = " tvc-guide-placeholders=\"86400\"";
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
const attrs = "#EXTINF:-1 channel-id=\"" + name + "\"" + channelNumberAttr + groupTitleAttr + logoAttr + " tvg-name=\"" + displayName + "\"" + stationIdAttr +
|
|
151
|
+
tvcPlaceholdersAttr + tvcTagsAttr + tvgShiftAttr;
|
|
110
152
|
const extinfLine = attrs + "," + displayName;
|
|
111
153
|
lines.push(extinfLine);
|
|
112
154
|
lines.push(streamUrl);
|
|
@@ -123,26 +165,37 @@ const VALID_SORT_DIRECTIONS = new Set(["asc", "desc"]);
|
|
|
123
165
|
* @param app - The Express application.
|
|
124
166
|
*/
|
|
125
167
|
export function setupPlaylistEndpoint(app) {
|
|
126
|
-
// GET /playlist - Returns the M3U playlist file. Supports optional query parameters: ?
|
|
127
|
-
// override, and ?direction= for sort direction override.
|
|
168
|
+
// GET /playlist - Returns the M3U playlist file. Supports optional query parameters: ?service= for filtering by streaming service, ?tag= for filtering by
|
|
169
|
+
// organizational tags, ?sort= for sort field override, and ?direction= for sort direction override.
|
|
128
170
|
app.get("/playlist", (req, res) => {
|
|
129
171
|
const baseUrl = resolveBaseUrl(req);
|
|
130
|
-
const
|
|
172
|
+
const serviceParam = typeof req.query.service === "string" ? req.query.service.trim() : undefined;
|
|
173
|
+
const tagParam = typeof req.query.tag === "string" ? req.query.tag.trim() : undefined;
|
|
131
174
|
const sortParam = typeof req.query.sort === "string" ? req.query.sort.trim() || undefined : undefined;
|
|
132
175
|
const directionParam = typeof req.query.direction === "string" ? req.query.direction.trim().toLowerCase() || undefined : undefined;
|
|
133
|
-
let
|
|
134
|
-
|
|
135
|
-
if
|
|
136
|
-
|
|
176
|
+
let serviceFilter;
|
|
177
|
+
let tagFilter;
|
|
178
|
+
// Parse and validate the service filter if specified.
|
|
179
|
+
if (serviceParam) {
|
|
180
|
+
const result = parseServiceFilter(serviceParam);
|
|
181
|
+
if ("error" in result) {
|
|
182
|
+
res.status(400).json({ error: result.error, validTags: result.validTags });
|
|
183
|
+
return;
|
|
184
|
+
}
|
|
185
|
+
serviceFilter = result.filter;
|
|
186
|
+
}
|
|
187
|
+
// Parse and validate the tag filter if specified.
|
|
188
|
+
if (tagParam) {
|
|
189
|
+
const result = parseTagFilter(tagParam);
|
|
137
190
|
if ("error" in result) {
|
|
138
191
|
res.status(400).json({ error: result.error, validTags: result.validTags });
|
|
139
192
|
return;
|
|
140
193
|
}
|
|
141
|
-
|
|
194
|
+
tagFilter = result.filter;
|
|
142
195
|
}
|
|
143
196
|
// Validate the sort field if specified.
|
|
144
197
|
if (sortParam && !VALID_SORT_FIELDS.has(sortParam)) {
|
|
145
|
-
res.status(400).json({ error: "Invalid sort field: " + sortParam + ".", validFields: [...VALID_SORT_FIELDS].
|
|
198
|
+
res.status(400).json({ error: "Invalid sort field: " + sortParam + ".", validFields: [...VALID_SORT_FIELDS].toSorted() });
|
|
146
199
|
return;
|
|
147
200
|
}
|
|
148
201
|
// Validate the sort direction if specified.
|
|
@@ -152,7 +205,7 @@ export function setupPlaylistEndpoint(app) {
|
|
|
152
205
|
}
|
|
153
206
|
const sort = sortParam;
|
|
154
207
|
const direction = directionParam;
|
|
155
|
-
const playlist = generatePlaylistContent(baseUrl,
|
|
208
|
+
const playlist = generatePlaylistContent(baseUrl, serviceFilter, tagFilter, sort, direction);
|
|
156
209
|
res.set("Content-Type", "audio/x-mpegurl");
|
|
157
210
|
res.send(playlist);
|
|
158
211
|
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"playlist.js","sourceRoot":"","sources":["../../src/routes/playlist.ts"],"names":[],"mappings":"AAMA,OAAO,EAAE,iBAAiB,EAAE,kBAAkB,EAAE,
|
|
1
|
+
{"version":3,"file":"playlist.js","sourceRoot":"","sources":["../../src/routes/playlist.ts"],"names":[],"mappings":"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"}
|