diff --git a/app/components-react/root/StartStreamingButton.tsx b/app/components-react/root/StartStreamingButton.tsx index 0b15371f1524..00d2ae6a4f25 100644 --- a/app/components-react/root/StartStreamingButton.tsx +++ b/app/components-react/root/StartStreamingButton.tsx @@ -203,6 +203,11 @@ function StartStreamingButton(p: { disabled?: boolean }) { if (!primaryPlatform) return false; + // In unprotected mode, only a Twitch ingest url can show the Go Live window. This is for legacy reasons. + if (!StreamSettingsService.state.protectedModeEnabled) { + return isTwitchUnprotectedStream && updateStreamInfoOnLive; + } + if (streamShiftStatus === 'pending') { return true; } @@ -219,21 +224,10 @@ function StartStreamingButton(p: { disabled?: boolean }) { return true; } - // For Twitch, there are two cases to check for the ability to show the Go Live window: - // 1. In protected mode: when Twitch is the primary platform - // 2. In unprotected mode: when the ingest url is for Twitch. The unprotected mode behavior for Twitch is for legacy reasons - if ( - (StreamSettingsService.state.protectedModeEnabled && primaryPlatform === 'twitch') || - isTwitchUnprotectedStream - ) { - // For Twitch, we can show the Go Live window even with protected mode off - // This is mainly for legacy reasons. + if (primaryPlatform === 'twitch') { return isMultiplatformMode || updateStreamInfoOnLive; } else { - return ( - StreamSettingsService.state.protectedModeEnabled && - StreamSettingsService.isSafeToModifyStreamKey() - ); + return StreamSettingsService.isSafeToModifyStreamKey(); } }, [ primaryPlatform, diff --git a/app/services/streaming/stream-destination.ts b/app/services/streaming/stream-destination.ts index ee9fdfaa65a6..2f643509c80c 100644 --- a/app/services/streaming/stream-destination.ts +++ b/app/services/streaming/stream-destination.ts @@ -15,6 +15,7 @@ export function isCommonTwitchService(destination: IStreamDestination): boolean export function isTwitchStreamDestination(destination: IStreamDestination): boolean { if (destination.streamType === 'rtmp_common') return isCommonTwitchService(destination); if (destination.streamType !== 'rtmp_custom' || !destination.server) return false; + if (destination.server.trim().toLowerCase() === 'auto') return true; try { // Electron's browser URL parser treats RTMP URLs as opaque and has no hostname. diff --git a/app/services/streaming/streaming-view.ts b/app/services/streaming/streaming-view.ts index 45c636395c97..8df1e8d999cc 100644 --- a/app/services/streaming/streaming-view.ts +++ b/app/services/streaming/streaming-view.ts @@ -188,7 +188,7 @@ export class StreamInfoView extends ViewHandler { return ( !this.protectedModeEnabled && this.userView.isLoggedIn && - this.isPrimaryPlatform('twitch') && + this.isPlatformLinked('twitch') && isTwitchStreamDestination(this.streamSettingsView.settings) ); } @@ -1165,9 +1165,6 @@ export class StreamInfoView extends ViewHandler { } get showFeatureToggleCards() { - if (!this.incrementalRolloutView.featureIsEnabled(EAvailableFeatures.liveOutputEditing)) { - return false; - } - return !this.isMidStreamMode; + return this.protectedModeEnabled && !this.isMidStreamMode; } } diff --git a/test/regular/settings/streaming.ts b/test/regular/settings/streaming.ts index 4ad4d2d79843..36453a4152a9 100644 --- a/test/regular/settings/streaming.ts +++ b/test/regular/settings/streaming.ts @@ -43,26 +43,41 @@ test('Populates stream settings after go live', withUser('twitch'), async t => { ); await stopStream(); - // Validate that the stream key persists when switching types and back to recommended settings await showSettingsWindow('Stream', async () => { + // Validate that the stream key resets when switching from Streaming Services to Custom Streaming Server await fillForm({ streamType: 'Streaming Services' }); await waitForDisplayed('label=Service'); const fields2 = (await readFields()) as Record; - t.is(fields2.key, key, 'Stream key should persist when switching types'); + t.is( + fields2.key, + '', + 'Stream key should reset when switching from Streaming Services to Custom Streaming Server', + ); + await fillForm({ key }); - // Switch back to Custom Streaming Server type and validate that the stream key is still present + // Validate that the stream key persists when switching from Streaming Services to Custom Streaming Server await fillForm({ streamType: 'Custom Streaming Server' }); await waitForDisplayed('label=URL'); const fields3 = (await readFields()) as Record; t.is( fields3.key, key, - 'Stream key should persist when switching back to Custom Streaming Server type', + 'Stream key should persist when switching from Streaming Services to Custom Streaming Server', ); + // Can switch back to recommended settings, which will restore protected mode + await clickButton('Use recommended settings'); + await waitForDisplayed('a=Stream to custom ingest', { + timeout: 5000, + timeoutMsg: 'Switched back to protected mode', + }); + await clickButton('Close'); }); + await goLive(); + await stopStream(); + // TODO: Validate non-Twitch target // await showSettingsWindow('Stream', async () => { // await fillForm({ streamType: 'Custom Streaming Server' }); @@ -73,21 +88,6 @@ test('Populates stream settings after go live', withUser('twitch'), async t => { // await clickGoLive(); // t.false(await chatIsVisible(), 'Chat should be collapsed when going live in unprotected mode '); // await stopStream(); - - // Can switch back to protected mode - await showSettingsWindow('Stream', async () => { - // Can switch back to recommended settings - await clickButton('Use recommended settings'); - await waitForDisplayed('a=Stream to custom ingest', { - timeout: 5000, - timeoutMsg: 'Recommended settings should restore protected mode', - }); - - await clickButton('Close'); - }); - - await goLive(); - await stopStream(); }); test('Populates stream key after go live', async t => { diff --git a/test/regular/streaming/twitch-stream-destination.ts b/test/regular/streaming/twitch-stream-destination.ts index 6df59bec5c18..ec9905b45491 100644 --- a/test/regular/streaming/twitch-stream-destination.ts +++ b/test/regular/streaming/twitch-stream-destination.ts @@ -84,7 +84,7 @@ const destinations = [ name: 'unresolved automatic selection', streamType: 'rtmp_custom', server: 'auto', - twitch: false, + twitch: true, enhanced: false, }, { name: 'empty server', streamType: 'rtmp_custom', server: '', twitch: false, enhanced: false }, diff --git a/test/regular/streaming/twitch.ts b/test/regular/streaming/twitch.ts index e6a8455c1ce7..a64b4184ccf0 100644 --- a/test/regular/streaming/twitch.ts +++ b/test/regular/streaming/twitch.ts @@ -116,11 +116,14 @@ test('Migrate the twitch account to the protected mode', async t => { }); // TODO: Add validation that the destination switchers in the go live window are hidden (requires multistream test account) // TODO: Add validation that the Twitch edit stream form in the go live window is the only form (requires multistream test account) - await waitForStreamStop(); + await stopStream(); // check that settings have been switched to the Custom Ingest mode await showSettingsWindow('Stream'); - t.true(await isDisplayed('button=Use recommended settings'), 'Protected mode should be disabled'); + t.false( + await isDisplayed('button=Use recommended settings'), + 'Protected mode should be disabled', + ); }); // TODO: Re-enable after reauthing userpool