139 lines
3.6 KiB
Bash
Executable File
139 lines
3.6 KiB
Bash
Executable File
#!/usr/bin/env sh
|
|
set -eu
|
|
|
|
PROJECT_DIR="/opt/people-flow"
|
|
CONFIG_TEMPLATE="${PROJECT_DIR}/config/config.example.yaml"
|
|
CONFIG_PATH="${CONFIG_PATH:-${PROJECT_DIR}/config/local.yaml}"
|
|
OUTPUT_DIR="${OUTPUT_DIR:-${PROJECT_DIR}/outputs}"
|
|
RTSP_URL="${RTSP_URL:-}"
|
|
API_HOST="${API_HOST:-0.0.0.0}"
|
|
API_PORT="${API_PORT:-18082}"
|
|
RTSP_STALL_TIMEOUT_SECONDS="${RTSP_STALL_TIMEOUT_SECONDS:-180}"
|
|
DEEPFACE_CACHE_DIR="/root/.deepface/weights"
|
|
DEEPFACE_SOURCE_DIR="${PROJECT_DIR}/weights/deepface"
|
|
|
|
mkdir -p "${OUTPUT_DIR}" "$(dirname "${CONFIG_PATH}")" "${DEEPFACE_CACHE_DIR}"
|
|
|
|
if [ -d "${DEEPFACE_SOURCE_DIR}" ]; then
|
|
find "${DEEPFACE_SOURCE_DIR}" -maxdepth 1 -name '*.h5' -exec cp {} "${DEEPFACE_CACHE_DIR}/" \;
|
|
fi
|
|
|
|
if [ ! -f "${CONFIG_PATH}" ]; then
|
|
cp "${CONFIG_TEMPLATE}" "${CONFIG_PATH}"
|
|
fi
|
|
|
|
python - "$CONFIG_PATH" "$RTSP_URL" "$OUTPUT_DIR" <<'PY'
|
|
from pathlib import Path
|
|
import sys
|
|
import yaml
|
|
|
|
config_path = Path(sys.argv[1])
|
|
rtsp_url = sys.argv[2]
|
|
output_dir = sys.argv[3]
|
|
|
|
raw = yaml.safe_load(config_path.read_text(encoding="utf-8")) or {}
|
|
runtime = raw.setdefault("runtime", {})
|
|
if rtsp_url:
|
|
runtime["rtsp_url"] = rtsp_url
|
|
runtime["output_dir"] = output_dir
|
|
yolo = raw.setdefault("yolo", {})
|
|
yolo.setdefault("model_path", "weights/yolo11n.pt")
|
|
config_path.write_text(
|
|
yaml.safe_dump(raw, allow_unicode=True, sort_keys=False),
|
|
encoding="utf-8",
|
|
)
|
|
PY
|
|
|
|
RTSP_OUTPUT_SUBDIR="$(python - "$CONFIG_PATH" <<'PY'
|
|
from pathlib import Path
|
|
import sys
|
|
import yaml
|
|
|
|
config_path = Path(sys.argv[1])
|
|
raw = yaml.safe_load(config_path.read_text(encoding="utf-8")) or {}
|
|
rtsp = raw.get("rtsp") or {}
|
|
print(rtsp.get("output_subdir", "rtsp_stream"))
|
|
PY
|
|
)"
|
|
RTSP_STATUS_PATH="${OUTPUT_DIR}/${RTSP_OUTPUT_SUBDIR}/worker_status.json"
|
|
|
|
exec python - "$CONFIG_PATH" "$API_HOST" "$API_PORT" "$RTSP_STATUS_PATH" "$RTSP_STALL_TIMEOUT_SECONDS" <<'PY'
|
|
from pathlib import Path
|
|
import signal
|
|
import subprocess
|
|
import sys
|
|
import time
|
|
|
|
from src.people_flow.worker_status import worker_status_stall_reason
|
|
|
|
config_path, api_host, api_port, status_path_raw, stall_timeout_raw = sys.argv[1:6]
|
|
status_path = Path(status_path_raw)
|
|
stall_timeout_seconds = max(float(stall_timeout_raw), 30.0)
|
|
commands = [
|
|
[sys.executable, "main.py", "--config", config_path, "rtsp"],
|
|
[
|
|
sys.executable,
|
|
"main.py",
|
|
"--config",
|
|
config_path,
|
|
"manage-api",
|
|
"--host",
|
|
api_host,
|
|
"--port",
|
|
api_port,
|
|
],
|
|
]
|
|
processes = [subprocess.Popen(command) for command in commands]
|
|
supervisor_started_at = time.time()
|
|
|
|
|
|
def stop_all(excluded_index=None):
|
|
for index, process in enumerate(processes):
|
|
if index == excluded_index or process.poll() is not None:
|
|
continue
|
|
process.terminate()
|
|
deadline = time.time() + 10
|
|
for index, process in enumerate(processes):
|
|
if index == excluded_index or process.poll() is not None:
|
|
continue
|
|
timeout = max(0, deadline - time.time())
|
|
try:
|
|
process.wait(timeout=timeout)
|
|
except subprocess.TimeoutExpired:
|
|
process.kill()
|
|
|
|
|
|
def stale_reason():
|
|
if processes[0].poll() is not None:
|
|
return None
|
|
|
|
return worker_status_stall_reason(
|
|
status_path,
|
|
started_at=supervisor_started_at,
|
|
max_age_seconds=stall_timeout_seconds,
|
|
)
|
|
|
|
|
|
def terminate_all(signum, _frame):
|
|
stop_all()
|
|
raise SystemExit(128 + signum)
|
|
|
|
|
|
for handled_signal in (signal.SIGINT, signal.SIGTERM):
|
|
signal.signal(handled_signal, terminate_all)
|
|
|
|
while True:
|
|
for index, process in enumerate(processes):
|
|
return_code = process.poll()
|
|
if return_code is None:
|
|
continue
|
|
stop_all(excluded_index=index)
|
|
raise SystemExit(return_code)
|
|
reason = stale_reason()
|
|
if reason is not None:
|
|
print(reason, flush=True)
|
|
stop_all()
|
|
raise SystemExit(1)
|
|
time.sleep(0.5)
|
|
PY
|