Huge delay between realtime and display on the site when using an RTSP stream

Hello.

I wrote a script that, using yolo, detects the number of people in a zone, tracks them and counts them. I checked the script in Streamlit and also tried to record video to a file - everything works and the lag from real time is about 1 second.

Now I need to make a serious project based on this and I want to use Django for this.
I took my script (object_counter.py) and transferred it to my application. Then I made a view to show the processed image on the page.

── peoplecounting
   ├── manage.py
   ├── peoplecounting
   │   ├── asgi.py
   │   ├── gunicorn.conf.py
   │   ├── settings.py
   │   ├── static
   │   │   └── admin
   │   ├── urls.py
   │   └── wsgi.py
   ├── peoplecountingapp
   │   ├── admin.py
   │   ├── apps.py
   │   ├── __init__.py
   │   ├── models.py
   │   ├── object_counter.py
   │   ├── templates
   │   │   └── index.html
   │   ├── tests.py
   │   └── views.py
   ├── yolov8s.pt
   ├── zone_0.tmp
   └── zone_1.tmp

I could have done something wrong, since the information is very scattered and I had to collect it from several sources.

One way or another, everything worked for me, except for one very unpleasant moment - the lag between realtime and display on the page is 24 seconds.

That is, the Man passed, and only after 24 seconds he appears on the screen.

Please tell me how to optimize this lag? I didn’t find any settings for this. I am attaching the views file, I can attach my script if necessary.

import cv2

from django.shortcuts import render

from django.http import StreamingHttpResponse
from django.views.decorators import gzip
from .object_counter import CountObject, VideoCapture, write_zone_value_to_file

class VideoCamera:
    def __init__(self, rtsp_url):
        self.cap = cv2.VideoCapture(rtsp_url)
        self.count_object_instance = CountObject(rtsp_url)

    def __del__(self):
        self.cap.release()

    def get_frame(self):
        ret, frame = self.cap.read()
        annotated_frame = self.count_object_instance.process_frame(frame)
        _, jpeg = cv2.imencode('.jpg', annotated_frame)
        return jpeg.tobytes()

@gzip.gzip_page
def video_feed(request):
    rtsp_url = "rtsp://.../cam/realmonitor?channel=1&subtype=00&authbasic=[AUTH]"  
    return StreamingHttpResponse(video_generator(VideoCamera(rtsp_url)), content_type='multipart/x-mixed-replace; boundary=frame')

def video_generator(camera):
    while True:
        frame = camera.get_frame()
        yield (b'--frame\r\n'
               b'Content-Type: image/jpeg\r\n\r\n' + frame + b'\r\n')

def index(request):
    return render(request, 'index.html')

This version works flawlessly


from django.http import StreamingHttpResponse
from django.views.decorators import gzip
from .object_counter import CountObject, VideoCapture
import cv2

# Create an instance of CountObject and VideoCapture
rtsp_url = "rtsp://.../cam/realmonitor?channel=1&subtype=00&authbasic=[AUTH]"  
count_object_instance = CountObject(rtsp_url)
video_capture = VideoCapture(rtsp_url)

@gzip.gzip_page
def video_feed(request):
    def generate():
        while True:
            frame = video_capture.read()
            annotated_frame = count_object_instance.process_frame(frame)
            _, buffer = cv2.imencode('.jpg', annotated_frame)
            frame_bytes = buffer.tobytes()
            yield (b'--frame\r\n'
                   b'Content-Type: image/jpeg\r\n\r\n' + frame_bytes + b'\r\n')

    return StreamingHttpResponse(generate(), content_type='multipart/x-mixed-replace; boundary=frame')