Added the ability change the video codec via the config file.

Changed the install script to now install the application in the /opt
directory and then symm link to /usr/bin. Doing this allowed me to
create a run script to start the application and enable the
OPENCV_VIDEOIO_DEBUG parameter for opencv. This should make it easier to
diagnose video-io issues with opencv.

Updated the README documentation with all of the changes done to the
application since v1.5.
This commit is contained in:
Maurice ONeal 2022-12-18 10:25:46 -05:00
parent f8f7564911
commit 2e10d31ab6
7 changed files with 110 additions and 54 deletions

111
README.md
View File

@ -33,41 +33,39 @@ recording_stream = rtsp://1.2.3.4:554/h264
# this is the url to the main stream of the IP camera that will be used # this is the url to the main stream of the IP camera that will be used
# to record footage. # to record footage.
# #
output_dir = /path/to/footage/directory web_root = /var/www/html
# this is the output directory that will be used to store recorded footage # this is the output directory that will be used to store recorded footage
# from the camera. the file naming convention uses the current date for # from the cameras as well as the web interface for the application. it is
# playlist files which points to hidden video clips taken from the camera. # recommended to leave it on the default value if using apache2 as the
# http(s) server.
# #
buff_dir = /tmp/ramdisk/cam_name buff_dir = /tmp
# this application records small clips of the footage from the camera and # this application records small clips of the footage from the camera and
# then stores them into this directory. any clips with motion detected in # then stores them into this directory. any clips with motion detected in
# them are moved to output_dir, if no motion they are deleted. highly # them are moved to web_root; if no motion is detected, they are deleted.
# recommend to use a ramdisk tempfs for this since this directory is used # it is highly recommend to use a ramdisk tempfs for this since this
# for lots of writes. # directory is used for large amounts of writes.
# #
consec_threshold = 512 cam_name = cam-1
# motion is detected by comparing each frame in the camera feed for # this is the optional camera name parameter to identify the camera. this
# differences in the pixels. this value determine how many consecutive # name will be used to form the directory structure in the web_root as
# pixels need to different or how large the suspect object in motion # well as buff_dir. if not defined, the name of the config file will be
# needs to be. # used.
# #
block_threshold = 1024 pix_thresh = 150
# this value tells the application how many "lines" of pixels need to # this value tells the application how far different the pixels need to be
# exceed consec_threshold before being considered motion. # before the pixels are actually considered different. think of this as
# pixel diff sensitivity, the higher the value the lesser the sensitivity.
# #
block_x = 64 frame_gap = 10
# this is the x coordinate size or horizontal size of a block of pixels # this value is used to tell the application how far in between frames to
# that the application will use to detect the presents of motion. # check the pixel diffs for motion. the lower the value, the more frames
# will be checked, however with that comes higher cpu usage.
# #
block_y = 60 img_thresh = 1024
# this is the y coordinate size or vertical size of a block of pixels # this indicates how many pixels need to be different in between frame_gap
# that the application will use to detect the presents of motion. # before it is considered motion. any video clips found with frames
# # exceeding this value will be moved from buff_dir to web_root.
duration = 60
# this sets the internal timer used to reset to the detection loop and
# then call post_cmd if it is defined. note: this time is extended if
# motion was detected. this will also reload the config file so changes
# to the settings will be applied without restarting the application.
# #
post_cmd = move_the_ptz_camera.py post_cmd = move_the_ptz_camera.py
# this an optional command to run after the internal timer duration has # this an optional command to run after the internal timer duration has
@ -75,35 +73,64 @@ post_cmd = move_the_ptz_camera.py
# position of it's patrol pattern. note: the call to this command will be # position of it's patrol pattern. note: the call to this command will be
# delayed if motion was detected. # delayed if motion was detected.
# #
duration = 60
# this sets the internal timer used to reset to the detection loop and
# then call post_cmd if it is defined. this will also reload the config
# file so changes to any settings will be applied without restarting the
# application.
#
max_days = 15 max_days = 15
# this defines the maximum amount of days worth of video clips that is # this defines the maximum amount of days worth of video clips that is
# allowed to be stored in the output_dir. whenever this limit is met, # allowed to be stored in the web_root. whenever this limit is met, the
# the oldest day is deleted. # oldest day and all of it's associated video clips will be deleted.
#
max_clips = 30
# this is the maximum amount of video clips that is allowed to be stored
# in web_root per day. whenever this limit is met, the oldest clip is
# deleted.
#
max_log_size = 50000
# this is the maximum byte size of all log files that can be stored in
# web_root. whenever this limit is met, the log file will be deleted and
# then eventually recreated blank.
# #
vid_container = mp4 vid_container = mp4
# this is the video file format to use from recording footage from the # this is the video file format to use for recording footage from the
# camera. the format support depends entirely on the under laying ffmpeg # camera. the format support depends entirely on the under laying ffmpeg
# installation. # installation.
#
vid_codec = copy
# this is the video codec to use when pulling footage from the camera
# via ffmpeg. the default is "copy" meaning it will just match the codec
# from the camera itself without trans-coding.
#
web_text = #dee5ee
# this can be used to customize the color of the text in the web
# interface. it can be defined as any color understood by html5 standard.
#
web_bg = #485564
# this can be used to customize the background color of the web
# interface. just like web_text, it also follows the html5 standard.
#
web_font = courier
# this will customize the text font family to use in the web interface.
# it is recommended to use mono-spaced font because this is also used to
# display logs and logs are best displayed in mono-spaced font.
``` ```
### Setup/Build/Install ### ### Setup/Build/Install ###
This application is currently only compatible with a Linux based operating This application is currently only compatible with a Linux based operating
systems that are capable of building and installing the opencv API from source. systems that are capable of installing opencv. The following 3 scripts make
building and then installing convenient.
The following 3 scripts make this convenient by downloading, compiling and then
installing the opencv API for you directly from opencv's git repository. This
also makes sure FFMPEG and all of it's dependencies are installed because this
application needs it to work properly.
```
note 1: be sure to run setup.sh and install.sh as root (or use sudo).
note 2: if building from scratch the following scripts will need to
be run in this order - setup.sh -> build.sh -> install.sh.
```
``` ```
sh ./setup.sh <--- only need to run this once if compiling for the first sh ./setup.sh <--- only need to run this once if compiling for the first
sh ./build.sh time or if upgrading from the ground up. sh ./build.sh time or if upgrading from the ground up.
sh ./install.sh sh ./install.sh
``` ```
```
note 1: be sure to run setup.sh and install.sh as root (or use sudo).
note 2: if building from scratch the following scripts will need to
be run in this order - setup.sh -> build.sh -> install.sh.
```

