ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

树莓派搭建视频监控平台

2020-07-09 09:05:32  阅读:239  来源: 互联网

标签:视频 树莓 sudo module nginx rtmpUri recorder 搭建


上一次用树莓派搭建了Nexus私服,终于让树莓派不再成为吃灰派了,这次用树莓派搭建视频监控平台,并实现视频画面推流到流媒体服务器。

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中看到视频画面。

raspi-ffmpeg

3. 测试摄像头

要搞视频监控还需要一个摄像头,这里使用的是树莓派CSI接口中的摄像头,如果摄像头功能没有开启的话需要在树莓派开启。

sudo raspi-config

选择 1. Interfacing Options

raspi5

然后再选择 P1 Camera

raspip1

选择“是”,然后重启树莓派。

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

然后填写推流地址,点击开始监控即可。

raspi-stream

这样,基于树莓派的视频监控平台就部署好了。如果要关闭视频监控,只需要点击页面上的 断开监控 即可。

6. 拓展玩法

这里为了实践我是自己在树莓派上搭建了一个基于nginx + flv module 的流媒体服务器,当然还有很多玩法。

比如:

a. 在线上服务器搭建流媒体服务器,然后将视频流推送到线上服务器,这样就可以实现远程视频监控。

b. 另外也可以将视频流推送到直播平台,实现直播。

=========================================================
项目源码可关注公众号 “HiIT青年” 发送 “raspi-video” 获取。

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

标签:视频,树莓,sudo,module,nginx,rtmpUri,recorder,搭建
来源: https://www.cnblogs.com/itqn/p/13268916.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有