213 lines
9.2 KiB
PowerShell
213 lines
9.2 KiB
PowerShell
param(
|
|
[Parameter(Position = 0)]
|
|
[string]$Action = "start",
|
|
|
|
[string]$MediaConfig = "configs/sample_cam1.json",
|
|
[string]$VideoFile = "",
|
|
[string]$SafesightdConfig = "safesightd.json"
|
|
)
|
|
|
|
$ErrorActionPreference = "Stop"
|
|
|
|
$scriptDir = Split-Path -Parent $MyInvocation.MyCommand.Path
|
|
$controlDir = (Resolve-Path (Join-Path $scriptDir "..")).Path
|
|
$edgeDir = (Resolve-Path (Join-Path $controlDir "..\safesight-edge")).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
|
|
if ($Args -and $Args.Count -gt 0) {
|
|
$proc = Start-Process -FilePath $Exe -ArgumentList $Args -WindowStyle Minimized -PassThru
|
|
} else {
|
|
$proc = Start-Process -FilePath $Exe -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 推流视频文件路径"
|
|
}
|
|
}
|