#!/bin/sh # Low-confidence snapshot helper for yolov5 inference. # Expected arguments: # 1 source RTSP URL or local video file path from yolov5 -s # 2 camera_id Camera id from yolov5 -c # 3 timestamp Unix timestamp of the detection event # 4 class_name Detected class name # 5 confidence Detection confidence # 6 left Box left # 7 top Box top # 8 right Box right # 9 bottom Box bottom # # The script prints status lines to stdout/stderr. The inference program should # capture those lines and write them into its own detect log. SOURCE="$1" CAMERA_ID="$2" TS="$3" CLASS_NAME="$4" CONF="$5" LEFT="$6" TOP="$7" RIGHT="$8" BOTTOM="$9" SCRIPT_DIR="$(CDPATH= cd -- "$(dirname -- "$0")" && pwd)" SNAPSHOT_TIMEOUT="${SNAPSHOT_TIMEOUT:-15}" LOG_ROOT="${LOG_ROOT:-${SCRIPT_DIR}/.log}" SNAPSHOT_DAY="$(date -d "@${TS}" "+%Y-%m-%d" 2>/dev/null || date "+%Y-%m-%d")" SNAPSHOT_ROOT="${SNAPSHOT_ROOT:-${LOG_ROOT}/snapshots/${SNAPSHOT_DAY}}" now_text() { date "+%Y-%m-%d %H:%M:%S" } log_info() { echo "$(now_text) low_conf_snapshot INFO $*" } log_error() { echo "$(now_text) low_conf_snapshot ERROR $*" >&2 } sanitize() { echo "$1" | tr -c 'A-Za-z0-9_.-' '_' } if [ "$#" -lt 9 ]; then log_error "invalid arguments: expected 9, got $#" log_error "usage: $0 " exit 2 fi if ! command -v ffmpeg >/dev/null 2>&1; then log_error "ffmpeg not found" exit 127 fi CLASS_SAFE="$(sanitize "$CLASS_NAME")" CONF_SAFE="$(sanitize "$CONF")" BOX_SAFE="$(sanitize "${LEFT}_${TOP}_${RIGHT}_${BOTTOM}")" OUT_DIR="${SNAPSHOT_ROOT}" OUT_FILE="${OUT_DIR}/${TS}_${CAMERA_ID}_${CLASS_SAFE}_${CONF_SAFE}_${BOX_SAFE}.jpg" if ! mkdir -p "$OUT_DIR"; then log_error "failed to create output dir: $OUT_DIR" exit 1 fi log_info "start source=\"$SOURCE\" camera_id=\"$CAMERA_ID\" ts=\"$TS\" class=\"$CLASS_NAME\" conf=\"$CONF\" box=($LEFT $TOP $RIGHT $BOTTOM)" if command -v timeout >/dev/null 2>&1; then TIMEOUT_CMD="timeout ${SNAPSHOT_TIMEOUT}" else TIMEOUT_CMD="" fi case "$SOURCE" in rtsp://*|RTSP://*) # For RTSP streams, capture one live frame from the camera. # shellcheck disable=SC2086 $TIMEOUT_CMD ffmpeg -y -rtsp_transport tcp -i "$SOURCE" -frames:v 1 -q:v 2 "$OUT_FILE" >/tmp/low_conf_snapshot_ffmpeg.log 2>&1 RET=$? ;; *) # For local mp4/h264 test files, capture the first decodable frame. # shellcheck disable=SC2086 $TIMEOUT_CMD ffmpeg -y -i "$SOURCE" -frames:v 1 -q:v 2 "$OUT_FILE" >/tmp/low_conf_snapshot_ffmpeg.log 2>&1 RET=$? ;; esac if [ "$RET" -ne 0 ]; then log_error "ffmpeg failed ret=$RET output=\"$OUT_FILE\"" if [ -f /tmp/low_conf_snapshot_ffmpeg.log ]; then sed 's/^/ffmpeg: /' /tmp/low_conf_snapshot_ffmpeg.log >&2 fi rm -f "$OUT_FILE" exit "$RET" fi if [ ! -s "$OUT_FILE" ]; then log_error "snapshot file is empty or missing: $OUT_FILE" exit 1 fi log_info "saved output=\"$OUT_FILE\"" exit 0