- asyncio: Модуль для асинхронного программирования.
- base64: Модуль для кодирования и декодирования данных в формате base64.
- contextlib: Контекстные менеджеры и утилиты для работы с ними.
- io: Модуль для работы с потоками ввода/вывода.
- json: Модуль для работы с JSON-данными.
- sys: Модуль для работы с параметрами командной строки и другими системными функциями.
- threading: Модуль для многопоточности.
- PIL.Image: Библиотека для обработки изображений.
- cv2: Библиотека OpenCV для обработки изображений и видео.
- tornado.ioloop, tornado.web, tornado.websocket: Tornado - веб-фреймворк для создания веб-приложений и работы с WebSocket.
- socket: Модуль для сетевого взаимодействия.
ПАРАМЕТРЫ ПОДКЛЮЧЕНИЯ
global massmass=Noneiflen(sys.argv)>1:# Первый аргумент после имени скрипта будет содержать данные о портах port_data = sys.argv[1] port_data = port_data.split(',')print(port_data) ports = port_data[0].split(':') ports2 = port_data[1].split(':') ip_site=ports[0] port_site=ports[1] host = ports2[0] port =int(ports2[1]) rtsp = port_data[2]else:print("Данные о портах не были переданы")
Этот блок кода обрабатывает аргументы командной строки, чтобы установить параметры подключения:
- sys.argv: Используется для получения аргументов командной строки.
- port_data: Информация о портах для веб-сервера и RTSP потока.
НАСТРОЙКА СОКЕТА
server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_SNDBUF, 65536)server_socket.bind((host, port))server_socket.listen(5)print(f"Server listening on {host}:{port}")
Здесь происходит создание и настройка сокета для прослушивания входящих соединений.
ИНИЦИАЛЗАЦИЯ КЛАССА MainHandler
classMainHandler(tornado.web.RequestHandler):""" Обработка GET-запроса. Описание: Метод вызывается при получении GET-запроса от клиента. Он отвечает за рендеринг HTML-шаблона 'in.html'. """defget(self): self.render("in.html")
В этом классе происходит обработка GET-запроса и рендеринг HTML-шаблона.
ИНИЦИАЛИЗАЦИЯ КЛАССА SimpleWebSocket
classSimpleWebSocket(tornado.websocket.WebSocketHandler):defopen(self):""" Обработка открытия WebSocket. Описание: Метод вызывается при установлении нового WebSocket соединения с клиентом. Он инициирует асинхронную задачу отправки обновлений клиенту.
"""print("WebSocket opened") asyncio.create_task(self.send_updates())asyncdefsend_updates(self):""" Асинхронная отправка обновлений клиенту. Описание: Метод выполняется в бесконечном цикле, отправляя клиенту кадры (frame) и данные графика (plot), если они доступны. Использует глобальную переменную 'mass' для отправки данных графика.
"""whileTrue: frame =get_frame()# plot_data = create_plotly_figure()if frame:await self.write_message(json.dumps({'type': 'frame', 'frame': frame}))global massifnot mass==None:await self.write_message(json.dumps({'type': 'plot', 'plot': mass}))await asyncio.sleep(0)# Передача управления для обработки других задачdefon_message(self,message):""" Обработка входящих сообщений от клиента. Описание: Метод вызывается при получении сообщения от клиента. В текущей реализации метод не выполняет никаких действий. """# print(message)passdefon_close(self):""" Обработка закрытия WebSocket. Описание: Метод вызывается при закрытии WebSocket соединения. Выводит сообщение о закрытии соединения. """print("WebSocket closed")
В этом классе происходит обработка открытия, получения сообщений и закрытия WebSocket соединения, так же асинхронная отправка обновлений клиенту.
ЗАХВАТ ВИДЕО
cap=cv2.VideoCapture(rtsp)defget_frame():""" Захват кадра из видеопотока и его преобразование в строку base64. Библиотеки: - cv2: для захвата видео - io: для работы с потоками ввода/вывода - PIL: для работы с изображениями - base64: для кодирования данных в формат base64 Возвращает: - str: Строка, содержащая изображение в формате JPEG, закодированное в base64. Описание: Функция захватывает кадр из видеопотока, преобразует его в формат JPEG и кодирует в строку base64. Если захват кадра не удался, функция возвращает None. """ _, img = cap.read()if img isnotNone: buffer = io.BytesIO() pil_img = Image.fromarray(cv2.cvtColor(img, cv2.COLOR_BGR2RGB)) pil_img.save(buffer, format='JPEG') img_str = base64.b64encode(buffer.getvalue()).decode('utf-8')return img_strelse:returnNone
В этом блоке кода инициализируется функция для захвата кадра из RTSP потока и его кодирования в формат base64.
ЗАПУСК TORNADO
asyncdefstart_tornado():""" Настройка и запуск асинхронного веб-сервера Tornado. Библиотеки: - tornado.web: для создания веб-приложения - tornado.websocket: для работы с WebSocket - asyncio: для асинхронного программирования Параметры: - Нет параметров. Описание: Функция создает экземпляр веб-приложения Tornado с обработчиками для HTTP и WebSocket, запускает его на указанном IP-адресе и порту, и ожидает событий. """ app= tornado.web.Application([ (r"/", MainHandler), (r"/websocket", SimpleWebSocket), ]) app.listen(port_site,ip_site)print(f"Сервер Tornado запущен на http://{ip_site}:{port_site}")await asyncio.Event().wait()
Это асинхронная функция для настройки и запуска веб-сервера Tornado.
ОБРАБОТКА СОКЕТОВ
defasync_task():""" Обработка входящих соединений и данных от клиентов. Библиотеки: - socket: для работы с сетевыми сокетами - threading: для многопоточности Параметры: - Нет параметров. Возвращает: - Ничего не возвращает. Описание: Функция ожидает входящие соединения на сокете сервера. При установлении соединения данные от клиента считываются и сохраняются в глобальной переменной `mass`. После обработки данных соединение закрывается. """global masswhileTrue: client_socket, addr = server_socket.accept()print(f"Connected by {addr}")try:whileTrue: data = client_socket.recv(65536).decode('utf-8')ifnot data: mass=Nonebreak mass=datafinally: client_socket.close()print("Connection closed.")# return
Это функция для обработки входящих соединений через сокеты и получения данных от клиентов
ГЛАВНАЯ ФУНКЦИЯ
asyncdefmain():# Создание задачи для асинхронной функции socket_thread = threading.Thread(target=async_task, daemon=True) socket_thread.start()with contextlib.suppress(KeyboardInterrupt):# Запуск сервера Tornadoawaitstart_tornado() socket_thread.join()
Это основная функция запуска, которая инициализирует поток для обработки сокетов и запускает сервер Tornado.
Здесь происходит закрытие сокета и сервера Tornado
Процесс подготовки кода:
Создайте файл и назовите его Server_site.py
Поэтапно скопируйте код в файл:
Установите необходимые библиотеки: в данном случае у нас не предустановлены следующие библиотеки: PIL (Pillow), cv2 и tornado. Если у вас не установлены эти библиотеки, выполните следующие действия:
Откройте терминал VS Code (Terminal -> New Termial или комбинацией Ctrl + Shift + `)
В терминале поочередно введите и запустите следующие команды: pip install pillow; pip install opencv-python, pip install tornado