Release: v2.7.0 + Dokumentation ausgelagert
This commit is contained in:
+283
-15
@@ -8,15 +8,15 @@
|
||||
# Web: https://www.cleveradmin.de
|
||||
# Repository: https://git.techniverse.net/scriptos/stream-recorder.git
|
||||
# License: MIT
|
||||
# Version: v2.6.2
|
||||
# Date: 06.09.2026
|
||||
# Modifications: Mehrtägige Aufnahmen nun möglich
|
||||
# Version: v2.7.0
|
||||
# Date: 07.09.2026
|
||||
# Modifications: Segment-Splitting, erweiterter Status, verbessertes Stoppen
|
||||
###############################################
|
||||
|
||||
set -uo pipefail
|
||||
|
||||
readonly SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
readonly VERSION="2.6.0"
|
||||
readonly VERSION="2.7.0"
|
||||
|
||||
# --- Standardwerte (überschreibbar via Konfiguration) ---
|
||||
CONFIG_FILE="${SCRIPT_DIR}/config/stream-recorder.conf"
|
||||
@@ -224,6 +224,57 @@ parse_duration() {
|
||||
echo "$total"
|
||||
}
|
||||
|
||||
format_elapsed() {
|
||||
local seconds=$1
|
||||
local d=$((seconds / 86400))
|
||||
local h=$(( (seconds % 86400) / 3600 ))
|
||||
local m=$(( (seconds % 3600) / 60 ))
|
||||
local s=$((seconds % 60))
|
||||
|
||||
if [[ $d -gt 0 ]]; then
|
||||
printf "%dd %dh %dm" "$d" "$h" "$m"
|
||||
elif [[ $h -gt 0 ]]; then
|
||||
printf "%dh %dm %ds" "$h" "$m" "$s"
|
||||
else
|
||||
printf "%dm %ds" "$m" "$s"
|
||||
fi
|
||||
}
|
||||
|
||||
format_size() {
|
||||
local bytes=$1
|
||||
if [[ $bytes -ge 1073741824 ]]; then
|
||||
awk "BEGIN {printf \"%.1f GB\", $bytes/1073741824}"
|
||||
elif [[ $bytes -ge 1048576 ]]; then
|
||||
awk "BEGIN {printf \"%.1f MB\", $bytes/1048576}"
|
||||
elif [[ $bytes -ge 1024 ]]; then
|
||||
awk "BEGIN {printf \"%.1f KB\", $bytes/1024}"
|
||||
else
|
||||
printf "%d B" "$bytes"
|
||||
fi
|
||||
}
|
||||
|
||||
write_job_info() {
|
||||
local job_id="$1" stream_name="$2" output_dir="$3" output_file="$4"
|
||||
local stream_type="$5" segment_mode="$6" job_file="$7"
|
||||
local info_file="${PID_DIR}/${job_id}.info"
|
||||
|
||||
cat > "$info_file" <<INFOEOF
|
||||
STREAM_NAME="${stream_name}"
|
||||
STREAM_TYPE="${stream_type}"
|
||||
OUTPUT_DIR="${output_dir}"
|
||||
OUTPUT_FILE="${output_file}"
|
||||
START_TIME="$(date '+%Y-%m-%d %H:%M:%S')"
|
||||
START_EPOCH=$(date +%s)
|
||||
SEGMENT_MODE="${segment_mode}"
|
||||
JOB_FILE="${job_file}"
|
||||
INFOEOF
|
||||
}
|
||||
|
||||
remove_job_info() {
|
||||
local job_id="$1"
|
||||
rm -f "${PID_DIR}/${job_id}.info" 2>/dev/null || true
|
||||
}
|
||||
|
||||
# --- Tages-/Zeitplanung ---
|
||||
|
||||
_day_name_to_num() {
|
||||
@@ -298,7 +349,13 @@ load_config() {
|
||||
# shellcheck source=/dev/null
|
||||
source "$CONFIG_FILE"
|
||||
else
|
||||
log "WARN" "Konfigurationsdatei nicht gefunden: ${CONFIG_FILE} - verwende Standardwerte"
|
||||
local dist_file="${CONFIG_FILE}.dist"
|
||||
if [[ -f "$dist_file" ]]; then
|
||||
log "WARN" "Konfigurationsdatei nicht gefunden: ${CONFIG_FILE}"
|
||||
log "INFO" "Vorlage kopieren: cp ${dist_file} ${CONFIG_FILE}"
|
||||
else
|
||||
log "WARN" "Konfigurationsdatei nicht gefunden: ${CONFIG_FILE} - verwende Standardwerte"
|
||||
fi
|
||||
fi
|
||||
mkdir -p "$DOWNLOAD_PATH" "$LOG_DIR" "$PID_DIR" "$STATE_DIR" 2>/dev/null || true
|
||||
}
|
||||
@@ -360,6 +417,7 @@ load_job() {
|
||||
SCHEDULE_STOP=""
|
||||
PLIK_ENABLED="false"
|
||||
DELETE_AFTER_UPLOAD="false"
|
||||
SEGMENT_DURATION=""
|
||||
|
||||
if [[ ! -f "$job_file" ]]; then
|
||||
log "ERROR" "Job-Datei nicht gefunden: ${job_file}"
|
||||
@@ -462,6 +520,58 @@ mark_schedule_started() {
|
||||
fi
|
||||
}
|
||||
|
||||
# =============================================
|
||||
# Segment-Upload
|
||||
# =============================================
|
||||
|
||||
_segment_upload_loop() {
|
||||
local output_dir="$1" segment_glob="$2" stream_name="$3"
|
||||
local uploaded_list="$4" stop_flag="$5"
|
||||
|
||||
while [[ ! -f "$stop_flag" ]]; do
|
||||
sleep 60
|
||||
[[ -f "$stop_flag" ]] && break
|
||||
|
||||
local -a all_segments=()
|
||||
for f in "$output_dir"/$segment_glob; do
|
||||
[[ -f "$f" ]] && all_segments+=("$f")
|
||||
done
|
||||
|
||||
IFS=$'\n' all_segments=($(sort <<<"${all_segments[*]}")); unset IFS
|
||||
|
||||
[[ ${#all_segments[@]} -lt 2 ]] && continue
|
||||
|
||||
local i
|
||||
for (( i=0; i < ${#all_segments[@]} - 1; i++ )); do
|
||||
local seg="${all_segments[$i]}"
|
||||
if ! grep -qxF "$seg" "$uploaded_list" 2>/dev/null; then
|
||||
if [[ -s "$seg" ]]; then
|
||||
log "INFO" "Segment-Upload: $(basename "$seg")"
|
||||
upload_to_plik "$seg" "$stream_name" && echo "$seg" >> "$uploaded_list"
|
||||
fi
|
||||
fi
|
||||
done
|
||||
done
|
||||
}
|
||||
|
||||
_upload_remaining_segments() {
|
||||
local output_dir="$1" segment_glob="$2" stream_name="$3" uploaded_list="$4"
|
||||
|
||||
local count=0
|
||||
for seg in "$output_dir"/$segment_glob; do
|
||||
[[ -f "$seg" ]] || continue
|
||||
[[ -s "$seg" ]] || continue
|
||||
if ! grep -qxF "$seg" "$uploaded_list" 2>/dev/null; then
|
||||
log "INFO" "Segment-Upload (verbleibend): $(basename "$seg")"
|
||||
upload_to_plik "$seg" "$stream_name" && echo "$seg" >> "$uploaded_list"
|
||||
count=$((count + 1))
|
||||
fi
|
||||
done
|
||||
|
||||
[[ $count -gt 0 ]] && log "INFO" "${count} verbleibende(s) Segment(e) hochgeladen"
|
||||
rm -f "$uploaded_list" 2>/dev/null || true
|
||||
}
|
||||
|
||||
# =============================================
|
||||
# Aufnahme
|
||||
# =============================================
|
||||
@@ -480,12 +590,26 @@ record_stream() {
|
||||
local ext="${OUTPUT_FORMAT}"
|
||||
[[ -z "$ext" ]] && ext=$(default_extension "$stream_type")
|
||||
|
||||
local segment_seconds=""
|
||||
local segment_mode=false
|
||||
if [[ -n "${SEGMENT_DURATION:-}" ]]; then
|
||||
segment_seconds=$(parse_duration "$SEGMENT_DURATION")
|
||||
if [[ -n "$segment_seconds" && "$segment_seconds" -gt 0 ]]; then
|
||||
segment_mode=true
|
||||
fi
|
||||
fi
|
||||
|
||||
local safe_name
|
||||
safe_name=$(echo "$STREAM_NAME" | tr -cs 'A-Za-z0-9_-' '_' | sed 's/_$//')
|
||||
local timestamp
|
||||
timestamp=$(date +'%Y%m%d_%H%M%S')
|
||||
local output_dir="${DOWNLOAD_PATH}/${safe_name}"
|
||||
local output_file="${output_dir}/${safe_name}_${timestamp}.${ext}"
|
||||
local output_pattern=""
|
||||
if $segment_mode; then
|
||||
output_file="${output_dir}/${safe_name}_${timestamp}_seg%03d.${ext}"
|
||||
output_pattern="${safe_name}_${timestamp}_seg*.${ext}"
|
||||
fi
|
||||
local pid_file="${PID_DIR}/${job_id}.pid"
|
||||
local ffmpeg_log="${LOG_DIR}/ffmpeg_${job_id}.log"
|
||||
|
||||
@@ -496,8 +620,13 @@ record_stream() {
|
||||
return 1
|
||||
fi
|
||||
|
||||
log "INFO" "Starte Aufnahme: ${STREAM_NAME} [${stream_type}] -> ${output_file}"
|
||||
if $segment_mode; then
|
||||
log "INFO" "Starte Aufnahme: ${STREAM_NAME} [${stream_type}] -> ${output_dir} (Segment: alle $(format_elapsed "$segment_seconds"))"
|
||||
else
|
||||
log "INFO" "Starte Aufnahme: ${STREAM_NAME} [${stream_type}] -> ${output_file}"
|
||||
fi
|
||||
notify "start" "Aufnahme gestartet" "${STREAM_NAME} [${stream_type}]"
|
||||
write_job_info "$job_id" "$STREAM_NAME" "$output_dir" "$output_file" "$stream_type" "$segment_mode" "$job_file"
|
||||
|
||||
local ffmpeg_loglevel="warning"
|
||||
[[ "$VERBOSE" == "true" ]] && ffmpeg_loglevel="info"
|
||||
@@ -509,6 +638,10 @@ record_stream() {
|
||||
*) ffmpeg_args+=(-i "$STREAM_URL" -c copy) ;;
|
||||
esac
|
||||
|
||||
if $segment_mode; then
|
||||
ffmpeg_args+=(-f segment -segment_time "$segment_seconds" -reset_timestamps 1)
|
||||
fi
|
||||
|
||||
[[ -n "$MAX_DURATION" ]] && ffmpeg_args+=(-t "$MAX_DURATION")
|
||||
|
||||
if [[ -n "$EXTRA_FFMPEG_ARGS" ]]; then
|
||||
@@ -521,16 +654,33 @@ record_stream() {
|
||||
|
||||
_SR_FFMPEG_PID=""
|
||||
_SR_PID_FILE="$pid_file"
|
||||
_SR_JOB_ID="$job_id"
|
||||
_SR_SEGMENT_STOP_FLAG=""
|
||||
_SR_SEGMENT_UPLOADER_PID=""
|
||||
_cleanup() {
|
||||
if [[ -n "${_SR_SEGMENT_STOP_FLAG:-}" ]]; then
|
||||
touch "$_SR_SEGMENT_STOP_FLAG" 2>/dev/null || true
|
||||
fi
|
||||
if [[ -n "${_SR_SEGMENT_UPLOADER_PID:-}" ]] && kill -0 "$_SR_SEGMENT_UPLOADER_PID" 2>/dev/null; then
|
||||
wait "$_SR_SEGMENT_UPLOADER_PID" 2>/dev/null || true
|
||||
fi
|
||||
if [[ -n "${_SR_FFMPEG_PID:-}" ]] && kill -0 "$_SR_FFMPEG_PID" 2>/dev/null; then
|
||||
kill -INT "$_SR_FFMPEG_PID" 2>/dev/null || true
|
||||
wait "$_SR_FFMPEG_PID" 2>/dev/null || true
|
||||
fi
|
||||
rm -f "${_SR_PID_FILE:-}"
|
||||
rm -f "${_SR_PID_FILE%.pid}.scheduled" 2>/dev/null || true
|
||||
remove_job_info "${_SR_JOB_ID:-}"
|
||||
rm -f "${_SR_SEGMENT_STOP_FLAG:-}" 2>/dev/null || true
|
||||
}
|
||||
trap _cleanup EXIT TERM INT
|
||||
|
||||
local _sr_uploaded_list=""
|
||||
if $segment_mode; then
|
||||
_sr_uploaded_list=$(mktemp)
|
||||
_SR_SEGMENT_STOP_FLAG=$(mktemp -u)
|
||||
fi
|
||||
|
||||
local retry=0
|
||||
while true; do
|
||||
if [[ "$VERBOSE" == "true" ]]; then
|
||||
@@ -541,12 +691,28 @@ record_stream() {
|
||||
_SR_FFMPEG_PID=$!
|
||||
echo "$_SR_FFMPEG_PID" > "$pid_file"
|
||||
|
||||
if $segment_mode; then
|
||||
rm -f "$_SR_SEGMENT_STOP_FLAG" 2>/dev/null || true
|
||||
_segment_upload_loop "$output_dir" "$output_pattern" "$STREAM_NAME" "$_sr_uploaded_list" "$_SR_SEGMENT_STOP_FLAG" &
|
||||
_SR_SEGMENT_UPLOADER_PID=$!
|
||||
fi
|
||||
|
||||
local ret=0
|
||||
wait "$_SR_FFMPEG_PID" || ret=$?
|
||||
_SR_FFMPEG_PID=""
|
||||
|
||||
if [[ -n "${_SR_SEGMENT_UPLOADER_PID:-}" ]] && kill -0 "$_SR_SEGMENT_UPLOADER_PID" 2>/dev/null; then
|
||||
touch "$_SR_SEGMENT_STOP_FLAG" 2>/dev/null || true
|
||||
wait "$_SR_SEGMENT_UPLOADER_PID" 2>/dev/null || true
|
||||
_SR_SEGMENT_UPLOADER_PID=""
|
||||
fi
|
||||
|
||||
if [[ $ret -eq 0 ]]; then
|
||||
if [[ -s "$output_file" ]]; then
|
||||
if $segment_mode; then
|
||||
_upload_remaining_segments "$output_dir" "$output_pattern" "$STREAM_NAME" "$_sr_uploaded_list"
|
||||
log "INFO" "Aufnahme abgeschlossen: ${STREAM_NAME} (segmentiert)"
|
||||
notify "stop" "Aufnahme abgeschlossen" "${STREAM_NAME} (segmentiert)"
|
||||
elif [[ -s "$output_file" ]]; then
|
||||
log "INFO" "Aufnahme abgeschlossen: ${output_file}"
|
||||
notify "stop" "Aufnahme abgeschlossen" "${STREAM_NAME}: ${output_file}"
|
||||
upload_to_plik "$output_file" "$STREAM_NAME"
|
||||
@@ -561,7 +727,9 @@ record_stream() {
|
||||
if [[ $ret -eq 143 || $ret -eq 130 ]]; then
|
||||
log "INFO" "Aufnahme gestoppt: ${STREAM_NAME}"
|
||||
notify "stop" "Aufnahme gestoppt" "${STREAM_NAME} wurde gestoppt"
|
||||
if [[ -s "$output_file" ]]; then
|
||||
if $segment_mode; then
|
||||
_upload_remaining_segments "$output_dir" "$output_pattern" "$STREAM_NAME" "$_sr_uploaded_list"
|
||||
elif [[ -s "$output_file" ]]; then
|
||||
upload_to_plik "$output_file" "$STREAM_NAME"
|
||||
fi
|
||||
break
|
||||
@@ -570,7 +738,9 @@ record_stream() {
|
||||
if [[ ! -f "$pid_file" ]]; then
|
||||
log "INFO" "Aufnahme gestoppt: ${STREAM_NAME}"
|
||||
notify "stop" "Aufnahme gestoppt" "${STREAM_NAME} wurde gestoppt"
|
||||
if [[ -s "$output_file" ]]; then
|
||||
if $segment_mode; then
|
||||
_upload_remaining_segments "$output_dir" "$output_pattern" "$STREAM_NAME" "$_sr_uploaded_list"
|
||||
elif [[ -s "$output_file" ]]; then
|
||||
upload_to_plik "$output_file" "$STREAM_NAME"
|
||||
fi
|
||||
break
|
||||
@@ -592,18 +762,38 @@ record_stream() {
|
||||
|
||||
log "WARN" "Verbindung zu '${STREAM_NAME}' verloren (Code: ${ret})${retry_info}. Reconnect in ${RETRY_DELAY}s..."
|
||||
notify "error" "Stream abgerissen" "${STREAM_NAME}: Verbindung verloren (Code: ${ret}). Reconnect in ${RETRY_DELAY}s..." "default"
|
||||
|
||||
if $segment_mode; then
|
||||
_upload_remaining_segments "$output_dir" "$output_pattern" "$STREAM_NAME" "$_sr_uploaded_list"
|
||||
fi
|
||||
|
||||
sleep "$RETRY_DELAY"
|
||||
|
||||
timestamp=$(date +'%Y%m%d_%H%M%S')
|
||||
output_file="${output_dir}/${safe_name}_${timestamp}.${ext}"
|
||||
if $segment_mode; then
|
||||
output_file="${output_dir}/${safe_name}_${timestamp}_seg%03d.${ext}"
|
||||
output_pattern="${safe_name}_${timestamp}_seg*.${ext}"
|
||||
else
|
||||
output_file="${output_dir}/${safe_name}_${timestamp}.${ext}"
|
||||
fi
|
||||
ffmpeg_args[-1]="$output_file"
|
||||
done
|
||||
|
||||
trap - EXIT TERM INT
|
||||
rm -f "$pid_file"
|
||||
rm -f "${pid_file%.pid}.scheduled" 2>/dev/null || true
|
||||
remove_job_info "$job_id"
|
||||
rm -f "${_SR_SEGMENT_STOP_FLAG:-}" 2>/dev/null || true
|
||||
|
||||
if [[ -f "$output_file" && ! -s "$output_file" ]]; then
|
||||
if $segment_mode; then
|
||||
for seg in "$output_dir"/$output_pattern; do
|
||||
[[ -f "$seg" ]] || continue
|
||||
if [[ ! -s "$seg" ]]; then
|
||||
rm -f "$seg"
|
||||
log "WARN" "Leeres Segment entfernt: ${seg}"
|
||||
fi
|
||||
done
|
||||
elif [[ -f "$output_file" && ! -s "$output_file" ]]; then
|
||||
rm -f "$output_file"
|
||||
log "WARN" "Leere Ausgabedatei entfernt: ${output_file}"
|
||||
fi
|
||||
@@ -887,6 +1077,19 @@ create_job() {
|
||||
fi
|
||||
fi
|
||||
|
||||
echo ""
|
||||
echo "--- Segment-Splitting (optional) ---"
|
||||
local segment_duration=""
|
||||
read -rp "Aufnahme in Segmente teilen? (z.B. 1h, 2h oder leer=nein): " segment_input
|
||||
if [[ -n "$segment_input" ]]; then
|
||||
segment_duration=$(parse_duration "$segment_input")
|
||||
if [[ -n "$segment_duration" && "$segment_duration" -gt 0 ]]; then
|
||||
echo " Segmente alle $(format_elapsed "$segment_duration")"
|
||||
else
|
||||
segment_duration=""
|
||||
fi
|
||||
fi
|
||||
|
||||
echo ""
|
||||
echo "--- Plik-Upload (optional) ---"
|
||||
local plik_enabled="false"
|
||||
@@ -930,6 +1133,11 @@ create_job() {
|
||||
duration_display+="${d_h}h ${d_m}m"
|
||||
fi
|
||||
echo " Dauer: ${duration_display}"
|
||||
if [[ -n "$segment_duration" ]]; then
|
||||
echo " Segmente: alle $(format_elapsed "$segment_duration")"
|
||||
else
|
||||
echo " Segmente: deaktiviert"
|
||||
fi
|
||||
if [[ "$sched_enabled" == "true" ]]; then
|
||||
if [[ "$sched_once" == "true" ]]; then
|
||||
echo " Zeitplan: einmalig ${sched_date} ${sched_start}${sched_stop:+ - ${sched_stop}}"
|
||||
@@ -963,6 +1171,13 @@ OUTPUT_FORMAT="${ext}"
|
||||
MAX_DURATION="${duration}"
|
||||
EXTRA_FFMPEG_ARGS=""
|
||||
|
||||
###############################################
|
||||
# Segment-Splitting (optional)
|
||||
# Aufnahme in Teile zerlegen, z.B. 1h, 2h, 30m
|
||||
###############################################
|
||||
|
||||
SEGMENT_DURATION="${segment_duration}"
|
||||
|
||||
###############################################
|
||||
# Zeitplanung (optional)
|
||||
###############################################
|
||||
@@ -1032,6 +1247,13 @@ list_jobs() {
|
||||
extra_info+=" (Dauer: ${MAX_DURATION}s)"
|
||||
fi
|
||||
fi
|
||||
if [[ -n "${SEGMENT_DURATION:-}" ]]; then
|
||||
local seg_secs
|
||||
seg_secs=$(parse_duration "$SEGMENT_DURATION")
|
||||
if [[ -n "$seg_secs" && "$seg_secs" -gt 0 ]]; then
|
||||
extra_info+="${extra_info:+ | }Segmente: alle $(format_elapsed "$seg_secs")"
|
||||
fi
|
||||
fi
|
||||
if [[ "${PLIK_ENABLED:-false}" == "true" ]]; then
|
||||
extra_info+="${extra_info:+ | }Plik-Upload: an"
|
||||
fi
|
||||
@@ -1062,7 +1284,7 @@ list_jobs() {
|
||||
|
||||
show_status() {
|
||||
echo "Laufende Aufnahmen:"
|
||||
echo "$(printf '=%.0s' {1..50})"
|
||||
echo "$(printf '=%.0s' {1..60})"
|
||||
echo ""
|
||||
|
||||
local found=false
|
||||
@@ -1078,9 +1300,48 @@ show_status() {
|
||||
found=true
|
||||
local mode="manuell"
|
||||
[[ -f "${PID_DIR}/${job_id}.scheduled" ]] && mode="geplant"
|
||||
printf " %-20s PID: %-10s [%s]\n" "$job_id" "$pid" "$mode"
|
||||
|
||||
local info_file="${PID_DIR}/${job_id}.info"
|
||||
if [[ -f "$info_file" ]]; then
|
||||
local STREAM_NAME="" STREAM_TYPE="" OUTPUT_DIR="" OUTPUT_FILE=""
|
||||
local START_TIME="" START_EPOCH="" SEGMENT_MODE=""
|
||||
# shellcheck source=/dev/null
|
||||
source "$info_file"
|
||||
|
||||
printf " %-20s %s\n" "$job_id" "$STREAM_NAME"
|
||||
printf " %-20s PID: %s | Modus: %s | Typ: %s\n" "" "$pid" "$mode" "$STREAM_TYPE"
|
||||
printf " %-20s Gestartet: %s" "" "$START_TIME"
|
||||
|
||||
if [[ -n "$START_EPOCH" ]]; then
|
||||
local now_epoch elapsed
|
||||
now_epoch=$(date +%s)
|
||||
elapsed=$((now_epoch - START_EPOCH))
|
||||
printf " | Laufzeit: %s" "$(format_elapsed "$elapsed")"
|
||||
fi
|
||||
echo ""
|
||||
|
||||
local total_size=0
|
||||
if [[ "$SEGMENT_MODE" == "true" && -n "$OUTPUT_DIR" ]]; then
|
||||
local seg_count=0
|
||||
for seg in "$OUTPUT_DIR"/*_seg*; do
|
||||
[[ -f "$seg" ]] || continue
|
||||
local s
|
||||
s=$(stat -c%s "$seg" 2>/dev/null || echo 0)
|
||||
total_size=$((total_size + s))
|
||||
seg_count=$((seg_count + 1))
|
||||
done
|
||||
printf " %-20s Verzeichnis: %s | Segmente: %d | Größe: %s\n" "" "$OUTPUT_DIR" "$seg_count" "$(format_size "$total_size")"
|
||||
elif [[ -n "$OUTPUT_FILE" && -f "$OUTPUT_FILE" ]]; then
|
||||
total_size=$(stat -c%s "$OUTPUT_FILE" 2>/dev/null || echo 0)
|
||||
printf " %-20s Datei: %s | Größe: %s\n" "" "$OUTPUT_FILE" "$(format_size "$total_size")"
|
||||
fi
|
||||
else
|
||||
printf " %-20s PID: %-10s [%s]\n" "$job_id" "$pid" "$mode"
|
||||
fi
|
||||
echo ""
|
||||
else
|
||||
rm -f "$pid_file"
|
||||
rm -f "${PID_DIR}/${job_id}.info" 2>/dev/null || true
|
||||
fi
|
||||
done
|
||||
|
||||
@@ -1181,10 +1442,10 @@ Befehle:
|
||||
create Neuen Job interaktiv erstellen
|
||||
quick Interaktive Schnellaufnahme (URL eingeben)
|
||||
upload <datei> Vorhandene Datei nach Plik hochladen
|
||||
stop <name> Aufnahme stoppen
|
||||
stop <name> Aufnahme stoppen (Teilaufnahme wird hochgeladen)
|
||||
stop-all Alle Aufnahmen stoppen
|
||||
list Jobs und deren Zeitpläne anzeigen
|
||||
status Laufende Aufnahmen und Scheduler-Status
|
||||
status Laufende Aufnahmen mit Details anzeigen
|
||||
scheduler Zeitplanung prüfen und Jobs starten/stoppen
|
||||
logs Log-Ausgabe live verfolgen
|
||||
|
||||
@@ -1195,6 +1456,11 @@ Optionen:
|
||||
-h, --help Diese Hilfe
|
||||
-v, --version Version
|
||||
|
||||
Segment-Splitting:
|
||||
Aufnahmen können in Segmente (z.B. 1h, 2h) geteilt werden.
|
||||
Jedes Segment wird einzeln nach Plik hochgeladen.
|
||||
Konfiguration: SEGMENT_DURATION in der Job-Datei.
|
||||
|
||||
Zeitplanung:
|
||||
Aufnahmen werden über die Job-Dateien geplant (SCHEDULE_*).
|
||||
Der Scheduler wird automatisch per systemd-Timer ausgeführt.
|
||||
@@ -1204,6 +1470,8 @@ Beispiele:
|
||||
$(basename "$0") record mein-stream
|
||||
$(basename "$0") quick
|
||||
$(basename "$0") -V record mein-stream
|
||||
$(basename "$0") status
|
||||
$(basename "$0") stop mein-stream
|
||||
$(basename "$0") list
|
||||
$(basename "$0") logs
|
||||
|
||||
|
||||
Reference in New Issue
Block a user