Skip to content

Multi Server Mode for NetGear API

Abhishek Thakur edited this page Apr 25, 2020 · 67 revisions

VidGear Logo

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.

 

 

Table of Contents

 

 

Key Features

  • 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.

 

 


Important Information ⚠️

  • 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.
  • In Multi-Server Mode, If all the connected servers on the network get disconnected, the Client itself automatically exits to save resources.


 

 

Attributes and Parameters:

Attributes:

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 to True. Its default value is False. 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 🔽.

Parameters:

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 to recv() function at Client's end through its send() function. See its usage example below

 

 

Usage 🔨

 


Note 💡

  • 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 with pip install imutils.


 

Multi-Server Mode using OpenCV with NetGear:

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.

A. Client's End Code:

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()

 

B1. Server-1's End Code:

Open the terminal on System (a.k.a Server-1) with a webcam connected to it and execute the following python code.

⚠️ Remember to replace the IP address in the following code with Client's IP address copied earlier and also copy the unique port address of this system(required by Client to identify this system).

# 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()

 

B2. Server-2's End Code:

Open the terminal on System (a.k.a Server-2) also with a webcam connected to it and execute the following python code.

⚠️ Remember to replace the IP address in the following code with Client's IP address copied earlier and also copy the unique port address of this system(required by Client to identify this system).

# 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()

 

 

Multi-Server Mode with Custom Message Transfer:

💡 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.

A. Client's End Code:

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()

 

B1. Server-1's End Code:

Open the terminal on System (a.k.a Server-1) with a webcam connected to it and execute the following python code.

⚠️ Remember to replace the IP address in the following code with Client's IP address copied earlier and also copy the unique port address of this system(required by Client to identify this system).

# 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()

 

B2. Server-2's End Code:

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()

 

 

Multi-Server Mode with Custom Filter:

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.

A. Client's End Code:

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()

 

B1. Server-1's End Code:

Open the terminal on System (a.k.a Server-1) with a webcam connected to it and execute the following python code.

⚠️ Remember to replace the IP address in the following code with Client's IP address copied earlier and also copy the unique port address of this system(required by Client to identify this system).

# 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()

 

B2. Server-2's End Code:

Open the terminal on System (a.k.a Server-2) also with a webcam connected to it and execute the following python code.

⚠️ Remember to replace the IP address in the following code with Client's IP address copied earlier and also copy the unique port address of this system(required by Client to identify this system).

# 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()