python读取监控流通过websocket连接发送到java服务端,服务端推流到前端

news2025/7/14 8:39:58

在这里插入图片描述

  • python读取逐帧读取监控
import websocket
import base64
import cv2
import numpy as np

videoPath = "rtmp://ns8.indexforce.com/home/mystream"  // 此为公开RTSP流

def on_message(ws, message):
    print(1)


def connection_tmp(ws):
    websocket.enableTrace(True)
    ws = websocket.WebSocketApp("ws://127.0.0.1:8080/video",
                                on_message=on_message,
                                on_error=on_error,
                                on_close=on_close)

    ws.on_open = on_open
    cap = cv2.VideoCapture(videoPath)
    try:
        ws.run_forever()
    except KeyboardInterrupt:
        ws.close()
    except:
        ws.close()

def on_error(ws, error):
    reconnect_count=0
    print(type(error))
    print(error)
    print("正在尝试第%d次重连" % reconnect_count)
    reconnect_count += 1
    if reconnect_count < 100:
        connection_tmp(ws)



def on_close(ws, close_status_code, close_msg):
    print("Connection closed:", close_status_code, close_msg)


def on_open(ws):
    while cap.isOpened():
        ret, frame = cap.read()
        if not ret:
            break

        encode_param = [int(cv2.IMWRITE_JPEG_QUALITY), 90]
        result, imgencode = cv2.imencode('.jpg', frame, encode_param)
        data = np.array(imgencode)
        img = data.tostring()
        img = base64.b64encode(img).decode()

        try:
            ws.send("img=" + img)
        except websocket.WebSocketConnectionClosedException:
            print("WebSocket connection is closed. Cannot send data.")
            break



websocket.enableTrace(True)
ws = websocket.WebSocketApp("ws://127.0.0.1:8080/video",
                                on_message=on_message,
                                on_error=on_error,
                                on_close=on_close)

ws.on_open = on_open
cap = cv2.VideoCapture(videoPath)
try:
    ws.run_forever()
except KeyboardInterrupt:
    ws.close()
  • Springboot集成websocket接收websocket连接请求
    pom文件添加配置
  <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-websocket</artifactId>
            <version>3.1.2</version>
        </dependency>
        <dependency>
            <groupId>org.java-websocket</groupId>
            <artifactId>Java-WebSocket</artifactId>
            <version>1.3.5</version>
        </dependency>

EnableWebsocket开启websocket

@SpringBootApplication(exclude={DataSourceAutoConfiguration.class,HibernateJpaAutoConfiguration.class})
@EnableWebSocket
public class MyblogApplication {

    public static void main(String[] args) {
        SpringApplication.run(MyblogApplication.class, args);
    }

}

package sxu.edu.hkj.myblog.config;//package sxu.edu.hkj.myblog.config;


import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.socket.config.annotation.EnableWebSocket;
import org.springframework.web.socket.config.annotation.WebSocketConfigurer;
import org.springframework.web.socket.config.annotation.WebSocketHandlerRegistry;
import org.springframework.web.socket.server.standard.ServletServerContainerFactoryBean;
import sxu.edu.hkj.myblog.controller.VideoWebSocketHandler;

@Configuration
@EnableWebSocket
public class WebSocketConfig implements WebSocketConfigurer {
    @Override
    public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {
        // 在这里配置WebSocket处理程序并指定自定义端点路径
        registry.addHandler(new VideoWebSocketHandler(), "/video").setAllowedOrigins("*");
    }

    @Bean
    public ServletServerContainerFactoryBean createWebSocketContainer() {
        ServletServerContainerFactoryBean container = new ServletServerContainerFactoryBean();
        // 在此处设置bufferSize
        container.setMaxTextMessageBufferSize(1024000);
        container.setMaxBinaryMessageBufferSize(1024000);
        container.setMaxSessionIdleTimeout(15 * 60000L);
        return container;
    }

}


通信服务:

