safesight-control/scripts/dev-env.ps1

209 lines
9.1 KiB
PowerShell

param(
[Parameter(Position = 0)]
[string]$Action = "start",
[string]$MediaConfig = "configs/sample_cam1.json",
[string]$VideoFile = "",
[string]$SafesightdConfig = "..\safesight-control\safesightd.json"
)
$ErrorActionPreference = "Stop"
$scriptDir = Split-Path -Parent $MyInvocation.MyCommand.Path
$edgeDir = (Resolve-Path (Join-Path $scriptDir "..")).Path
$controlDir = (Resolve-Path (Join-Path $edgeDir "..\safesight-control")).Path
# ── paths ──────────────────────────────────────────────
$mediamtx = "C:\Software\mediamtx\mediamtx.exe"
$ffmpeg = "ffmpeg"
$minio = "C:\Users\Tellme\minio\minio.exe"
$minioData = "C:\Users\Tellme\minio\myminio"
$mockAlarm = Join-Path $scriptDir "mock_alarm_server.py"
$safesightdExe = Join-Path $controlDir "safesightd.exe"
$safesightdConfig = Join-Path $controlDir $SafesightdConfig
$mediaServerConfig = Join-Path $edgeDir $MediaConfig
$mediaServerExe = Join-Path $edgeDir "build\media-server.exe"
$rtspUrl = "rtsp://10.0.0.49:8554/cam"
$defaultVideo = "C:\Users\Tellme\Pictures\人脸库\reg_008_unk_011_多人_正面_黑色鞋_白色鞋_1.mp4"
function Write-Banner {
param([string]$Text)
Write-Host ("`n" + ("=" * 54)) -ForegroundColor Cyan
Write-Host " $Text" -ForegroundColor Cyan
Write-Host ("=" * 54) -ForegroundColor Cyan
}
function Start-Detached {
param([string]$Name, [string]$Exe, [string[]]$Args)
if (-not (Test-Path $Exe)) {
Write-Host " [SKIP] $Name : 未找到 $Exe" -ForegroundColor Yellow
return $null
}
Write-Host " [START] $Name" -ForegroundColor Green
$proc = Start-Process -FilePath $Exe -ArgumentList $Args -WindowStyle Minimized -PassThru
Start-Sleep -Milliseconds 500
return $proc
}
function Stop-ByName {
param([string]$Name)
$procs = Get-Process -Name $Name -ErrorAction SilentlyContinue
if ($procs) {
$procs | Stop-Process -Force
Write-Host " [STOP] $Name" -ForegroundColor DarkYellow
}
}
# ════════════════════════════════════════════════════════
# START
# ════════════════════════════════════════════════════════
function Invoke-Start {
# 1. RTSP server
Write-Banner "1/5 RTSP Server (mediamtx)"
Start-Detached "mediamtx" $mediamtx
# 2. ffmpeg push
Write-Banner "2/5 RTSP 推流 (ffmpeg)"
$videoToUse = if ($VideoFile -and (Test-Path $VideoFile)) { $VideoFile } elseif (Test-Path $defaultVideo) { $defaultVideo } else { $null }
if ($videoToUse) {
$ffArgs = @("-re", "-stream_loop", "-1", "-i", $videoToUse,
"-c", "copy", "-rtsp_transport", "tcp", "-f", "rtsp", $rtspUrl)
Write-Host " 视频文件: $videoToUse"
} else {
# Try to find a webcam
$webcam = (& $ffmpeg -list_devices true -f dshow -i dummy 2>&1 |
Select-String '\[dshow.*"(.+)"' |
ForEach-Object { $_.Matches.Groups[1].Value } |
Select-Object -First 1)
if ($webcam) {
Write-Host " 摄像头: $webcam"
$ffArgs = @("-f", "dshow", "-rtbufsize", "100M", "-video_size", "1280x720",
"-framerate", "30", "-vcodec", "mjpeg", "-i", "video=$webcam",
"-c:v", "libx264", "-preset", "ultrafast", "-pix_fmt", "yuv420p",
"-f", "rtsp", $rtspUrl)
} else {
Write-Host " [SKIP] 未指定视频文件,也未检测到摄像头" -ForegroundColor Yellow
$ffArgs = $null
}
}
if ($ffArgs) {
Start-Detached "ffmpeg" $ffmpeg $ffArgs
}
# 3. Media server (edge)
Write-Banner "3/5 Media Server (Edge)"
if (-not (Test-Path $mediaServerExe)) {
Write-Host " [WARN] 未找到 $mediaServerExe,请先编译" -ForegroundColor Yellow
} elseif (-not (Test-Path $mediaServerConfig)) {
Write-Host " [WARN] 未找到配置文件 $mediaServerConfig" -ForegroundColor Yellow
} else {
$msProc = Start-Process -FilePath $mediaServerExe `
-ArgumentList "-c", $mediaServerConfig `
-WorkingDirectory $edgeDir `
-WindowStyle Minimized `
-PassThru
Write-Host " [START] media-server (PID=$($msProc.Id)) 配置: $MediaConfig" -ForegroundColor Green
}
# 4. Mock alarm server (if uv available)
Write-Banner "4/5 Mock Alarm Server"
if (Get-Command uv -ErrorAction SilentlyContinue) {
$alarmProc = Start-Process -FilePath "uv" `
-ArgumentList "run", "--with", "flask", $mockAlarm `
-WorkingDirectory $scriptDir `
-WindowStyle Minimized `
-PassThru
Write-Host " [START] mock_alarm_server (PID=$($alarmProc.Id))" -ForegroundColor Green
} else {
Write-Host " [SKIP] uv 未安装" -ForegroundColor Yellow
}
# 5. Management server (safesightd)
Write-Banner "5/5 Management Server (safesightd)"
if (Test-Path $safesightdExe) {
Start-Process -FilePath $safesightdExe `
-ArgumentList $safesightdConfig `
-WorkingDirectory $controlDir `
-WindowStyle Minimized
Write-Host " [START] safesightd" -ForegroundColor Green
Write-Host " URL: http://localhost:18080" -ForegroundColor White
} elseif (Get-Command go -ErrorAction SilentlyContinue) {
Write-Host " [START] go run (safesightd 未编译)" -ForegroundColor Green
Start-Process -FilePath "go" `
-ArgumentList "run", ".\cmd\safesightd\", $safesightdConfig `
-WorkingDirectory $controlDir `
-WindowStyle Minimized
} else {
Write-Host " [SKIP] 既无 exe 也无 go" -ForegroundColor Yellow
}
# 6. MinIO (optional)
Write-Banner "MinIO (object storage)"
if (Test-Path $minio) {
if (-not (Test-Path $minioData)) { New-Item -ItemType Directory -Path $minioData -Force | Out-Null }
Start-Detached "minio" $minio @("server", $minioData, "--address", ":9000", "--console-address", ":9001")
Write-Host " Console: http://localhost:9001 (admin/password)" -ForegroundColor White
}
# Summary
Write-Banner "全部启动完成"
Write-Host " RTSP 输入: $rtspUrl"
Write-Host " 默认视频: $defaultVideo"
Write-Host " 管理端: http://localhost:18080"
Write-Host " 视频监控: http://localhost:18080/ui/monitor"
Write-Host " MinIO: http://localhost:9001"
Write-Host ""
Write-Host " 停止所有: powershell .\scripts\dev-env.ps1 stop" -ForegroundColor DarkGray
}
# ════════════════════════════════════════════════════════
# STOP
# ════════════════════════════════════════════════════════
function Invoke-Stop {
Write-Banner "停止所有模拟环境进程"
Stop-ByName "mediamtx"
Stop-ByName "ffmpeg"
Stop-ByName "media-server"
Stop-ByName "minio"
Stop-ByName "safesightd"
# Kill python mock_alarm if running
Get-Process -Name "python" -ErrorAction SilentlyContinue |
Where-Object { $_.CommandLine -match "mock_alarm" } |
Stop-Process -Force
Write-Host ""
Write-Host " 已全部停止" -ForegroundColor Green
}
# ════════════════════════════════════════════════════════
# STATUS
# ════════════════════════════════════════════════════════
function Invoke-Status {
Write-Banner "模拟环境状态"
@(
@{Name="mediamtx"; Port=8554; URL="rtsp://localhost:8554"},
@{Name="safesightd"; Port=18080; URL="http://localhost:18080/health"},
@{Name="minio"; Port=9000; URL="http://localhost:9000"}
) | ForEach-Object {
$proc = Get-Process -Name $_.Name -ErrorAction SilentlyContinue
$status = if ($proc) { "● 运行中" } else { "○ 未运行" }
$color = if ($proc) { "Green" } else { "DarkGray" }
Write-Host " $status $($_.Name) $($_.URL)" -ForegroundColor $color
}
}
# ════════════════════════════════════════════════════════
switch ($Action.ToLowerInvariant()) {
"start" { Invoke-Start }
"stop" { Invoke-Stop }
"status" { Invoke-Status }
default {
Write-Host "用法: powershell .\scripts\dev-env.ps1 [start|stop|status]"
Write-Host ""
Write-Host "可选参数 (仅 start):"
Write-Host " -MediaConfig media-server 配置 (默认: configs/sample_cam1.json)"
Write-Host " -VideoFile 推流视频文件路径"
}
}