一、后端到摄像头(监控摄像头IOT)

news2025/1/5 7:20:19

前言:

开发流程从 后端到摄像头 打通是第一步,那么我们可以着手设计 后端实现 的具体步骤,确保能够稳定地接收和处理来自摄像头的视频流,并提供后续的功能扩展,如视频流转发、存储和控制。

1. 后端系统架构设计

在开始实现之前,我们需要先明确后端系统的基本架构和功能模块。主要包括以下几个部分:

  • 视频流接入与处理模块:负责从摄像头接收视频流,解析和转码(如果需要)。
  • 摄像头管理与控制模块:控制摄像头(如启动、停止、变更分辨率等)。
  • 流媒体转发模块:负责将摄像头的视频流推送到 WebRTC 或流媒体服务器进行分发。
  • 存储模块:存储视频流,并提供存档、回放等功能。

2. 后端实现步骤

2.1 摄像头视频流接入与处理

我们假设摄像头通过 RTSP 协议进行视频流传输(也可以是 WebRTC,具体取决于摄像头设备支持的协议)。后端需要能够接收这个视频流并进行处理。

使用 FFmpegKurento(作为流媒体服务器)来接收和转发视频流。
  • 如果使用 FFmpeg,可以通过命令行工具启动 RTSP 客户端,将视频流转发到流媒体服务器或者进行本地存储。
  • 如果使用 Kurento,可以用 Kurento Media Server(KMS)来接收视频流,并通过 WebRTC 协议将其推送到 Web 端。

后端实现流程

  1. 接收 RTSP 流

    • 使用 FFmpegKurento 等工具,后端通过接口或命令行方式启动摄像头的视频流接入。
ProcessBuilder pb = new ProcessBuilder("ffmpeg", "-i", "rtsp://camera_ip_address/stream", "-c:v", "libx264", "-f", "flv", "rtmp://media_server/stream");
pb.start();
  • 视频流转发

    • 如果你需要通过 WebRTC 向客户端推送视频流,可以通过 Kurento 等流媒体服务器实现,将 RTSP 流转为 WebRTC 流。
    • 这一步通常需要创建一个 WebRTC PeerConnection,并将视频流从摄像头转发到浏览器客户端。
  • 视频流存储

    • 使用 FFmpegKurento 提供的功能,将流存储为 MP4 或 WebM 格式,供后续的回放和存档使用。
    • 可以使用以下 FFmpeg 命令将视频存储到本地或云存储:
ffmpeg -i rtsp://camera_ip_address/stream -c:v libx264 -f mp4 /path/to/storage/video.mp4
  1. 视频流转码与处理

    • 如果需要将摄像头的视频流转码为更适合浏览器播放的格式(如 H.264 到 VP8),可以通过 FFmpeg 完成转码任务。
2.2 摄像头管理与控制

后端需要提供接口来控制摄像头的行为(例如:启动/停止视频流、调节分辨率、控制视角等)。通常,摄像头支持一些标准的控制协议(如 ONVIF、RTSP),或者提供自定义 API 接口。

关键步骤:
  1. 摄像头注册与配置

    • 在后端提供一个 摄像头管理模块,允许管理员添加、配置和管理摄像头设备。可以通过 REST API 接收摄像头的配置请求(例如,IP 地址、用户名、密码等)。
@RestController
public class CameraController {
    @PostMapping("/registerCamera")
    public ResponseEntity<String> registerCamera(@RequestBody CameraConfig config) {
        // 将摄像头配置信息存储在数据库
        cameraService.registerCamera(config);
        return ResponseEntity.ok("Camera registered successfully");
    }
}

控制摄像头

  • 后端可以通过 API 向摄像头发送控制命令,如启动视频流、改变分辨率、变更旋转角度等。这些控制通常通过 ONVIFRTSP 相关协议实现。
@PostMapping("/startCameraStream")
public ResponseEntity<String> startCameraStream(@RequestParam String cameraId) {
    // 根据 cameraId 启动对应摄像头的视频流
    cameraService.startStream(cameraId);
    return ResponseEntity.ok("Camera stream started");
}
  1. 监控摄像头状态

    • 提供接口来查询摄像头的状态,例如,摄像头是否在线,视频流是否正常等。
2.3 视频流转发模块

如果要将视频流转发到前端浏览器,后端需要有一个模块来支持 WebRTC流媒体服务器

通过 Kurento 转发 RTSP 流到 Web 前端:
  1. WebRTC 建立连接

    • 使用 Kurento Media Server 来处理 RTSP 视频流,并通过 WebRTC 将其转发到前端浏览器。
    • 在后端实现 WebRTC 信令,完成客户端与服务端之间的连接。
  2. 流媒体服务器转发视频流

    • 如果不使用 WebRTC,后端可以将视频流推送到 流媒体服务器(如 WowzaNginx RTMP),并通过 RTMP 或 HLS 协议向 Web 端提供视频流。