package sxu.edu.hkj.myblog.controller;
import lombok.SneakyThrows;
import org.springframework.stereotype.Component;
import org.springframework.web.socket.BinaryMessage;
import org.springframework.web.socket.CloseStatus;
import org.springframework.web.socket.TextMessage;
import org.springframework.web.socket.WebSocketSession;
import org.springframework.web.socket.handler.BinaryWebSocketHandler;

import java.io.IOException;
import java.util.concurrent.CopyOnWriteArraySet;
import java.nio.ByteBuffer;

@Component
public class VideoWebSocketHandler extends BinaryWebSocketHandler {

    private static final CopyOnWriteArraySet<WebSocketSession> SESSIONS = new CopyOnWriteArraySet<>();

    @Override
    public void afterConnectionEstablished(WebSocketSession session) {
        SESSIONS.add(session);
        System.out.println("WebSocket消息】有新的连接,总数为:" + SESSIONS.size());
    }

    @Override
    public void afterConnectionClosed(WebSocketSession session, CloseStatus status) {
        SESSIONS.remove(session);
        System.out.println("【WebSocket消息】连接断开,总数为:" + SESSIONS.size());
    }

    @SneakyThrows
    @Override
    protected void handleTextMessage(WebSocketSession session, TextMessage message){
        // Handle incoming text messages here, if needed
        String textMessage = message.getPayload();
//        System.out.println("Received text message: " + textMessage);

        // Broadcast the received text message to all connected clients
        for (WebSocketSession clientSession : SESSIONS) {
                if (clientSession.isOpen() && !clientSession.equals(session)) {
                    clientSession.sendMessage(new TextMessage(textMessage));
                }

        }
    }

