From bfc50ffc0183ee5af69cf1d6c445bfc6c57ead6c Mon Sep 17 00:00:00 2001 From: cpu Date: Thu, 15 Feb 2024 15:59:52 +0100 Subject: [PATCH] Initial --- capture_video.sh | 143 ++++++++++++++++++++++++++++++++++++++++ webcam-cleanup.service | 22 +++++++ webcam-cleanup.timer | 14 ++++ webcam-streamer | 15 +++++ webcam-streamer.service | 61 +++++++++++++++++ 5 files changed, 255 insertions(+) create mode 100755 capture_video.sh create mode 100644 webcam-cleanup.service create mode 100644 webcam-cleanup.timer create mode 100644 webcam-streamer create mode 100644 webcam-streamer.service diff --git a/capture_video.sh b/capture_video.sh new file mode 100755 index 0000000..4fd6a25 --- /dev/null +++ b/capture_video.sh @@ -0,0 +1,143 @@ +#!/bin/bash + +if [[ "$1" == *help ]]; then + echo "Example usage: ${0} [-duration 10] [-sound plughw:1,0]" + echo "optional -duration is in seconds" + echo "optional -sound values: [none, anullsrc, plughw:1,0]" + echo "default -sound is none i.e. no sound" + exit 1 +fi + +#VIDEO_RES_HEIGHT="1080" +#VIDEO_RES_WIDTH="1920" +#VIDEO_FRAMERATE="30" + +#VIDEO_RES_HEIGHT="972" +#VIDEO_RES_WIDTH="1296" +#VIDEO_FRAMERATE="43" + +VIDEO_RES_HEIGHT="480" +VIDEO_RES_WIDTH="640" +VIDEO_FRAMERATE="10" +VIDEO_BITRATE="700000" + +VIDEO_DIR="video-storage" +VIDEO_FILE="${VIDEO_DIR}/camera_$(date +%Y-%m-%d_%H-%M-%S)" +VIDEO_FILE_SEGMENTED="${VIDEO_DIR}/camera_%Y-%m-%d_%H-%M-%S" +VIDEO_FILE_EXT="mp4" +VIDEO_DURATION="1000000000" +SOUND_SOURCE="none" + +LIVE_KEY="LIVE-STREAM-KEY" +PEERTUBE_LIVE="rtmp://peertube.virtonline.eu:1935/live/" + +mkdir -p $VIDEO_DIR + +while [[ $# -gt 0 ]]; do + case $1 in + -sound) + if [ -n "$2" ]; then + SOUND_SOURCE="$2" + shift + fi + ;; + -duration) + if [ -n "$2" ]; then + VIDEO_DURATION="$2" + shift + fi + ;; + *) + echo "Unknown parameter $1" + exit 1 + esac + shift +done + +# Set up a trap to check for SIGINT +trap "pkill rpicam-vid; exit 130" SIGINT + +# Start the pipeline +rpicam-vid --inline \ + -n \ + -t 0 \ + --width ${VIDEO_RES_WIDTH} \ + --height ${VIDEO_RES_HEIGHT} \ + --nopreview \ + --exposure long \ + --sharpness 1.2 \ + --contrast 1.4 \ + --brightness 0.2 \ + --saturation 1.0 \ + --awb auto \ + --denoise auto \ + --rotation 0 \ + --autofocus-mode auto \ + --codec h264 \ + --framerate ${VIDEO_FRAMERATE} \ + -b ${VIDEO_BITRATE} \ + -o - | \ + +if [ "${SOUND_SOURCE}" = "none" ]; then + # ffmpeg params without audio + ffmpeg -hide_banner \ + -thread_queue_size 1024 \ + -t ${VIDEO_DURATION} \ + -i pipe:0 \ + -c:v copy \ + -f tee -map 0:0 -flags +global_header -flvflags no_duration_filesize \ + "[f=segment \ + :segment_time=3600 \ + :reset_timestamps=1 \ + :strftime=1 \ + :segment_format=mp4 \ + :onfail=ignore \ + ]${VIDEO_FILE_SEGMENTED}.${VIDEO_FILE_EXT} \ + | \ + [f=fifo \ + :fifo_format=flv \ + :drop_pkts_on_overflow=1 \ + :attempt_recovery=1 \ + :recovery_wait_time=1 \ + :use_wallclock_as_timestamps=1 \ + ]${PEERTUBE_LIVE}${LIVE_KEY}" \ + & +elif [ "${SOUND_SOURCE}" = "anullsrc" ]; then + # ffmpeg params with silent audio + ffmpeg -hide_banner \ + -f lavfi \ + -i anullsrc=channel_layout=stereo:sample_rate=44100 \ + -thread_queue_size 1024 \ + -use_wallclock_as_timestamps 1 \ + -i pipe:0 \ + -c:v copy \ + -c:a aac \ + -preset fast \ + -strict experimental \ + -f mp4 \ + -t ${VIDEO_DURATION} \ + ${VIDEO_FILE}.${VIDEO_FILE_EXT} & +else + # ffmpeg params with audio + ffmpeg -hide_banner \ + -f alsa \ + -thread_queue_size 1024 \ + -ac 2 \ + -i ${SOUND_SOURCE} \ + -thread_queue_size 1024 \ + -use_wallclock_as_timestamps 1 \ + -i pipe:0 \ + -c:v copy \ + -c:a aac \ + -b:a 32k \ + -ar 44100 \ + -f mp4 \ + -t ${VIDEO_DURATION} \ + ${VIDEO_FILE}.${VIDEO_FILE_EXT} & +fi + +# Get process ID +pid=$! + +# Wait for process to finish or get terminated signal +wait || pkill rpicam-vid; exit 130 diff --git a/webcam-cleanup.service b/webcam-cleanup.service new file mode 100644 index 0000000..80064f7 --- /dev/null +++ b/webcam-cleanup.service @@ -0,0 +1,22 @@ +[Unit] +Description=Webcam Cleanup service +Requires=docker.service +After=docker.service +DefaultDependencies=no + +[Service] +Type=simple +User=pi +Group=pi + +Environment="HOME=/home/pi" +EnvironmentFile=/etc/default/webcam-streamer +WorkingDirectory=/home/pi + +# The corresponding .timer will invoke this service every hour. + +# Delete video files older then e.q. 14 days +ExecStart=/usr/bin/find ${DIR} -name '${FILENAME_PREFIX}*.${FILENAME_EXT}' -mtime +${REMOVE_OLDER_THEN_DAYS} -exec rm -vf {} \; + +[Install] +WantedBy=multi-user.target diff --git a/webcam-cleanup.timer b/webcam-cleanup.timer new file mode 100644 index 0000000..2f3cdcd --- /dev/null +++ b/webcam-cleanup.timer @@ -0,0 +1,14 @@ +[Unit] +Description=Reloads webcam-cleanup periodically to delete old video files + +[Timer] +Unit=webcam-cleanup.service + +# Run on every hour of every day +OnCalendar=*-*-* *:00:00 + +# Do not execute job if it missed a run due to machine being off +Persistent=false + +[Install] +WantedBy=timers.target diff --git a/webcam-streamer b/webcam-streamer new file mode 100644 index 0000000..561f3ab --- /dev/null +++ b/webcam-streamer @@ -0,0 +1,15 @@ +LIVE_KEY="LIVE-STREAM-KEY" +PEERTUBE_LIVE="rtmp://peertube.virtonline.eu:1935/live/" + +BITRATE="700000" +RES_HEIGHT="480" +RES_WIDTH="640" +FRAMERATE="10" + +DIR="/home/pi/video-storage" +FILENAME_PREFIX="camera_" +FILENAME_SEGMENT_PATTERN="%Y-%m-%d_%H-%M-%S" +FILENAME_EXT="mp4" +SEGMENT_DURATION=3600 + +REMOVE_OLDER_THEN_DAYS=14 diff --git a/webcam-streamer.service b/webcam-streamer.service new file mode 100644 index 0000000..79b0fde --- /dev/null +++ b/webcam-streamer.service @@ -0,0 +1,61 @@ +[Unit] +Description=Webcam Streamer service +Requires=network-online.target +After=network-online.target +DefaultDependencies=no + +[Service] +Type=simple + +User=pi +Group=pi + +Environment="HOME=/home/pi" +EnvironmentFile=/etc/default/webcam-streamer + +WorkingDirectory=/home/pi + +ExecStartPre=-/usr/bin/env sh -c 'killall rpicam-vid 2>/dev/null || true' +ExecStartPre=-/usr/bin/env sh -c 'mkdir -p $DIR' + +ExecStart=/bin/bash -c 'rpicam-vid --inline \ + -t 0 \ + --width ${RES_WIDTH} \ + --height ${RES_HEIGHT} \ + --nopreview \ + --awb auto \ + --denoise auto \ + --rotation 0 \ + --autofocus-mode auto \ + --codec h264 \ + -b ${BITRATE} \ + -o - | \ + ffmpeg -hide_banner \ + -thread_queue_size 1024 \ + -i pipe:0 \ + -c:v copy \ + -f tee -map 0:0 -flags +global_header -flvflags no_duration_filesize \ + "[f=segment \ + :segment_format=mp4 \ + :segment_time=${SEGMENT_DURATION} \ + :reset_timestamps=1 \ + :strftime=1 \ + :onfail=ignore \ + ]${DIR}/${FILENAME_PREFIX}${FILENAME_SEGMENT_PATTERN}.${FILENAME_EXT} \ + | \ + [f=fifo \ + :fifo_format=flv \ + :drop_pkts_on_overflow=1 \ + :attempt_recovery=1 \ + :recovery_wait_time=1 \ + :use_wallclock_as_timestamps=1 \ + ]${PEERTUBE_LIVE}${LIVE_KEY}"' + +ExecStop=-/usr/bin/env sh -c 'killall rpicam-vid 2>/dev/null || true' + +Restart=always +RestartSec=3 +SyslogIdentifier=webcam-streamer + +[Install] +WantedBy=multi-user.target