1

I am trying to create a simple video streaming site with Django. I am using cv2 for starting the webcam and ZMQ for transferring data from client to server. I found this link with which I wrote the networking part of the code.

The code by itself works fine, but when I create a simple HTML file to start the live stream through the browser the code fails with this error message

zmq.error.ZMQError: Address in use

I guess this error arises because the IP Django uses and the IP ZMQ tries to uses is the same. But I am not sure how to rectify this error.

This is my code so far

server.py

def start_server():
    context = zmq.Context()
    footage_socket = context.socket(zmq.SUB)
    print('socket created')

    footage_socket.setsockopt_string(zmq.SUBSCRIBE, np.unicode(''))
    footage_socket.bind('tcp://192.168.1.18:5020')

    print('binding complete')
    print('server ready')

    return footage_socket

def recv_content(socket, face_cascade_path):

    cascade = cv2.CascadeClassifier(face_cascade_path)

    while True:
        try:
            data = socket.recv_string()
            img = base64.b64decode(data)
            npimg = np.fromstring(img, dtype=np.uint8)
            frame = cv2.imdecode(npimg, 1)
            print(frame)

            face = cascade.detectMultiScale(frame, scaleFactor=1.3, minNeighbors=3)

            for (x, y, w, h) in face:
                cv2.rectangle(frame, (x, y), (x+w, y+h), (0, 0, 255), 2)

            if cv2.waitKey(1) & 0xFF == ord('q'):
                break

            cv2.imshow("Stream", frame)

        except KeyboardInterrupt:
            cv2.destroyAllWindows()
            break

views.py

from server import *

def index(request):

    face_cascade_path = '../../../TRAINED MODELS/FACE/haarcascade_frontalface_default.xml'
    footage_socket = start_server()
    recv_content(footage_socket, face_cascade_path)

    return render(request, 'index.html')

def start_client(request):
    context = zmq.Context()
    footage_socket = context.socket(zmq.PUB)
    footage_socket.connect('tcp://192.168.1.18:5020')

    print('connected to server')
    print('starting video on client machine')

    camera = cv2.VideoCapture(0)  # init the camera

    while True:
        try:
            grabbed, frame = camera.read()  # grab the current frame
            frame = cv2.resize(frame, (640, 480))  # resize the frame
            frame = cv2.flip(frame, 1)
            encoded, buffer = cv2.imencode('.jpg', frame)
            jpg_as_text = base64.b64encode(buffer)
            footage_socket.send(jpg_as_text)

        except KeyboardInterrupt:
            camera.release()
            cv2.destroyAllWindows()
            break

index.html

<html>
<head>

</head>
<body>
  <div class='container'>
    <h2>CAMERA SERVER CLIENT TEST</h2>

    <p>
    Click the start_client button to start camera. Each frame of the stream is sent to the server.
    </p>
    <p>
      The camera code is running on the client side.
    </p>

    <a href ='start_client/'><button>start client</button></a>

  </div>
</body>
</html>

Please help me.

Thank you in advance

EDIT 1 - I have edited to add the client part of the code and index.html as well. The start_client function is under views.py. This function is run when the start_client button in index.html is clicked

EDIT 2 - I have edited the question to add a screenshot of my problem. While I dont face the "address in use" error when I refresh the page after adding the try-except block, the webpage is still not loading.

enter image description here

Sashaank
  • 880
  • 2
  • 20
  • 54

1 Answers1

1

You should adopt another port instead of the common 8000 port which usually is in use.

Another idea is that any socket options must be placed before bind or connect method in ZMQ.

So your code will look something like this:

def start_server():
    context = zmq.Context()
    footage_socket = context.socket(zmq.SUB)
    footage_socket.setsockopt_string(zmq.SUBSCRIBE, np.unicode(''))

    try:
        footage_socket.bind('tcp://192.168.1.18:5020')  # Another port used.
    except:
        pass

    return footage_socket

[NOTE]:

Do not forget to change the port on the client side (.connect()) to 5020.


[UPDATE]:

Benyamin Jafari
  • 27,880
  • 26
  • 135
  • 150
  • Hey! I tried changing the port to the server and the client. Now when I start the django server and navigate to the ip address the page just keeps loading. and nothing happens. If I try reloading the page, I get address in use error. What am I doing wrong? – Sashaank Dec 05 '18 at 04:36
  • The django server runs in 192.168.1.18:8000, zmq server runs in 192.168.1.18:5020 and I changed the port in client accordingly as well – Sashaank Dec 05 '18 at 04:37
  • @Sashaank Can you put on client code with an edit in your question? Did you change the socket option placement (before binding the IP)? – Benyamin Jafari Dec 05 '18 at 06:43
  • I have just added the client part of the code. I changed the socket option placement in server.py. I have added that code as well – Sashaank Dec 05 '18 at 07:14
  • At first I thought, because of the while loop under **recv_content()** function in **server.py** the code was not going to the next line in **views.py**. So I removed the while loop and started the django server again. I am still facing the same issue. The page never loads. if I try refreshing, I encounter address in use error. Please help me – Sashaank Dec 06 '18 at 05:44
  • Hi. I have edited to question and added a screenshot of my error. I added the try-except block and am no longer facing the address in use error. But the webpage still does not load. Is this because of the while loop in server.py? how do I rectify this? – Sashaank Dec 06 '18 at 09:11
  • Hi. Just figured out that there is no problem in the server.py file. the recv_content() function in server.py gets executed when i navigate to the IP address. Then when I start client.py in a separate command prompt, the camera feed is executed. – Sashaank Dec 06 '18 at 09:22
  • I wanted the website to open where I would press a button named start_client and when the button is pressed the camera feed is started. – Sashaank Dec 06 '18 at 09:23
  • I just changed the code to add a start_server button in index.html. Now the code works fine. But the when start_client button is pressed from the client machine, only the camera on the server side is activated. How do I rectify that? – Sashaank Dec 06 '18 at 09:35
  • @Sashaank I haven't any experienced todo that. – Benyamin Jafari Dec 06 '18 at 09:50
  • @Sashaank I think your problem is that, both view.py(zmq.PUB) and server.py(zmq.SUB) placed in your server, so you can't get the client camera with this method. – Benyamin Jafari Dec 06 '18 at 09:57
  • @Sashaank Might be you need to JS language to overcome that, I suggest open another post(question) with this content: `How to get camera data from the client side to server side using Django?` – Benyamin Jafari Dec 06 '18 at 10:00
  • @Sashaank There is no bother. If this post helped you, a +1 would be appreciated. – Benyamin Jafari Dec 06 '18 at 10:10