82 lines
3.0 KiB
PowerShell
82 lines
3.0 KiB
PowerShell
#Requires -Version 5.1
|
|
<#
|
|
.SYNOPSIS
|
|
Sends a SaveReplayBuffer request to OBS via WebSocket v5 (built into OBS 28+).
|
|
Returns $true on success, $false on any failure.
|
|
|
|
.PARAMETER Port
|
|
OBS WebSocket port. Defaults to the value in config.psd1.
|
|
#>
|
|
|
|
param(
|
|
[int]$Port = 0
|
|
)
|
|
|
|
$ErrorActionPreference = 'SilentlyContinue'
|
|
|
|
$config = Import-PowerShellDataFile -Path (Join-Path $PSScriptRoot '..\config.psd1')
|
|
if ($Port -eq 0) {
|
|
$Port = $config.WebSocketPort
|
|
}
|
|
|
|
# --- Start transcript logging ---
|
|
try {
|
|
$logDir = Join-Path $config.LogPath $env:USERNAME
|
|
New-Item -ItemType Directory -Path $logDir -Force -ErrorAction SilentlyContinue | Out-Null
|
|
Start-Transcript -Path (Join-Path $logDir 'OBSReplayBuffer-Save.log') -Append -ErrorAction Stop
|
|
} catch {
|
|
# Log path unavailable — continue without transcript
|
|
}
|
|
|
|
Write-Host "$(Get-Date -Format 'yyyy-MM-dd HH:mm:ss') [INFO] Invoke-ReplaySave started. Target: ws://localhost:$Port"
|
|
|
|
$ws = $null
|
|
$cts = $null
|
|
|
|
try {
|
|
$ws = New-Object System.Net.WebSockets.ClientWebSocket
|
|
$cts = New-Object System.Threading.CancellationTokenSource(5000) # 5-second timeout
|
|
$uri = [System.Uri]"ws://localhost:$Port"
|
|
|
|
$ws.ConnectAsync($uri, $cts.Token).Wait()
|
|
Write-Host "$(Get-Date -Format 'yyyy-MM-dd HH:mm:ss') [INFO] WebSocket connected."
|
|
|
|
$buffer = New-Object byte[] 8192
|
|
|
|
# Receive Hello (opcode 0)
|
|
$null = $ws.ReceiveAsync($buffer, $cts.Token).Result
|
|
Write-Host "$(Get-Date -Format 'yyyy-MM-dd HH:mm:ss') [INFO] Received Hello (op 0)."
|
|
|
|
# Send Identify (opcode 1) — no authentication
|
|
$identify = [System.Text.Encoding]::UTF8.GetBytes('{"op":1,"d":{"rpcVersion":1}}')
|
|
$ws.SendAsync($identify, [System.Net.WebSockets.WebSocketMessageType]::Text, $true, $cts.Token).Wait()
|
|
Write-Host "$(Get-Date -Format 'yyyy-MM-dd HH:mm:ss') [INFO] Sent Identify (op 1)."
|
|
|
|
# Receive Identified (opcode 2)
|
|
$null = $ws.ReceiveAsync($buffer, $cts.Token).Result
|
|
Write-Host "$(Get-Date -Format 'yyyy-MM-dd HH:mm:ss') [INFO] Received Identified (op 2)."
|
|
|
|
# Send SaveReplayBuffer request (opcode 6)
|
|
$request = [System.Text.Encoding]::UTF8.GetBytes('{"op":6,"d":{"requestType":"SaveReplayBuffer","requestId":"itrecord-1"}}')
|
|
$ws.SendAsync($request, [System.Net.WebSockets.WebSocketMessageType]::Text, $true, $cts.Token).Wait()
|
|
Write-Host "$(Get-Date -Format 'yyyy-MM-dd HH:mm:ss') [INFO] Sent SaveReplayBuffer request (op 6)."
|
|
|
|
# Receive RequestResponse (opcode 7)
|
|
$null = $ws.ReceiveAsync($buffer, $cts.Token).Result
|
|
Write-Host "$(Get-Date -Format 'yyyy-MM-dd HH:mm:ss') [INFO] Received response (op 7)."
|
|
|
|
$ws.CloseAsync([System.Net.WebSockets.WebSocketCloseStatus]::NormalClosure, 'Done', $cts.Token).Wait()
|
|
Write-Host "$(Get-Date -Format 'yyyy-MM-dd HH:mm:ss') [INFO] WebSocket closed. Save completed successfully."
|
|
|
|
return $true
|
|
}
|
|
catch {
|
|
Write-Host "$(Get-Date -Format 'yyyy-MM-dd HH:mm:ss') [ERROR] Save failed: $_"
|
|
return $false
|
|
}
|
|
finally {
|
|
if ($ws) { $ws.Dispose() }
|
|
if ($cts) { $cts.Dispose() }
|
|
Stop-Transcript -ErrorAction SilentlyContinue
|
|
}
|