View File

@ -1,7 +1,5 @@
#!/bin/sh #!/bin/sh
mkdir -p ./.build-mow mkdir -p ./.build-mow
cd ./.build-mow cd ./.build-mow
cmake .. cmake ..
make -j4 make -j4

View File

@ -1,3 +1,12 @@
#!/bin/sh #!/bin/sh
if [ ! -d "/opt/mow" ]; then
cp ./.build-mow/mow /usr/bin/mow mkdir /opt/mow
fi
cp ./.build-mow/mow /opt/mow/bin
printf "#!/bin/sh\n" > /opt/mow/run
printf "export OPENCV_VIDEOIO_DEBUG=1\n" >> /opt/mow/run
printf "/opt/mow/bin \$1 \$2 \$3\n" >> /opt/mow/run
chmod +x /opt/mow/run
chmod +x /opt/mow/bin
rm /usr/bin/mow
ln -s /opt/mow/run /usr/bin/mow

View File

@ -1,11 +1,28 @@
#!/bin/sh #!/bin/sh
apt update -y apt update -y
apt install -y pkg-config apt install -y pkg-config
apt install -y cmake g++ wget unzip git ffmpeg gstreamer1.0* libavcodec-dev libavformat-dev libavutil-dev libswscale-dev libgstreamer1.0-dev libgstreamer-plugins-base1.0-dev apt install -y cmake
apt install -y x264 libx264-dev apt install -y make
apt install -y libopencv-dev apache2 apt install -y g++
apt install -y wget
apt install -y unzip
apt install -y git
apt install -y ffmpeg
apt install -y gstreamer1.0*
apt install -y libavcodec-dev
apt install -y libavformat-dev
apt install -y libavutil-dev
apt install -y libswscale-dev
apt install -y libgstreamer1.0-dev
apt install -y x264
apt install -y libx264-dev
apt install -y libopencv-dev
apt install -y apache2
add-apt-repository -y ppa:ubuntu-toolchain-r/test add-apt-repository -y ppa:ubuntu-toolchain-r/test
apt update -y apt update -y
apt install -y gcc-10 gcc-10-base gcc-10-doc g++-10 apt install -y gcc-10
apt install -y libstdc++-10-dev libstdc++-10-doc apt install -y gcc-10-base
apt install -y gcc-10-doc
apt install -y g++-10
apt install -y libstdc++-10-dev
apt install -y libstdc++-10-doc

