RTSP-камера в режиме реального времени на сервере Django или в приложении React

Я хочу транслировать видео с камеры на своем веб-сайте, используя django и react.

в VLC -> Медиа -> Открытом сетевом потоке я устанавливаю этот URL-адрес RTSP на вкладке Сеть, и я могу отлично видеть видео с камеры в реальном времени:

rtsp://user:password%40123@ip:port

Но я не могу сделать это в django. или, может быть, мне не нужно делать это в django и я могу сделать это только в react.

лучшее, чего я смог добиться, - это этот код, который работал только локально с VPN:

class VideoCamera:
    def __init__(self):
        url = "rtsp://user:password%40123@ip:port"
        self.video = cv2.VideoCapture(url, cv2.CAP_FFMPEG)

        if not self.video.isOpened():
            print("Failed to open RTSP stream")
            self.running = False
            return
        
        self.running = True
        self.grabbed, self.frame = self.video.read()
        self.lock = threading.Lock()  # Prevents race conditions
        self.thread = threading.Thread(target=self.update, daemon=True)
        self.thread.start()

    def update(self):
        while self.running:
            grabbed, frame = self.video.read()
            if not grabbed:
                print("Failed to grab frame, retrying...")
                continue  # Prevents self.frame from being None
            with self.lock:
                self.frame = frame

    def get_frame(self):
        with self.lock:
            if self.frame is None:
                return None

            success, jpeg = cv2.imencode('.jpg', self.frame)
            if not success:
                print("Encoding failed")
                return None  # Prevent sending invalid data

            return jpeg.tobytes()


    def stop(self):
        self.running = False
        self.thread.join()  # Ensures clean exit
        self.video.release()

def get_camera(camera):
    while camera.running:
        frame = camera.get_frame()
        if frame:
            yield (b'--frame\r\n'
                   b'Content-Type: image/jpeg\r\n\r\n' + frame + b'\r\n\r\n')
        else:
            print("No frame available")

def stream_video(request):
    cam = VideoCamera()
    if not cam.running:
        return StreamingHttpResponse("Failed to open RTSP stream", status=500)

    try:
        return StreamingHttpResponse(
            get_camera(cam),
            content_type='multipart/x-mixed-replace; boundary=frame'
        )
    except Exception as e:
        print(f"Error occurred: {e}")
        cam.stop()
    
    return StreamingHttpResponse("Stream stopped", status=500)

но когда я загружаю этот код на сервер, я не могу увидеть видео на веб-сайте. однако кадры были напечатаны правильно.

Я также протестировал этот WebRTC-код, но он не сработал:

import asyncio
import subprocess
from channels.generic.websocket import AsyncWebsocketConsumer

class StreamConsumer(AsyncWebsocketConsumer):
    async def connect(self):
        print("WebSocket connect attempt")
        # Accept WebSocket connection
        await self.accept()

        # Start FFmpeg process to capture RTSP stream
        try:
            self.ffmpeg_process = subprocess.Popen(
                [
                    'ffmpeg',
                    '-i', 'rtsp://admin:Admin%40123@192.168.10.11:554',  # Replace with your RTSP stream URL
                    '-f', 'mjpeg',  # MJPEG format
                    '-q:v', '5',  # Set quality level
                    '-'
                ],
                stdout=subprocess.PIPE,
                stderr=subprocess.PIPE
            )

            print("FFmpeg process started")

            # Start sending frames asynchronously
            asyncio.create_task(self.stream_video())

        except Exception as e:
            print(f"Error starting FFmpeg process: {e}")
            await self.close()

    async def stream_video(self):
        try:
            while True:
                # Read the video data (frame) from FFmpeg
                frame = self.ffmpeg_process.stdout.read(1024)
                if not frame:
                    print("No frame received. Exiting.")
                    break

                print("Sending frame to WebSocket")
                # Send the frame to WebSocket
                await self.send(bytes_data=frame)
        except Exception as e:
            print(f"Error while streaming video: {e}")

    async def disconnect(self, close_code):
        print(f"WebSocket disconnected with code {close_code}")
        if self.ffmpeg_process:
            self.ffmpeg_process.kill()
            print("FFmpeg process killed")

Я также протестировал его и получил 1-минутное видео, но оно не в реальном времени и его недостаточно:

сначала я использовал это для создания сегментов потока из rtsp:

ffmpeg -i rtsp://user:password%40123@ip:port -c:v libx264 -f hls -hls_time 10 -hls_list_size 6 -hls_flags delete_segments stream.m3u8

затем использовал это, чтобы сделать его доступным на порту 2025:

http-server . -p 2025

и, наконец:

<video width="100%" height="auto" controls>
  <source src="http://ip:2025/cam.mp4" type="video/mp4" />
</video>

Мне нужно надежное решение для прямой трансляции видео с камеры на моем веб-сайте django. пожалуйста, помогите мне.

Вернуться на верх