打造树莓派HTML5实时监控

更新列表

1.20170108 初次成文

为什么会有这篇文章

网上谈到树莓派监控基本上都是用motion,在chrome浏览器中体验确实不错,可是手机上一些精简过内核的浏览器根本无法读取视频流,这次nodejs又机制地解了这个跨平台问题。

硬件准备,既然是树莓派实时监控,当然需要一个树莓派和一个摄像头。

树莓派不多说了,我习惯是原装的Raspbian系统。

摄像头可以用树莓派原装摄像头,不过经济的解决方案是USB摄像头,Linux内核真的很强大,摄像头的驱动基本都能识别,实时监控因为网络带宽对像素质量要求不高,咸鱼上十几块软妹币就能解决问题。

树莓派插好摄像头,判断树莓派是否正确识别摄像头。

lsusb一行显示webcamera

/dev目录下寻找vedio设备

找到/dev/vedio后说明摄像头已经驱动好了。还有一点,关于树莓派供电问题,最好输入线是2.5A的,否则外加摄像头会引起供电不足,解决办法是换充电头或摄像头外接USB供电(像那种USB线)。

使用motion

可以直接采用motion
motion用起来十分简单,安装和配置到运行花不了几分钟。

sudo apt install motion

配置motion

修改/etc/default/motion

start_motion_daemon=yes

motion启动完成后,会占用树莓派的8081端口。

打开浏览器输入https://树莓派IP:8081即可看到实时监控。同样使用VLC视频播放器也可以播放。

不过在手机上就没那么好使了,除了chrome以外,像QQ内置浏览器就一直在加载。

接触过在线视频技术的同学应该知道这种实时播放采用的是RTSP协议,一些精简过内核的html5浏览器并不支持直接播放。

html5实时监控

网上已经有在html5上播放视频流的解决方案

原理就是酱紫的

stearm -> ffmpeg -> nodejs -> websocket -> html5

ffmpeg解码视频流后交给nodejsnodejs会处理视频流并通过 WebSockets 发送浏览器,

ffmpeg

ffmpeg强大之处可以在维基百科上找到,在这个项目中的作用是重定向视频流。

ffmpeg官网下载好源码,放在树莓派上编译。

wget https://www.ffmpeg.org/releases/ffmpeg-3.2.2.tar.gz
tar zxvf ffmpeg-3.2.2.tar.gz
cd ffmpeg-3.2.2
./configure --enable-shared --disable-yasm --prefix=/usr/local/ffmpeg
make && make install 

由于树莓派编译速度比较慢,大概花了20分钟才完全编译好,不想等的同学可以直接用我编译好的这个。

wget https://coding.net/u/sfantree/p/self_use_OSS/git/raw/master/pi_vedio/ffmpeg_armv7_pi.tgz

注意为了防止找不到路径而报错,解压以后放在/usr/local/目录下运行。安装后运行可能会提示找不到动态链接库,全部链接至/usr/lib/目录下。

ln -s /usr/local/ffmpeg/lib/* /usr/lib/

nodejs

关于树莓派上的node版本我还在纠结,下了个6.2版本发现ghost只支持4.2,而4.2版本运行cpm会报错,不过这个项目使用6.2不会报错。

安装nodejs

nodejs官网已经提供了armv7平台的安装包。

wget https://npm.taobao.org/mirrors/node/v6.2.0/node-v6.2.0-linux-armv7l.tar.gz
tar zxvf node-v6.2.0-linux-armv7l.tar.gz
mv node-v6.2.0-linux-armv7l /usr/local

将node的bin目录添加至环境变量,方便起见,直接将这句话加到/etc/profile里面。

export PATH=$PATH:/usr/local/node-v6.2.0-linux-armv7l/bin

自己node一下试试

node -v

下载源码

git clone https://github.com/phoboslab/jsmpeg

stream-server.js作用就是将视频流转为websocket发送给浏览器。
stream-example.html为测试的网页文件
jsmpg.js解析服务端发来的websocket,渲染后显示在Canvas

stream-example.htmljsmpg.js一起移动到网页根目录,稍后再作修改。

启动后端服务。

node stream-server.js 12333

12333这里只是防止视频流不被窃取,stream-server.js后面跟的参数在源码里可以看到。

成功运行会显示这些信息。

stream-server.js将监听8082端口上的视频流,并使用8084端口websocket与浏览器通信。

接下来启动ffmpeg,启动之前最好杀掉占用摄像头的进程,比如motion

cd /usr/local/ffmpeg/bin
sudo ./ffmpeg -s 320x240 -f video4linux2 -i /dev/video0 -f mpeg1video -b 256k -r 24 https://127.0.0.1:8082/12333/320/240

-s设定分辨率大小,-f指定格式,-i指定接口,-b指定视频流比特率,-r指定帧率,后面的url填上在stream-server.js设置好的格式。

修改stream-example.htmlwebsocket替换为stream-server.js设置的url

注意这里IP的设置,根据你想访问的网络来设置,比如在树莓派本机可以用127.0.0.1,局域网192.168.x.x,如果映射到互联网,那么就要填写外网地址。

外网访问

关于内网穿透老生常谈的话题,这里依然使用自建的Ngrok搭建步骤原来写过,改变一下穿透的端口。

其实让websocket使用的8084端口穿透出去就行,这个网页很符合前后端分离的设计,静态网页拿到websocket直接渲染成视频。

使用内网穿透的话,因为中转服务器的带宽存在瓶颈,比如我使用的阿里云学生机只有1M带宽,这时为了节省服务器浏览可以将启动ffmpeg-b参数尽量改小一些。

下面是在QQ内置浏览器的效果。

画质烂是因为摄像头的原因,换个好的也许更清晰一点,不过考虑外网访问,这个AV画质很合适。

打造树莓派HTML5实时监控》上有2条评论

  1. 仁宇桑

    我正在用树莓派做一个带摄像头的小车,小车的控制端页面通过frp穿透可以公网访问了,小车的视频页面8082端口在公网显示loading。
    视频页面的页面审查中 显示
    index.html:42 WebSocket connection to 'ws://x.x.xom:8084/' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED (anonymous) @ index.html:42
    视频传输用的 https://github.com/waveform80/pistreaming 也用的jsmpg.js 看原理应该与你的做法是一样的,非计算机相关专业,还不知道该怎么改动,如果作者有空能够指导一二则不胜感谢。
    祝好

    回复
    1. popy32 文章作者

      除了控制页面的HTTP服务以外,websocket的视频流一样需要映射到公网端口
      frp新建一个tcp规则 127.0.0.1:8084 -> abc.com:8084
      然后html页面也要改 index.html

      //var client = new WebSocket('ws://' + window.location.hostname + ':${WS_PORT}/');
      var client = new WebSocket('ws://abc.com:8084');

      回复

发表评论

电子邮件地址不会被公开。 必填项已用*标注