Compare commits
20 Commits
master
...
legacy-ipc
Author | SHA1 | Date | |
---|---|---|---|
![]() |
077495eba6 | ||
![]() |
b83f3e0eb7 | ||
![]() |
3a8961837c | ||
![]() |
40bcc7f5f4 | ||
![]() |
c17410c073 | ||
![]() |
cc67e1e2db | ||
![]() |
f95472b413 | ||
![]() |
9ee4fc4fde | ||
![]() |
4af565b27d | ||
![]() |
75b2517c50 | ||
![]() |
b9de2f2ce5 | ||
![]() |
e505c57464 | ||
![]() |
2ebc4c68ce | ||
![]() |
8d4045f6c3 | ||
![]() |
72a45b8521 | ||
![]() |
014f310353 | ||
![]() |
c712beb699 | ||
![]() |
c857f58b40 | ||
![]() |
ae2787b3ae | ||
![]() |
e26851a600 |
14
systemd/ipcam_rtsp2hls_rkmpp@.service
Normal file
14
systemd/ipcam_rtsp2hls_rkmpp@.service
Normal file
@ -0,0 +1,14 @@
|
||||
[Unit]
|
||||
Description=convert rtsp to hls for viewing live camera feeds in browser
|
||||
After=network-online.target
|
||||
|
||||
[Service]
|
||||
Restart=always
|
||||
RestartSec=3
|
||||
User=root
|
||||
Group=root
|
||||
EnvironmentFile=/etc/ipcam_rtsp2hls.conf.d/%i.conf
|
||||
ExecStart=/home/user/homekit/tools/ipcam_rtsp2hls_rkmpp.sh --name %i --user $USER --password $PASSWORD --ip $IP --port $PORT --force-tcp $ARGS
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
@ -94,6 +94,8 @@ done
|
||||
[ -z "$CREDS" ] && die "You must specify credentials (--creds)."
|
||||
validate_channel "$CHANNEL"
|
||||
|
||||
mountpoint "$(dirname "$OUTDIR")" || die "$(dirname "$OUTDIR") is not a mountpint!"
|
||||
|
||||
if [ ! -d "${OUTDIR}" ]; then
|
||||
mkdir "${OUTDIR}" || die "Failed to create ${OUTDIR}/${NAME}!"
|
||||
echo "Created $OUTDIR."
|
||||
@ -106,14 +108,10 @@ else
|
||||
args="$args -nostats -loglevel warning"
|
||||
fi
|
||||
|
||||
if [ "$FORCE_TCP" = "1" ]; then
|
||||
args="$args -rtsp_transport tcp"
|
||||
elif [ "$FORCE_UDP" = "1" ]; then
|
||||
args="$args -rtsp_transport udp"
|
||||
fi
|
||||
|
||||
[ ! -z "$CREDS" ] && CREDS="${CREDS}@"
|
||||
|
||||
ffmpeg $args -i rtsp://${CREDS}${IP}:${PORT}/Streaming/Channels/${CHANNEL} \
|
||||
-c copy -f segment -strftime 1 -segment_time 00:10:00 -segment_atclocktime 1 \
|
||||
ffmpeg -nostdin $args -rtsp_transport tcp -i rtsp://${CREDS}${IP}:${PORT}/Streaming/Channels/${CHANNEL} \
|
||||
-c copy -f segment -strftime 1 -segment_time 00:10:00 -segment_format_options movflags=+faststart \
|
||||
-segment_time_delta 0.01 -segment_atclocktime 1 -reset_timestamps 1 -bufsize 2M \
|
||||
-reconnect 1 -reconnect_at_eof 1 -reconnect_streamed 1 -reconnect_delay_max 2 \
|
||||
"$OUTDIR/record_%Y-%m-%d-%H.%M.%S.${EXTENSION}"
|
||||
|
4
tools/ipcam_capture_restart_all.sh
Executable file
4
tools/ipcam_capture_restart_all.sh
Executable file
@ -0,0 +1,4 @@
|
||||
#!/bin/sh
|
||||
for service in $(systemctl list-units --type service --plain --no-legend | grep ipcam_capture | awk '{print $1}'); do
|
||||
systemctl restart $service
|
||||
done
|
102
tools/ipcam_cleanup.sh
Executable file
102
tools/ipcam_cleanup.sh
Executable file
@ -0,0 +1,102 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Function to display usage
|
||||
usage() {
|
||||
echo "Usage: $0 --dir <dir1> [<dir2> ...] [--min-free-space <space_in_GiB>] [--debug]" 1>&2
|
||||
}
|
||||
|
||||
# Function to output error messages and exit
|
||||
error_msg() {
|
||||
echo "Error: $1" 1>&2
|
||||
exit 1
|
||||
}
|
||||
|
||||
# Function to output debug messages
|
||||
debug_msg() {
|
||||
if $DEBUG_MODE; then
|
||||
echo "$1"
|
||||
fi
|
||||
}
|
||||
|
||||
# Initialize variables
|
||||
declare -a DIRS
|
||||
MIN_FREE_SPACE=200 # Default minimum free space in GiB
|
||||
DEBUG_MODE=false
|
||||
PARSE_DIRS=false
|
||||
|
||||
# Parse command-line arguments
|
||||
for arg in "$@"; do
|
||||
if $PARSE_DIRS; then
|
||||
if [[ "$arg" =~ ^-- ]]; then
|
||||
PARSE_DIRS=false
|
||||
else
|
||||
DIRS+=("$arg")
|
||||
continue
|
||||
fi
|
||||
fi
|
||||
|
||||
case $arg in
|
||||
--dir)
|
||||
PARSE_DIRS=true
|
||||
;;
|
||||
--min-free-space)
|
||||
MIN_FREE_SPACE="$2"
|
||||
shift # Remove argument value
|
||||
;;
|
||||
--debug)
|
||||
DEBUG_MODE=true
|
||||
;;
|
||||
*)
|
||||
if [ "$arg" != "${DIRS[-1]}" ]; then
|
||||
usage
|
||||
error_msg "Unknown parameter passed: $arg"
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
# Check if at least one directory is provided and if it is indeed a directory
|
||||
if [ ${#DIRS[@]} -eq 0 ]; then
|
||||
usage
|
||||
error_msg "No directories specified."
|
||||
fi
|
||||
|
||||
for DIR in "${DIRS[@]}"; do
|
||||
if [ ! -d "$DIR" ]; then
|
||||
error_msg "'$DIR' is not a directory."
|
||||
fi
|
||||
done
|
||||
|
||||
# Check if all directories are on the same disk
|
||||
PREV_DISK=""
|
||||
for DIR in "${DIRS[@]}"; do
|
||||
CURRENT_DISK=$(df "$DIR" | tail -n 1 | awk '{print $1}')
|
||||
if [ -n "$PREV_DISK" ] && [ "$PREV_DISK" != "$CURRENT_DISK" ]; then
|
||||
usage
|
||||
error_msg "Directories are not on the same disk."
|
||||
fi
|
||||
PREV_DISK=$CURRENT_DISK
|
||||
done
|
||||
|
||||
# Convert GiB to KiB (as df outputs in KiB)
|
||||
MIN_FREE_SPACE_KiB=$((MIN_FREE_SPACE * 1024 * 1024))
|
||||
|
||||
# Get the free space on the disk where the directories are located
|
||||
FREE_SPACE_KiB=$(df "${DIRS[0]}" | tail -n 1 | awk '{print $4}')
|
||||
|
||||
# Find files (not directories) in all specified directories, sort them by modification time (oldest first)
|
||||
if [ $FREE_SPACE_KiB -lt $MIN_FREE_SPACE_KiB ]; then
|
||||
debug_msg "Less than $MIN_FREE_SPACE GiB free, cleaning up..."
|
||||
find "${DIRS[@]}" -type f -printf '%T+ %p\n' | sort | while IFS= read -r line; do
|
||||
if [ $(df "${DIRS[0]}" | tail -n 1 | awk '{print $4}') -ge $MIN_FREE_SPACE_KiB ]; then
|
||||
break
|
||||
fi
|
||||
FILE=$(echo "$line" | cut -d ' ' -f2-)
|
||||
debug_msg "Deleting $FILE"
|
||||
rm -f -- "$FILE"
|
||||
REMAINING_SPACE_KiB=$(df "${DIRS[0]}" | tail -n 1 | awk '{print $4}')
|
||||
debug_msg "Remaining space: $((REMAINING_SPACE_KiB / 1024 / 1024)) GiB"
|
||||
done
|
||||
else
|
||||
debug_msg "Enough free space available."
|
||||
fi
|
5
tools/ipcam_restart_rtsp2hls_rkmpp_3hr_cron.sh
Executable file
5
tools/ipcam_restart_rtsp2hls_rkmpp_3hr_cron.sh
Executable file
@ -0,0 +1,5 @@
|
||||
#!/bin/sh
|
||||
|
||||
for service in $(systemctl list-units --type service | grep ipcam_rtsp2hls_rkmpp | awk '{print $1}' | grep -v \.slice\$); do
|
||||
systemctl restart $service
|
||||
done
|
@ -120,7 +120,7 @@ else
|
||||
path="$CUSTOM_PATH"
|
||||
fi
|
||||
|
||||
ffmpeg $args -i "rtsp://${USER}:${PASSWORD}@${IP}:${PORT}${path}" \
|
||||
ffmpeg $args -nostdin -i "rtsp://${USER}:${PASSWORD}@${IP}:${PORT}${path}" \
|
||||
-c:v copy -c:a copy -bufsize 1835k \
|
||||
-pix_fmt yuv420p \
|
||||
-flags -global_header -hls_time 2 -hls_list_size 3 -hls_flags delete_segments \
|
||||
|
126
tools/ipcam_rtsp2hls_rkmpp.sh
Executable file
126
tools/ipcam_rtsp2hls_rkmpp.sh
Executable file
@ -0,0 +1,126 @@
|
||||
#!/bin/bash
|
||||
|
||||
PROGNAME="$0"
|
||||
OUTDIR=/var/ipcamfs # should be tmpfs
|
||||
PORT=554
|
||||
NAME=
|
||||
IP=
|
||||
USER=
|
||||
PASSWORD=
|
||||
DEBUG=0
|
||||
CHANNEL=1
|
||||
FORCE_UDP=0
|
||||
FORCE_TCP=0
|
||||
CUSTOM_PATH=
|
||||
|
||||
die() {
|
||||
echo >&2 "error: $@"
|
||||
exit 1
|
||||
}
|
||||
|
||||
usage() {
|
||||
cat <<EOF
|
||||
usage: $PROGNAME [OPTIONS] COMMAND
|
||||
|
||||
Options:
|
||||
--ip camera IP
|
||||
--port RTSP port (default: 554)
|
||||
--name camera name (chunks will be stored under $OUTDIR/{name}/)
|
||||
--user
|
||||
--password
|
||||
--debug
|
||||
--force-tcp
|
||||
--force-udp
|
||||
--channel 1|2
|
||||
--custom-path PATH
|
||||
|
||||
EOF
|
||||
exit
|
||||
}
|
||||
|
||||
validate_channel() {
|
||||
local c="$1"
|
||||
case "$c" in
|
||||
1|2)
|
||||
:
|
||||
;;
|
||||
*)
|
||||
die "Invalid channel"
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
[ -z "$1" ] && usage
|
||||
|
||||
while [[ $# -gt 0 ]]; do
|
||||
case "$1" in
|
||||
--ip|--port|--name|--user|--password)
|
||||
_var=${1:2}
|
||||
_var=${_var^^}
|
||||
printf -v "$_var" '%s' "$2"
|
||||
shift
|
||||
;;
|
||||
|
||||
--debug)
|
||||
DEBUG=1
|
||||
;;
|
||||
|
||||
--force-tcp)
|
||||
FORCE_TCP=1
|
||||
;;
|
||||
|
||||
--force-udp)
|
||||
FORCE_UDP=1
|
||||
;;
|
||||
|
||||
--channel)
|
||||
CHANNEL="$2"
|
||||
shift
|
||||
;;
|
||||
|
||||
--custom-path)
|
||||
CUSTOM_PATH="$2"
|
||||
shift
|
||||
;;
|
||||
|
||||
*)
|
||||
die "Unrecognized argument: $1"
|
||||
;;
|
||||
esac
|
||||
shift
|
||||
done
|
||||
|
||||
[ -z "$IP" ] && die "You must specify camera IP address (--ip)."
|
||||
[ -z "$PORT" ] && die "Port can't be empty."
|
||||
[ -z "$NAME" ] && die "You must specify camera name (--name)."
|
||||
[ -z "$USER" ] && die "You must specify username (--user)."
|
||||
[ -z "$PASSWORD" ] && die "You must specify username (--password)."
|
||||
validate_channel "$CHANNEL"
|
||||
|
||||
if [ ! -d "${OUTDIR}/${NAME}" ]; then
|
||||
mkdir "${OUTDIR}/${NAME}" || die "Failed to create ${OUTDIR}/${NAME}!"
|
||||
fi
|
||||
|
||||
args=
|
||||
if [ "$DEBUG" = "1" ]; then
|
||||
args="-v info"
|
||||
else
|
||||
args="-nostats -loglevel error"
|
||||
fi
|
||||
|
||||
if [ "$FORCE_TCP" = "1" ]; then
|
||||
args="$args -rtsp_transport tcp"
|
||||
elif [ "$FORCE_UDP" = "1" ]; then
|
||||
args="$args -rtsp_transport udp"
|
||||
fi
|
||||
|
||||
if [ -z "$CUSTOM_PATH" ]; then
|
||||
path="/Streaming/Channels/${CHANNEL}"
|
||||
else
|
||||
path="$CUSTOM_PATH"
|
||||
fi
|
||||
|
||||
/home/user/FFmpeg/ffmpeg $args -nostdin -i "rtsp://${USER}:${PASSWORD}@${IP}:${PORT}${path}" \
|
||||
-c:v h264_rkmpp_encoder -preset ultrafast -an -vsync drop \
|
||||
-flags -global_header -hls_time 2 -hls_list_size 3 -hls_flags delete_segments \
|
||||
${OUTDIR}/${NAME}/live.m3u8
|
Loading…
x
Reference in New Issue
Block a user