Skip to content

Commit a2e8684

Browse files
authored
feat(ui): dynamically adapt MoQ URL based on selected pipeline (#13)
1 parent 4e05b01 commit a2e8684

File tree

2 files changed

+98
-1
lines changed

2 files changed

+98
-1
lines changed

ui/src/utils/moqPeerSettings.ts

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
// SPDX-FileCopyrightText: © 2025 StreamKit Contributors
2+
//
3+
// SPDX-License-Identifier: MPL-2.0
4+
5+
import { load } from 'js-yaml';
6+
7+
export interface MoqPeerSettings {
8+
gatewayPath?: string;
9+
inputBroadcast?: string;
10+
outputBroadcast?: string;
11+
}
12+
13+
type ParsedNode = {
14+
kind?: string;
15+
params?: {
16+
gateway_path?: string;
17+
input_broadcast?: string;
18+
output_broadcast?: string;
19+
};
20+
};
21+
22+
type ParsedYaml = {
23+
nodes?: Record<string, ParsedNode>;
24+
};
25+
26+
/**
27+
* Extracts moq_peer settings from a pipeline YAML string.
28+
* Looks for any node with kind 'transport::moq::peer' and returns its
29+
* gateway_path, input_broadcast, and output_broadcast parameters.
30+
*
31+
* @param yamlContent - The YAML string to parse
32+
* @returns MoqPeerSettings if a moq_peer node is found, null otherwise
33+
*/
34+
export function extractMoqPeerSettings(yamlContent: string): MoqPeerSettings | null {
35+
try {
36+
const parsed = load(yamlContent) as ParsedYaml;
37+
38+
if (!parsed || typeof parsed !== 'object' || !parsed.nodes) {
39+
return null;
40+
}
41+
42+
// Find the first node with kind 'transport::moq::peer'
43+
for (const nodeConfig of Object.values(parsed.nodes)) {
44+
if (nodeConfig.kind === 'transport::moq::peer' && nodeConfig.params) {
45+
return {
46+
gatewayPath: nodeConfig.params.gateway_path,
47+
inputBroadcast: nodeConfig.params.input_broadcast,
48+
outputBroadcast: nodeConfig.params.output_broadcast,
49+
};
50+
}
51+
}
52+
53+
return null;
54+
} catch {
55+
return null;
56+
}
57+
}
58+
59+
/**
60+
* Updates a URL's path with a new path while preserving the protocol, host, and port.
61+
*
62+
* @param baseUrl - The original URL string
63+
* @param newPath - The new path to set
64+
* @returns The updated URL string, or the original if parsing fails
65+
*/
66+
export function updateUrlPath(baseUrl: string, newPath: string): string {
67+
try {
68+
const url = new URL(baseUrl);
69+
url.pathname = newPath;
70+
return url.toString();
71+
} catch {
72+
// If URL parsing fails, try a simple path replacement
73+
// Handle URLs like "https://example.com:4545/moq" -> "https://example.com:4545/moq/transcoder"
74+
const match = baseUrl.match(/^(https?:\/\/[^/]+)(\/.*)?$/);
75+
if (match) {
76+
return match[1] + newPath;
77+
}
78+
return baseUrl;
79+
}
80+
}

ui/src/views/StreamView.tsx

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ import { createSession } from '@/services/sessions';
1717
import { useSchemaStore, ensureSchemasLoaded } from '@/stores/schemaStore';
1818
import type { Event } from '@/types/types';
1919
import { getLogger } from '@/utils/logger';
20+
import { extractMoqPeerSettings, updateUrlPath } from '@/utils/moqPeerSettings';
2021
import { orderSamplePipelinesSystemFirst } from '@/utils/samplePipelineOrdering';
2122

2223
import { useStreamStore } from '../stores/streamStore';
@@ -505,9 +506,25 @@ const StreamView: React.FC = () => {
505506
if (template) {
506507
viewState.setSelectedTemplateId(templateId);
507508
viewState.setPipelineYaml(template.yaml);
509+
510+
// Auto-adjust connection settings based on moq_peer node in the pipeline
511+
const moqSettings = extractMoqPeerSettings(template.yaml);
512+
if (moqSettings) {
513+
// Update gateway URL path if specified
514+
if (moqSettings.gatewayPath && serverUrl) {
515+
setServerUrl(updateUrlPath(serverUrl, moqSettings.gatewayPath));
516+
}
517+
// Update broadcast names if specified
518+
if (moqSettings.inputBroadcast) {
519+
setInputBroadcast(moqSettings.inputBroadcast);
520+
}
521+
if (moqSettings.outputBroadcast) {
522+
setOutputBroadcast(moqSettings.outputBroadcast);
523+
}
524+
}
508525
}
509526
},
510-
[viewState]
527+
[viewState, serverUrl, setServerUrl, setInputBroadcast, setOutputBroadcast]
511528
);
512529

513530
// Handle session creation

0 commit comments

Comments
 (0)