2.4 视频存储模块

后端系统需要能够存储接收到的视频流,并提供回放、下载等功能。视频存储模块通常包括以下几个步骤:

  1. 视频存储

    • 将视频流保存为标准视频格式(如 MP4 或 WebM),并存储到本地或云存储服务中。
public void storeVideoStream(InputStream videoStream, String cameraId) {
    // 将流保存为文件
    File file = new File("/storage/" + cameraId + "_video.mp4");
    try (FileOutputStream out = new FileOutputStream(file)) {
        byte[] buffer = new byte[1024];
        int bytesRead;
        while ((bytesRead = videoStream.read(buffer)) != -1) {
            out.write(buffer, 0, bytesRead);
        }
    } catch (IOException e) {
        e.printStackTrace();
    }
}

视频回放(点播)

  • 后端应提供接口,支持根据摄像头 ID 和时间段检索存储的视频文件。
@GetMapping("/getVideo")
public ResponseEntity<Resource> getVideo(@RequestParam String cameraId, @RequestParam String timeRange) {
    // 根据摄像头 ID 和时间范围检索视频文件
    File videoFile = videoService.getVideoFile(cameraId, timeRange);
    return ResponseEntity.ok().body(new FileSystemResource(videoFile));
}
  1. 云存储集成

    • 可以将视频文件上传到 云存储(如 AWS S3、Aliyun OSS 等),并提供远程访问功能。
    • 配置云存储 SDK(如 AWS SDK 或阿里云 SDK)并上传文件。

3. 后端开发技术栈

  • 编程语言:Java(Spring Boot)
  • 流媒体库/工具
    • FFmpeg:处理 RTSP 流、转码、存储等。
    • Kurento Media Server:处理 WebRTC 连接,支持流转发、存储、视频处理。
  • 数据库:用于存储摄像头信息、用户操作日志等。
  • 消息队列(可选):用于解耦摄像头数据与其他模块之间的通信(如 Kafka、RabbitMQ)。

4. 开发计划与任务拆分

阶段 1:摄像头视频流接入与转发
  • 实现接收 RTSP 流并转发到服务端。
  • 选择使用 KurentoFFmpeg 来接入视频流。
  • 在服务端处理视频流转发(WebRTC 或流媒体协议)。
阶段 2:摄像头管理与控制
  • 提供摄像头的管理接口(注册、启动、停止)。
  • 实现控制接口(如启动视频流、控制视角)。
阶段 3:视频存储与回放
  • 实现视频存储功能,并能够将视频保存到本地或云存储。
  • 提供视频回放接口,支持按时间段、摄像头 ID 检索视频文件。
阶段 4:视频流转发到 Web 前端

在这一步,后端系统的目标是通过 WebRTC 或流媒体服务器将视频流推送到前端。下面详细描述如何完成这一阶段。

1. WebRTC 实现

如果选择使用 WebRTC,后端需要设置 WebRTC 信令服务,允许浏览器客户端和后端建立实时的点对点连接。具体步骤如下:

  1. WebRTC 信令服务

    • 信令服务是 WebRTC 的核心,负责在客户端和服务端之间交换会话描述信息(SDP)和候选网络地址(ICE candidates)。这可以通过 WebSocket 实现。
@Controller
public class WebRtcSignalingController {
    private final WebSocketSession session;

    @MessageMapping("/webrtc/offer")
    @SendTo("/topic/offer")
    public String handleOffer(String offer) {
        // 接收到前端发来的 offer,转发给其他客户端
        return offer;
    }

    @MessageMapping("/webrtc/answer")
    @SendTo("/topic/answer")
    public String handleAnswer(String answer) {
        // 转发 answer 给客户端
        return answer;
    }

    @MessageMapping("/webrtc/candidate")
    @SendTo("/topic/candidate")
    public String handleCandidate(String candidate) {
        // 转发 ICE candidate
        return candidate;
    }
}
    • 在此代码中,WebSocket 用于接收和转发信令消息。前端和后端通过这个信令交换 SDP 和 ICE 信息。
  • 后端与 Kurento 配置 WebRTC 会话

    • 使用 Kurento Media Server (KMS) 来管理 WebRTC 会话,并将摄像头的视频流转发到浏览器客户端。
    • 后端需要与 Kurento 配合,创建媒体管道和 WebRTC 端点,将摄像头的视频流通过 WebRTC 协议传输到客户端。

    示例:使用 Kurento 的 Java API 创建 WebRTC 会话。

