CNCjs Setup #3 (Install webcam support)
1. FFmpeg with the OpenMAX H.264 GPU acceleration
sudo apt-get install libomxil-bellagio-dev -y
git clone https://github.com/FFmpeg/FFmpeg.git
cd FFmpeg
sudo ./configure --arch=armel --target-os=linux --enable-gpl --enable-omx --enable-omx-rpi --enable-nonfree
#For pi3
sudo make -j4
sudo make install
2. Install MJPEG-Streamer
# Update & Install Tools
sudo apt-get update
sudo apt-get upgrade -y
sudo apt-get install build-essential libjpeg8-dev imagemagick libv4l-dev cmake -y
# Clone Repo in /tmp
cd /tmp
git clone https://github.com/jacksonliam/mjpg-streamer.git
cd mjpg-streamer/mjpg-streamer-experimental
# Make
make
sudo make install
3. Let MJPEG-Streamer auto start
nano /home/pi/mjpg-streamer.sh
#!/bin/bash
# chmod +x mjpg-streamer.sh
# Crontab: @reboot /home/pi/mjpg-streamer/mjpg-streamer.sh start
# Crontab: @reboot /home/pi/mjpg-streamer/mjpg-streamer-experimental/mjpg-streamer.sh start
MJPG_STREAMER_BIN="/usr/local/bin/mjpg_streamer" # "$(dirname $0)/mjpg_streamer"
MJPG_STREAMER_WWW="/usr/local/share/mjpg-streamer/www"
MJPG_STREAMER_LOG_FILE="${0%.*}.log" # "$(dirname $0)/mjpg-streamer.log"
RUNNING_CHECK_INTERVAL="2" # how often to check to make sure the server is running (in seconds)
HANGING_CHECK_INTERVAL="3" # how often to check to make sure the server is not hanging (in seconds)
VIDEO_DEV="/dev/video0"
FRAME_RATE="5"
QUALITY="80"
RESOLUTION="1280x720" # 160x120 176x144 320x240 352x288 424x240 432x240 640x360 640x480 800x448 800x600 960x544 1280x720 1920x1080 (QVGA, VGA, SVGA, WXGA) # lsusb -s 001:006 -v | egrep "Width|Height" # https://www.textfixer.com/tools/alphabetical-order.php # v4l2-ctl --list-formats-ext # Show Supported Video Formates
PORT="8081"
YUV="yes"
################INPUT_OPTIONS="-r ${RESOLUTION} -d ${VIDEO_DEV} -f ${FRAME_RATE} -q ${QUALITY} -pl 60hz"
INPUT_OPTIONS="-r ${RESOLUTION} -d ${VIDEO_DEV} -q ${QUALITY} -pl 60hz --every_frame 2" # Limit Framerate with "--every_frame ", ( mjpg_streamer --input "input_uvc.so --help" )
if [ "${YUV}" == "true" ]; then
INPUT_OPTIONS+=" -y"
fi
OUTPUT_OPTIONS="-p ${PORT} -w ${MJPG_STREAMER_WWW}"
# ==========================================================
function running() {
if ps aux | grep ${MJPG_STREAMER_BIN} | grep ${VIDEO_DEV} >/dev/null 2>&1; then
return 0
else
return 1
fi
}
function start() {
if running; then
echo "[$VIDEO_DEV] already started"
return 1
fi
export LD_LIBRARY_PATH="$(dirname $MJPG_STREAMER_BIN):."
echo "Starting: [$VIDEO_DEV] ${MJPG_STREAMER_BIN} -i \"input_uvc.so ${INPUT_OPTIONS}\" -o \"output_http.so ${OUTPUT_OPTIONS}\""
${MJPG_STREAMER_BIN} -i "input_uvc.so ${INPUT_OPTIONS}" -o "output_http.so ${OUTPUT_OPTIONS}" >> ${MJPG_STREAMER_LOG_FILE} 2>&1 &
sleep 1
if running; then
if [ "$1" != "nocheck" ]; then
check_running & > /dev/null 2>&1 # start the running checking task
check_hanging & > /dev/null 2>&1 # start the hanging checking task
fi
echo "[$VIDEO_DEV] started"
return 0
else
echo "[$VIDEO_DEV] failed to start"
return 1
fi
}
function stop() {
if ! running; then
echo "[$VIDEO_DEV] not running"
return 1
fi
own_pid=$$
if [ "$1" != "nocheck" ]; then
# stop the script running check task
ps aux | grep $0 | grep start | tr -s ' ' | cut -d ' ' -f 2 | grep -v ${own_pid} | xargs -r kill
sleep 0.5
fi
# stop the server
ps aux | grep ${MJPG_STREAMER_BIN} | grep ${VIDEO_DEV} | tr -s ' ' | cut -d ' ' -f 2 | grep -v ${own_pid} | xargs -r kill
echo "[$VIDEO_DEV] stopped"
return 0
}
function check_running() {
echo "[$VIDEO_DEV] starting running check task" >> ${MJPG_STREAMER_LOG_FILE}
while true; do
sleep ${RUNNING_CHECK_INTERVAL}
if ! running; then
echo "[$VIDEO_DEV] server stopped, starting" >> ${MJPG_STREAMER_LOG_FILE}
start nocheck
fi
done
}
function check_hanging() {
echo "[$VIDEO_DEV] starting hanging check task" >> ${MJPG_STREAMER_LOG_FILE}
while true; do
sleep ${HANGING_CHECK_INTERVAL}
# treat the "error grabbing frames" case
if tail -n2 ${MJPG_STREAMER_LOG_FILE} | grep -i "error grabbing frames" > /dev/null; then
echo "[$VIDEO_DEV] server is hanging, killing" >> ${MJPG_STREAMER_LOG_FILE}
stop nocheck
fi
done
}
function help() {
echo "Usage: $0 [start|stop|restart|status]"
return 0
}
if [ "$1" == "start" ]; then
start && exit 0 || exit -1
elif [ "$1" == "stop" ]; then
stop && exit 0 || exit -1
elif [ "$1" == "restart" ]; then
stop && sleep 1
start && exit 0 || exit -1
elif [ "$1" == "status" ]; then
if running; then
echo "[$VIDEO_DEV] running"
exit 0
else
echo "[$VIDEO_DEV] stopped"
exit 1
fi
else
help
fi
# Make Executable
chmod +x /home/pi/mjpg-streamer.sh
# Open Cron Job
crontab -e
# Add line
@reboot /home/pi/mjpg-streamer.sh start
4. Make MJPEG-Streamer recording script (with FFmpeg)
nano /home/pi/record_mp4.sh
#!/bin/bash
# MJPEG Streamer Recorder w/ FFMpeg - v1
# chmod +x record.sh
# sh ~/record.sh start
FFMPEG_STREAMER_BIN="$(which ffmpeg)"
INPUT_OPTIONS="-y -f mjpeg -re"
SOURCE_STREAM="http://localhost:8080/?action=stream"
OUTPUT_OPTIONS="-q:v 10"
DESTINATION_DIRECTORY="/home/pi/Videos"
DESTINATION_FILE="xcarve-recording_$(date +'%Y%m%d_%H%M%S').mp4"
# ==========================================================
function running() {
if ps aux | grep ${FFMPEG_STREAMER_BIN} | grep "${SOURCE_STREAM}" >/dev/null 2>&1; then
return 0
else
return 1
fi
}
function start() {
if running; then
echo "already started"
return 1
fi
export LD_LIBRARY_PATH="$(dirname $FFMPEG_STREAMER_BIN):."
echo "Starting: ${FFMPEG_STREAMER_BIN} ${INPUT_OPTIONS} -i \"${SOURCE_STREAM}\" ${OUTPUT_OPTIONS} \"${DESTINATION_DIRECTORY}/${DESTINATION_FILE}\""
#${FFMPEG_STREAMER_BIN} ${INPUT_OPTIONS} -i "${SOURCE_STREAM}" ${OUTPUT_OPTIONS} "${DESTINATION_DIRECTORY}/${DESTINATION_FILE}" </dev/null >/dev/null 2>record_ffmpeg.log & # https://trac.ffmpeg.org/wiki/PHP
${FFMPEG_STREAMER_BIN} ${INPUT_OPTIONS} -i "${SOURCE_STREAM}" ${OUTPUT_OPTIONS} "${DESTINATION_DIRECTORY}/${DESTINATION_FILE}" >/dev/null 2>/dev/null & # No Log File
sleep 1
if running; then
# if [ "$1" != "nocheck" ]; then
# check_running & > /dev/null 2>&1 # start the running checking task
# check_hanging & > /dev/null 2>&1 # start the hanging checking task
# fi
echo "started"
return 0
else
echo "failed to start"
return 1
fi
}
function stop() {
if ! running; then
echo "not running"
return 1
fi
own_pid=$$
if [ "$1" != "nocheck" ]; then
# stop the script running check task
ps aux | grep $0 | grep start | tr -s ' ' | cut -d ' ' -f 2 | grep -v ${own_pid} | xargs -r kill
sleep 0.5
fi
# stop the process
ps aux | grep ${FFMPEG_STREAMER_BIN} | grep "${SOURCE_STREAM}" | tr -s ' ' | cut -d ' ' -f 2 | grep -v ${own_pid} | xargs -r kill
echo "stopped"
return 0
}
function check_running() {
echo "starting running check task" >> ${MJPG_STREAMER_LOG_FILE}
while true; do
sleep ${RUNNING_CHECK_INTERVAL}
if ! running; then
echo "server stopped, starting" >> ${MJPG_STREAMER_LOG_FILE}
start nocheck
fi
done
}
function check_hanging() {
echo "starting hanging check task" >> ${MJPG_STREAMER_LOG_FILE}
while true; do
sleep ${HANGING_CHECK_INTERVAL}
# treat the "error grabbing frames" case
if tail -n2 ${MJPG_STREAMER_LOG_FILE} | grep -i "error grabbing frames" > /dev/null; then
echo "server is hanging, killing" >> ${MJPG_STREAMER_LOG_FILE}
stop nocheck
fi
done
}
function help() {
echo "Usage: $0 [start|stop|restart|status]"
return 0
}
if [ "$1" == "start" ]; then
start && exit 0 || exit -1
elif [ "$1" == "stop" ]; then
stop && exit 0 || exit -1
elif [ "$1" == "restart" ]; then
stop && sleep 1
start && exit 0 || exit -1
elif [ "$1" == "status" ]; then
if running; then
echo "running"
exit 0
else
echo "stopped"
exit 1
fi
else
help
fi
5. Add event for recording MJPEG-Streaming to mp4
1) G-Code Start : /home/pi/record_mp4.sh start
2) G-Code Stop : /home/pi/record_mp4.sh stop