上一次用树莓派搭建了Nexus私服,终于让树莓派不再成为吃灰派了,这次用树莓派搭建视频监控平台,并实现视频画面推流到流媒体服务器。
树莓派相关文章:
- 树莓派搭建nexus2.x私服
- 树莓派搭建视频监控平台(本文)
- 树莓派视频监控平台实现录制归档
- 树莓派实现人脸打卡机
1. 安装nginx
要实现将视频画面推动到媒体服务器,需要搭建一个流媒体服务器,这里选择nginx + flv module 来搭建,需要用到的源码包如下:
nginx1.15.4.tar.gz
nginx-http-flv-module-1.2.6.tar.gz
openssl-1.1.0j.tar.gz
pcre-8.40.tar.gz
将上面所有的源码在/usr/local/src下面解压,然后配置并编译安装nginx。
cd nginx1.15.4
sudo ./configure
--sbin-path=/usr/local/nginx/nginx
--conf-path=/usr/local/nginx/nginx.conf
--pid-path=/usr/local/nginx/nginx.pid
--add-module=../nginx-http-flv-module-1.2.6
--with-http_flv_module --with-http_mp4_module
--with-http_ssl_module
--with-pcre=../pcre-8.40
--with-http_ssl_module
--with-openssl=../openssl-1.1.0j
sudo make
sudo make install
安装完成后会在/usr/local/中多一个nginx目录,这里就是安装好的nginx,这里备份默认nginx配置nginx.conf,然后编写自己的nginx配置。
cd /usr/local/nginx
sudo mv nginx.conf nginx.conf.def
sudo vim nginx.conf
自己的nginx.conf如下:
worker_processes 1;
events {
worker_connections 1024;
}
rtmp {
server {
listen 1935;
application live {
live on;
}
}
}
2. 测试推流
nginx + flv module 搭建完后可以是用 ffmpeg 测试推流,首先启动nginx。
cd /usr/local/nginx
sudo ./nginx
然后在windows平台中使用ffmpeg推流
ffmpeg.exe -ss 0 -i out.mp4 -acodec copy -f flv rtmp://192.168.1.26:1935/live/t1
最后用VLC播放视频流,如果以上所有操作没有出现错误,将可以在VLC中看到视频画面。
3. 测试摄像头
要搞视频监控还需要一个摄像头,这里使用的是树莓派CSI接口中的摄像头,如果摄像头功能没有开启的话需要在树莓派开启。
sudo raspi-config
选择 5. Interfacing Options
然后再选择 P1 Camera
选择“是”,然后重启树莓派。
sudo reboot
树莓派重启之后,可以执行下面指令用摄像头截图,如果截图成功说明摄像头配置成功。
sudo modprobe bcm2835-v4l2
sudo raspistill -v -o camera.jpg
4. 平台开发
所有环境准备完成后,剩下的就是开发一个可以管理摄像头推流的平台了,这里选用JavaCV + JFinal来开发视频监控管理平台。
下载JFinal demo
从JFinal官网下载JFinal 4.9 demo for maven的源码,导入Eclipse开发工具,删除不需要的代码包括数据库配置等。
只留下我们需要的代码:
DemoConfig.java
IndexController.java
index.html
开发摄像头推流器
使用OpenCV采集摄像头的视频帧,然后使用FFmpeg推流,编码方式采用H264,帧率是25。
package com.demo.stream;
/**
* @author itqn
*/
public class StreamSender implements Runnable {
private static final int FPS = 25;
private String rtmpUri;
private OpenCVFrameGrabber grabber;
private FFmpegFrameRecorder recorder;
private boolean running = false;
public int width;
public int height;
public StreamSender(String rtmpUri) {
this.rtmpUri = rtmpUri;
this.init();
}
@Override
public void run() {
running = true;
long startTime = System.currentTimeMillis();
long timestamp = 0;
while (running) {
timestamp = 1000 * (System.currentTimeMillis() - startTime);
if (timestamp > recorder.getTimestamp()) {
recorder.setTimestamp(timestamp);
}
try {
recorder.record(grabber.grab());
} catch (Throwable e) {
close();
}
try {
TimeUnit.MILLISECONDS.sleep(1000 / FPS);
} catch (Exception ignore) {}
}
}
public void close() {
running = false;
try {
TimeUnit.SECONDS.sleep(1);
} catch (Exception ignore) {}
destroy();
}
private void init() {
try {
grabber = new OpenCVFrameGrabber(0);
grabber.start();
Frame frame = grabber.grab();
width = frame.imageWidth;
height = frame.imageHeight;
recorder = new FFmpegFrameRecorder(rtmpUri, width, height);
recorder.setFormat("flv");
recorder.setFrameRate(FPS);
recorder.setPixelFormat(avutil.AV_PIX_FMT_YUV420P);
recorder.setVideoCodec(avcodec.AV_CODEC_ID_H264);
recorder.setVideoOption("preset", "slow");
recorder.setVideoOption("tune", "zerolatency");
recorder.start();
} catch (Throwable e) {
throw new RuntimeException(e);
}
}
private void destroy() {
try {
recorder.close();
} catch (Throwable ignore) {}
try {
grabber.close();
} catch (Throwable ignore) {}
}
}
编写控制接口
调整一下IndexController的代码,新增启动监控和停止监控的接口。
public void start() {
String rtmpUri = get("rtmpUri");
if (StrKit.isBlank(rtmpUri)) {
redirect("/?e=1");
return;
}
try {
StreamManager.INSTANCE.startSender(rtmpUri);
redirect("/");
} catch (Throwable e) {
redirect("/?e=2");
}
}
public void stop() {
StreamManager.INSTANCE.stopSender();
redirect("/");
}
编写播放页面
rtmp流播放采用videojs这个库
<!DOCTYPE html>
<html>
<head>
<title>树莓派视频监控</title>
<link href="/css/video-js.css" rel="stylesheet">
<script src="/js/video.js"></script>
</head>
<body>
<video id="video" class="video-js vjs-default-skin" controls
poster="http://vjs.zencdn.net/v/oceans.png" preload="auto"
width="#(width)" height="#(height)" data-setup="{}">
<source src="#(streamUri)" type="rtmp/flv">
</video>
<br>
<br>
<div style="color: #ff0000">#(e)</div>
<div>
<form action="/start">
推流地址 :
<input name="rtmpUri" value="#(streamUri??'rtmp://127.0.0.1:1935/hls/test')"/>
<br><br>
<button>开启监控</button>
</form>
<br>
<form action="/stop">
<button>断开监控</button>
</form>
</div>
</body>
</html>
5. 部署平台
平台开发完成后需要将平台部署到树莓派中运行起来即可,JFinal默认的demo已经提供了启停脚本,所以只需要在Eclipse中执行 mvn install
即可。
打包成功后,在项目的target目录下面会有如下结构:
jfinal_demo_for_maven-release
jfinal_demo_for_maven
-config
-lib
-webapp
-jfinal.sh
# 另外我们需要将target目录下的jfinal_demo_for_maven-4.9.jar复制到lib目录下。
将上面的jfinal_demo_for_maven整个目录FTP上传到树莓派中,启动平台:
sudo ./jfinal.sh start
# 这里可以改动jfinal.sh中指定的平台访问端口
启动成功后,可以在电脑上访问平台:
http://192.168.1.26:8080
然后填写推流地址,点击开始监控即可。
这样,基于树莓派的视频监控平台就部署好了。如果要关闭视频监控,只需要点击页面上的 断开监控 即可。
6. 拓展玩法
这里为了实践我是自己在树莓派上搭建了一个基于nginx + flv module 的流媒体服务器,当然还有很多玩法。
比如:
a. 在线上服务器搭建流媒体服务器,然后将视频流推送到线上服务器,这样就可以实现远程视频监控。
b. 另外也可以将视频流推送到直播平台,实现直播。
=========================================================
项目源码可关注公众号 “HiIT青年” 发送 “raspi-video” 获取。
关注公众号,阅读更多文章。
!文章被用户(百度账号:cuixiaoyande)抄袭,同时在头条号(头条号:cuixiaoyande)上也被此用户抄袭。
百家号文章
头条举报结果