examples/Webcam-Timelapse.ps1
|
<# .SYNOPSIS Webcam and timelapse examples. .DESCRIPTION Demonstrates how to work with webcams, capture snapshots, and create timelapses during prints. #> Import-Module KlippyCLI #region List Webcams # Get all configured webcams Get-KlippyWebcam | Format-Table Name, Service, StreamUrl, SnapshotUrl # Get specific webcam details $webcam = Get-KlippyWebcam -Name "main_camera" Write-Host "Webcam: $($webcam.Name)" Write-Host " Stream URL: $($webcam.StreamUrl)" Write-Host " Snapshot URL: $($webcam.SnapshotUrl)" Write-Host " Rotation: $($webcam.Rotation)" Write-Host " FPS: $($webcam.TargetFps)" #endregion #region Capture Snapshots # Save a snapshot (auto-named with timestamp) Save-KlippyWebcamSnapshot # Save to specific path Save-KlippyWebcamSnapshot -Path "C:\PrinterSnapshots\current.jpg" # Save from specific webcam Save-KlippyWebcamSnapshot -WebcamName "bed_camera" -Path "C:\PrinterSnapshots\bed.jpg" # Save snapshots from all webcams Get-KlippyWebcam | Save-KlippyWebcamSnapshot -Path "C:\PrinterSnapshots" # Save with force overwrite Save-KlippyWebcamSnapshot -Path "C:\PrinterSnapshots\latest.jpg" -Force #endregion #region Simple Timelapse Capture function Start-PrintTimelapse { <# .SYNOPSIS Capture timelapse images during a print #> param( [string]$OutputFolder, [int]$IntervalSeconds = 30, [string]$WebcamName ) # Create output folder if (-not (Test-Path $OutputFolder)) { New-Item -ItemType Directory -Path $OutputFolder -Force | Out-Null } $frameNumber = 0 $status = Get-KlippyStatus while ($status.State -eq "printing") { $frameNumber++ $frameName = "frame_{0:D5}.jpg" -f $frameNumber $framePath = Join-Path $OutputFolder $frameName $params = @{ Path = $framePath Force = $true } if ($WebcamName) { $params['WebcamName'] = $WebcamName } Save-KlippyWebcamSnapshot @params | Out-Null $job = Get-KlippyPrintJob $progress = [math]::Round($job.Progress * 100, 1) Write-Host "Frame $frameNumber captured ($progress% complete)" Start-Sleep -Seconds $IntervalSeconds $status = Get-KlippyStatus } Write-Host "Timelapse capture complete: $frameNumber frames in $OutputFolder" -ForegroundColor Green return $frameNumber } # Usage - Start print then capture timelapse Start-KlippyPrint -FileName "benchy.gcode" $frames = Start-PrintTimelapse -OutputFolder "C:\Timelapses\benchy_$(Get-Date -Format 'yyyyMMdd')" -IntervalSeconds 15 #endregion #region Advanced Timelapse with FFmpeg function New-TimelapseVideo { <# .SYNOPSIS Create video from captured frames using FFmpeg #> param( [string]$FramesFolder, [string]$OutputVideo, [int]$Fps = 30 ) # Check for FFmpeg if (-not (Get-Command ffmpeg -ErrorAction SilentlyContinue)) { Write-Error "FFmpeg not found. Please install FFmpeg and add to PATH." return } $inputPattern = Join-Path $FramesFolder "frame_%05d.jpg" $ffmpegArgs = @( "-framerate", $Fps, "-i", $inputPattern, "-c:v", "libx264", "-pix_fmt", "yuv420p", "-y", $OutputVideo ) Write-Host "Creating timelapse video..." & ffmpeg @ffmpegArgs if (Test-Path $OutputVideo) { $fileSize = (Get-Item $OutputVideo).Length / 1MB Write-Host "Timelapse created: $OutputVideo ($([math]::Round($fileSize, 2)) MB)" -ForegroundColor Green } } # Usage New-TimelapseVideo -FramesFolder "C:\Timelapses\benchy_20240101" -OutputVideo "C:\Timelapses\benchy_timelapse.mp4" -Fps 30 #endregion #region Layer-Change Timelapse function Start-LayerChangeTimelapse { <# .SYNOPSIS Capture images at each layer change (requires G-code macro integration) Note: This requires a TIMELAPSE_TAKE_FRAME macro in your Klipper config that's called at layer changes in your slicer. #> param( [string]$OutputFolder, [int]$CheckIntervalMs = 500 ) # Create output folder if (-not (Test-Path $OutputFolder)) { New-Item -ItemType Directory -Path $OutputFolder -Force | Out-Null } $lastLayer = 0 $frameNumber = 0 while ((Get-KlippyStatus).State -eq "printing") { # Get current layer from print stats $job = Get-KlippyPrintJob # Check if layer changed (this depends on your slicer/config exposing layer info) # Alternative: Monitor for specific G-code or use webhooks # For now, capture at regular intervals during printing $frameNumber++ $framePath = Join-Path $OutputFolder ("layer_{0:D4}.jpg" -f $frameNumber) Save-KlippyWebcamSnapshot -Path $framePath -Force | Out-Null Start-Sleep -Milliseconds $CheckIntervalMs } return $frameNumber } #endregion #region Snapshot on Event function Watch-PrinterAndCapture { <# .SYNOPSIS Monitor printer and capture snapshots on state changes #> param( [string]$OutputFolder ) if (-not (Test-Path $OutputFolder)) { New-Item -ItemType Directory -Path $OutputFolder -Force | Out-Null } $lastState = "" while ($true) { $status = Get-KlippyStatus $currentState = $status.State if ($currentState -ne $lastState) { $timestamp = Get-Date -Format "yyyyMMdd_HHmmss" $snapshotPath = Join-Path $OutputFolder "${timestamp}_${currentState}.jpg" Save-KlippyWebcamSnapshot -Path $snapshotPath -Force | Out-Null Write-Host "State change: $lastState -> $currentState (captured: $snapshotPath)" $lastState = $currentState } # Exit on certain states if ($currentState -in @("shutdown", "error")) { Write-Host "Monitoring stopped due to state: $currentState" -ForegroundColor Yellow break } Start-Sleep -Seconds 5 } } #endregion |