使用树莓派搭建视频监控平台去年就简单的实现了,只不过功能比较简陋,最近抽时间重构了原来的平台。

环境搭建

环境部分,参考旧版的安装及配置:

  1. 树莓派搭建视频监控平台
  2. 树莓派视频监控平台实现录制归档

框架选型

之前的平台是采用JFinal和JavaCV开发的, 这次重构,调整为Springboot + JavaCV实现,主要用到的框架有:

  1. spring-webmvc
  2. spring-websocket
  3. spring-jdbc
  4. oshi
  5. javacv
  6. vue
  7. iview
  8. flv.js

功能完善

这次重构完善了很多功能,引入了服务器监控、采用VUE+IVIEW对页面重新开发,另外还支持了在线回访录制视频,目前已实现的功能有:

  1. 摄像头监控画面实时预览
  2. 自动录制
  3. 分段录制
  4. 磁盘保护
  5. 树莓派运行参数监控
  6. 录制管理(支持录制回放)
  7. 登录鉴权

除了上面功能外,此次重构还大大降低了延迟,以及增加多种拉流类型,在无buffer拉流的情况下,FLV、RTMP流延迟在1秒以内(600ms左右),拉流端支持FLV、RTMP、HLS。

界面预览

由于浏览器已经不再支持Flash,所以本次监控画面实时预览采用FLV,播放器采用flv.js,实时预览延迟1秒内。

监控录制由原来的FLV,调整为mp4,支持H5原生播放器观看监控回放,这里由于我在画面上加了时间戳滤镜,导致录制效果不是很好,后期需要排查优化一下。

功能实现

  1. 画面采集,FFmpeg推流

在旧版的实现中,采用的是JavaCV采集画面,并实现推流,在实际使用情况中,这种效果并不理想,延迟太高。所以在新版重构时,选择raspivid + ffmpeg来替代JavaCV实现。

画面采集采用raspivid:

raspivid -n -t 0 -w 1920 -h 1080 -fps 25 -b 600000 -o -

推流采用FFmpeg:

ffmpeg -i - -vcodec copy -an -f flv rtmp://192.168.1.5:1935/hls/stream0
  1. 拉流,录制

拉流还是采用JavaCV,这里分为两部分,拉流及流加工录制,如果不需要对流进行处理的话,直接录制流即可。

拉流:

grabber = new FFmpegFrameGrabber(streamUri);
Frame f = grabber.grab();
if (f != null && f.image != null) {
if (f != null && f.image != null) {
Iterator <StreamListener> it = listeners.iterator();
while (it.hasNext()) {
StreamListener sl = it.next();
final Frame ff = f.clone();
sl.onVideo(ff);
}
}
}

录制:

public void onVideo(Frame frame) {
// 分段录制
if (timeLimit > 0 && System.currentTimeMillis() - startTime > timeLimit) {
try {
RecordINF inf = stop();
if (timeoutCB != null) {
timeoutCB.accept(inf);
}
startTime = System.currentTimeMillis();
timestamp = 0;
videoFile = new File(videoDir, startTime + ".mp4");
start();
} catch (Exception e) {
LOG.error(e.getMessage(), e);
}
} try {
if (timestamp == 0) {
timestamp = System.currentTimeMillis();
}
videoTS = 1000 * (System.currentTimeMillis() - timestamp);
if (videoTS > recorder.getTimestamp()) {
recorder.setTimestamp(videoTS);
}
recorder.record(frame);
} catch (org.bytedeco.javacv.FrameRecorder.Exception e) {
LOG.error(e.getMessage(), e);
}
}
  1. 磁盘保护

监控平台会不断录制视频,所有如果不对磁盘容量进行监控的话,可能会出现录制视频塞爆磁盘的情况,这里只针对录制文件存放的挂载盘进行监控。

@Scheduled(fixedRate = 30_000)
public void execute() {
long byteG = settingService.setting().getStorageLimit() * G;
List<OSFileStore> dsList = si.getOperatingSystem().getFileSystem().getFileStores();
dsList.forEach(osf -> {
if (appCfg.getMonitorMountDir().equals(osf.getMount()) && osf.getFreeSpace() < byteG) {
clean();
}
});
}
  1. 树莓派运行参数监控

平台启动后定时采集运行参数信息,采用websocket的形式,定时推送到web端展示。

