-
-
Notifications
You must be signed in to change notification settings - Fork 254
Multi Server Mode for NetGear API
In this exclusive mode, NetGear API robustly handles Multiple Servers at once through its Publish/Subscribe (
zmq.PUB/zmq.SUB
) and Request/Reply(zmq.REQ/zmq.REP
) messaging patterns, thereby providing seamless access to frames and unidirectional data transfer from multiple Sources/Servers/Devices across the network in real-time.
This mode can be easily activated through multiserver_mode
boolean attribute in **option
dictionary parameter of Netgear API, during its initialization.
-
Enables Multiple Server messaging support with a single client.
-
Ability to send any additional data of any datatype along with frames in real-time.
-
Number of Servers can be extended to several 100s depending upon your System Hardware and requirements.
-
Employs powerful Publish/Subscribe & Request/Reply messaging patterns.
-
Each new Server on the network can be identified on the single Client's end by using its unique port address.
-
API actively tracks the current state of each connected Server.
-
If all the connected servers on the network get disconnected, the client itself automatically exits to save resources.
-
In Multi-Server Mode:
- A unique PORT address MUST be assigned to each Server on the network using its
port
parameter. - A list/tuple of PORT addresses of all unique Servers MUST be assigned at Client's end using its
port
parameter for a successful connection. - The
address
parameter value of each Server MUST exactly match the Client.
- A unique PORT address MUST be assigned to each Server on the network using its
-
In Multi-Server Mode, If all the connected servers on the network get disconnected, the Client itself automatically exits to save resources.
To tweak Multi-Server Mode, NetGear API provide certain internal attribute for its **option
** dictionary parameter, which are discussed as follows:
-
multiserver_mode
(boolean) : This attribute activates Multi-Server Mode if it is set toTrue
. Its default value isFalse
. Its usage is as follows:options = {'multiserver_mode':True} # activates Multi-Server Mode
💡 See its usage example below 🔽.
-
filter
(string): this attribute assigns a custom topic filter to allow only specific Servers at the Clients-end in Multi-Server Mode only. Its usage is as follows:options = {'multiserver_mode':True, 'filter':'5565'} # activate Multi-Server Mode and set filter to allow data from topic `5565` only
💡 See its usage example below 🔽.
NetGear API also supports real-time unidirectional data transfer along with frames in Multi-Server Mode.
-
message
: [For Server-end only] enables us to send data(of any datatype) directly torecv()
function at Client's end through itssend()
function. See its usage example below
-
For sake of simplicity, in these examples we will use only two unique Servers, but the number of these Servers can be extended to several numbers depending upon your requirements and System configurations.
-
All of these Servers will be transferring frames to a single Client system at the same time, which will be displaying received frames as a montage(multiple frames concatenated together).
-
For building montage with simplicity at Client's end, We are going to use
imutils
python library function to build montages by concatenating various output video frames received from different servers together. Therefore, Kindly install this library withpip install imutils
.
In this example, we will capture live frames from two Sources (a.k.a Servers) - each with a webcam using OpenCV. Then, those frames will be transferred over the network to a single system(a.k.a Client) at the same time using Multi-Server Mode, and those received frames will be displayed as a real-time montage.
Open a terminal on the System (a Client, where you want to display the frames received from the Multiple Servers) and execute the following python code:
💡 Remember to note the IP-address of this system(required at Server's end) by executing the command: hostname -I
in your terminal and also replace it in the following code.
# import required libraries
from vidgear.gears import NetGear
from imutils import build_montages
import cv2
# activate multiserver_mode
options = {'multiserver_mode': True}
# Define Netgear Client with `port` addresses of all unique Server((5566,5567) in our case). Also, Remember to change following IP address '192.168.x.xxx' with yours, plus activate Request/Reply(`1`) pattern, `recieve_mode`:
client = NetGear(address = '192.168.x.x', port = (5566,5567), protocol = 'tcp', pattern = 1, receive_mode = True, **options)
# Define received frame dictionary
frame_dict = {}
# loop over until Keyboard Interrupted
while True:
try:
# receive data from network
data = client.recv()
# check if data received isn't None
if data is None:
break
# extract unique port address and its respective frame
unique_address, frame = data
# {do something with the extracted frame here}
# get extracted frame's shape
(h, w) = frame.shape[:2]
# update the extracted frame in the received frame dictionary
frame_dict[unique_address] = frame
# build a montage using data dictionary
montages = build_montages(frame_dict.values(), (w, h), (2, 1))
# display the montage(s) on the screen
for (i, montage) in enumerate(montages):
cv2.imshow("Montage Footage {}".format(i), montage)
# check for 'q' key if pressed
key = cv2.waitKey(1) & 0xFF
if key == ord("q"):
break
except KeyboardInterrupt:
break
# close output window
cv2.destroyAllWindows()
# safely close client
client.close()
Open the terminal on System (a.k.a Server-1) with a webcam connected to it and execute the following python code.
# import libraries
from vidgear.gears import NetGear
import cv2
# Open suitable video stream (webcam on first index in our case)
stream = cv2.VideoCapture(0)
# activate multiserver_mode
options = {'multiserver_mode': True}
# change following IP address '192.168.1.xxx' with Client's IP address and assign unique port address (5566 in our case) but keep rest of settings similar to Client
server = NetGear(address = '192.168.x.x', port = '5566', protocol = 'tcp', pattern = 1, **options)
# loop over until Keyboard Interrupted
while True:
try:
# read frames from stream
(grabbed, frame) = stream.read()
# check for frame if not grabbed
if not grabbed:
break
# {do something with the frame here}
# send frame to server
server.send(frame)
except KeyboardInterrupt:
break
# safely close video stream
stream.release()
# safely close server
server.close()
Open the terminal on System (a.k.a Server-2) also with a webcam connected to it and execute the following python code.
# import libraries
from vidgear.gears import NetGear
import cv2
# Open suitable video stream (webcam on first index in our case)
stream = cv2.VideoCapture(0)
# activate multiserver_mode
options = {'multiserver_mode': True}
# change following IP address '192.168.1.xxx' with Client's IP address and assign unique port address (5567 in our case) but keep rest of settings similar to Client
server = NetGear(address = '192.168.x.x', port = '5567', protocol = 'tcp', pattern = 1, **options)
# loop over until Keyboard Interrupted
while True:
try:
# read frames from stream
(grabbed, frame) = stream.read()
# check for frame if not grabbed
if not grabbed:
break
# {do something with the frame here}
# send frame to server
server.send(frame)
except KeyboardInterrupt:
break
# safely close video stream
stream.release()
# safely close server
server.close()
💡 Remember you can send any type of additional data of any datatype along with the frame as message, for example, dict, list, tuple,string, int etc.
!
In this example, We will transfer live frames and data (text message in this example) unidirectionally from different Servers (consisting of a Raspberry Pi with RaspiCamera Module and a PC with webcam) to a single system (a.k.a Client) over the network, where it is displayed as a real-time montage.
Open a terminal on the System (a Client, where you want to display the frames received from the Multiple Servers) and execute the following python code:
💡 Remember to note the IP-address of this system(required at Server's end) by executing the command: hostname -I
in your terminal and also replace it in the following code.
# import required libraries
from vidgear.gears import NetGear
from imutils import build_montages
import cv2
# activate multiserver_mode
options = {'multiserver_mode': True}
# Define Netgear Client with `port` addresses of all unique Server((5577,5578) in our case). Also, Remember to change following IP address '192.168.x.xxx' with yours, plus activate Publisher/Subscriber(`2`) pattern, `recieve_mode`, and `logging` for debugging:
client = NetGear(address = '192.168.x.x', port = (5577,5578), protocol = 'tcp', pattern = 2, receive_mode = True, logging = True, **options)
# Define received frame dictionary
frame_dict = {}
# loop over until Keyboard Interrupted
while True:
try:
# receive data from network
data = client.recv()
# check if data received isn't None
if data is None:
break
# extract unique port address and its respective frame and received data
unique_address, extracted_data, frame = data
# {do something with the extracted frame and data here}
# let's display extracted data on our extracted frame
cv2.putText(frame, extracted_data, (10, frame.shape[0] - 10), cv2.FONT_HERSHEY_SIMPLEX, 0.6, (0,255,0),2)
# get extracted frame's shape
(h, w) = frame.shape[:2]
# update the extracted frame in the frame dictionary
frame_dict[unique_address] = frame
# build a montage using data dictionary
montages = build_montages(frame_dict.values(), (w, h), (2, 1))
# display the montage(s) on the screen
for (i, montage) in enumerate(montages):
cv2.imshow("Montage Footage {}".format(i), montage)
# check for 'q' key if pressed
key = cv2.waitKey(1) & 0xFF
if key == ord("q"):
break
except KeyboardInterrupt:
break
# close output window
cv2.destroyAllWindows()
# safely close client
client.close()
Open the terminal on System (a.k.a Server-1) with a webcam connected to it and execute the following python code.
# import libraries
from vidgear.gears import NetGear
from vidgear.gears import VideoGear
import cv2
# Open suitable video stream (webcam on first index in our case)
stream = VideoGear(source=0).start()
# activate multiserver_mode
options = {'multiserver_mode': True}
# change following IP address '192.168.1.xxx' with Client's IP address and assign unique port address (5577 in our case) but keep rest of settings similar to Client
server = NetGear(address = '192.168.x.x', port = '5577', protocol = 'tcp', pattern = 2, logging = True, **options)
# loop over until Keyboard Interrupted
while True:
try:
# read frames from stream
frame = stream.read()
# check for frame if Nonetype
if frame is None:
break
# {do something with frame and data(to be sent) here}
# let's prepare a text string as data
text = "I'm Server-1 at Port: 5577"
# send frame and data through server
server.send(frame, message = text)
except KeyboardInterrupt:
break
# safely close video stream
stream.stop()
# safely close server
server.close()
Now, Open the terminal on System-2 (Server-2) on a Raspberry Pi with Raspi-Camera Module connected to it and execute the following python code. Also, remember to assign and write down a unique port address(different from System-1) and replace the IP address with Client's IP address copied earlier
# import libraries
from vidgear.gears import NetGear
from vidgear.gears import PiGear
import cv2
# add various Picamera tweak parameters to dictionary
options = {"hflip": True, "exposure_mode": "auto", "iso": 800, "exposure_compensation": 15, "awb_mode": "horizon", "sensor_mode": 0}
# open pi video stream with defined parameters
stream = PiGear(resolution=(640, 480), framerate=60, logging=True, **options).start()
# activate multiserver_mode
options = {'multiserver_mode': True}
# change following IP address '192.168.1.xxx' with Client's IP address and assign unique port address (5578 in our case) but keep rest of settings similar to Client
server = NetGear(address = '192.168.1.xxx', port = '5578', protocol = 'tcp', pattern = 2, logging = True, **options)
# loop over until Keyboard Interrupted
while True:
try:
# read frames from stream
frame = stream.read()
# check for frame if Nonetype
if frame is None:
break
# {do something with frame and data(to be sent) here}
# let's prepare a text string as data
text = "I'm Server-2 at Port: 5578"
# send frame and data through server
server.send(frame, message = text)
except KeyboardInterrupt:
break
# safely close video stream.
stream.stop()
# safely close server
server.close()
In this example, We will transfer live frames from different Servers (each with webcam) to a single system (a.k.a Client) over the network but we are going to implement a filter at Client's end to filter data from only one of the given Servers.
Open a terminal on the System (a Client, where you want to display the frames received from the Multiple Servers) and execute the following python code:
💡 Remember to note the IP-address of this system(required at Server's end) by executing the command: hostname -I
in your terminal and also replace it in the following code.
# import required libraries
from vidgear.gears import NetGear
from imutils import build_montages
import cv2
# activate multiserver_mode add filter for port `5567`
options = {'multiserver_mode': True, 'filter': '5567'}
# Define Netgear Client with `port` addresses of all unique Server((4567,5567) in our case). Also, Remember to change following IP address '192.168.x.xxx' with yours, plus activate Request/Reply(`1`) pattern, `recieve_mode`:
client = NetGear(address = '192.168.x.x', port = (4567,5567), protocol = 'tcp', pattern = 1, receive_mode = True, **options)
# Define received frame dictionary
frame_dict = {}
# loop over until Keyboard Interrupted
while True:
try:
# receive data from network
data = client.recv()
# check if data received isn't None
if data is None:
break
# extract unique port address and its respective frame
unique_address, frame = data
# {do something with the extracted frame here}
# get extracted frame's shape
(h, w) = frame.shape[:2]
# update the extracted frame in the received frame dictionary
frame_dict[unique_address] = frame
# build a montage using data dictionary
montages = build_montages(frame_dict.values(), (w, h), (2, 1))
# display the montage(s) on the screen
for (i, montage) in enumerate(montages):
cv2.imshow("Montage Footage {}".format(i), montage)
# check for 'q' key if pressed
key = cv2.waitKey(1) & 0xFF
if key == ord("q"):
break
except KeyboardInterrupt:
break
# close output window
cv2.destroyAllWindows()
# safely close client
client.close()
Open the terminal on System (a.k.a Server-1) with a webcam connected to it and execute the following python code.
# import libraries
from vidgear.gears import NetGear
import cv2
# Open suitable video stream (webcam on first index in our case)
stream = cv2.VideoCapture(0)
# activate multiserver_mode
options = {'multiserver_mode': True}
# change following IP address '192.168.1.xxx' with Client's IP address and assign unique port address (4567 in our case) but keep rest of settings similar to Client
server = NetGear(address = '192.168.x.x', port = '4567', protocol = 'tcp', pattern = 1, **options)
# loop over until Keyboard Interrupted
while True:
try:
# read frames from stream
(grabbed, frame) = stream.read()
# check for frame if not grabbed
if not grabbed:
break
# {do something with the frame here}
# send frame to server
server.send(frame)
except KeyboardInterrupt:
break
# safely close video stream
stream.release()
# safely close server
server.close()
Open the terminal on System (a.k.a Server-2) also with a webcam connected to it and execute the following python code.
# import libraries
from vidgear.gears import NetGear
import cv2
# Open suitable video stream (webcam on first index in our case)
stream = cv2.VideoCapture(0)
# activate multiserver_mode
options = {'multiserver_mode': True}
# change following IP address '192.168.1.xxx' with Client's IP address and assign unique port address (5567 in our case) but keep rest of settings similar to Client
server = NetGear(address = '192.168.x.x', port = '5567', protocol = 'tcp', pattern = 1, **options)
# loop over until Keyboard Interrupted
while True:
try:
# read frames from stream
(grabbed, frame) = stream.read()
# check for frame if not grabbed
if not grabbed:
break
# {do something with the frame here}
# send frame to server
server.send(frame)
except KeyboardInterrupt:
break
# safely close video stream
stream.release()
# safely close server
server.close()