Primitive webcam server using inetd and fswebcam

Hi all!

This weekend I was thinking how to make my webcam connected to OrangePI send a picture “on demand”. There are daemons (e.g. motion or webcam-mjpg) which do this but they capture images even when you are not watching and I wanted to avoid this. There are also projects (fswebcam) which are able to take single picture, save it to disk and end. I just needed to run it after http request and send back the image. Installing full webserver with some kind of interpreter (php, lua,…) seemed to me like an overkill. So I came to an idea to use inetd.

And this is how I did.

First you need to install inetd and fswebcam:

apt install openbsd-inetd fswebcam

Then you make it listen on some TCP  port and define which script to run. To  do this add following line to /etc/inetd.conf

8083    stream  tcp,sndbuf=64k  nowait  root    /root/webcam.sh

and restart it

service inetd restart

Then you need a script which will run the webcam binary and fake a HTTP response.

Create /root/webcam.sh

In case you want just one shot:

#!/bin/bash

FILE=/tmp/webcam.jpg

fswebcam --resolution 640x480 --save $FILE &>/dev/null 
len=stat -c '%s' $FILE

echo "HTTP/1.1 200 OK"
echo "Content-Type: image/jpeg"
echo "Content-Length: $len"
echo
cat $FILE

# let the client to close the connection
sleep 1

In case you want a mjpeg stream:

#!/bin/bash

FILE=/tmp/webcam.jpg

function cleanup {
  killall fswebcam
}
trap cleanup EXIT

fswebcam --loop 1 --resolution "640x480" --timestamp "%d-%m-%Y %H:%M:%S (%Z)" --save $FILE --background

BOUND="AA3284238420182340189sdsadwZZ"

echo -e "HTTP/1.1 200 OK\r"
echo -e "Content-Type: multipart/x-mixed-replace;boundary=$BOUND\r"
echo -e "\r"

OK=0

echo -e "--$BOUND\r"
while [ $OK -eq 0 ]
do
  if [ "stat --format=%Y $FILE" == "$MOD" ]
  then
    sleep 1
  else
    MOD=stat --format=%Y $FILE
    echo -e "Content-Type: image/jpeg\r"
    len=stat -c '%s' $FILE
    echo -e "Content-Length: $len\r"
    echo -e "\r"
    cat $FILE
    OK=$?
    echo -e "\r\n--$BOUND\r"
  fi
  if ! ps | grep fswebcam &> /dev/null
  then
    exit 1
  fi
done

Then make it executable

chmod +x /root/webcam.sh

And you are done!

This way you can run any shell script with various output (text, binary, image, etc.).

Looking forrward to your comments.

 

Leave a Reply

Your email address will not be published. Required fields are marked *