@Scheduled(fixedRate = 5000)
public void send() throws InterruptedException {
OperatingSystem os = si.getOperatingSystem();
CentralProcessor cpu = si.getHardware().getProcessor(); info.setOs(os.getManufacturer() + " " + os.getFamily() + " " + os.getVersionInfo().getVersion());
String ipV4Gateway = os.getNetworkParams().getIpv4DefaultGateway();
ipV4Gateway = ipV4Gateway.substring(0, ipV4Gateway.lastIndexOf("."));
info.setIp("");
List < NetworkIF > nList = si.getHardware().getNetworkIFs();
for (NetworkIF f : nList) {
if (Arrays.toString(f.getIPv4addr()).replace("[", "").replace("]", "").startsWith(ipV4Gateway)) {
info.setIp(Arrays.toString(f.getIPv4addr()).replace("[", "").replace("]", ""));
break;
}
} long[] pts = cpu.getSystemCpuLoadTicks();
TimeUnit.SECONDS.sleep(1);
long[] cts = cpu.getSystemCpuLoadTicks();
long t = 0;
for (int i = 0; i < pts.length; i++) {
t += cts[i];
}
info.setCpr(
new DecimalFormat("#.##%").format(1.0 - (cts[CentralProcessor.TickType.IDLE.getIndex()] * 1.0 / t)));
info.setCpt(String.valueOf(si.getHardware().getSensors().getCpuTemperature())); LocalDateTime btime = LocalDateTime.ofInstant(Instant.ofEpochSecond(os.getSystemBootTime()),
ZoneId.systemDefault());
info.setBtime(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss").format(btime));
info.setUtime(FormatUtil.formatElapsedSecs(os.getSystemUptime())); List < OSFileStore > dsList = si.getOperatingSystem().getFileSystem().getFileStores();
info.getFs().clear();
dsList.forEach(ds -> info.addFs(ds.getName() + "(" + ds.getMount() + ")" + ":" //
+ FormatUtil.formatBytes(ds.getFreeSpace()) + "/"
+ FormatUtil.formatBytes(ds.getTotalSpace())));
template.convertAndSend(AppWSConst.TOPIC_MONITOR, JSON.toJSONString(info));
}
  1. 实时监控画面预览

由于浏览器已经不再支持Flash,所以画面预览采用FLV流。

livePlay(url) {
if (!!!url) return
if (this.player) {
this.player.destroy()
}
this.living = true
this.buildPlayer({
live: true, autoplay: true,
video: {
url: url,
type: 'flv'
},
pluginOptions: {
flv: {
config: {
enableStashBuffer: false
}
}
}
})
}
  1. 录制回放

录制的视频是mp4格式,采用flv.js直接播放即可。

videoPlay(url) {
if (!!!url) return
if (this.living || !this.player) {
this.buildPlayer({
autoplay: true, hotkey: true,
video: {
url: url,
type: 'mp4'
}
})
} else {
this.player.switchVideo({ url: url, type: 'mp4' })
}
this.living = false
}

应用部署

在部署方面,所有服务均部署在树莓派3B+中,并设置开机自启,这样只要树莓派通电,所有功能就启动并运行。

关注公众号“HiIT青年”,了解更多关于树莓派及JavaCV开发的文章

=========================================================

关注 公众号 “HiIT青年” 发送 “javacv-raspi-iview” 获取树莓派开机推流设置方式。(如果没有收到回复,可能是你之前取消过关注。)



关注公众号,阅读更多文章。

JavaCV 树莓派打造监控系统平台的更多相关文章

  1. WIndows下使用Grafana+InfluxDB打造监控系统

     前言 对于一个运维DBA来说,了解数据库的TPS.QPS很有必要(QPS:每秒查询数,即对数据库每秒的DML的操作数:TPS:每秒事物处理,即对数据库每秒DDL操作数),通过了解他们,可以掌握一个实 ...

  2. Grafana3.0.1+Zabbix3.0.4监控系统平台搭建

    前言 本文的Zabbix部分知识只介绍它的基础安装,Zabbix的使用以及配置优化并不在本文的介绍范围之内. 本文只介绍在CentOS6系列下的安装和部署,其他发行版与其他版本号暂不涉及 本文默认使用 ...

  3. 利用树莓派实现监控系统二(用motion实现监控)

    终于要开始实现监控啦!ಠ౪ಠ 看起来很简单的步骤,但是过程却无比艰辛,踩坑是最好的成长 (/= _ =)/~┴┴ 第一步,不是安装!而是 update!ㄟ( ▔, ▔ )ㄏ sudo apt-get ...

  4. 树莓派 + Windows IoT Core 搭建环境监控系统

    前言:Windows IoT 是微软为嵌入式开发板设计的一种物联网操作系统,运行Windows UWP(C# 开发),可以设计出丰富的交互界面,驱动GPIO,连接一些传感器做有意思的事,本文详细介绍如 ...

  5. 开源倾情奉献:基于.NET打造IP智能网络视频监控系统(一)开放源代码

    本文为 Dennis Gao 原创技术文章,发表于博客园博客,未经作者本人允许禁止任何形式的转载. 开源倾情奉献系列链接 开源倾情奉献:基于.NET打造IP智能网络视频监控系统(一)开放源代码 开源倾 ...

  6. 使用 Grafana、collectd 和 InfluxDB 打造现代监控系统

    想打造 New Relic 那样漂亮的实时监控系统我们只需要 InfluxDB/collectd/Grafana 这三个工具,这三个工具的关系是这样的: 采集数据(collectd)-> 存储数 ...

  7. Legolas工业自动化平台案例 —— 水源地自动化监控系统

    天津港爆炸事件后,除了安置群众.追究事故责任外,人们最关心的莫过于爆炸污染物对于周边环境的影响,其中最重要的一块就是饮用水的安全.所幸的是,水源的安全监测是实实在在有据可依的.环保单位和供水企业在建设 ...

  8. 基于.NET打造IP智能网络视频监控系统

    开源倾情奉献:基于.NET打造IP智能网络视频监控系统(一)开放源代码   开源倾情奉献系列链接 开源倾情奉献:基于.NET打造IP智能网络视频监控系统(一)开放源代码 开源倾情奉献:基于.NET打造 ...

  9. 手把手教你树莓派实现简易室内监控系统(C)之BOA服务器的搭建

    本篇主要讲利用BOA服务器做室内监控系统的服务器端. 古人云:万事开头靠百度,实在不行就Google.小编也是一步一步的,亲自搭建成功,不能说是万全之策,仅仅是给大家一个参考就满足了. 第一步: 1. ...

随机推荐

  1. Linux命令:sysctl

    sysctl命令用于运行时配置或查看内核参数,这些参数位于/proc/sys目录下.可以使用sysctl命令来设置或重新设置网络联网功能,如:IP转发.IP碎片去除以及源路由检查等.用户可以编辑/et ...

  2. 容器之List接口下各实现类(Vector,ArrayList 和LinkedList)的线程安全问题

    Vector .ArrayList 和LinkedList都是List接口下的实现类,但是他们之间的区别和联系是什么呢? 首先: 然后: 如果您仅仅想知道结论,那么可以关闭了. 下面我讨论讨论为什么. ...

  3. Leetcode(11)-盛最多水的容器

    给定 n 个非负整数 a1,a2,...,an,每个数代表坐标中的一个点 (i, ai) .画 n 条垂直线,使得垂直线 i 的两个端点分别为 (i, ai) 和 (i, 0).找出其中的两条线,使得 ...

  4. 多线程(四) AQS底层原理分析

    J.U.C 简介 Java.util.concurrent 是在并发编程中比较常用的工具类,里面包含很多用来在并发 场景中使用的组件.比如线程池.阻塞队列.计时器.同步器.并发集合等等.并 发包的作者 ...

  5. 数仓增量更新hive实现

    注:参考文末文章,加上自己的理解. 1.增量更新 有一个 base_table 表存放的是 12 月 15 日之前的所有数据,当 12 月 16 日的数据产生后,生成了一个 incremental_t ...

  6. Vue UI lib missing vue bug

    Vue UI lib missing vue bug Error Uncaught TypeError: Cannot read property 'prototype' of undefined a ...

  7. 如何用 js 实现一个 call 函数

    如何用 js 实现一个 call 函数 原理 实现方式 总结 refs https://developer.mozilla.org/en-US/docs/Web/JavaScript/Referenc ...

  8. node.js & ORM & ODM

    node.js & ORM & ODM ODM & NoSQL Object Data Modeling 对象数据模型 Object Document Mapping 对象文档 ...

  9. macOS 屏幕共享, 远程协助

    macOS 屏幕共享, 远程协助 Screen Sharing App 隐藏 app bug command + space 搜索 https://macflow.net/p/397.html Tea ...

  10. Nestjs mongodb

    nestjs 文档 mongoose 文档 使用"@meanie/mongoose-to-json"转换查询后返回的json数据 将"_id"转为"i ...