Publish IP camera videos on web pages
Publish a video of an IP camera installed at home on a web page.
Thanks to ahonomics, I am now a country of poor people without hiding, and I try to achieve this on the lowest possible budget. At this time, I rely on (1) cheap and high-quality IP cameras made in China, (2) free and high-quality free software (open source software), and (3) useful life. It is a used laptop computer that has passed.
As prerequisites, (A) a home LAN with an optical line and (B) a web server installed on the Internet are assumed. (A) is mandatory. It would be possible without (B), but the intended readers of this article will not complain even if we proceed as if it were.
1: IP camera
The IP camera used is a model called SV-801W-1080P-HX of the SV3C brand, and the main specifications are as follows.
–Aluminum die-cast housing, IP66 waterproof / dustproof
–Fixed angle of view 2 million pixels (1920 x 1080)
–Both wired / WiFi compatible
–Power supply by AC adapter
–Infrared night vision photography
–Motion detection
–Supports micro SD card (up to 64 GB)
–RTSP compatible
–ONVIF compatible
- send e-mail
–FTP upload
The price is 4,899 yen (as of October 2020) on Amazon.co.jp, which is one of the cheapest, but at first glance it is robust and equipped with all the functions expected of this kind of surveillance camera. ing. There are other similar products, but I have the impression that the manuals on the support site are relatively substantial, so I choose the SV3C one.
It’s important to support ** RTSP ** and ** ONVIF **, but it’s rare for today’s IP cameras to support it.
1-1: IP camera setup
Set up the camera before installing it outdoors (on the edge of the house).
The following explanation is based on the SV3C SV-801W-1080P-HX, but I think that the procedure will be similar for cameras from other companies. I’m sorry if it’s different.
1-1-1: Micro SD card
First, attach the micro SD card (64GB, 1,596 yen) that you bought together to the camera.
This product is a little more difficult to work with because you can’t access the card slots on the board without removing the lens cover and pulling out the contents. However, once inserted, it is a card that will never be taken out, so I think this is fine.
The camera works without a card. You don’t need a card for video distribution, and even if you use it for crime prevention, you can omit the card when connecting to NVR (Network Video Recorder).
However, if you have a card installed, you can automatically record and save videos and snapshots. Besides, adding cards after installation is a hassle. It’s cheap, so it’s better to wear it from the beginning.
1-1-2: Connect to home LAN
Turn on the camera by connecting it to a router (or hub, etc.) on your home LAN with a LAN cable.
The router’s DHCP will now get the camera a dynamic IP address.
1-1-2 : CamHi
Install and launch an app called CamHi on your smartphone. By searching for and connecting to an IP camera connected to your home LAN with this app, you will be able to watch videos and access camera settings. Needless to say, smartphones need to be connected to the home LAN via WiFi in advance.
Subsequent settings can be done with CamHi, but it is easier to access the camera settings screen with a web browser, so just make a note of the camera’s IP address and CamHi will quit. (It will be used again later to check the image during outdoor installation work.)
1-1-3: Setting by web browser
Access the camera’s IP address with a web browser and configure the camera settings.
The browser uses ** Internet Explorer **. You will first be asked to install the ActiveX for video playback. I wonder what this is, but follow the instructions. It can be set with other browsers, but it is inconvenient because the image is not displayed. Give up and use IE.
There are a wide variety of items that can be set. For items that you do not understand well, leave the default settings and make the following initialization and setting changes that are considered to be the minimum necessary.
–Change the administrator password
–The IP address is a static address (here, 192.168.0.101
)
–Set the time zone to GMT +09: 00
–Set the NTP server to ntp.nict.jp
–Initialize SD card
This time, we will go with a wired connection in consideration of the installation location and stability, so turn off WiFi. Also, since the purpose is different, it is set not to use functions for crime prevention such as infrared night vision, motion detection, alarm by e-mail or FTP.
1-2: Outdoor installation work of IP camera
Install an IP camera on the eaves of your home, where you will be shooting videos.
While checking the image with CamHi of the smart phone, decide the installation position and shooting direction and fix it. Since it is a wide-angle lens, it is inevitable that the peripheral part will be distorted, but since the human eye is sensitive to horizontal deviation, the angle of the camera is determined by paying close attention to the horizontal and vertical parts of the center of the image.
Since it is a place exposed to rain, the joint between the LAN cable and the power cable should be waterproofed with self-bonding tape.
1-3: Delivery of still images
With the SV3C HX series, it will be possible to deliver still images at this point.
There is a function to upload snapshots to an external FTP server on a regular basis, so if you take advantage of this and perform appropriate processing on the web server side, you can display almost real-time still images on a web page. You can.
This time, we will create a page to distribute still images in case the video distribution stops.
1-3-1: Client side (HTML + javascript)
<img id="live-img" width="950" height="534"
src="/livecam/snapshot"
alt="Live camera snapshot" />
The source of the image is the URL / livecam / snapshot
. It makes the work on the server side easier than specifying it by file name like " snapshot.jpg "
. You no longer have to worry about the negative effects of the file cache.
function updateImage() {
$('#live-img').attr('src', '/livecam/snapshot');
}
var timer = setInterval(updateImage, 30000);
Then the javascript timer requests the image from the server every 30 seconds.
1-3-2: Server side
On the server side, the image data is sent to the client from the action corresponding to the URL / livecam / snapshot
.
Since snapshots from the camera are being uploaded one after another to the directory specified in advance, select the newest file among them, read the contents, and add the header of 'Content-Type: image / jpeg'
. And send it.
To put it in detail, it requires some troublesome processing such as resizing images and deleting unnecessary files, but I will omit the details.
2: Video distribution
2-1: Schematic diagram
In order to distribute videos from IP cameras, ** video conversion server ** and ** video distribution server ** are required in addition to the conventional web server, as shown in the figure.
First, the ** video conversion server ** converts the stream of video data output by the camera according to ** RTSP ** (Real Time Streaming Protocol) into data according to ** RTMP ** (Real Time Messaging Protocol). Convert. The substance of this video conversion server is an application program called ** ffmpeg **.
Then, the ** video distribution server ** that receives the output of ** RTMP ** from the video conversion server distributes the stream converted to the ** HLS ** (HTTP Live Streaming) protocol to the web client. The substance of this video distribution server is a web server program called ** NGINX ** equipped with ** nginx-rtmp-module **.
Although not supported this time and not shown in the figure, this video distribution server can distribute ** RTMP ** streams as they are, or ** MPEG-DASH ** protocol (DASH is Dynamic Adaptive Streaming over HTTP). It is also possible to convert it to) and distribute it.
2-2: Video server
Make a used laptop computer into a server that combines video conversion and video distribution, and install it on your home LAN.
In some cases, it may be better to have only a video conversion server on the home LAN and let a web server on the Internet also serve as video distribution.
2-2-1 : CentOS 8
Install CentOS 8 on your laptop. Nothing has changed in particular.
The reason for CentOS is simply because you’re used to it, and there’s no other reason. It should be any linux distribution.
The IP address of this video server on the home LAN is 192.168.0.99
.
2-2-2 : ffmpeg
There are many articles on the net that build ffmpeg from source, but if you go there, you’ll usually be in distress. Until a decade ago, I would have had no choice but to do so, but now that I have a package, I don’t have to worry about it.
Specifically, install ffmpeg using the ** RPM Fusion ** repository.
First, the ʻEPEL` repository is required, so install it.
# dnf -y install epel-release
Then enable the repositories PowerTools
and ʻepel-playground`.
# dnf config-manager --set-enabled PowerTools
# dnf config-manager --set-enabled epel-playground
Then install the RPM Fusion
repository.
# rpm -ivh https://download1.rpmfusion.org/free/el/rpmfusion-free-release-8.noarch.rpm
You can now install ffmpeg
.
# dnf install ffmpeg
For details, see ** “Install FFmpeg on CentOS 8 with RPMFusion repo” **. The title is English, but the article is in Japanese.
2-2-3 : NGINX + nginx-rtmp-module
If you only use NGINX, you can use the package, but in order to use nginx-rtmp-module, you need to get the source and build it.
First, install the tools you use to build.
$ sudo yum update
$ sudo yum groupinstall "Development Tools"
$ sudo yum install git
Next, install the dependent packages.
$ sudo yum groupinstall pcre-devel zlib-devel openssl-devel
Then, create an appropriate build directory, go into it, and clone the sources of nginx-rtmp-module
and nginx
from github
to get them.
$ cd /path/to/build/dir
$ git clone https://github.com/arut/nginx-rtmp-module.git
$ git clone https://github.com/nginx/nginx.git
Then go into the nginx
directory, add nginx-rtmp-module
to your configuration, and run the build and install.
$ cd nginx
$ ./auto/configure --add-module=../nginx-rtmp-module
$ make
$ sudo make install
This will make NGINX work, so check it just in case.
$ sudo systemctl start nginx
When you access the home page of the video server (http://192.168.0.99/
) from a personal computer connected to your home LAN, the NGINX welcome page should be displayed.
I can’t stream the video yet (naturally because I haven’t set it up yet), but once I put in ** ffmpeg ** and ** NGINX + nginx-rtmp-module **, it’s like winning. ..
The rest is the setting of video conversion by ffmpeg and the setting of video distribution by NGINX, but before that, I will finish the work of environment maintenance necessary for the operation of the video server.
2-2-4: Video server environment maintenance
2-2-4-1: Firewall
Open ports for http
, https
, RTSP
, and RTMP
.
$ sudo firewall-cmd --permanent --add-service=http
$ sudo firewall-cmd --permanent --add-service=https
$ sudo firewall-cmd --permanent --add-service=rtsp
$ sudo firewall-cmd --permanent --add-port=1935/tcp
$ sudo firewall-cmd --reload
1935 / tcp
is the standard port for RTMP
. RTSP
uses 554 / tcp
and 554 / udp
as standard ports, but in CentOS 8 it can be set using --add-service = rtsp
.
2-2-4-2: Router port mapping
Change the port mapping setting of the router of the home LAN so that the video server can be accessed from the Internet, and the incoming call to the WAN side global address is the local address of the LAN side video server (192.168.0.99
). Try to go to.
You can just use http (80)
, https (443)
, rtmp (1935)
, but also map ssh (22)
for remote management.
2-2-4-3 : DDNS (Dynamic DNS)
Use the DDNS (Dynamic DNS) service so that you can specify the video server by domain name instead of IP address.
Change server_name
in nginx.conf
to the DDNS domain name (assuming it is camsvr.on.ddns
) and restart NGINX.
nginx.conf
http {
server {
server_name camsvr.on.ddns;
At this point, I’d like to see if the router’s port mapping and DDNS are working as expected, but to do that I need to go out of my home LAN. When I access http://camsvr.on.ddns/
with a web browser on a PC connected to my home LAN, the NGINX welcome page of the video server is not displayed, and the home page of the router (http:: //192.168.0.1/
) is displayed. In short, port mapping does not work for access from within the LAN. It’s a good idea to use a smartphone browser with WiFi turned off for testing.
2-2-4-4 : Let’s Encrypt
The plan is that the video distribution web page will be a mix of content from the new video server with the page provided by the existing web server. The web server is already SSL
and provides the https
page as a whole. If there is a http
content that does not support SSL
, it will be sick.
Therefore, let’s Encrypt is used to make the video server SSL
.
For the procedure, please refer to ** “Simple free SSL conversion to CentOS8 (nginx) using certbot & SSL automatic update” **.
After completing the above (1) firewall, (2) router port mapping, and (3) DDNS settings, (4) start certbot
with NGINX running. Then, at the same time as getting the certificate, it will make appropriate changes to nginx.conf
and make the video server SSL.
nginx.conf
http {
server {
server_name camsvr.on.ddns;
listen 443 ssl; # managed by Certbot
ssl_certificate /etc/letsencrypt/live/camsvr.on.ddns/fullchain.pem; # managed by Certbot
ssl_certificate_key /etc/letsencrypt/live/camsvr.on.ddns/privkey.pem; # managed by Certbot
include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot
}
server {
if ($host = camsvr.on.ddns) {
return 301 https://$host$request_uri;
} # managed by Certbot
listen 80;
server_name camsvr.on.ddns;
return 404; # managed by Certbot
}
}
The commented # managed by Certbot
is where certbot
rewrote or added.
2-2-4-5: CORS header
As mentioned just above, video distribution web pages will be a mix of content from the new video server with pages provided by existing web servers. At this time, the problem of CORS (Cross-Origin Resource Sharing)
arises.
To deal with this, add a CORS-enabled header to the response from the video server.
nginx.conf
http {
server {
location / {
# CORS start
add_header 'Access-Control-Allow-Origin' 'https://my.web.server' always;
# Allow CORS preflight requests
if ($request_method = 'OPTIONS') {
add_header 'Access-Control-Allow-Origin' 'https://my.web.server';
add_header 'Access-Control-Max-Age' 1728000;
add_header 'Content-Type' 'text/plain charset=UTF-8';
add_header 'Content-Length' 0;
return 204;
}
# CORS end
}
}
}
The setting is to allow only specific origins who know their identity. To be honest, I’m not sure about CORS. For the time being, shake it off to the safe side.
2-2-5: Video distribution by NGINX
** “Enabling Video Streaming for Remote Learning with NGINX and NGINX Plus” ** Add the video distribution settings to nginx.conf
.
The following are the settings for HLS
.
nginx.conf
http {
server {
location / {
root /tmp/hls;
}
}
types {
application/vnd.apple.mpegurl m3u8;
video/mp2t ts;
text/html html;
}
}
rtmp {
server {
listen 1935;
application livecam {
live on;
interleave on;
hls on;
hls_path /tmp/hls;
hls_fragment 5s;
}
}
}
–http
> server
> location /
root
changed to / tmp / hls
–Additional settings for http
> types
blocks
–In addition to html
, set the types of m3u8
and ts
for HLS
–Additional settings for rtmp
block
–hls_path
should be / tmp / hls
The location
> root
setting on the http
side and the hls_path
setting on the rtmp
side are paired. This video server is set to deliver HLS
videos directly under /
.
2-2-6: Video conversion by ffmpeg
Finally, ffmpeg converts the IP camera’s RTSP stream into an RTMP stream and sends it to the video distribution server.
$ ffmpeg -i rtsp://192.168.0.101/12.amp -c copy -an -f flv rtmp://192.168.0.99/livecam/std
–-i rtsp: //192.168.0.101/12.amp
… Specify the RTSP stream of the IP camera as input.
–The 12
part depends on the IP camera used.
–SV3C SV-801W-1080P-HX provides two streams, 11
(1920 x 1080) and 12
(640 x 352). The latter is used here.
–-c copy
… Leave the codec as input.
–-an
… No audio output.
–-f flv
… Specify the output format. FLV is Flash Video.
– rtmp: //192.168.0.99/livecam/std
… Specify the output destination.
–livecam
… application name.
–std
… Stream name.
–The URL for RTMP
will be rtmp: //camsvr.on.ddns/livecam/std
.
–The URL for HLS
will be https://camsvr.on.ddns/std.m3u8
.
If you don’t need to process the video, you can use -c copy
. It saves you the trouble of decoding the input and encoding the output, so there is almost no load on the CPU.
Resizing the image and adjusting the tint can be a bit more complicated and CPU-intensive.
$ ffmpeg -i rtsp://192.168.0.101/12.amp -c:v libx264 -b:v 512k -r 15 -vf hue=h=10 -an -f flv rtmp://192.168.0.99/livecam/std
–-c: v libx264
… Specify the video codec. It is H.264.
–-b: v 512k
… Specify the bit rate of the video. 512kb / sec.
–-r 15
… Specifying the frame rate. 15 fps.
–-vf hue = h = 10
… Specify the video filter. Rotate the hue 10 degrees.
The final hue adjustment is to correct the redness of the image, whether it is a characteristic of this IP camera as a model or an individual.
The strength of ffmpeg is endless.
2-2-6-1: ffmpeg monitoring (obsoleted)
If the RTSP stream is disturbed due to a malfunction of the IP camera, ffmpeg may end. That’s not good as a video conversion server, so create a shell script that monitors the operation of ffmpeg and restarts it if it stops.
#!/usr/bin/bash
# The script runs for 18 hours (12 x 60 x 18 = 12960)
limit=12960
counter=0
while [ $counter -le $limit ]; do
sleep 5
alive=`ps -aef | grep ffmpeg | grep livecam | wc -l`
# echo `date` ":ffmpeg alive ="$alive
if [ $alive = 0 ]; then
echo `date` " : ffmpeg is not running."
echo "starting ffmpeg ..."
ffmpeg -i rtsp://192.168.0.101/12.amp -c:v libx264 -an -r 15 -b:v 512k -vf hue=h=10 -f flv rtmp://192.168.0.99/livecam/std 2>>/var/log/nginx/ffmpeg.log &
echo "done."
fi
((counter++))
done
Check ffmpeg for survival every 5 seconds for 18 hours and launch if dead. Start this script with cron
every day at 3:00 AM. It is a crazy setting that you can die between 9:00 PM and 3:00 AM.
2-2-6-2: Start ffmpeg on NGINX
Actually, you don’t have to start ffmpeg yourself and monitor it as described above. Just start ffmpeg on NGINX.
nginx.conf
application livecam {
live on;
interleave on;
hls on;
hls_path /tmp/hls;
hls_fragment 5s;
exec_static /usr/bin/ffmpeg -i rtsp://192.168.0.101/12.amp -c:v libx264 -an -r 15 -b:v 512k -f flv rtmp: //192.168.0.99/livecam/std 2>>/var/log/nginx/ffmpeg-std.log;
}
I’m using ʻexec_static here because, for some reason, ʻexec_push
doesn’t start ffmpeg as expected in my environment. This failure is also recorded as an open issue on github of nginx-rtmp-module
, which seems to bother a lot of people.
Fortunately, ʻexec_static` will start successfully. And even if you kill the launched ffmpeg, another instance will be launched immediately, probably because NGINX is monitoring it. When you quit NGINX, ffmpeg also quits. This is fine.
2-3: Client side
On the client side, use the JavaScript video playback library ** VIDEO JS **.
<head>
<link href="https://vjs.zencdn.net/7.8.4/video-js.css" rel="stylesheet" />
</head>
<body>
<video id="live-cam" class="video-js" controls autoplay
width="640" height="352" data-setup="{}">
<source src="https://camsvr.on.ddns/std.m3u8" type="application/x-mpegURL" />
<p class="vjs-no-js">
To watch this video, enable JavaScript and
Use a browser that supports the HTML5 video tag.
</p>
</video>
<script src="https://vjs.zencdn.net/7.8.4/video.js"></script>
</body>
For details, see ** “Getting Started” ](https://videojs.com/getting-started) and documentation on [ VIDEO JS Official Site **. Please refer.
That’s it for publishing IP camera videos on web pages.
If there is something wrong, strange, or something that needs improvement, please let us know.