public class WebRTCService {
    private KurentoClient kurentoClient;
    private MediaPipeline pipeline;
    private WebRtcEndpoint webRtcEndpoint;

    public WebRTCService(KurentoClient kurentoClient) {
        this.kurentoClient = kurentoClient;
    }

    public void startWebRtcSession(String sdpOffer) {
        pipeline = kurentoClient.createMediaPipeline();
        webRtcEndpoint = new WebRtcEndpoint.Builder(pipeline).build();

        // Set up the SDP offer and return an SDP answer
        String sdpAnswer = webRtcEndpoint.processOffer(sdpOffer);
        webRtcEndpoint.gatherCandidates();

        // Send back the SDP answer to the client
        return sdpAnswer;
    }

    public void stopWebRtcSession() {
        webRtcEndpoint.release();
        pipeline.release();
    }
}
    • 在上面的代码中,WebRtcEndpoint 是一个处理 WebRTC 媒体流的关键组件。通过 processOffer 方法,后端将摄像头的流作为 WebRTC 流推送给前端。
  • 前端 WebRTC 连接

    • 在前端,使用 JavaScript 来与 WebRTC 服务端建立连接。前端需要通过 WebSocket 接收信令消息,创建 WebRTC 会话,进行媒体流的传输。

    示例:前端使用 WebRTC 和 WebSocket 与后端建立连接。

const signalingSocket = new WebSocket("ws://server_address/webrtc");
signalingSocket.onmessage = (message) => {
    const signal = JSON.parse(message.data);

    if (signal.sdpOffer) {
        // Handle offer, create answer
        const answer = await peerConnection.createAnswer();
        signalingSocket.send(JSON.stringify({ sdpAnswer: answer.sdp }));
    } else if (signal.iceCandidate) {
        // Handle ICE candidate
        peerConnection.addIceCandidate(new RTCIceCandidate(signal.iceCandidate));
    }
};

const peerConnection = new RTCPeerConnection();
peerConnection.onicecandidate = (event) => {
    if (event.candidate) {
        signalingSocket.send(JSON.stringify({ iceCandidate: event.candidate }));
    }
};

// Add media stream from camera or video element to the connection
const mediaStream = await navigator.mediaDevices.getUserMedia({ video: true });
mediaStream.getTracks().forEach(track => peerConnection.addTrack(track, mediaStream));
2. 流媒体服务器转发

如果选择使用流媒体服务器(如 WowzaNginx RTMPKurento),后端需要将摄像头的视频流推送到这些服务器,并通过适合的协议(如 RTMP、HLS)进行流转发。

配置流媒体服务器

例如,使用 Nginx 配置 RTMP 流:

  • WowzaNginx RTMP 上配置推流和播放端点。将摄像头的视频流推送到这些服务器,然后通过 RTMP 或 HLS 协议将流转发给 Web 客户端。
rtmp {
    server {
        listen 1935;
        chunk_size 4096;

        application live {
            live on;
            push rtmp://your-stream-server;
        }
    }
}

  后端推送流到流媒体服务器

  • 后端通过 FFmpegKurento 将 RTSP 流转发到流媒体服务器。例如,使用 FFmpeg 将 RTSP 流推送到 RTMP 服务器:
ffmpeg -i rtsp://camera_ip_address/stream -c:v libx264 -f flv rtmp://your-rtmp-server/live/stream

Web 客户端播放流

  • Web 客户端通过 HLSRTMP 协议接收视频流。例如,可以通过 HTML5 <video> 标签播放 HLS 流:
<video id="video-player" controls>
    <source src="http://your-rtmp-server/live/stream.m3u8" type="application/x-mpegURL">
</video>
  1. 或者,如果是使用 WebRTC,浏览器将通过 WebRTC 协议接收并播放视频流。

4. 开发阶段与任务拆分

阶段 1:视频流接入与推送
  • 任务
    • 完成 RTSP 流的接入(使用 FFmpeg 或 Kurento)。
    • 实现视频流转发到 WebRTC 或流媒体服务器(如 RTMP)。
阶段 2:摄像头管理与控制
  • 任务
    • 完成摄像头的注册、启动、停止等控制接口。
    • 实现摄像头的状态监控(例如摄像头在线/离线状态)。
阶段 3:视频存储与回放
  • 任务
    • 完成视频流的存储模块,支持存档视频。
    • 实现视频回放功能,支持按时间段和摄像头检索视频。
