上一次用树莓派搭建了Nexus私服,终于让树莓派再也不成为吃灰派了,此次用树莓派搭建视频监控平台,并实现视频画面推流到流媒体服务器。css
树莓派相关文章:html
要实现将视频画面推进到媒体服务器,须要搭建一个流媒体服务器,这里选择nginx + flv module 来搭建,须要用到的源码包以下:java
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。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配置。web
cd /usr/local/nginx sudo mv nginx.conf nginx.conf.def sudo vim nginx.conf
本身的nginx.conf以下:shell
worker_processes 1; events { worker_connections 1024; } rtmp { server { listen 1935; application live { live on; } } }
nginx + flv module 搭建完后能够是用 ffmpeg 测试推流,首先启动nginx。数据库
cd /usr/local/nginx sudo ./nginx
而后在windows平台中使用ffmpeg推流vim
ffmpeg.exe -ss 0 -i out.mp4 -acodec copy -f flv rtmp://192.168.1.26:1935/live/t1
最后用VLC播放视频流,若是以上全部操做没有出现错误,将能够在VLC中看到视频画面。windows
要搞视频监控还须要一个摄像头,这里使用的是树莓派CSI接口中的摄像头,若是摄像头功能没有开启的话须要在树莓派开启。服务器
sudo raspi-config
选择 5. Interfacing Options
而后再选择 P1 Camera
选择“是”,而后重启树莓派。
sudo reboot
树莓派重启以后,能够执行下面指令用摄像头截图,若是截图成功说明摄像头配置成功。
sudo modprobe bcm2835-v4l2 sudo raspistill -v -o camera.jpg
全部环境准备完成后,剩下的就是开发一个能够管理摄像头推流的平台了,这里选用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>
平台开发完成后须要将平台部署到树莓派中运行起来便可,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
而后填写推流地址,点击开始监控便可。
这样,基于树莓派的视频监控平台就部署好了。若是要关闭视频监控,只须要点击页面上的 断开监控 便可。
这里为了实践我是本身在树莓派上搭建了一个基于nginx + flv module 的流媒体服务器,固然还有不少玩法。
好比:
a. 在线上服务器搭建流媒体服务器,而后将视频流推送到线上服务器,这样就能够实现远程视频监控。
b. 另外也能够将视频流推送到直播平台,实现直播。
=========================================================
项目源码可关注公众号 “HiIT青年” 发送 “raspi-video” 获取。
关注公众号,阅读更多文章。
!文章被用户(百度帐号:cuixiaoyande)抄袭,同时在头条号(头条号:cuixiaoyande)上也被此用户抄袭。
百家号文章
头条举报结果