    @Override
    protected void handleBinaryMessage(WebSocketSession session, BinaryMessage message) throws IOException {
        byte[] frameData = message.getPayload().array();
        System.out.println(frameData);
        // 将接收到的二进制图像数据发送给所有客户端
        for (WebSocketSession clientSession : SESSIONS) {
            try {
                if (clientSession.isOpen() && !clientSession.equals(session)) {
                    // 创建一个新的BinaryMessage并发送给客户端
                    BinaryMessage responseMessage = new BinaryMessage(ByteBuffer.wrap(frameData));
                    clientSession.sendMessage(responseMessage);
                    System.out.println("发送关闭广播++++++++++++++++++++++"+frameData);
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}


前端接收websocket广播信息,并绑定dom到前端


  <img
              class="resizable-image11"
              :src="image3Source"
              alt="Image"
              v-show="isCalibrating"
              style="opacity: 0.6; height: 560px; width: 1168px; margin:-569px -29px 12px -30.06px; pointer-events: none; filter: contrast(550%)"
            />



let ws = new WebSocket("ws://127.0.0.1:8082/video");

ws.onopen = function(evt) {
};
ws.onopen = function (evt) {
    ws.send("Hello WebSockets!");
    isWebSocketConnected.value = true; // WebSocket is open
};

ws.onclose = function (evt) {
    isWebSocketConnected.value = false; // WebSocket is closed
    var reconnect_count=0
   
    reconnect_count += 1
    if (reconnect_count < 100){
      let ws = new WebSocket("ws://127.0.0.1:8082/video");
    }
      
};

ws.onmessage = function (event) {
    const message = event.data;
    const parts = message.split('=');
    const dataType = parts[0];
    const data = parts[1];

    if (dataType === 'img') {
        const imageData = 'data:image/jpeg;base64,' + data;

        document.getElementById('resImg').src = imageData;
    } else if (dataType === 'a1') {

    }
};

ws.onclose = function(evt) {
};

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/996697.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

时序分解 | MATLAB实现基于小波分解信号分解分量可视化

时序分解 | MATLAB实现基于小波分解信号分解分量可视化 目录 时序分解 | MATLAB实现基于小波分解信号分解分量可视化效果一览基本介绍程序设计参考资料 效果一览 基本介绍 基于小波分解的分量可视化&#xff0c;MATLAB编程程序&#xff0c;用于将信号分解成不同尺度和频率的子信…

动态库的制作和使用

动态库和静态库的工作原理 配置环境变量 方式1&#xff1a; 坏处&#xff1a;环境变量是临时的 方式2&#xff1a; 1 用户级别的配置&#xff1a; 进入到/home&#xff0c;找到.bashrc&#xff0c;进入 先去找到库的路径 然后再到.bashrc最后一行输入路径 使其生效 2 系统…

芯片产业链补齐,中国成全球唯一拥有全部工业门类的国家

随着一款国产5G手机的发布&#xff0c;中国制造在芯片产业链方面也形成了自己的完整体系&#xff0c;成为全球唯一一个拥有全部工业门类的国家&#xff0c;这是非常值得高兴的消息。 中国早在2010年就成为全球最大制造国&#xff0c;不过当时中国制造所需要的芯片大多都需要从海…

解决img标签和p标签不能水平居中对齐的问题

现象如下&#xff1a; <div class"children"><div class"wrap"><ul><li class"product"><a href"#"><img src"./images/miphone1.jpg"><p>小米手机</p></a></li&…

【LeetCode-中等题】27. 移除元素

文章目录 题目方法一&#xff1a;快慢指针 题目 方法一&#xff1a;快慢指针 int fast 0;// 快指针 用于扫描需要的元素int slow 0;//慢指针 用于记录需要存放元素的位置class Solution { // 快慢指针public int removeElement(int[] nums, int val) {int fast 0;// 快指针…

页面分布引导新手指引(driver.js)

页面分布引导&#xff08;driver.js&#xff09; 最近由于有一个需求——做新手指引&#xff0c;在新用户进入页面的时候提供指引和帮助,快速让用户熟悉页面的功能,但是为了不要过多影响现有的页面逻辑和样式,找到一款非常好用的工具driver.js:Driver.js是一个功能强大且高度可…

golang-bufio 缓冲扫描

前面两篇博客&#xff0c;介绍了 bufio 包中的缓冲读和写&#xff08;bufio.go&#xff09;&#xff0c;下面再来介绍一下缓冲扫描&#xff08;scan.go&#xff09;。这个扫描的是用来对缓存读的更高级封装&#xff0c;提供了一些更易用的方法。 缓冲扫描 Scanner 提供了一个…

电子技术基础(三)__第2章放大电路原理__英文简称

静态分析&#xff0c; 又称为直流分析&#xff0c; 用于求出电路的直流工作状态&#xff0c; 即l输入信号 。 一 . 先看几个英文符号 : 集电极及发射极间电压, 简称管压降 : 发射结电压降&#xff0c; 二. 接着看 加上Q点的英文简称 Q点: 放大电路的静态工作点&#…

【Spring面试】二、BeanFactory与IoC容器的加载

文章目录 Q1、BeanFactory的作用是什么&#xff1f;Q2、BeanDefinition的作用是什么&#xff1f;Q3、BeanFactory和ApplicationContext有什么区别&#xff1f;Q4、BeanFactory和FactoryBean有什么区别&#xff1f;Q5、说下Spring IoC容器的加载过程&#xff08;※&#xff09;Q…

《向量数据库》——向量数据库的使用场景有哪些?

向量数据库在许多应用领域都有广泛的用途,特别是那些需要存储、检索和分析向量数据的场景。以下是一些常见的向量数据库使用场景: 1、相似性搜索: 推荐系统:用于根据用户的历史行为或兴趣,搜索相似用户或物品,以提供个性化推荐。图像检索:允许用户通过图像查询相似的图像…

Leangoo领歌 -敏捷任务管理软件,任务管理更轻松更透明

​任务管理&#xff0c;简单易懂&#xff0c;就是对任务进行管理。那怎么可以更好进行任务管理呢&#xff1f;怎么样样可以让任务进度可视化&#xff0c;一目了然呢&#xff1f;有效的管理可以让我们事半功倍。 接下来我们看一下如何借助任务管理软件高效的做任务管理。 首先…

机器学习实战-系列教程6:SVM分类实战1(鸢尾花数据集/软间隔/线性SVM/非线性SVM/scikit-learn框架)项目实战、原理解读、代码解读

&#x1f308;&#x1f308;&#x1f308;机器学习 实战系列 总目录 本篇文章的代码运行界面均在Pycharm中进行 本篇文章配套的代码资源已经上传 SVM分类实战1 SVM分类实战2 支持向量机&#xff08;Support Vector Machines&#xff0c;SVM&#xff09;&#xff0c;用于分类和…

开箱报告,Simulink Toolbox库模块使用指南(六)——S-Fuction模块(TLC)

文章目录 前言 Target Language Compiler&#xff08;TLC&#xff09; C MEX S-Function模块 编写TLC文件 生成代码 Tips 分析和应用 总结 前言 见《开箱报告&#xff0c;Simulink Toolbox库模块使用指南&#xff08;一&#xff09;——powergui模块》 见《开箱报告&am…

Unity中Shader抓取屏幕并实现扭曲效果实现

文章目录 前言一、屏幕抓取&#xff0c;在上一篇文章已经写了二、实现抓取后的屏幕扭曲实现思路&#xff1a;1、屏幕扭曲要借助传入 UV 贴图进行扭曲2、传入贴图后在顶点着色器的输入参数处&#xff0c;传入一个 float2 uv : TEXCOORD&#xff0c;用于之后对扭曲贴图进行采样3、…

【鲁棒电力系统状态估计】基于投影统计的电力系统状态估计的鲁棒GM估计器(Matlab代码实现)

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 ⛳️座右铭&a…

Orangepi Zero2 全志H616(一):配置初始化和启动流程

目录 一&#xff0c;Orangepi简单说明 ①为什么使用全志H616 ②基本特性 ③配套操作系统支持 二&#xff0c;刷机和系统启动 ①准备工具 ②登录系统 ● 开发板供电 ● 登录 ● 开发板上板载LED灯测试说明 ③修改登录密码 ④网络配置 ⑤SSH登陆开发板 三&#xff…

(二十六)大数据实战——kafka集群之Kraft模式安装与部署

前言 本节内容主要介绍kafka3.0版本以后&#xff0c;一种新的kafka集群搭建模式看kraft&#xff0c;在该模式下&#xff0c;kafka高可用不在依赖于zookeeper&#xff0c;用 controller 节点代替 zookeeper&#xff0c;元数据保存在 controller 中&#xff0c;由 controller 直…

产品路线图管理,实践如何管理产品路线图和路线图规划

​什么是产品路线图&#xff1f; 产品路线图是一个高层次的战略计划&#xff0c;它描述了产品在未来一段时间可能会如何发展和壮大。 产品路线图确保整个产品团队持续关注产品的目标&#xff0c;帮助产品负责人把握产品的战略方向&#xff0c;调整产品的优先级和产品规划。 …

【实践篇】Redis最强Java客户端Redisson

文章目录 1. 前言2. Redisson基础概念2.1 数据结构和并发工具2.1.1 对Redis原生数据类型的封装和使用2.1.2 分布式锁实现和应用2.1.3 分布式集合使用方法 2.2 Redisson的高级特性2.2.1 分布式对象实现和使用2.2.2 分布式消息队列实现和使用2.2.3 分布式计数器实现和使用 3. 参考…

hadoop伪分布模式配置

1、修改/usr/local/hadoop/etc/hadoop/core-site.xml和/usr/local/hadoop/etc/hadoop/hdfs-site.xml文件 core-site.xml内容 <configuration><property><name>hadoop.tmp.dir</name><value>file:/usr/local/hadoop/tmp</value><descr…