阶段 4:视频流转发与前端播放
  • 任务
    • 实现 WebRTC 信令服务,并建立 WebRTC 点对点连接。
    • 完成 Web 前端的播放器,支持实时视频播放(使用 WebRTC 或 HLS/RTMP)。

5. 后端开发工具和技术栈

  • 编程语言:Java(Spring Boot)
  • 流媒体库
    • Kurento Media Server:处理视频流转发和 WebRTC 会话。
    • FFmpeg:接收、转码视频流,并推送到流媒体服务器。
  • WebSocket:用于 WebRTC 信令服务。
  • 流媒体协议:RTMP、HLS(如果选择流媒体服务器)。
  • 数据库:存储摄像头配置、视频元数据、用户数据等。

总结

通过上述步骤和架构设计,你的后端将能够实现从摄像头接入视频流、处理视频流、转发到前端,并支持视频存储和回放。开发的顺序从 摄像头接入与处理摄像头管理与控制视频流转发与存储。选择 WebRTC 或流媒体服务器的具体实现方式可以根据实际的需求来定:WebRTC 更适合低延迟的实时应用,而流媒体服务器适合大规模广播和存储需求。

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

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

相关文章

[最佳方法] 如何将视频从 Android 发送到 iPhone

概括 将大视频从 Android 发送到 iPhone 或将批量视频从 iPhone 传输到 Android 并不是一件容易的事情。也许您已经尝试了很多关于如何将视频从 Android 发送到 iPhone 15/14 的方法&#xff0c;但都没有效果。但现在&#xff0c;通过本文中的这 6 种强大方法&#xff0c;您可…

MetaRename for Mac,适用于 Mac 的文件批量重命名工具

在处理大量文件时&#xff0c;为每个文件手动重命名既耗时又容易出错。对于摄影师、设计师、开发人员等需要频繁处理和整理文件的专业人士来说&#xff0c;找到一款能够简化这一过程的工具是至关重要的。MetaRename for Mac 就是这样一款旨在提高工作效率的应用程序&#xff0c…

QEMU网络配置简介

本文简单介绍下qemu虚拟机网络的几种配置方式。 通过QEMU的支持&#xff0c;常见的可以实现以下4种网络形式&#xff1a; 基于网桥&#xff08;bridge&#xff09;的虚拟网络。基于NAT&#xff08;Network Addresss Translation&#xff09;的虚拟网络。QEMU内置的用户模式网…

Elasticsearch向量检索需要的数据集以及768维向量生成

Elasticsearch8.17.0在mac上的安装 Kibana8.17.0在mac上的安装 Elasticsearch检索方案之一&#xff1a;使用fromsize实现分页 快速掌握Elasticsearch检索之二&#xff1a;滚动查询(scrool)获取全量数据(golang) Elasticsearch检索之三&#xff1a;官方推荐方案search_after…

MySQL:安装配置(完整教程)

这里写目录标题 一、MySQL 简介二、下载 MySQL三、安装 MySQL四、配置环境变量五、配置 MySQL5.1 初始化 MySQL5.2 启动 MySQL 服务 六、修改 MySQL 密码七、卸载 MySQL八、结语 一、MySQL 简介 MySQL 是一款广泛使用的开源关系型数据库管理系统&#xff08;RDBMS&#xff09;…

您的公司需要小型语言模型

当专用模型超越通用模型时 “越大越好”——这个原则在人工智能领域根深蒂固。每个月都有更大的模型诞生&#xff0c;参数越来越多。各家公司甚至为此建设价值100亿美元的AI数据中心。但这是唯一的方向吗&#xff1f; 在NeurIPS 2024大会上&#xff0c;OpenAI联合创始人伊利亚…

如何用CSS3创建圆角矩形并居中显示?

在网页设计中&#xff0c;圆角矩形因其美观和现代感而被广泛使用&#xff0c;居中显示元素也是一个常见的需求。今天&#xff0c;我们将学习如何使用CSS3的border-radius属性来创建圆角矩形&#xff0c;并将其居中显示在页面上。 如果你正在学习CSS&#xff0c;那么这个实例将非…

PhPMyadmin-cms漏洞复现

一.通过日志文件拿Shell 打开靶场连接数据库 来到sql中输入 show global variables like %general%; set global general_logon; //⽇志保存状态开启&#xff1b; set global general_log_file D:/phpstudy/phpstudy_pro/WWW/123.php //修改日志保存位置 show global varia…

本地LLM部署--llama.cpp

–图源GitHub项目主页 概述 llama.cpp是以一个开源项目&#xff08;GitHub主页&#xff1a;llamma.cpp&#xff09;&#xff0c;也是本地化部署LLM模型的方式之一&#xff0c;除了自身能够作为工具直接运行模型文件&#xff0c;也能够被其他软件或框架进行调用进行集成。 其…

