Создание видеостены для RTSP потоков с использованием Python, OpenCV и Flet


Узнайте, как создать простую видеостену для одновременного отображения нескольких RTSP потоков с помощью Python. Мы рассмотрим принцип работы программы, плюсы и минусы использования OpenCV для захвата видеопотоков и Flet для создания интерфейса, а также пример настройки многопоточной обработки.
Данный код представляет собой простую видеостену для отображения RTSP (Real-Time Streaming Protocol) потоков. В её основе используется библиотека OpenCV для захвата кадров с видеопотоков и библиотека Flet для создания пользовательского интерфейса. Основная задача программы — получить видео с нескольких RTSP-камер и вывести их в реальном времени на экран.
Установка
pip install opencv-python flet numpy pillow
Основные плюсы
- Параллельная обработка потоков: благодаря использованию потоков, программа может обрабатывать и отображать несколько RTSP потоков одновременно, что позволяет создать видеостену с несколькими камерами.
- Легкость масштабирования: код легко масштабируется для работы с различным количеством камер, достаточно изменить список RTSP URL-ов.
- Минимальные зависимости: код использует лишь несколько библиотек (OpenCV, Flet, NumPy), что делает её относительно легковесной и простой в установке.
# -*- coding: utf-8 -*-
import cv2
import threading
import flet as ft
import numpy as np
import base64
from io import BytesIO
import time
# Подготовка кадра
def image_to_base64(image):
_, buffer = cv2.imencode('.jpg', image)
img_bytes = BytesIO(buffer)
img_base64 = base64.b64encode(img_bytes.getvalue()).decode('utf-8')
return img_base64
# Видео поток
class rtsp_stream:
def __init__(self, rtsp_url, video_widget):
self.capture = cv2.VideoCapture(rtsp_url, cv2.CAP_FFMPEG)
self.frame = None
self.video_widget = video_widget
self.running = True
self.lock = threading.Lock()
def start_stream(self):
while self.running:
try:
ret, frame = self.capture.read()
if ret:
with self.lock:
self.frame = frame
except Exception as e:
pass
time.sleep(0.01)
def display_frame(self):
while self.running:
try:
with self.lock:
if self.frame is not None:
base64_img = image_to_base64(self.frame)
self.video_widget.src_base64 = base64_img
self.video_widget.update()
except Exception as e:
pass
time.sleep(0.01)
def stop(self):
self.running = False
self.capture.release()
# Старт
def main(page: ft.Page):
page.window.width = 900
page.window.height = 560
page.title = ""
# Вводим URL RTSP потоков
rtsp_urls = [
"http://158.58.130.148:80/mjpg/video.mjpg",
"http://158.58.130.148:80/mjpg/video.mjpg",
"http://158.58.130.148:80/mjpg/video.mjpg",
"http://158.58.130.148:80/mjpg/video.mjpg"
]
# Подготовка внешнего вида
video_widgets = []
rv = ft.ResponsiveRow([])
for url in rtsp_urls:
video_elem = ft.Image(src="")
video_widgets.append(video_elem)
var_elem = ft.Container(
video_elem,
padding=5,
col={"sm": 6, "md": 6, "xl": 6},
border = ft.border.all(1, ft.colors.PRIMARY)
)
rv.controls.append(var_elem)
lv = ft.ListView(expand = 1, spacing = 10, padding = 10)
lv.controls.append(rv)
page.add(lv)
# Создаем объект RTSP потока и запускаем поток захвата кадров
for i, widget in enumerate(video_widgets):
# Запуск потоков захвата и отображения
stream = rtsp_stream(rtsp_urls[i], widget)
threading.Thread(target=stream.start_stream, daemon=True).start()
threading.Thread(target=stream.display_frame, daemon=True).start()
# Остановка потока при закрытии страницы
page.on_disconnect = lambda: stream.stop()
# Запуск приложения
ft.app(target=main)
Заключение
Программа демонстрирует базовую концепцию видеостены, которая обрабатывает несколько RTSP потоков с использованием параллельных потоков для захвата и отображения видео. Несмотря на свою простоту, она является гибким решением для реализации видеонаблюдения или других задач, требующих многопоточного видео.
- 16.10.2024
- 71
- 0
Создание видеостены для RTSP потоков с использованием Python, OpenCV и Flet
Данный код представляет собой простую видеостену для отображения RTSP (Real-Time Streaming Protocol) потоков. В её основе используется библиотека OpenCV для захвата кадров с видеопотоков и библиотека Flet для создания пользовательского интерфейса. Основная задача программы — получить видео с нескольких RTSP-камер и вывести их в реальном времени на экран.
Установка
pip install opencv-python flet numpy pillow
Основные плюсы
- Параллельная обработка потоков: благодаря использованию потоков, программа может обрабатывать и отображать несколько RTSP потоков одновременно, что позволяет создать видеостену с несколькими камерами.
- Легкость масштабирования: код легко масштабируется для работы с различным количеством камер, достаточно изменить список RTSP URL-ов.
- Минимальные зависимости: код использует лишь несколько библиотек (OpenCV, Flet, NumPy), что делает её относительно легковесной и простой в установке.
# -*- coding: utf-8 -*-
import cv2
import threading
import flet as ft
import numpy as np
import base64
from io import BytesIO
import time
# Подготовка кадра
def image_to_base64(image):
_, buffer = cv2.imencode('.jpg', image)
img_bytes = BytesIO(buffer)
img_base64 = base64.b64encode(img_bytes.getvalue()).decode('utf-8')
return img_base64
# Видео поток
class rtsp_stream:
def __init__(self, rtsp_url, video_widget):
self.capture = cv2.VideoCapture(rtsp_url, cv2.CAP_FFMPEG)
self.frame = None
self.video_widget = video_widget
self.running = True
self.lock = threading.Lock()
def start_stream(self):
while self.running:
try:
ret, frame = self.capture.read()
if ret:
with self.lock:
self.frame = frame
except Exception as e:
pass
time.sleep(0.01)
def display_frame(self):
while self.running:
try:
with self.lock:
if self.frame is not None:
base64_img = image_to_base64(self.frame)
self.video_widget.src_base64 = base64_img
self.video_widget.update()
except Exception as e:
pass
time.sleep(0.01)
def stop(self):
self.running = False
self.capture.release()
# Старт
def main(page: ft.Page):
page.window.width = 900
page.window.height = 560
page.title = ""
# Вводим URL RTSP потоков
rtsp_urls = [
"http://158.58.130.148:80/mjpg/video.mjpg",
"http://158.58.130.148:80/mjpg/video.mjpg",
"http://158.58.130.148:80/mjpg/video.mjpg",
"http://158.58.130.148:80/mjpg/video.mjpg"
]
# Подготовка внешнего вида
video_widgets = []
rv = ft.ResponsiveRow([])
for url in rtsp_urls:
video_elem = ft.Image(src="")
video_widgets.append(video_elem)
var_elem = ft.Container(
video_elem,
padding=5,
col={"sm": 6, "md": 6, "xl": 6},
border = ft.border.all(1, ft.colors.PRIMARY)
)
rv.controls.append(var_elem)
lv = ft.ListView(expand = 1, spacing = 10, padding = 10)
lv.controls.append(rv)
page.add(lv)
# Создаем объект RTSP потока и запускаем поток захвата кадров
for i, widget in enumerate(video_widgets):
# Запуск потоков захвата и отображения
stream = rtsp_stream(rtsp_urls[i], widget)
threading.Thread(target=stream.start_stream, daemon=True).start()
threading.Thread(target=stream.display_frame, daemon=True).start()
# Остановка потока при закрытии страницы
page.on_disconnect = lambda: stream.stop()
# Запуск приложения
ft.app(target=main)
Заключение
Программа демонстрирует базовую концепцию видеостены, которая обрабатывает несколько RTSP потоков с использованием параллельных потоков для захвата и отображения видео. Несмотря на свою простоту, она является гибким решением для реализации видеонаблюдения или других задач, требующих многопоточного видео.