View File

@ -199,7 +199,9 @@ bool rdConf(shared_t *share)
share->maxLogSize = 50000; share->maxLogSize = 50000;
share->camName = path(share->conf.c_str()).filename(); share->camName = path(share->conf.c_str()).filename();
share->webRoot = "/var/www/html"; share->webRoot = "/var/www/html";
share->buffDir = "/tmp";
share->vidExt = "mp4"; share->vidExt = "mp4";
share->vidCodec = "copy";
share->recLoopWait = false; share->recLoopWait = false;
share->skipCmd = false; share->skipCmd = false;
share->webBg = "#485564"; share->webBg = "#485564";
@ -228,11 +230,13 @@ bool rdConf(shared_t *share)
rdLine("max_clips = ", line, &share->maxClips); rdLine("max_clips = ", line, &share->maxClips);
rdLine("max_log_size = ", line, &share->maxLogSize); rdLine("max_log_size = ", line, &share->maxLogSize);
rdLine("vid_container = ", line, &share->vidExt); rdLine("vid_container = ", line, &share->vidExt);
rdLine("vid_codec = ", line, &share->vidCodec);
} }
} while(!line.empty()); } while(!line.empty());
share->outDir = cleanDir(share->webRoot) + "/" + share->camName; share->outDir = cleanDir(share->webRoot) + "/" + share->camName;
share->buffDir = cleanDir(share->buffDir) + "/" + share->camName;
share->recLogPath = share->outDir + "/rec_log_lines.html"; share->recLogPath = share->outDir + "/rec_log_lines.html";
share->detLogPath = share->outDir + "/det_log_lines.html"; share->detLogPath = share->outDir + "/det_log_lines.html";

View File

@ -35,7 +35,7 @@ using namespace cv;
using namespace std; using namespace std;
using namespace std::filesystem; using namespace std::filesystem;
#define APP_VER "1.5.t12" #define APP_VER "1.5.t13"
#define APP_NAME "Motion Watch" #define APP_NAME "Motion Watch"
struct shared_t struct shared_t
@ -51,6 +51,7 @@ struct shared_t
string conf; string conf;
string buffDir; string buffDir;
string vidExt; string vidExt;
string vidCodec;
string camName; string camName;
string webBg; string webBg;
string webTxt; string webTxt;

View File

@ -102,7 +102,7 @@ void recLoop(shared_t *share)
auto bufPath = cleanDir(share->buffDir) + "/%03d." + share->vidExt; auto bufPath = cleanDir(share->buffDir) + "/%03d." + share->vidExt;
auto secs = to_string(share->secs); auto secs = to_string(share->secs);
auto limSecs = to_string(share->secs + 3); auto limSecs = to_string(share->secs + 3);
auto cmd = "timeout -k 1 " + limSecs + " ffmpeg -hide_banner -i " + share->recordUrl + " -y -vcodec copy -map 0 -segment_time 00:00:10 -f segment -t " + secs + " " + bufPath; auto cmd = "timeout -k 1 " + limSecs + " ffmpeg -hide_banner -i " + share->recordUrl + " -y -vcodec " + share->vidCodec + " -map 0 -segment_time 00:00:10 -f segment -t " + secs + " " + bufPath;
thread th2(detectLoop, share); thread th2(detectLoop, share);