# Hardware validation for Windows. Not yet run on Windows: it is the first # job for the Windows implementor, who should fix what it finds. # # powershell -ExecutionPolicy Bypass -File scripts\validate\windows.ps1 [-Out ] [-GameWindow ":<class>:<exe>"] # # Needs: Rust (rustup, MSVC toolchain), Visual Studio Build Tools (C++), # Git for Windows (its bash runs scripts/obs/assemble-windows.sh) and FFmpeg # on PATH for the segment checks (winget install Gyan.FFmpeg). # # -GameWindow is OBS's window identifier for a running game, as shown in OBS # Studio's Game Capture "Window" list: "<title>:<window class>:<executable>". param( [string]$Out = "$env:TEMP\clipbin-windows", [string]$GameWindow = "" ) $ErrorActionPreference = "Stop" $repo = Resolve-Path "$PSScriptRoot\..\.." $report = Join-Path $Out "report.txt" Remove-Item -Recurse -Force $Out -ErrorAction SilentlyContinue New-Item -ItemType Directory -Force $Out | Out-Null function Log($text) { $text | Tee-Object -FilePath $report -Append } Log "Clipbin Windows validation $(Get-Date -Format o)" Log "os: $((Get-CimInstance Win32_OperatingSystem).Caption) $([Environment]::OSVersion.Version)" Log "gpu: $((Get-CimInstance Win32_VideoController).Name -join ', ')" # 1. The pinned official OBS runtime, with the Game Capture hook still signed. & bash "$repo/scripts/obs/assemble-windows.sh" if ($LASTEXITCODE -ne 0) { throw "assembling the OBS runtime failed" } $runtime = Join-Path $repo "target\obs-runtime\windows-x86_64" Get-ChildItem "$runtime\data\obs-plugins\win-capture\*" -Include *.exe, *.dll | ForEach-Object { $signature = Get-AuthenticodeSignature $_.FullName Log ("signature {0}: {1} ({2})" -f $_.Name, $signature.Status, $signature.SignerCertificate.Subject) } # 2. Build the probe (also checks the Windows code paths compile and link). Push-Location $repo cargo build --locked -p clipbin-probe if ($LASTEXITCODE -ne 0) { throw "building clipbin-probe failed" } Pop-Location $probe = Join-Path $repo "target\debug\clipbin-probe.exe" $format = @("--width", "2560", "--height", "1440", "--fps", "60", "--bitrate", "40000") function Record($name, $codec, [string[]]$arguments) { $dir = Join-Path $Out $name & $probe record @arguments --codec $codec @format --seconds 20 --out $dir > "$dir.log" 2> "$dir.obs.log" $recordExit = $LASTEXITCODE & $probe check --codec $codec --out $dir >> "$dir.log" 2>&1 $checkExit = $LASTEXITCODE Log "${name}: record_exit=$recordExit check_exit=$checkExit $((Select-String -Path "$dir.log" -Pattern '^(encoder|recorded|check)=').Line -join ' ')" Log ((Select-String -Path "$dir.log" -Pattern 'status=').Line -join ' ') } # 3. Hardware encoders: NVENC, AMF or QSV for H.264, HEVC and AV1. & $probe encoders --verify @format --out (Join-Path $Out "encoders") > "$Out\encoders.log" 2> "$Out\encoders.obs.log" Log ((Select-String -Path "$Out\encoders.log" -Pattern '^(obs_version|usable\.|verify\.)').Line -join "`n") # 4. Monitor capture with each usable codec. foreach ($codec in "h264", "hevc", "av1") { if (Select-String -Path "$Out\encoders.log" -Pattern "^usable\.$codec=none" -Quiet) { Log "SKIP ${codec}: no usable hardware encoder" continue } Record "monitor-$codec" $codec @("--target", "monitor") } # 5. Game Capture (signed hook) and Window Capture of a running game. if ($GameWindow) { Record "game-capture" "h264" @("--target", "game", "--window", $GameWindow) Record "window-capture" "h264" @("--target", "window", "--window", $GameWindow) Write-Host "Last: start a recording, then quit the game about 5 seconds in." Read-Host "Press Enter when ready" $dir = Join-Path $Out "game-closed" & $probe record --target game --window $GameWindow @format --seconds 20 --out $dir > "$dir.log" 2> "$dir.obs.log" Log "game-closed: exit=$LASTEXITCODE $((Select-String -Path "$dir.log" -Pattern 'status=failed').Line | Select-Object -First 1)" } else { Log "SKIP game capture: pass -GameWindow with a running game's window identifier" } Write-Host "Report: $report"