Fix browser source audio control for individual stream management
All checks were successful
Lint and Build / build (pull_request) Successful in 2m50s

- Enable "Control audio via OBS" checkbox on browser sources using reroute_audio: true
- Remove redundant separate audio capture sources (_audio suffixed sources)
- Browser sources now properly route audio through OBS for individual mute/unmute control
- Preserve URL settings in all SetInputSettings calls to prevent URL clearing
- Simplify audio management - no more duplicate audio sources cluttering OBS

This allows users to mute/unmute individual Twitch streams directly in OBS without
having to manually mute each stream in the browser or deal with separate audio sources.

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
Decobus 2025-07-22 18:03:56 -04:00
parent 612be2b227
commit a89493b89f

View file

@ -392,6 +392,8 @@ 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,
@ -400,20 +402,46 @@ async function createStreamGroup(groupName, streamName, teamName, url) {
width: 1920,
height: 1080,
url,
control_audio: true,
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
},
});
console.log(`Created browser source "${sourceName}" in nested scene`);
console.log(`Created browser source "${sourceName}" in nested scene with URL: ${url}`);
// Mute the audio stream for the browser source
// 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)
try {
await obsClient.call('SetInputMute', {
inputName: sourceName,
inputMuted: true
});
console.log(`Muted audio for browser source "${sourceName}"`);
console.log(`Muted browser source audio for "${sourceName}" (can be unmuted in OBS for individual control)`);
} catch (muteError) {
console.error(`Failed to mute audio for "${sourceName}":`, muteError.message);
console.error(`Failed to mute browser source audio for "${sourceName}":`, muteError.message);
}
} else {
// Add existing source to nested scene
@ -421,16 +449,32 @@ async function createStreamGroup(groupName, streamName, teamName, url) {
sceneName: streamGroupName,
sourceName: sourceName
});
console.log(`Added existing browser source "${sourceName}" to nested scene`);
// Ensure audio is muted for existing source too
// Ensure existing browser source has audio control enabled and correct URL
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(`Ensured audio is muted for existing browser source "${sourceName}"`);
} catch (muteError) {
console.error(`Failed to mute audio for existing source "${sourceName}":`, muteError.message);
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);
}
}
@ -614,7 +658,7 @@ async function deleteStreamComponents(streamName, teamName, groupName) {
console.log(`Nested scene "${streamGroupName}" not found:`, error.message);
}
// 3. Remove the browser source (if it's not used elsewhere)
// 3. Remove the browser source
try {
const { inputs } = await obsClient.call('GetInputList');
const browserSource = inputs.find(input => input.inputName === sourceName);