add helper scripts
This commit is contained in:
1 parent
1853360506
commit
bebdeab0d5
2 files changed
+487
No files matched your search
@@ -103,6 +103,40 @@ Zeigt:
|
|||||||
|
|
||||||
Zeigt alle verfügbaren Kamera-Auflösungen und Formate.
|
Zeigt alle verfügbaren Kamera-Auflösungen und Formate.
|
||||||
|
|
||||||
|
## Multi-Camera: alle Kameras auf einmal
|
||||||
|
|
||||||
|
`start_all_cameras.sh` erkennt alle angeschlossenen, von VIZION unterstützten
|
||||||
|
Kameras (via `vizion-ctl -l`, Fallback: `lsusb`/Cypress 04b4) und startet für
|
||||||
|
jede der Reihe nach eine `vizionStreamer`-Instanz mit eigenem Socket
|
||||||
|
(`/tmp/vizion_cam<idx>.sock`) und startet den Stream.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Erkannte Kameras auflisten
|
||||||
|
./scripts/start_all_cameras.sh --list
|
||||||
|
|
||||||
|
# Alle Kameras per UDP streamen (Port 5000 + Kamera-Index)
|
||||||
|
./scripts/start_all_cameras.sh --udp 192.168.1.100 5000
|
||||||
|
|
||||||
|
# Alle Kameras als MJPEG-HTTP-Stream (Port 8080 + Kamera-Index)
|
||||||
|
./scripts/start_all_cameras.sh --mjpeg 8080
|
||||||
|
|
||||||
|
# Alle Kameras in Dateien aufnehmen (/tmp/cam<idx>.mp4)
|
||||||
|
./scripts/start_all_cameras.sh --file /home/user/recordings
|
||||||
|
|
||||||
|
# Lokale Anzeige
|
||||||
|
./scripts/start_all_cameras.sh --display
|
||||||
|
|
||||||
|
# Eigene Pipeline ({port} wird durch 5000+Kamera-Index ersetzt)
|
||||||
|
./scripts/start_all_cameras.sh --pipeline "videoconvert ! x264enc tune=zerolatency ! rtph264pay ! udpsink host=192.168.1.100 port={port}"
|
||||||
|
|
||||||
|
# Alle gestarteten Instanzen stoppen
|
||||||
|
./scripts/start_all_cameras.sh --stop
|
||||||
|
```
|
||||||
|
|
||||||
|
Ohne Modus-Option wird standardmäßig per UDP nach `127.0.0.1` gestreamt.
|
||||||
|
Das Script läuft im Vordergrund und stoppt mit `Ctrl+C` alle Instanzen
|
||||||
|
sauber (Stream stoppen + Prozess beenden). Logs: `/tmp/vizion_cam<idx>.log`.
|
||||||
|
|
||||||
## Typischer Workflow
|
## Typischer Workflow
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
|
|||||||
Executable
+453
@@ -0,0 +1,453 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
#
|
||||||
|
# start_all_cameras.sh
|
||||||
|
#
|
||||||
|
# Sucht alle angeschlossenen, von VIZION unterstützten Kameras und startet
|
||||||
|
# für jede (der Reihe nach) eine vizionStreamer-Instanz mit eigenem
|
||||||
|
# Control-Socket und startet den Stream.
|
||||||
|
#
|
||||||
|
# Erkennung:
|
||||||
|
# 1. vizion-ctl -l (VizionSDK, /opt/vizionsdk/bin/vizion-ctl) - offizielle
|
||||||
|
# Kameradetection (USB + MIPI)
|
||||||
|
# 2. Fallback: lsusb (Cypress USB-Geräte, Vendor 04b4)
|
||||||
|
#
|
||||||
|
# Pro Kamera werden angelegt:
|
||||||
|
# /tmp/vizion_cam<idx>.sock Control-Socket
|
||||||
|
# /tmp/vizion_cam<idx>.pid PID-Datei
|
||||||
|
# /tmp/vizion_cam<idx>.log Log der Instanz
|
||||||
|
#
|
||||||
|
# Copyright (c) 2025 Maik Jurischka
|
||||||
|
# Lizenziert unter CC BY-NC-SA 4.0 - https://creativecommons.org/licenses/by-nc-sa/4.0/
|
||||||
|
|
||||||
|
set -u
|
||||||
|
|
||||||
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||||
|
ROOT_DIR="$(dirname "$SCRIPT_DIR")"
|
||||||
|
BINARY="$ROOT_DIR/build/vizionStreamer"
|
||||||
|
|
||||||
|
# VizionSDK-Tool (offizielle Kameradetection)
|
||||||
|
VIZION_CTL="$(command -v vizion-ctl 2>/dev/null || true)"
|
||||||
|
[ -n "$VIZION_CTL" ] || VIZION_CTL="/opt/vizionsdk/bin/vizion-ctl"
|
||||||
|
|
||||||
|
SOCKET_PREFIX="/tmp/vizion_cam" # /tmp/vizion_cam<idx>.sock
|
||||||
|
PID_PREFIX="/tmp/vizion_cam" # /tmp/vizion_cam<idx>.pid
|
||||||
|
LOG_PREFIX="/tmp/vizion_cam" # /tmp/vizion_cam<idx>.log
|
||||||
|
WAIT_TIMEOUT=15 # Sekunden, die auf den Socket gewartet wird
|
||||||
|
|
||||||
|
# ---------------------------------------------------------------------------
|
||||||
|
# Ausgabe-Helfer
|
||||||
|
# ---------------------------------------------------------------------------
|
||||||
|
log() { echo "[$(date '+%Y-%m-%d %H:%M:%S')] $*"; }
|
||||||
|
err() { echo "[$(date '+%Y-%m-%d %H:%M:%S')] ERROR: $*" >&2; }
|
||||||
|
|
||||||
|
usage() {
|
||||||
|
cat <<'EOF'
|
||||||
|
Nutzung: start_all_cameras.sh [Optionen]
|
||||||
|
|
||||||
|
Sucht alle angeschlossenen VIZION-Kameras und startet für jede (der Reihe
|
||||||
|
nach) einen Stream.
|
||||||
|
|
||||||
|
Optionen:
|
||||||
|
--list Nur erkannte Kameras auflisten
|
||||||
|
--udp <host> [port] UDP H.264-Stream (Standard: 127.0.0.1, Port 5000+Kamera-Index)
|
||||||
|
--mjpeg [port] MJPEG HTTP-Stream (Standard: Port 8080+Kamera-Index)
|
||||||
|
--file [dir] Aufnahme in Datei (Standard: /tmp/cam<idx>.mp4)
|
||||||
|
--display Lokale Anzeige (autovideosink)
|
||||||
|
--pipeline <pipe> Eigene GStreamer-Pipeline (für {port} wird 5000+Kamera-Index eingesetzt)
|
||||||
|
--stop Alle von diesem Script gestarteten Instanzen stoppen
|
||||||
|
-h, --help Diese Hilfe anzeigen
|
||||||
|
|
||||||
|
Beispiele:
|
||||||
|
./scripts/start_all_cameras.sh --list
|
||||||
|
./scripts/start_all_cameras.sh --udp 192.168.1.100 5000
|
||||||
|
./scripts/start_all_cameras.sh --mjpeg 8080
|
||||||
|
./scripts/start_all_cameras.sh --file /home/user/recordings
|
||||||
|
./scripts/start_all_cameras.sh --pipeline "videoconvert ! x264enc tune=zerolatency ! rtph264pay ! udpsink host=192.168.1.100 port={port}"
|
||||||
|
|
||||||
|
Empfangen (UDP, auf dem Zielrechner):
|
||||||
|
gst-launch-1.0 udpsrc port=5000 ! application/x-rtp,encoding-name=H264 ! rtph264depay ! h264parse ! avdec_h264 ! videoconvert ! autovideosink
|
||||||
|
EOF
|
||||||
|
}
|
||||||
|
|
||||||
|
# ---------------------------------------------------------------------------
|
||||||
|
# Socket-Helfer
|
||||||
|
# ---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
# send_cmd <socket> <json> - JSON-Command an eine Instanz senden
|
||||||
|
send_cmd() {
|
||||||
|
echo "$2" | socat - "UNIX-CONNECT:$1" 2>/dev/null
|
||||||
|
}
|
||||||
|
|
||||||
|
# wait_for_socket <socket> - bis der Socket existiert warten
|
||||||
|
wait_for_socket() {
|
||||||
|
local sock="$1"
|
||||||
|
local i
|
||||||
|
for ((i = 0; i < WAIT_TIMEOUT * 2; i++)); do
|
||||||
|
[ -S "$sock" ] && return 0
|
||||||
|
sleep 0.5
|
||||||
|
done
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
|
||||||
|
# json_escape <string> - String für JSON-Strings escapen
|
||||||
|
json_escape() {
|
||||||
|
local s="$1"
|
||||||
|
s=${s//\\/\\\\}
|
||||||
|
s=${s//\"/\\\"}
|
||||||
|
printf '%s' "$s"
|
||||||
|
}
|
||||||
|
|
||||||
|
# ---------------------------------------------------------------------------
|
||||||
|
# Kamera-Erkennung
|
||||||
|
# ---------------------------------------------------------------------------
|
||||||
|
CAMERAS=()
|
||||||
|
DETECT_OUTPUT=""
|
||||||
|
|
||||||
|
detect_cameras() {
|
||||||
|
if [ -x "$VIZION_CTL" ]; then
|
||||||
|
DETECT_OUTPUT="$("$VIZION_CTL" -l 2>&1)"
|
||||||
|
|
||||||
|
# Indizes aus Zeilen wie "[0] VCI-AR0234 ..." extrahieren
|
||||||
|
local idxs
|
||||||
|
idxs="$(echo "$DETECT_OUTPUT" | grep -oE '^[[:space:]]*\[[0-9]+\]' | tr -d '[]' | sort -n -u)"
|
||||||
|
if [ -n "$idxs" ]; then
|
||||||
|
while IFS= read -r i; do
|
||||||
|
CAMERAS+=("$i")
|
||||||
|
done <<< "$idxs"
|
||||||
|
else
|
||||||
|
# Fallback: Anzahl aus "Found N camera(s)" o.ä. parsen
|
||||||
|
local n
|
||||||
|
n="$(echo "$DETECT_OUTPUT" | grep -oiE '[0-9]+[[:space:]]*camera' | grep -oE '^[0-9]+' | head -1)"
|
||||||
|
if [ -n "$n" ]; then
|
||||||
|
local i
|
||||||
|
for ((i = 0; i < n; i++)); do
|
||||||
|
CAMERAS+=("$i")
|
||||||
|
done
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
log "vizion-ctl nicht gefunden ($VIZION_CTL) - verwende lsusb als Fallback"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Fallback: Cypress USB-Geräte (Vendor 04b4) zählen
|
||||||
|
if [ ${#CAMERAS[@]} -eq 0 ] && command -v lsusb >/dev/null 2>&1; then
|
||||||
|
local nusb
|
||||||
|
nusb="$(lsusb 2>/dev/null | grep -cE 'ID 04b4:')"
|
||||||
|
if [ "$nusb" -gt 0 ]; then
|
||||||
|
log "lsusb hat $nusb Cypress-USB-Gerät(e) (Vendor 04b4) gefunden"
|
||||||
|
local i
|
||||||
|
for ((i = 0; i < nusb; i++)); do
|
||||||
|
CAMERAS+=("$i")
|
||||||
|
done
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# ---------------------------------------------------------------------------
|
||||||
|
# Pipeline je nach Modus (Parameter: Kamera-Index)
|
||||||
|
# ---------------------------------------------------------------------------
|
||||||
|
make_pipeline() {
|
||||||
|
local i="$1"
|
||||||
|
case "$MODE" in
|
||||||
|
udp)
|
||||||
|
echo "videoconvert ! x264enc tune=zerolatency bitrate=2000 ! rtph264pay ! udpsink host=$UDP_HOST port=$((UDP_PORT + i))"
|
||||||
|
;;
|
||||||
|
mjpeg)
|
||||||
|
echo "videoconvert ! jpegenc ! multipartmux ! tcpserversink host=0.0.0.0 port=$((MJPEG_PORT + i))"
|
||||||
|
;;
|
||||||
|
file)
|
||||||
|
echo "videoconvert ! x264enc ! mp4mux ! filesink location=$FILE_DIR/cam${i}.mp4"
|
||||||
|
;;
|
||||||
|
display)
|
||||||
|
echo "videoconvert ! autovideosink"
|
||||||
|
;;
|
||||||
|
custom)
|
||||||
|
local p="$CUSTOM_PIPELINE"
|
||||||
|
if [[ "$p" == *"{port}"* ]]; then
|
||||||
|
p="${p//\{port\}/$((5000 + i))}"
|
||||||
|
fi
|
||||||
|
echo "$p"
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
echo ""
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
}
|
||||||
|
|
||||||
|
# ---------------------------------------------------------------------------
|
||||||
|
# Instanz starten (Parameter: Kamera-Index)
|
||||||
|
# ---------------------------------------------------------------------------
|
||||||
|
PIDS=()
|
||||||
|
|
||||||
|
start_camera() {
|
||||||
|
local i="$1"
|
||||||
|
local sock="$SOCKET_PREFIX${i}.sock"
|
||||||
|
local pidfile="$PID_PREFIX${i}.pid"
|
||||||
|
local logf="$LOG_PREFIX${i}.log"
|
||||||
|
local pipeline resp pid
|
||||||
|
|
||||||
|
# Läuft für diese Kamera bereits eine Instanz?
|
||||||
|
if [ -f "$pidfile" ] && kill -0 "$(cat "$pidfile" 2>/dev/null)" 2>/dev/null; then
|
||||||
|
log "Kamera $i: läuft bereits (PID $(cat "$pidfile")) - wird übersprungen"
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
pipeline="$(make_pipeline "$i")"
|
||||||
|
if [ -z "$pipeline" ]; then
|
||||||
|
err "Kamera $i: keine Pipeline konfiguriert"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Eventuelle alte Socket-Datei entfernen (Instanz ist laut PID-Check nicht aktiv)
|
||||||
|
rm -f "$sock"
|
||||||
|
|
||||||
|
log "Kamera $i: starte vizionStreamer (Socket: $sock)"
|
||||||
|
"$BINARY" --camera "$i" --socket "$sock" >> "$logf" 2>&1 &
|
||||||
|
pid=$!
|
||||||
|
echo "$pid" > "$pidfile"
|
||||||
|
PIDS+=("$pid")
|
||||||
|
|
||||||
|
if ! wait_for_socket "$sock"; then
|
||||||
|
err "Kamera $i: Socket ist nicht aufgetaucht (Kamera nicht verfügbar? Log: $logf)"
|
||||||
|
wait "$pid" 2>/dev/null
|
||||||
|
rm -f "$pidfile"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Pipeline setzen
|
||||||
|
resp="$(send_cmd "$sock" "{\"command\":\"set_pipeline\",\"params\":{\"pipeline\":\"$(json_escape "$pipeline")\"}}")"
|
||||||
|
if ! echo "$resp" | grep -q '"status"[[:space:]]*:[[:space:]]*"success"'; then
|
||||||
|
err "Kamera $i: set_pipeline fehlgeschlagen: $resp"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Stream starten
|
||||||
|
send_cmd "$sock" '{"command":"start_stream"}' >/dev/null 2>&1
|
||||||
|
sleep 1
|
||||||
|
|
||||||
|
# Status prüfen
|
||||||
|
resp="$(send_cmd "$sock" '{"command":"get_status"}')"
|
||||||
|
if echo "$resp" | grep -q '"streaming"[[:space:]]*:[[:space:]]*true'; then
|
||||||
|
log "Kamera $i: [OK] Stream läuft | $pipeline"
|
||||||
|
return 0
|
||||||
|
else
|
||||||
|
err "Kamera $i: Stream konnte nicht gestartet werden: $resp"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# ---------------------------------------------------------------------------
|
||||||
|
# Alle Instanzen stoppen
|
||||||
|
# ---------------------------------------------------------------------------
|
||||||
|
stop_all() {
|
||||||
|
local found=0
|
||||||
|
local pidfile idx sock pid
|
||||||
|
for pidfile in "$PID_PREFIX"*.pid; do
|
||||||
|
[ -e "$pidfile" ] || continue
|
||||||
|
idx="${pidfile#"$PID_PREFIX"}"
|
||||||
|
idx="${idx%.pid}"
|
||||||
|
sock="$SOCKET_PREFIX$idx.sock"
|
||||||
|
pid="$(cat "$pidfile" 2>/dev/null || true)"
|
||||||
|
|
||||||
|
# Zuerst den Stream stoppen (best effort)
|
||||||
|
if [ -S "$sock" ]; then
|
||||||
|
send_cmd "$sock" '{"command":"stop_stream"}' >/dev/null 2>&1
|
||||||
|
fi
|
||||||
|
if [ -n "$pid" ] && kill -0 "$pid" 2>/dev/null; then
|
||||||
|
kill "$pid" 2>/dev/null
|
||||||
|
log "Kamera $idx: gestoppt (PID $pid)"
|
||||||
|
fi
|
||||||
|
rm -f "$pidfile"
|
||||||
|
found=1
|
||||||
|
done
|
||||||
|
[ "$found" -eq 1 ] || log "Keine laufenden Instanzen gefunden."
|
||||||
|
}
|
||||||
|
|
||||||
|
cleanup() {
|
||||||
|
echo
|
||||||
|
log "Stoppe alle Streams..."
|
||||||
|
stop_all
|
||||||
|
log "Fertig."
|
||||||
|
exit 0
|
||||||
|
}
|
||||||
|
|
||||||
|
# ---------------------------------------------------------------------------
|
||||||
|
# Argumente parsen
|
||||||
|
# ---------------------------------------------------------------------------
|
||||||
|
MODE=""
|
||||||
|
UDP_HOST="127.0.0.1"
|
||||||
|
UDP_PORT=5000
|
||||||
|
MJPEG_PORT=8080
|
||||||
|
FILE_DIR="/tmp"
|
||||||
|
CUSTOM_PIPELINE=""
|
||||||
|
LIST_ONLY=0
|
||||||
|
STOP_ONLY=0
|
||||||
|
|
||||||
|
while [ $# -gt 0 ]; do
|
||||||
|
case "$1" in
|
||||||
|
--list)
|
||||||
|
LIST_ONLY=1
|
||||||
|
;;
|
||||||
|
--stop)
|
||||||
|
STOP_ONLY=1
|
||||||
|
;;
|
||||||
|
--udp)
|
||||||
|
MODE="udp"
|
||||||
|
if [ $# -ge 2 ] && [[ "$2" != --* ]]; then UDP_HOST="$2"; shift; fi
|
||||||
|
if [ $# -ge 2 ] && [[ "$2" =~ ^[0-9]+$ ]]; then UDP_PORT="$2"; shift; fi
|
||||||
|
;;
|
||||||
|
--mjpeg)
|
||||||
|
MODE="mjpeg"
|
||||||
|
if [ $# -ge 2 ] && [[ "$2" =~ ^[0-9]+$ ]]; then MJPEG_PORT="$2"; shift; fi
|
||||||
|
;;
|
||||||
|
--file)
|
||||||
|
MODE="file"
|
||||||
|
if [ $# -ge 2 ] && [[ "$2" != --* ]]; then FILE_DIR="$2"; shift; fi
|
||||||
|
;;
|
||||||
|
--display)
|
||||||
|
MODE="display"
|
||||||
|
;;
|
||||||
|
--pipeline)
|
||||||
|
MODE="custom"
|
||||||
|
if [ $# -lt 2 ]; then
|
||||||
|
err "--pipeline benötigt ein Argument"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
CUSTOM_PIPELINE="$2"
|
||||||
|
shift
|
||||||
|
;;
|
||||||
|
-h|--help)
|
||||||
|
usage
|
||||||
|
exit 0
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
err "Unbekannte Option: $1"
|
||||||
|
usage
|
||||||
|
exit 1
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
shift
|
||||||
|
done
|
||||||
|
|
||||||
|
# ---------------------------------------------------------------------------
|
||||||
|
# Hauptablauf
|
||||||
|
# ---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
# Nur stoppen?
|
||||||
|
if [ $STOP_ONLY -eq 1 ]; then
|
||||||
|
stop_all
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Nur auflisten?
|
||||||
|
if [ $LIST_ONLY -eq 1 ]; then
|
||||||
|
detect_cameras
|
||||||
|
if [ ${#CAMERAS[@]} -eq 0 ]; then
|
||||||
|
echo "Keine VIZION-Kameras gefunden."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
echo "Gefunden: ${#CAMERAS[@]} VIZION-Kamera(n)"
|
||||||
|
if [ -n "$DETECT_OUTPUT" ]; then
|
||||||
|
echo "$DETECT_OUTPUT"
|
||||||
|
else
|
||||||
|
for i in "${CAMERAS[@]}"; do
|
||||||
|
echo " [$i] (Cypress USB-Gerät)"
|
||||||
|
done
|
||||||
|
fi
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Standardmodus
|
||||||
|
if [ -z "$MODE" ]; then
|
||||||
|
MODE="udp"
|
||||||
|
log "Kein Modus angegeben - Standard: UDP nach 127.0.0.1 (mit --udp <host> an einen Remote-Rechner streamen)"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Abhängigkeiten prüfen
|
||||||
|
if [ ! -x "$BINARY" ]; then
|
||||||
|
err "vizionStreamer nicht gefunden: $BINARY"
|
||||||
|
err "Erst bauen: cmake -B build -S . && cmake --build build"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
if ! command -v socat >/dev/null 2>&1; then
|
||||||
|
err "socat nicht gefunden (installieren mit: sudo apt install socat)"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
if [ "$MODE" = "file" ]; then
|
||||||
|
mkdir -p "$FILE_DIR" || { err "Kann Verzeichnis $FILE_DIR nicht anlegen"; exit 1; }
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Kameras erkennen
|
||||||
|
detect_cameras
|
||||||
|
if [ ${#CAMERAS[@]} -eq 0 ]; then
|
||||||
|
err "Keine VIZION-Kameras gefunden."
|
||||||
|
err "Verbindung prüfen (dmesg) und ggf. /opt/vizionsdk/init_driver.sh ausführen."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
log "Gefunden: ${#CAMERAS[@]} VIZION-Kamera(n): ${CAMERAS[*]}"
|
||||||
|
|
||||||
|
# Ctrl+C -> alles sauber stoppen
|
||||||
|
trap cleanup INT TERM
|
||||||
|
|
||||||
|
# Der Reihe nach: für jede Kamera Instanz starten + Stream
|
||||||
|
OK_COUNT=0
|
||||||
|
FAIL_COUNT=0
|
||||||
|
for i in "${CAMERAS[@]}"; do
|
||||||
|
if start_camera "$i"; then
|
||||||
|
OK_COUNT=$((OK_COUNT + 1))
|
||||||
|
else
|
||||||
|
FAIL_COUNT=$((FAIL_COUNT + 1))
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
# Zusammenfassung
|
||||||
|
echo
|
||||||
|
echo "========================================"
|
||||||
|
echo "Streams gestartet: $OK_COUNT / ${#CAMERAS[@]}"
|
||||||
|
case "$MODE" in
|
||||||
|
udp)
|
||||||
|
for i in "${CAMERAS[@]}"; do
|
||||||
|
echo " Kamera $i -> udp://$UDP_HOST:$((UDP_PORT + i))"
|
||||||
|
done
|
||||||
|
echo "Empfangen (Zielrechner, Kamera 0):"
|
||||||
|
echo " gst-launch-1.0 udpsrc port=$UDP_PORT ! application/x-rtp,encoding-name=H264 ! rtph264depay ! h264parse ! avdec_h264 ! videoconvert ! autovideosink"
|
||||||
|
;;
|
||||||
|
mjpeg)
|
||||||
|
for i in "${CAMERAS[@]}"; do
|
||||||
|
echo " Kamera $i -> http://<board-ip>:$((MJPEG_PORT + i))"
|
||||||
|
done
|
||||||
|
echo "Im Browser oder mit: ffplay http://<board-ip>:$MJPEG_PORT"
|
||||||
|
;;
|
||||||
|
file)
|
||||||
|
for i in "${CAMERAS[@]}"; do
|
||||||
|
echo " Kamera $i -> $FILE_DIR/cam${i}.mp4"
|
||||||
|
done
|
||||||
|
;;
|
||||||
|
display)
|
||||||
|
echo " Fenster werden lokal angezeigt"
|
||||||
|
;;
|
||||||
|
custom)
|
||||||
|
echo " Pipeline: $CUSTOM_PIPELINE"
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
if [ $FAIL_COUNT -gt 0 ]; then
|
||||||
|
echo " ($FAIL_COUNT Kamera(n) fehlgeschlagen - Logs unter /tmp/vizion_cam<idx>.log)"
|
||||||
|
fi
|
||||||
|
echo "========================================"
|
||||||
|
echo "Drücke Ctrl+C, um alle Streams zu stoppen."
|
||||||
|
|
||||||
|
# Überwachung: melden, wenn eine Instanz stirbt
|
||||||
|
while true; do
|
||||||
|
sleep 5
|
||||||
|
alive=0
|
||||||
|
for pid in ${PIDS[@]+"${PIDS[@]}"}; do
|
||||||
|
if kill -0 "$pid" 2>/dev/null; then
|
||||||
|
alive=$((alive + 1))
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
if [ "$alive" -eq 0 ]; then
|
||||||
|
log "Alle Instanzen haben sich beendet."
|
||||||
|
break
|
||||||
|
fi
|
||||||
|
done
|
||||||
Reference in new issue
Block a user