diff --git a/app/api/verifyGroups/route.ts b/app/api/verifyGroups/route.ts index d62aa94..1ed5515 100644 --- a/app/api/verifyGroups/route.ts +++ b/app/api/verifyGroups/route.ts @@ -27,14 +27,9 @@ interface GetSceneListResponse { export async function GET() { try { - // Get teams and streams from database + // Get teams from database const db = await getDatabase(); const teams = await db.all(`SELECT team_id, team_name, group_name, group_uuid FROM ${TABLE_NAMES.TEAMS} WHERE group_name IS NOT NULL OR group_uuid IS NOT NULL`); - const streams = await db.all(` - SELECT s.*, t.team_name, t.group_name as team_group_name - FROM ${TABLE_NAMES.STREAMS} s - LEFT JOIN ${TABLE_NAMES.TEAMS} t ON s.team_id = t.team_id - `); // Get scenes (groups) from OBS const obs = await getOBSClient(); @@ -42,11 +37,6 @@ export async function GET() { const obsData = response as GetSceneListResponse; const obsScenes = obsData.scenes; - // Helper function to clean OBS names (matching obsClient.js logic) - const cleanObsName = (name: string): string => { - return name.toLowerCase().replace(/\s+/g, '_'); - }; - // Compare database groups with OBS scenes using both UUID and name const verification = teams.map(team => { let exists_in_obs = false; @@ -85,42 +75,17 @@ export async function GET() { }; }); - // Generate expected stream scene names based on the database - const expectedStreamScenes = streams.map(stream => { - if (stream.team_group_name) { - const cleanGroupName = cleanObsName(stream.team_group_name); - const cleanStreamName = cleanObsName(stream.name); - return `${cleanGroupName}_${cleanStreamName}_stream`; - } - return null; - }).filter(Boolean); - - // Check for orphaned scenes - scenes that exist in OBS but aren't in our database - const orphanedScenes = obsScenes.filter(scene => { - // Check if it's a team scene - const isTeamScene = teams.some(team => - team.group_uuid === scene.sceneUuid || team.group_name === scene.sceneName - ); - - // Check if it's an expected stream scene - const isStreamScene = expectedStreamScenes.includes(scene.sceneName); - - // Check if it's a system scene - const isSystemScene = SYSTEM_SCENES.includes(scene.sceneName); - - // It's orphaned if it's none of the above - return !isTeamScene && !isStreamScene && !isSystemScene; - }); - return NextResponse.json({ success: true, data: { teams_with_groups: verification, obs_scenes: obsScenes.map(s => ({ name: s.sceneName, uuid: s.sceneUuid })), - expected_stream_scenes: expectedStreamScenes, missing_in_obs: verification.filter(team => !team.exists_in_obs), name_mismatches: verification.filter(team => team.name_changed), - orphaned_in_obs: orphanedScenes.map(s => ({ name: s.sceneName, uuid: s.sceneUuid })) + orphaned_in_obs: obsScenes.filter(scene => + !teams.some(team => team.group_uuid === scene.sceneUuid || team.group_name === scene.sceneName) && + !SYSTEM_SCENES.includes(scene.sceneName) + ).map(s => ({ name: s.sceneName, uuid: s.sceneUuid })) } }); diff --git a/components/Footer.tsx b/components/Footer.tsx index edbcb26..9d2e03c 100644 --- a/components/Footer.tsx +++ b/components/Footer.tsx @@ -81,10 +81,10 @@ export default function Footer() {
{/* Connection Status */}
-
-

OBS Studio

-
-
+
+
+
+

OBS Studio

{obsStatus?.connected ? 'Connected' : 'Disconnected'}

diff --git a/lib/obsClient.js b/lib/obsClient.js index 1232244..26dfbe4 100644 --- a/lib/obsClient.js +++ b/lib/obsClient.js @@ -392,8 +392,6 @@ async function createStreamGroup(groupName, streamName, teamName, url) { const browserSourceExists = inputs.some(input => input.inputName === sourceName); if (!browserSourceExists) { - // Create browser source with detailed audio control settings - console.log(`Creating browser source "${sourceName}" with URL: ${url}`); await obsClient.call('CreateInput', { sceneName: streamGroupName, // Create in the nested scene inputName: sourceName, @@ -402,46 +400,20 @@ async function createStreamGroup(groupName, streamName, teamName, url) { width: 1920, height: 1080, url, - control_audio: true, // Enable audio control so OBS can mute the browser source - restart_when_active: false, - shutdown: false, - // Try additional audio-related settings - reroute_audio: true, - audio_monitoring_type: 0 // Monitor Off + control_audio: true, }, }); - console.log(`Created browser source "${sourceName}" in nested scene with URL: ${url}`); + console.log(`Created browser source "${sourceName}" in nested scene`); - // Apply additional settings after creation to ensure they stick - try { - await obsClient.call('SetInputSettings', { - inputName: sourceName, - inputSettings: { - width: 1920, - height: 1080, - url, // Make sure URL is preserved - control_audio: true, - reroute_audio: true, - restart_when_active: false, - shutdown: false, - audio_monitoring_type: 0 - }, - overlay: false // Don't overlay, replace all settings - }); - console.log(`Applied complete settings to "${sourceName}" with URL: ${url}`); - } catch (settingsError) { - console.error(`Failed to apply settings to "${sourceName}":`, settingsError.message); - } - - // Mute the browser source audio by default (can be unmuted individually in OBS) + // Mute the audio stream for the browser source try { await obsClient.call('SetInputMute', { inputName: sourceName, inputMuted: true }); - console.log(`Muted browser source audio for "${sourceName}" (can be unmuted in OBS for individual control)`); + console.log(`Muted audio for browser source "${sourceName}"`); } catch (muteError) { - console.error(`Failed to mute browser source audio for "${sourceName}":`, muteError.message); + console.error(`Failed to mute audio for "${sourceName}":`, muteError.message); } } else { // Add existing source to nested scene @@ -449,32 +421,16 @@ async function createStreamGroup(groupName, streamName, teamName, url) { sceneName: streamGroupName, sourceName: sourceName }); - console.log(`Added existing browser source "${sourceName}" to nested scene`); - // Ensure existing browser source has audio control enabled and correct URL + // Ensure audio is muted for existing source too try { - await obsClient.call('SetInputSettings', { - inputName: sourceName, - inputSettings: { - width: 1920, - height: 1080, - url, // Update URL in case it changed - control_audio: true, - reroute_audio: true, - restart_when_active: false, - shutdown: false, - audio_monitoring_type: 0 - }, - overlay: false // Replace settings, don't overlay - }); - await obsClient.call('SetInputMute', { inputName: sourceName, inputMuted: true }); - console.log(`Updated existing browser source "${sourceName}" with URL: ${url} and enabled audio control`); - } catch (settingsError) { - console.error(`Failed to update settings for existing source "${sourceName}":`, settingsError.message); + console.log(`Ensured audio is muted for existing browser source "${sourceName}"`); + } catch (muteError) { + console.error(`Failed to mute audio for existing source "${sourceName}":`, muteError.message); } } @@ -658,7 +614,7 @@ async function deleteStreamComponents(streamName, teamName, groupName) { console.log(`Nested scene "${streamGroupName}" not found:`, error.message); } - // 3. Remove the browser source + // 3. Remove the browser source (if it's not used elsewhere) try { const { inputs } = await obsClient.call('GetInputList'); const browserSource = inputs.find(input => input.inputName === sourceName);