mirror of
https://github.com/dw-0/kiauh.git
synced 2025-12-18 13:14:28 +05:00
with the upcoming release of a new MainsailOS image, mjpg-streamer is replaced by crowsnest. it is therefore not possible anymore to pull the files from the mainsailOS repository. hence adding them to the KIAUH repository. Signed-off-by: Dominik Willner <th33xitus@gmail.com>
304 lines
12 KiB
Bash
304 lines
12 KiB
Bash
#!/bin/bash
|
|
|
|
########################################################################
|
|
### DO NOT EDIT THIS FILE TO CHANGE THE CONFIG!!! ###
|
|
### ---------------------------------------------------------------- ###
|
|
### There is no need to edit this file for changing resolution, ###
|
|
### frame rates or any other mjpg-streamer parameters. Please edit ###
|
|
### /home/pi/klipper_config/webcam.txt instead - that's what it's ###
|
|
### there for! You can even do this with your Pi powered down by ###
|
|
### directly accessing the file when using the SD card as thumb ###
|
|
### drive in your regular computer. ###
|
|
########################################################################
|
|
|
|
MJPGSTREAMER_HOME=/home/pi/mjpg-streamer
|
|
MJPGSTREAMER_INPUT_USB="input_uvc.so"
|
|
MJPGSTREAMER_INPUT_RASPICAM="input_raspicam.so"
|
|
|
|
brokenfps_usb_devices=("046d:082b" "1908:2310" "0458:708c" "1e4e:0102" "0471:0311" "038f:6001" "046d:0804" "046d:0825" "046d:0994" "0ac8:3450")
|
|
|
|
config_dir="/home/pi/klipper_config"
|
|
|
|
echo "Starting up webcamDaemon..."
|
|
echo ""
|
|
|
|
cfg_files=()
|
|
#cfg_files+=/boot/mainsail.txt
|
|
if [[ -d ${config_dir} ]]; then
|
|
cfg_files+=( `ls ${config_dir}/webcam*.txt` )
|
|
fi
|
|
|
|
array_camera_config=()
|
|
array_camera=()
|
|
array_camera_usb_options=()
|
|
array_camera_usb_device=()
|
|
array_camera_raspi_options=()
|
|
array_camera_http_webroot=()
|
|
array_camera_http_options=()
|
|
array_additional_brokenfps_usb_devices=()
|
|
array_camera_device=()
|
|
array_assigned_device=()
|
|
|
|
echo "--- Configuration: ----------------------------"
|
|
for cfg_file in ${cfg_files[@]}; do
|
|
# init configuration - DO NOT EDIT, USE /home/pi/klipper_config/webcam*.txt INSTEAD!
|
|
camera="auto"
|
|
camera_usb_options="-r 640x480 -f 10"
|
|
camera_raspi_options="-fps 10"
|
|
camera_http_webroot="./www-mjpgstreamer"
|
|
camera_http_options="-n"
|
|
additional_brokenfps_usb_devices=()
|
|
|
|
if [[ -e ${cfg_file} ]]; then
|
|
source "$cfg_file"
|
|
fi
|
|
usb_options="$camera_usb_options"
|
|
|
|
# if webcam device is explicitly given in /home/pi/klipper_config/webcam*.txt, save the path of the device
|
|
# to a variable and remove its parameter from usb_options
|
|
extracted_device=`echo $usb_options | sed 's@.*-d \(/dev/\(video[0-9]\+\|v4l/[^ ]*\)\).*@\1@'`
|
|
if [ "$extracted_device" != "$usb_options" ]
|
|
then
|
|
# the camera options refer to a device, save it in a variable
|
|
# replace video device parameter with empty string and strip extra whitespace
|
|
usb_options=`echo $usb_options | sed 's/\-d \/dev\/\(video[0-9]\+\|v4l\/[^ ]*\)//g' | awk '$1=$1'`
|
|
else
|
|
extracted_device=""
|
|
fi
|
|
|
|
# echo configuration
|
|
echo "cfg_file: $cfg_file"
|
|
echo "camera: $camera"
|
|
echo "usb options: $camera_usb_options"
|
|
echo "raspi options: $camera_raspi_options"
|
|
echo "http options: -w $camera_http_webroot $camera_http_options"
|
|
echo ""
|
|
echo "Explicitly USB device: $extracted_device"
|
|
echo "-----------------------------------------------"
|
|
echo ""
|
|
|
|
array_camera_config+=( $cfg_file )
|
|
array_camera+=( $camera )
|
|
array_camera_usb_options+=("$usb_options")
|
|
array_camera_usb_device+=("$extracted_device")
|
|
array_camera_raspi_options+=("$camera_raspi_options")
|
|
array_camera_http_webroot+=("$camera_http_webroot")
|
|
array_camera_http_options+=("$camera_http_options")
|
|
array_camera_brokenfps_usb_devices+=("${brokenfps_usb_devices[*]} ${additional_brokenfps_usb_devices[*]}")
|
|
array_camera_device+=("")
|
|
done
|
|
|
|
# check if array contains a string
|
|
function containsString() {
|
|
local e match="$1"
|
|
shift
|
|
for e; do [[ "$e" == "$match" ]] && return 0; done
|
|
return 1
|
|
}
|
|
|
|
# cleans up when the script receives a SIGINT or SIGTERM
|
|
function cleanup() {
|
|
# make sure that all child processed die when we die
|
|
local pids=$(jobs -pr)
|
|
[ -n "$pids" ] && kill $pids
|
|
exit 0
|
|
}
|
|
|
|
# says goodbye when the script shuts down
|
|
function goodbye() {
|
|
# say goodbye
|
|
echo ""
|
|
echo "Goodbye..."
|
|
echo ""
|
|
}
|
|
|
|
# runs MJPG Streamer, using the provided input plugin + configuration
|
|
function runMjpgStreamer {
|
|
input=$1
|
|
|
|
# There are problems with 0x000137ab firmware on VL805 (Raspberry Pi 4}).
|
|
# Try to autodetect offending firmware and temporarily fix the issue
|
|
# by changing power management mode
|
|
echo "Checking for VL805 (Raspberry Pi 4)..."
|
|
if [[ -f /usr/bin/vl805 ]]; then
|
|
VL805_VERSION=$(/usr/bin/vl805)
|
|
VL805_VERSION=${VL805_VERSION#*: }
|
|
echo " - version 0x${VL805_VERSION} detected"
|
|
case "$VL805_VERSION" in
|
|
00013701)
|
|
echo " - nothing to be done. It shouldn't cause USB problems."
|
|
;;
|
|
000137ab)
|
|
echo -e " - \e[31mThis version is known to cause problems with USB cameras.\e[39m"
|
|
echo -e " You may want to downgrade to 0x0013701."
|
|
echo -e " - [FIXING] Trying the setpci -s 01:00.0 0xD4.B=0x41 hack to mitigate the"
|
|
echo -e " issue. It disables ASPM L1 on the VL805. Your board may (or may not) get"
|
|
echo -e " slightly hotter. For details see:"
|
|
echo -e " https://www.raspberrypi.org/forums/viewtopic.php?f=28&t=244421"
|
|
setpci -s 01:00.0 0xD4.B=0x41
|
|
;;
|
|
*)
|
|
echo " - unknown firmware version. Doing nothing."
|
|
;;
|
|
esac
|
|
else
|
|
echo " - It seems that you don't have VL805 (Raspberry Pi 4)."
|
|
echo " There should be no problems with USB (a.k.a. select() timeout)"
|
|
fi
|
|
|
|
pushd $MJPGSTREAMER_HOME > /dev/null 2>&1
|
|
echo Running ./mjpg_streamer -o "output_http.so -w $camera_http_webroot $camera_http_options" -i "$input"
|
|
LD_LIBRARY_PATH=. ./mjpg_streamer -o "output_http.so -w $camera_http_webroot $camera_http_options" -i "$input" &
|
|
sleep 1 &
|
|
sleep_pid=$!
|
|
wait ${sleep_pid}
|
|
popd > /dev/null 2>&1
|
|
}
|
|
|
|
# starts up the RasPiCam
|
|
function startRaspi {
|
|
logger -s "Starting Raspberry Pi camera"
|
|
runMjpgStreamer "$MJPGSTREAMER_INPUT_RASPICAM $camera_raspi_options"
|
|
}
|
|
|
|
# starts up the USB webcam
|
|
function startUsb {
|
|
options="$usb_options"
|
|
device="video0"
|
|
|
|
# check for parameter and set the device if it is given as a parameter
|
|
input=$1
|
|
if [[ -n $input ]]; then
|
|
device=`basename "$input"`
|
|
fi
|
|
|
|
# add video device into options
|
|
options="$options -d /dev/$device"
|
|
|
|
uevent_file="/sys/class/video4linux/$device/device/uevent"
|
|
if [ -e $uevent_file ]; then
|
|
# let's see what kind of webcam we have here, fetch vid and pid...
|
|
product=`cat $uevent_file | grep PRODUCT | cut -d"=" -f2`
|
|
vid=`echo $product | cut -d"/" -f1`
|
|
pid=`echo $product | cut -d"/" -f2`
|
|
vidpid=`printf "%04x:%04x" "0x$vid" "0x$pid"`
|
|
|
|
# ... then look if it is in our list of known broken-fps-devices and if so remove
|
|
# the -f parameter from the options (if it's in there, else that's just a no-op)
|
|
for identifier in ${brokenfps_usb_devices[@]};
|
|
do
|
|
if [ "$vidpid" = "$identifier" ]; then
|
|
echo
|
|
echo "Camera model $vidpid is known to not work with -f parameter, stripping it out"
|
|
echo
|
|
options=`echo $options | sed -e "s/\(\s\+\|^\)-f\s\+[0-9]\+//g"`
|
|
fi
|
|
done
|
|
fi
|
|
|
|
logger -s "Starting USB webcam"
|
|
runMjpgStreamer "$MJPGSTREAMER_INPUT_USB $options"
|
|
}
|
|
|
|
# make sure our cleanup function gets called when we receive SIGINT, SIGTERM
|
|
trap "cleanup" SIGINT SIGTERM
|
|
# say goodbye when we EXIT
|
|
trap "goodbye" EXIT
|
|
|
|
# we need this to prevent the later calls to vcgencmd from blocking
|
|
# I have no idea why, but that's how it is...
|
|
vcgencmd version > /dev/null 2>&1
|
|
|
|
# keep mjpg streamer running if some camera is attached
|
|
while true; do
|
|
|
|
# get list of usb video devices into an array
|
|
video_devices=($(find /dev -regextype sed -regex '\/dev/video[0-9]\+' | sort -nk1.11 2> /dev/null))
|
|
|
|
# add list of raspi camera into an array
|
|
if [ "`vcgencmd get_camera`" = "supported=1 detected=1" ]; then
|
|
video_devices+=( "raspi" )
|
|
fi
|
|
|
|
echo "Found video devices:"
|
|
printf '%s\n' "${video_devices[@]}"
|
|
|
|
for scan_mode in "usb" "usb-auto" "raspi" "auto"; do
|
|
camera=$scan_mode
|
|
if [[ "usb-auto" == "$scan_mode" ]]; then
|
|
camera="usb"
|
|
fi
|
|
for ((i=0;i<${#array_camera[@]};i++)); do
|
|
if [[ -z ${array_camera_device[${i}]} ]] && [[ $camera == ${array_camera[${i}]} ]]; then
|
|
camera_config="${array_camera_config[${i}]}"
|
|
usb_options="${array_camera_usb_options[${i}]}"
|
|
camera_usb_device="${array_camera_usb_device[${i}]}"
|
|
camera_raspi_options="${array_camera_raspi_options[${i}]}"
|
|
camera_http_webroot="${array_camera_http_webroot[${i}]}"
|
|
camera_http_options="${array_camera_http_options[${i}]}"
|
|
brokenfps_usb_devices="${array_camera_brokenfps_usb_devices[${i}]}"
|
|
if [[ ${camera_usb_device} ]] && { [[ "usb" == ${scan_mode} ]] || [[ "auto" == ${scan_mode} ]]; }; then
|
|
# usb device is explicitly set in options
|
|
usb_device_path=`readlink -f ${camera_usb_device}`
|
|
if containsString "$usb_device_path" "${array_camera_device[@]}"; then
|
|
if [[ "auto" != ${scan_mode} ]]; then
|
|
array_camera_device[${i}]="alredy_in_use"
|
|
echo "config file='$camera_config':Video device already in use."
|
|
continue
|
|
fi
|
|
elif containsString "$usb_device_path" "${video_devices[@]}"; then
|
|
array_camera_device[${i}]="$usb_device_path"
|
|
# explicitly set usb device was found in video_devices array, start usb with the found device
|
|
echo "config file='$camera_config':USB device was set in options and found in devices, start MJPG-streamer with the configured USB video device: $usb_device_path"
|
|
startUsb "$usb_device_path"
|
|
continue
|
|
fi
|
|
elif [[ -z ${camera_usb_device} ]] && { [[ "usb-auto" == ${scan_mode} ]] || [[ "auto" == ${scan_mode} ]]; }; then
|
|
for video_device in "${video_devices[@]}"; do
|
|
if [[ "raspi" != "$video_device" ]]; then
|
|
if containsString "$video_device" "${array_camera_device[@]}"; then
|
|
: #already in use
|
|
else
|
|
array_camera_device[${i}]="$video_device"
|
|
# device is not set explicitly in options, start usb with first found usb camera as the device
|
|
echo "config file='$camera_config':USB device was not set in options, start MJPG-streamer with the first found video device: ${video_device}"
|
|
startUsb "${video_device}"
|
|
break
|
|
fi
|
|
fi
|
|
done
|
|
if [[ -n ${array_camera_device[${i}]} ]]; then
|
|
continue
|
|
fi
|
|
fi
|
|
if [[ "raspi" == ${scan_mode} ]] || [[ "auto" == ${scan_mode} ]]; then
|
|
video_device="raspi"
|
|
if containsString "$video_device" "${array_camera_device[@]}"; then
|
|
if [[ "auto" != ${scan_mode} ]]; then
|
|
array_camera_device[${i}]="alredy_in_use"
|
|
echo "config file='$camera_config':RasPiCam device already in use."
|
|
fi
|
|
elif containsString "$video_device" "${video_devices[@]}"; then
|
|
array_camera_device[${i}]="$video_device"
|
|
echo "config file='$camera_config':Start MJPG-streamer with video device: ${video_device}"
|
|
startRaspi
|
|
sleep 30 &
|
|
sleep_pid=$!
|
|
wait ${sleep_pid}
|
|
fi
|
|
fi
|
|
fi
|
|
done
|
|
done
|
|
array_assigned_device=( ${array_camera_device[*]} )
|
|
if [[ ${#array_camera[@]} -eq ${#array_assigned_device[@]} ]]; then
|
|
echo "Done bring up all configured video device"
|
|
exit 0
|
|
else
|
|
echo "Scan again in two minutes"
|
|
sleep 120 &
|
|
sleep_pid=$!
|
|
wait ${sleep_pid}
|
|
fi
|
|
done
|