基本算法——分类

目录 创建项目 导入依赖 加载数据 特征选择 学习算法 对新数据分类 评估与预测误差度量 混淆矩阵 通过模型的预测结果生成 ROC 曲线数据 选择分类算法 完整代码 结论 创建项目 首先创建spring boot项目&#xff0c;我这里用的JDK8&#xff0c;springboot2.7.6&…

【系统配置】3种方式修改用户登录显示名|统信|麒麟|方德

原文链接&#xff1a;【系统配置】3种方式修改用户登录显示名&#xff5c;统信&#xff5c;麒麟&#xff5c;方德 Hello&#xff0c;大家好啊&#xff01;今天给大家带来一篇关于 通过修改 /etc/passwd 文件、usermod 命令&#xff0c;以及图形化界面三种方式修改用户登录名 的…

TTL 传输中过期问题定位

问题&#xff1a; 工作环境中有一个acap的环境&#xff0c;ac的wan口ip是192.168.186.195/24&#xff0c;ac上lan上有vlan205&#xff0c;其ip子接口地址192.168.205.1/24&#xff0c;ac采用非nat模式&#xff0c;而是路由模式&#xff0c;在上级路由器上有192.168.205.0/24指向…

Cocos2dx Lua绑定生成中间文件时参数类型与源码类型不匹配

这两天维护的一个项目&#xff0c;使用arm64-v8a指令集编译时遇到了报错&#xff0c;提示类型不匹配&#xff0c;具体报错的代码【脚本根据C源文件生成的中间文件】如下&#xff1a; const google::protobuf::RepeatedField<unsigned long long>& ret cobj->equi…

连接Milvus

连接到Milvus 验证Milvus服务器正在侦听哪个本地端口。将容器名称替换为您自己的名称。 docker port milvus-standalone 19530/tcp docker port milvus-standalone 2379/tcp docker port milvus-standalone 192.168.1.242:9091/api/v1/health 使用浏览器访问连接地址htt…

走方格(蓝桥杯2020年试题H)

【问题描述】在平面上有一些二维点阵。这些点的编号就像二维数组的编号一样&#xff0c;从上到下依次为第1~n行&#xff0c;从左到右依次为第1~m列&#xff0c;每个点可以用行号和列号表示。 现在有个人站在第1行第1列&#xff0c;他要走到第n行第m列&#xff0c;只能向右或者向…

28. 二叉树遍历

题目描述 根据给定的二叉树结构描述字符串&#xff0c;输出该二叉树按照中序遍历结果字符串。中序遍历顺序为:左子树&#xff0c;根结点&#xff0c;右子树。 输入描述 由大小写字母、左右大括号、逗号组成的字符串: 1、字母代表一个节点值&#xff0c;左右括号内包含该节点的子…

Swift White Hawkstrider

Swift White Hawkstrider 迅捷白色陆行鸟 Swift White Hawkstrider - Item - 魔兽世界怀旧服TBC数据库_WOW2.43数据库_70级《燃烧的远征》数据库 Kaelthas Sunstrider (1) <Lord of the Blood Elves> 凯尔萨斯逐日者. 掉落 [80圣骑士][Alonsus-加丁][诺森德冒险补给品…

LeetCode算法题——有序数组的平方

题目描述 给你一个按非递减顺序排序的整数数组nums&#xff0c;返回每个数字的平方组成的新数组&#xff0c;要求也按非递减顺序排序。 题解 解法一&#xff1a;暴力解法 思路&#xff1a; 该题目可通过暴力解法解决&#xff0c;即利用for循环遍历数组&#xff0c;对数组每…

项目开发实践——基于SpringBoot+Vue3实现的在线考试系统(四)

文章目录 一、管理员角色功能实现1、添加教师功能实现1.1 页面设计1.2 前端功能实现1.3 后端功能实现1.4 效果展示2、教师管理功能实现2.1 页面设计2.2 前端功能实现2.3 后端功能实现2.3.1 后端查询接口实现2.3.2 后端编辑接口实现2.3.3 后端删除接口实现2.4 效果展示二、代码下…

DVWA靶场Brute Force (暴力破解) 漏洞low(低),medium(中等),high(高),impossible(不可能的)所有级别通关教程

目录 暴力破解low方法1方法2 mediumhighimpossible 暴力破解 暴力破解是一种尝试通过穷尽所有可能的选项来获取密码、密钥或其他安全凭证的攻击方法。它是一种简单但通常无效率的破解技术&#xff0c;适用于密码强度较弱的环境或当攻击者没有其他信息可供利用时。暴力破解的基…