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:
Decobus 2025-07-25 21:29:23 -04:00
parent 07028b0792
commit 3bad71cb26
8 changed files with 603 additions and 116 deletions

View file

@ -63,7 +63,7 @@ function generateOBSSourceName(teamSceneName: string, streamName: string): strin
}
export async function POST(request: NextRequest) {
let name: string, url: string, team_id: number, obs_source_name: string;
let name: string, url: string, team_id: number, obs_source_name: string, lockSources: boolean;
// Parse and validate request body
try {
@ -78,6 +78,7 @@ export async function POST(request: NextRequest) {
}
({ name, url, team_id } = validation.data!);
lockSources = body.lockSources !== false; // Default to true if not specified
} catch {
return NextResponse.json({ error: 'Invalid JSON in request body' }, { status: 400 });
@ -125,7 +126,7 @@ export async function POST(request: NextRequest) {
if (!sourceExists) {
// Create stream group with text overlay
await createStreamGroup(groupName, name, teamInfo.team_name, url);
await createStreamGroup(groupName, name, teamInfo.team_name, url, lockSources);
// Update team with group UUID if not set
if (!teamInfo.group_uuid) {

View file

@ -0,0 +1,62 @@
import { NextResponse } from 'next/server';
import { getOBSClient } from '../../../lib/obsClient';
export async function POST() {
try {
const obsClient = await getOBSClient();
// Check if studio mode is active
const { studioModeEnabled } = await obsClient.call('GetStudioModeEnabled');
if (!studioModeEnabled) {
return NextResponse.json(
{
success: false,
error: 'Studio mode is not enabled',
message: 'Studio mode must be enabled to trigger transitions'
},
{ status: 400 }
);
}
try {
// Trigger the studio mode transition (preview to program)
await obsClient.call('TriggerStudioModeTransition');
console.log('Successfully triggered studio mode transition');
// Get the updated scene information after transition
const [programResponse, previewResponse] = await Promise.all([
obsClient.call('GetCurrentProgramScene'),
obsClient.call('GetCurrentPreviewScene')
]);
return NextResponse.json({
success: true,
data: {
programScene: programResponse.currentProgramSceneName,
previewScene: previewResponse.currentPreviewSceneName
},
message: 'Successfully transitioned preview to program'
});
} catch (obsError) {
console.error('OBS WebSocket error during transition:', obsError);
return NextResponse.json(
{
success: false,
error: 'Failed to trigger transition in OBS',
details: obsError instanceof Error ? obsError.message : 'Unknown error'
},
{ status: 500 }
);
}
} catch (error) {
console.error('Error triggering transition:', error);
return NextResponse.json(
{
success: false,
error: 'Failed to connect to OBS or trigger transition'
},
{ status: 500 }
);
}
}