Add comprehensive studio mode support and stream organization
- Implement studio mode transition workflow with Go Live buttons - Add collapsible team grouping for better stream organization - Include source locking functionality for newly created streams - Enhance footer status indicators with improved visual styling - Create triggerTransition API endpoint for studio mode operations - Add CollapsibleGroup component for expandable content sections 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
parent
07028b0792
commit
3bad71cb26
8 changed files with 603 additions and 116 deletions
|
@ -363,7 +363,7 @@ async function createTextSource(sceneName, textSourceName, text) {
|
|||
}
|
||||
}
|
||||
|
||||
async function createStreamGroup(groupName, streamName, teamName, url) {
|
||||
async function createStreamGroup(groupName, streamName, teamName, url, lockSources = true) {
|
||||
try {
|
||||
const obsClient = await getOBSClient();
|
||||
|
||||
|
@ -443,14 +443,48 @@ async function createStreamGroup(groupName, streamName, teamName, url) {
|
|||
} catch (muteError) {
|
||||
console.error(`Failed to mute browser source audio for "${sourceName}":`, muteError.message);
|
||||
}
|
||||
|
||||
// Lock the newly created browser source if requested
|
||||
if (lockSources) {
|
||||
try {
|
||||
// Get the scene items to find the browser source's ID
|
||||
const { sceneItems } = await obsClient.call('GetSceneItemList', { sceneName: streamGroupName });
|
||||
const browserItem = sceneItems.find(item => item.sourceName === sourceName);
|
||||
|
||||
if (browserItem) {
|
||||
await obsClient.call('SetSceneItemLocked', {
|
||||
sceneName: streamGroupName,
|
||||
sceneItemId: browserItem.sceneItemId,
|
||||
sceneItemLocked: true
|
||||
});
|
||||
console.log(`Locked browser source "${sourceName}" in nested scene`);
|
||||
}
|
||||
} catch (lockError) {
|
||||
console.error(`Failed to lock browser source "${sourceName}":`, lockError.message);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// Add existing source to nested scene
|
||||
await obsClient.call('CreateSceneItem', {
|
||||
const { sceneItemId } = await obsClient.call('CreateSceneItem', {
|
||||
sceneName: streamGroupName,
|
||||
sourceName: sourceName
|
||||
});
|
||||
console.log(`Added existing browser source "${sourceName}" to nested scene`);
|
||||
|
||||
// Lock the scene item if requested
|
||||
if (lockSources) {
|
||||
try {
|
||||
await obsClient.call('SetSceneItemLocked', {
|
||||
sceneName: streamGroupName,
|
||||
sceneItemId: sceneItemId,
|
||||
sceneItemLocked: true
|
||||
});
|
||||
console.log(`Locked browser source "${sourceName}" in nested scene`);
|
||||
} catch (lockError) {
|
||||
console.error(`Failed to lock browser source "${sourceName}":`, lockError.message);
|
||||
}
|
||||
}
|
||||
|
||||
// Ensure existing browser source has audio control enabled and correct URL
|
||||
try {
|
||||
await obsClient.call('SetInputSettings', {
|
||||
|
@ -482,21 +516,49 @@ async function createStreamGroup(groupName, streamName, teamName, url) {
|
|||
const colorSourceName = `${textSourceName}_bg`;
|
||||
|
||||
try {
|
||||
await obsClient.call('CreateSceneItem', {
|
||||
const { sceneItemId: colorItemId } = await obsClient.call('CreateSceneItem', {
|
||||
sceneName: streamGroupName,
|
||||
sourceName: colorSourceName
|
||||
});
|
||||
console.log(`Added color source background "${colorSourceName}" to nested scene`);
|
||||
|
||||
// Lock the color source if requested
|
||||
if (lockSources) {
|
||||
try {
|
||||
await obsClient.call('SetSceneItemLocked', {
|
||||
sceneName: streamGroupName,
|
||||
sceneItemId: colorItemId,
|
||||
sceneItemLocked: true
|
||||
});
|
||||
console.log(`Locked color source background "${colorSourceName}"`);
|
||||
} catch (lockError) {
|
||||
console.error(`Failed to lock color source:`, lockError.message);
|
||||
}
|
||||
}
|
||||
} catch (error) {
|
||||
console.log('Color source background might already be in nested scene');
|
||||
}
|
||||
|
||||
try {
|
||||
await obsClient.call('CreateSceneItem', {
|
||||
const { sceneItemId: textItemId } = await obsClient.call('CreateSceneItem', {
|
||||
sceneName: streamGroupName,
|
||||
sourceName: textSourceName
|
||||
});
|
||||
console.log(`Added text source "${textSourceName}" to nested scene`);
|
||||
|
||||
// Lock the text source if requested
|
||||
if (lockSources) {
|
||||
try {
|
||||
await obsClient.call('SetSceneItemLocked', {
|
||||
sceneName: streamGroupName,
|
||||
sceneItemId: textItemId,
|
||||
sceneItemLocked: true
|
||||
});
|
||||
console.log(`Locked text source "${textSourceName}"`);
|
||||
} catch (lockError) {
|
||||
console.error(`Failed to lock text source:`, lockError.message);
|
||||
}
|
||||
}
|
||||
} catch (error) {
|
||||
console.log('Text source might already be in nested scene');
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue