Skip to content

🎬 Building a 24/7 Automated OBS Livestream with Scene Rotation and Visuals (Inspired by Lofi Girl)


🎬 Intro: Autopilot Your Vibes with PowerShell

Let’s be real. Restarting OBS and pressing stream every few hours is ✨a vibe killer✨. Whether you’re running a lo-fi chill zone, a silent productivity stream, or a 24/7 AI art showcase, doing it all manually is… very last season. 😤

Enter: my PowerShell-powered automation squad that’ll stop crashes, relaunch OBS, switch up scenes, and start streaming on its own. Yup — no hands, just vibes. 🌈🧠

In this post, I’ll walk you through a set of easy-to-customize PowerShell scripts that give your OBS setup a serious glow-up.

🧠 Code Files (With Copy Buttons)

There are four main files. Each one has a job, like your own little dev dream team. Copy-paste each one below into a file with the matching name.

1. restart_and_start_stream.ps1

This is your main launcher script. It checks if OBS is already running, closes it gracefully, clears crash logs, reopens it, and then uses a hotkey simulation to start the stream. Perfect for recovery after crashes or auto reboots.


# restart_and_start_stream.ps1
# Auto-elevate, kill OBS if needed, clean crash files, launch OBS, send hotkey

# === Config ===
$OBSPath = ""
$OBSWindowTitle = ""
$HotkeyCombination = '^%+S'
$OBSLaunchDelay = 5
$StopDelaySeconds = 3
$LogFile = ""

Function Log {
  param([string]$message)
  $timestamp = Get-Date -Format 'yyyy-MM-dd HH:mm:ss'
  $logEntry = "$timestamp | $message"
  Add-Content -Path $LogFile -Value $logEntry
  Write-Output $logEntry
}

# === Restart OBS ===
Get-Process obs64 -ErrorAction SilentlyContinue | ForEach-Object {
  $_.CloseMainWindow()
  $_.WaitForExit(5000)
}
Remove-Item "$env:APPDATA\\obs-studio\\crashes\\*" -Force -Recurse -ErrorAction SilentlyContinue

if (-not (Get-Process obs64 -ErrorAction SilentlyContinue)) {
  Start-Process -FilePath $OBSPath
  Start-Sleep -Seconds $OBSLaunchDelay
}

# === Simulate Hotkey via VBScript ===
$vbscript = @"
Set WshShell = WScript.CreateObject("WScript.Shell")
WshShell.AppActivate "$OBSWindowTitle"
WScript.Sleep 1000
WshShell.SendKeys "$HotkeyCombination"
"@

$vbpath = "$env:TEMP\\start_obs_hotkey.vbs"
$vbscript | Out-File -FilePath $vbpath -Encoding ASCII
Start-Process "wscript.exe" -ArgumentList "`"$vbpath`""
    

2. restart_stream.ps1

This script is a smarter version that uses OBS WebSocket API. It sends actual JSON requests to stop your current stream, relaunch OBS, select a random scene (if you want), and kick off the livestream with all settings in place.


# restart_stream.ps1
Import-Module "\\obs_control.psm1"
. "\\config.ps1"

Function Log {
  param([string]$message)
  $timestamp = Get-Date -Format 'yyyy-MM-dd HH:mm:ss'
  Add-Content -Path $LogFile -Value "$timestamp | $message"
  Write-Output "$timestamp | $message"
}

# Stop stream via WebSocket
$response = Invoke-OBSWebSocketRequest -Uri $OBSWebSocketHost -RequestType "StopStream"

# Gracefully close OBS
Get-Process obs64 -ErrorAction SilentlyContinue | ForEach-Object {
  $_.CloseMainWindow()
  $_.WaitForExit(5000)
}

# Relaunch OBS
if (-not (Get-Process obs64 -ErrorAction SilentlyContinue)) {
  Start-Process -FilePath $OBSPath
  Start-Sleep -Seconds $OBSLaunchDelay
}

# Pick scene
$selectedScene = if ($RandomizeScene) { Get-Random -InputObject $Scenes } else { $Scenes[0] }
Invoke-OBSWebSocketRequest -Uri $OBSWebSocketHost -RequestType "SetCurrentProgramScene" -RequestData @{sceneName=$selectedScene}

# Set profile and scene collection
Invoke-OBSWebSocketRequest -Uri $OBSWebSocketHost -RequestType "SetCurrentProfile" -RequestData @{profileName=$ProfileName}
Invoke-OBSWebSocketRequest -Uri $OBSWebSocketHost -RequestType "SetCurrentSceneCollection" -RequestData @{sceneCollectionName=$SceneCollection}

# Stream config
Invoke-OBSWebSocketRequest -Uri $OBSWebSocketHost -RequestType "SetStreamServiceSettings" -RequestData @{
  streamServiceType = "rtmp_custom"
  streamServiceSettings = @{
    server = $YouTubePrimary
    key = $StreamKey
  }
}

# Start stream
Invoke-OBSWebSocketRequest -Uri $OBSWebSocketHost -RequestType "StartStream"
    

3. config.ps1

This is your customizable config file. You put all your editable settings here — paths, WebSocket host, stream key, profile names, scenes, and delays.


# config.ps1
$OBSPath = ""
$OBSWebSocketHost = "ws://localhost:4455"
$StreamKey = ""
$YouTubePrimary = "rtmp://yourstream.rtmp.server"

$Scenes = @("Scene1", "Scene2")
$RandomizeScene = $true

$ProfileName = "YouTube"
$SceneCollection = "Default"

$OBSLaunchDelay = 5
$StopDelaySeconds = 3
$LogFile = ""
$OBSWindowTitle = "OBS 31.0.3"
    

4. obs_control.psm1

This PowerShell module sends WebSocket commands to OBS. Think of it as your “talk to OBS” translator — it handles sending/receiving JSON requests.


# obs_control.psm1
Function Invoke-OBSWebSocketRequest {
  param(
    [string]$Uri,
    [string]$RequestType,
    [hashtable]$RequestData = @{}
  )

  $Payload = @{
    op = 6
    d = @{
      requestType = $RequestType
      requestId = [guid]::NewGuid().ToString()
      requestData = $RequestData
    }
  } | ConvertTo-Json -Depth 10

  try {
    $WS = [System.Net.WebSockets.ClientWebSocket]::new()
    $WS.ConnectAsync($Uri, [Threading.CancellationToken]::None).Wait()
    $Bytes = [System.Text.Encoding]::UTF8.GetBytes($Payload)
    $WS.SendAsync([System.ArraySegment[byte]]::new($Bytes), [System.Net.WebSockets.WebSocketMessageType]::Text, $true, [Threading.CancellationToken]::None).Wait()
    $RecvBuffer = New-Object byte[] 8192
    $Result = $WS.ReceiveAsync([System.ArraySegment[byte]]::new($RecvBuffer), [Threading.CancellationToken]::None).Result
    $Response = [System.Text.Encoding]::UTF8.GetString($RecvBuffer, 0, $Result.Count)
    $WS.Dispose()
    return $Response | ConvertFrom-Json
  } catch {
    Write-Error "WebSocket Error: $_"
  }
}
Export-ModuleMember -Function Invoke-OBSWebSocketRequest
    

🪄 Recap & Real-World Vibes

Once you’ve dropped these four files into place and customized your config, your OBS stream becomes self-aware. It’ll restart, clean up, randomize scenes, and vibe on command. 🚀

Want to run it every morning? Hook restart_and_start_stream.ps1 into Task Scheduler. Crash recovery? Run restart_stream.ps1 on failure. It’s flexible, aesthetic, and 100% hands-free.

Have questions or want to flex your version? Drop a comment, smash that share button, and show off your automated stream setup to the squad.

Leave a Reply

Your email address will not be published. Required fields are marked *