Skip to content

NetGear

Abhishek Thakur edited this page Dec 31, 2019 · 69 revisions

VidGear Logo

NetGear API

NetGear is exclusively designed to transfer video frames & data synchronously (Pair & Request/Reply) as well as asynchronously (Publish/Subscribe) between various interconnecting systems over the network in real-time. This is achieved by implementing a high-level wrapper around PyZmQ python library that contains python bindings for ZeroMQ - a high-performance asynchronous distributed messaging library that aim to be used in distributed or concurrent applications. It provides a message queue, but unlike message-oriented middleware, a ZeroMQ system can run without a dedicated message broker.

NetGear as of now seamlessly supports three ZeroMQ messaging patterns:

whereas the supported protocol are: tcp, upd, pgm, inproc, ipc.

 

Modes of Operation:

1. PRIMARY MODES: NetGear API primarily has two modes of operations:

  • Send Mode: which employs send() function to send video frames over the network. You can also use this function to send additional data (along with video frames). Activate this mode by setting receive_mode = False.

  • Receive Mode: which employs recv() function to receive frames/data sent over the network with Send Mode. The mode sends back confirmation when the frame/data is received successfully. Activate this mode by setting receive_mode = True.

    :warning: Remember, Only one of the above primary mode can be activated during Netgear API initialization.

2. EXCLUSIVE MODES: In addition to these primary modes, NetGear API offers exclusive mode for specific applications:

  • Multi-Server Mode: In this exclusive mode, NetGear API robustly handles multiple servers at once through Publish/Subscribe (zmq.PUB/zmq.SUB) and Request/Reply(zmq.REQ/zmq.REP) messaging patterns, thereby providing access to seamless Live Streams across the various device in a network at the same time. Each new Server on the network can be identified on the client's end by using its unique port address. Also, it exhibits a feature where if all the connected servers on the network get disconnected, the client itself automatically exits to save resources. You can learn about this mode here.

  • Secure Mode: In this exclusive mode, NetGear API provides easy access to powerful, smart & secure ZeroMQ's Security Layers in NetGear API that enables strong encryption on data, and (as far as we know) unbreakable authentication between the Server and the Client with the help of custom certificates/keys and brings cheap, standardized privacy and authentication for distributed systems over the network. It uses a new wire protocol, ZMTP 3.0, that adds a security handshake to all ZeroMQ connections and a new security protocol, CurveZMQ, that implements "perfect forward security" between two ZeroMQ peers over a TCP connection. Learn more about this mode here.

  • Bi-directional Mode: This exclusive mode provides seamless support for bidirectional data transmission between receiver(client) and sender(server) through bi-directional synchronous messaging patterns such as zmq.PAIR (ZMQ Pair Pattern) & zmq.REQ/zmq.REP (ZMQ Request/Reply Pattern). Using this mode the User can now send data(of any datatype) from send() function at Server's end through its message parameter to Client and recv() function's return_data parameter at Client's end to return data back to Server easily. You can learn more about this mode here.

 


Important: :warning:

  • When compiling pyzmq (e.g. installing with pip on Linux), it is generally recommended that zeromq be installed separately, via homebrew, apt, yum, etc:

     # Debian-based
     sudo apt-get install libzmq3-dev
      
     # RHEL-based
     sudo yum install libzmq3-devel

    If this is not available, pyzmq will try to build libzmq as a Python Extension, though this is not guaranteed to work.

  • Kindly go through each given Usage Examples thoroughly before using NetGear API. Incorrect settings/parameters may result in multiple errors or no output at all.

  • Only either of two functions (i.e. send() and recv()) can be accessed at any given instance based on activated primary mode during API Initialization. If you trying to access any of the given functions in a non-valid mode (for e.g using send() function in Receive Mode) will instantly result in Value ERROR!


 

Importing:

You can easily import NetGear as follows:

from vidgear.gears import NetGear

 

Usage: :hammer:

1. Basic Usage:

A. Server End:(Bare-Minimum example)

Open your favorite terminal and execute the following python code:

Tip::bulb: You can end streaming anytime on both Server and Client by pressing [Ctrl+C] on your keyboard at Server's end!

# import libraries
from vidgear.gears import VideoGear
from vidgear.gears import NetGear

stream = VideoGear(source='test.mp4').start() #Open any video stream
server = NetGear() #Define netgear server with default settings

# infinite loop until [Ctrl+C] is pressed
while True:
	try: 
		frame = stream.read()
		# read frames

		# check if frame is None
		if frame is None:
			#if True break the infinite loop
			break

		# do something with frame here

		# send frame to server
		server.send(frame)
	
	except KeyboardInterrupt:
		#break the infinite loop
		break

# safely close video stream
stream.stop()
# safely close server
server.close()

B. Client End:(Bare-Minimum example)

Then open another terminal on the same system and execute the following python code and see the output:

# import libraries
from vidgear.gears import NetGear
import cv2

#define netgear client with `receive_mode = True` and default settings
client = NetGear(receive_mode = True)

# infinite loop
while True:
	# receive frames from network
	frame = client.recv()

	# check if frame is None
	if frame is None:
		#if True break the infinite loop
		break

	# do something with frame here

	# Show output window
	cv2.imshow("Output Frame", frame)

	key = cv2.waitKey(1) & 0xFF
	# check for 'q' key-press
	if key == ord("q"):
		#if 'q' key-pressed break out
		break

# close output window
cv2.destroyAllWindows()
# safely close client
client.close()

 

2. Advanced Usage: (flexible parameter control)

Usage with other VidGear Gears:

A. Client's End:

Open a terminal on the System(a Client, where you want to display the input frames received from the Server) and execute the following python code: Also, Remember the IP-address of this system(required at Server's end) by executing the command: hostname -I and also replace it in the following code.

# import libraries
from vidgear.gears import NetGear
import cv2

options = {'flag' : 0, 'copy' : False, 'track' : False}

#change following IP address '192.168.x.xxx' with yours
client = NetGear(address = '192.168.x.xxx', port = '5454', protocol = 'tcp',  pattern = 0, receive_mode = True, logging = True, **options) #Define netgear client at Server IP address.

# infinite loop
while True:
	# receive frames from network
	frame = client.recv()

	# check if frame is None
	if frame is None:
		#if True break the infinite loop
		break

	# do something with frame here

	# Show output window
	cv2.imshow("Output Frame", frame)

	key = cv2.waitKey(1) & 0xFF
	# check for 'q' key-press
	if key == ord("q"):
		#if 'q' key-pressed break out
		break

# close output window
cv2.destroyAllWindows()
# safely close client
client.close()

B. Server End:

Now, Open the terminal on another System(a Server, with a webcam connected to it) and execute the following python code: Also, remember to replace the IP address in the following code with Client's IP address copied earlier

Tip::bulb: You can end streaming anytime on both Server and Client by pressing [Ctrl+C] on your keyboard at Server's end!

# import libraries
from vidgear.gears import VideoGear
from vidgear.gears import NetGear

stream = VideoGear(source='test.mp4').start() #Open any video stream

options = {'flag' : 0, 'copy' : False, 'track' : False}

#change following IP address '192.168.x.xxx' with client's IP address
server = NetGear(address = '192.168.x.xxx', port = '5454', protocol = 'tcp',  pattern = 0, receive_mode = False, logging = True, **options) #Define netgear server at your system IP address.

# infinite loop until [Ctrl+C] is pressed
while True:
	try: 
		frame = stream.read()
		# read frames

		# check if frame is None
		if frame is None:
			#if True break the infinite loop
			break

		# do something with frame here

		# send frame to server
		server.send(frame)
	
	except KeyboardInterrupt:
		#break the infinite loop
		break

# safely close video stream
stream.stop()
# safely close server
server.close()

 

Usage with OpenCV Library:

A. Client's End:

Open a terminal on the System(a Client, where you want to display the input frames received from the Server) and execute the following python code: Also, Remember the IP-address of this system(required at Server's end) by executing the command: hostname -I and also replace it in the following code.

# import libraries
from vidgear.gears import NetGear
import cv2

options = {'flag' : 0, 'copy' : False, 'track' : False}

#change following IP address '192.168.x.xxx' with yours
client = NetGear(address = '192.168.x.xxx', port = '5454', protocol = 'tcp',  pattern = 0, receive_mode = True, logging = True, **options) #Define netgear client at Server IP address.

# infinite loop
while True:
	# receive frames from network
	frame = client.recv()

	# check if frame is None
	if frame is None:
		#if True break the infinite loop
		break

	# do something with frame here

	# Show output window
	cv2.imshow("Output Frame", frame)

	key = cv2.waitKey(1) & 0xFF
	# check for 'q' key-press
	if key == ord("q"):
		#if 'q' key-pressed break out
		break

# close output window
cv2.destroyAllWindows()
# safely close client
client.close()

B. Server End:

Now, Open the terminal on another System(a Server, with a webcam connected to it) and execute the following python code: Also, remember to replace the IP address in the following code with Client's IP address copied earlier

Tip::bulb: You can end streaming anytime on both Server and Client by pressing [Ctrl+C] on your keyboard at Server's end!

# import libraries
from vidgear.gears import NetGear
import cv2

stream = cv2.VideoCapture('test.mp4') #Open any video stream

options = {'flag' : 0, 'copy' : False, 'track' : False}

#change following IP address '192.168.x.xxx' with yours
server = NetGear(address = '192.168.x.xxx', port = '5454', protocol = 'tcp',  pattern = 0, receive_mode = False, logging = True, **options) #Define netgear server at your system IP address.

# infinite loop until [Ctrl+C] is pressed
while True:
	try: 
		(grabbed, frame) = stream.read()
		# read frames

		# check if frame is not grabbed
		if not grabbed:
			#if True break the infinite loop
			break

		# do something with frame here

		# send frame to server
		server.send(frame)
	
	except KeyboardInterrupt:
		#break the infinite loop
		break

# safely close video stream
stream.release()
# safely close server
server.close()

 

Parameters and Attributes: :wrench:

  1. address (string): sets the valid network address of the server/client. Network addresses unique identifiers across the network. Its default value is based on current primary mode, i.e 'localhost' for Send Mode and '*' for Receive Mode.

  2. port (string | list/tuple): sets the valid network port of the server/client. A network port is a number that identifies one side of a connection between two devices on the network. It is used determine to which process or application a message should be delivered.

    :warning: In Multi-Server Mode, a unique port number must be required for each connected server on the network, and a (list/tuple) of port addresses of each connected server is required at clients end at this parameter. See usage example here

  3. protocol (string): sets the valid messaging protocol between server and client. A network protocol is a set of established rules that dictates how to format, transmit and receive data so computer network devices - from servers and routers to endpoints - can communicate regardless of the differences in their underlying infrastructures, designs or standards. Supported protocol are: 'tcp', 'upd', 'pgm', 'inproc', 'ipc'. Its default value is 'tcp'.

  4. pattern (int): sets the supported messaging pattern(flow of communication) between server and client. Messaging patterns are the network-oriented architectural pattern that describes the flow of communication between interconnecting systems. NetGear provides access to ZeroMQ's pre-optimized sockets which enables you to take advantage of these patterns. Its default value is 0(i.e zmq.PAIR). The supported patterns are:

    • 0 zmq.PAIR: (PAIR) In this pattern, the communication is bidirectional. There is no specific state stored within the socket. There can only be one connected peer. The server listens on a certain port and a client connects to it.
    • 1 zmq.REQ/zmq.REP: (Request/Reply) In this pattern, it employs ZMQ REQ sockets that can connect to many servers. The requests will be interleaved or distributed to both the servers. socket zmq.REQ will block send unless it has successfully received a reply back and socket zmq.REP will block on recv() unless it has received a request.
    • 2 zmq.PUB,zmq.SUB: (Publish/Subscribe) is another classic pattern where senders of messages, called publishers, do not program the messages to be sent directly to specific receivers, called subscribers. Messages are published without the knowledge of what or if any subscriber of that knowledge exists. A ZMQ.SUB can connect to multiple ZMQ.PUB (publishers). No single publisher overwhelms the subscriber. The messages from both publishers are interleaved.
  5. receive_mode (boolean): set this flag to select the Netgear's Mode of operation. This basically activates Receive Mode(if True) and Send Mode(if False). Furthermore, recv() function will only work when this flag is enabled(i.e. Receive Mode) and send() function will only work when this flag is disabled(i.e.Send Mode). Its default value is False(i.e. Send Mode is activated by default).

  6. **options (dict): can be used to pass vital parameters to NetGear API. This attribute provides us the flexibility to change various NetGear API's powerful internal properties and modes directly. The supported attributes for this **option dictionary are as follows:

    • multiserver_mode(bool): Activates exclusive Multi-Server Mode if it is set to True. See its usage here

    • filter(string): In, Multi-Server Mode, it sets a custom user-defined filter to allow only specific Server ports at the Clients-end. See its usage here.

    • secure_mode(integer): This attribute activates and sets the exclusive Secure Mode (a.k.a ZMQ security Mechanism). Its possible values are: 0: Grassland(no security) & 1:StoneHouse & 2:IronHouse. See its usage here

    • custom_cert_location(string): In Secure Mode, this attribute sets a custom user-defined location/path to directory to generate/store public+secret keypair/certificates. This will thereby creates a .vidgear folder(only if not available) at the given custom path and then use that directory for reading/writing new keypairs.

    • overwrite_cert(bool): In Secure Mode, This attribute sets whether to overwrite existing Public+Secret keypair/certificates for enhanced security at server-end only. If True a new keypair will be generated during initialization :warning: overwrite_cert param is disabled for client-end

    • bidectional_mode (bool): This attribute enables Bi-directional Mode for bi-directional data transmission. See its usage here

    • force_terminate(bool): At Server's End, this attribute enables easy server-side termination when network is too slow to respond. User can use this attribute at the Server-end to enable force socket termination if the Client getting frozen on termination due to significant latency in the network. This attribute is compatible with all exclusive & primary modes . Its usage is as follows:

      options = {'force_terminate':True} #activates server-side force termination

      Note :writing_hand:: force_terminate is disabled for local servers and is enabled by default for Bi-directional Mode

    • compression_format(string): [For Server's End only] This attribute activates compression with selected encoding format at the server's end. The possible values are .jpg, .png, .bmp. :bulb: More information and usage example can be found here

    • compression_param(int & list/tuple): This attribute allow us to pass different Format-specific encoding parameters (such as compression quality) and decoding flags. :bulb: More information and usage example can be found here

    • flag(int): It can be either 0 or zmq.NOBLOCK( i.e. 1).

    • copy(bool): Should the message be received in a copying or non-copying manner? If False a Frame object is returned, if True a string copy of the message is returned.

    • track(bool): check if the message is tracked for notification that ZMQ has finished with it. (ignored if copy=True). Tip:bulb:: More information can be found here

  7. logging (boolean): set this flag to enable/disable error logging essential for debugging. Its default value is False.

You can’t perform that action at this time.