intel边缘计算盒子--系统程序

intel边缘计算盒子主要程序:

1.mqtt 用于程序心跳上报,盒子系统信息上报以及云端配置下发

2.本地web使用nginx+fcgi

4.frp 用于反向连接

5.推流程序ffmpeg以及截图进程

6.扫描局域网摄像机程序

7.定时任务进程用于bug fix

8.crontab的定时任务,清理日志等

9.supervisor管理所有应用层程序

一、新零售本地页面直播与录播

1. https://github.com/winshining/nginx-http-flv-module 使用了这个nginx的module,作为推流服务器

2. ffmpeg rtsp转rtmp

3. 直播是flv

4.录播是m3u8(ts文件)

因为不是做那种直播平台的,做的是监控上传ts文件。直播的延迟在7秒左右,长时间直播,延迟估计会越来越大,网上说有自动追帧的方法解决。

flv ---ngx---ffmpeg----rtsp

nginx的配置,nginx-http-flv-module 的官网或者rtmp server的官网都有介绍。

ffpmeg的硬编码:https://trac.ffmpeg.org/wiki/Hardware/QuickSync

可采用flv.js播放3.1返回的直播链接,javascript代码示例如下:

 if(flvjs.isSupported()) {varvideoElement=document.getElementById('videoElement');varflvPlayer=flvjs.createPlayer({type:'flv',url:'http://xxxxxx/live?app=cams&stream=C100172' });flvPlayer.attachMediaElement(videoElement);flvPlayer.load();flvPlayer.play(); } 

可采用hls.js播放3.2返回的录播链接,javascript代码示例如下:

 varvideo=document.getElementById('video');if(Hls.isSupported()) {varhls=newHls();hls.loadSource('http://xxxxxx/mplay.m3u8?cameraid=C100172&ts=1578450015000&reqid=8at425qhx37f23bz');

hls.attachMedia(video);hls.on(Hls.Events.MANIFEST_PARSED,function() {video.play(); }); }elseif(video.canPlayType('application/vnd.apple.mpegurl')) {video.src='http://xxxx:6109/mplay.m3u8?cameraid=C100172&ts=1578450015000&reqid=8at425qhx37f23bz';

video.addEventListener('loadedmetadata',function() {

video.play();

});

}

supervisord起的一个进程来实时管理ffmpeg推流

exec ffmpeg -stimeout 10000000 -rtsp_transport tcp -loglevel quiet -i $rtsp -c copy -f flv -an "rtmp://127.0.0.1/cams/$mac" >/dev/null 2>&1

截图:

 ffmpeg -stimeout 10000000 -rtsp_transport tcp -loglevel quiet -y -i $rtsp -vframes 1 /opt/$mac\_snapshot.jpg

二、红外疫情防控一体机的录屏的直播与录播

camid=$1

res=$2

if [  -f /home/gg/conf/ird_hires ]; then

  scale=1

  rate=10

else

  scale=0.5

  rate=5

fi

gop=$((rate * 2))

#sx=$((x/2))

#sy=$((y/2))

#exec nice -n 10 /usr/bin/ffmpeg -f x11grab -s "$x"x"$y" -r 5 -loglevel quiet -i :0.0 -vcodec libx264 -preset ultrafast -vf scale="$sx":"$sy" -f flv -an "rtmp://127.0.0.1/cams/$camid" >/dev/null 2>&1

exec nice -n 10 /usr/bin/ffmpeg -f x11grab -s "$res" -r $rate -loglevel quiet -i :0.0 -g $gop -vcodec libx264 -preset ultrafast -vf scale="iw*$scale":"ih*$scale" -f flv -an "rtmp://127.0.0.1/cams/$camid" >/dev/null 2>&1

移动侦测: 比较2帧前后的变化,变化大了,就开始录屏

camid=$1

res=$2  //桌面的分辨率

seg_size=4

seg_list=22500

hls_dir=/opt/hls/${camid}MD

if  ! sudo test -d $hls_dir ; then  mkdir -m 777 $hls_dir; fi

if [  -f /home/gg/conf/ird_hires ]; then

  scale=1

  rate=10

else

  scale=0.5

  rate=5

fi

exec nice -n 10 /usr/bin/ffmpeg -y -f x11grab -s "$res" -r $rate -loglevel quiet -i :0.0 -vcodec libx264 -preset ultrafast -vf "scale=iw*$scale:ih*$scale,select=gt(scene\,0.003),setpts=N/($rate*TB)" -g $gop -f hls -start_number 0 -hls_flags append_list -hls_time $seg_size -hls_list_size $seg_list -an -use_localtime 1 -hls_segment_filename "$hls_dir/%s000.ts" $hls_dir/index.m3u8 >/dev/null 2>&1

录屏远程看直播有个奇怪的问题,就是当前有人在操作桌面,看直播就是无限的增加,只有桌面进去,停止录屏的进程,离开在启动。这样的 解决方案。

三、本地页面web后端

盒子本地后端采用nginx+fastcgi方式,提供cgi接口给前端调用:

需要安装的软件有:nginx、fcgiwrap、spawn-fcgi和haserl

1. nginx作为web 服务器,主要是修改其配置⽂件,以⽀持⽤户认证与cgi脚本的执

⾏。如以下配置:

前端页面获取信息需要访问后端cgi脚本,cgi的脚本访问需要认证

location /web/cgi-bin {

 auth_request /auth;

 }

auth.cgi来进⾏认证检查,如果认证通过则可以继续访问,否则

跳转到login

location /auth {

 fastcgi_pass unix:/var/run/fcgiwrap.socket;

fastcgi_param SCRIPT_FILENAME $document_root/auth/auth.cgi;

include fastcgi_params;

 # error_page 403 =200 /login;

 }

login通过执⾏auth_fail.cgi返回信息到前端,前端弹出登陆⻚。

 error_page 403 =200 /login;

 location /login {

 fastcgi_pass unix:/var/run/fcgiwrap.socket;

 fastcgi_param SCRIPT_FILENAME $document_root/auth/auth_fail.cgi;

 include fastcgi_params;

 # proxy_pass http://127.0.0.1:80/trylogin.html;

 # proxy_set_header X-Target $request_uri;

 }

登陆⻚检查登陆信息是否正确,并记录状态。

 location /login.cgi {

 fastcgi_pass unix:/var/run/fcgiwrap.socket;

fastcgi_param PATH_INFO $fastcgi_path_info;

fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;

 include fastcgi_params;

}

认证成功的话则可以访问cgi脚本, cgi脚本的执⾏,通过传递脚本名称以及参数到fcgiwrap,由fcgiwrap来执⾏真正的脚本。脚本的执⾏由haserl解释并返回html⽂档。

 location /web/cgi-bin/ {

 auth_request /auth;

#fastcgi_pass 127.0.0.1:12345;

 fastcgi_pass unix:/var/run/fcgiwrap.socket;

# fastcgi_index /web/cgi-bin;

# fastcgi_split_path_info (/web/cgibin)(.*)$;

fastcgi_param PATH_INFO $fastcgi_path_info;

fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;

# fastcgi_param SCRIPT_FILENAME /ap_www/web/cgi-bin/sys-info.cgi;

include fastcgi_params;

 }

 }

2.fcgiwrap、 spawn-fcgi

/etc/init.d/fcgiwrap 脚本负责该服务的启动。该脚本中指定的unix socket或端⼝号要与nginx中匹配

3, haserl

cgi

脚本如以下形式。

 #!/usr/bin/haserl --shell=/bin/bash

 content-type: application/json   //正常的返回json

content-type: application/vnd.apple.mpegurl // 这个头是返回视频ts文件

<%

Shell scripts

%>

注意点: fcgi里的shell script不能阻塞,它以所有命令全部执行完后,才会echo输出。

cgi接口就是通过输入输出方式传递消息

或者就是使用nohup xxxxx & 放在后台执行去。

由于当时没有很多接口,后来由于cgi使用的单线程问题,接口都是代理文件的方式给出去。

所以说使用cgi刚开始就要配置多进程的方式。我因为是所有数据都是存文件的方式,没有使用数据库,如果再使用多进程,数据就会乱掉。。。。。

3.扫描局域网摄像机

因为相机上的onvif协议默认是关闭的。所以使用onvif协议去扫描相机是不能够实现的。之前做法是IPC的厂商的相机,默认是打开的,使用gsoap的框架扫描的,但是海康等都是关闭的,并且gsoap的框架太重。

所以决定使用相机的私有协议去发现它。

基本方法就是 :使用厂商的工具去发现,通过wireshark抓包分析。

海康的网上搜了下别人发现的海康的私有协议:https://blog.csdn.net/haoyitech/article/details/79552854

扫描程序是C语言编写:

sudo apt install -y -q libnet1   libnet的安装

gcc -lnet   编译加-lnet

使用了libnet库,libnet是一个raw socket的包,是二层的,可以构造任何的pkt来发送,不通过内核协议栈,加上dhcp+nat后经常出现奇怪的问题,发现摄像机需要的多播和广播包无法发送出去,所以只有用libnet来直接发送构造包发送。

还有就是所在的路由器和交换机会不会转发数据包。。。。

4. supervisord

   supervisord进程管理方式使用注意点:

    a. 管理的进程里的所需要的环境变量如HOME. 需要再其配置文件里添加下,supervisor没有继承系统的环境变量。实列如下:

environment=DISPLAY=":0",HOME=/home/xxx。 多个环境变量用逗号隔开。

四、获取局域网中的摄像头的配置以及配置摄像头的配置

之前2款相机,一个是海康和IPC的,IPC的根据http接口,海康则是调用海康的sdk,动态库,但是由于也是太重,就用python 爬页面方式获取和配置的。


四、常用命令

ffmpeg 从MP4、ts的文件中取出一帧

ffmpeg -y -loglevel quiet -i video.ts -vframes 1 -f image2 1.png

ffmpeg -y -loglevel quiet -i 1636020194752.ts -vframes 1 -s 640x480 -ss 2 -f image2 gao1.png

-ss 2 从第2秒取出一帧

-s 640x480  取出的图片是要640x48p

因为摄像机一般码流只能拉2路,盒子这拉一路,如果客户的店里的NVR再拉一路,截图就失败了,所以截图从最近的ts文件里获取。

五、ubunut系统常用配置信息获取

1.获取显示器的分辨率:sudo su - pi -c 'DISPLAY=:0.0 xdpyinfo' | awk '/dimensions/{print $2}'

2. 设置1080p的分辨率

3.获取显示器的厂商 :sudo grep 'vendor' /home/user/.local/share/xorg/Xorg.0.log |tail -n1 | awk -F \\\" '{print $2}'

4.调节ubuntu18.04.3的系统音量:

5.ubunutu18.04.3的系统声音打开和静音,需要循环,可能有多块声卡,比如外挂的蓝牙音箱等

6. 设置时区:sudo timedatectl set-timezone "$continent/$city"

六、红外测温--热成像仪(获取温度和红外图片)

红色箭头就是成像仪获取的热力图

我们使用的热成像仪是艾睿的产品,有网络热像仪和usb接口的热成像仪2种

我们提供2套接口:

1.http的接口,获取热力图图片  http jpg  url:  http://127.0.0.1:8008/video/infrared.jpg

2.tcp端口,用于获取温度: 127.0.0.1:8009

tcp socket 的数据包协议:

固定头(5字节)| 温度长度(4字节)|温度数据|时间戳

+TEMP        DataLen                  Data       Time

输出温度的是(288行,384列)的数组,数组的值是该像素对应的温度值(两个字节,单位开尔文),转换公式为,摄氏度=(开尔文+25000)/100 - 273.2。( 因为红外图像就是288x384的大小)                                                                                                                                                   

A: 网络热像仪(LT系列)

1. 首先就是根据私有协议,找到红外的设备(多播**)

设置2个sockfd属性
然后epoll_wait()等待io就绪,获取到IP和mac地址

2. 初始化2个scoket, 一个用于提供图片的,一个是用于提供温度的

3.处理网络IO数据

connect()用于建立连接accept,onRead()用于数据的获取
accept
热力图http数据包,jpgBuf也是全局变量
发送温度数据
tempBuf是全局变量
全局变量加的读写锁
jpgBuf直接memcpy
build

B. USB的热成像仪(at系列)

usb的,网络推送部分差不多,区别就是获取图片和温度数据,因为是usb的,所以需要用到v4l2的视频获取框架

https://www.linuxtv.org/downloads/v4l-dvb-apis-old/capture-example.html  参照官方的example                                        https://linuxtv.org/downloads/v4l-dvb-apis-new/userspace-api/v4l/capture.c.html                                                                      https://linuxtv.org/docs.php                                                                                                  https://www.kernel.org/doc/html/v4.9/media/uapi/v4l/vidioc-enum-fmt.html#c.v4l2_fmtdesc   

https://www.kernel.org/doc/html/v4.9/media/intro.html

https://github.com/gjasny/v4l-utils/blob/master/utils/v4l2-ctl/v4l2-ctl.cpp  v4l2的源码。

https://github.com/jacksonliam/mjpg-streamer   涉及到v4l2的框架使用,源码值得学习研究

atd的改动,是看v4l2-ctl的源码,看它是怎么获取Media Driver Info.。(因为母机的镜像从ubuntu18.04更新到20,底层驱动变化了)

atd需要看到那个关键词AT600来确定是at200,新的ubuntu是在 Media Driver Info里面,老的就在Driver Info,所以需要去获取Media Driver Info来做判断

v4l2的基本流程:

 打开设备-> 检查和设置设备属性-> 设置采集数据格式-> 设置一种输入输出方法(缓冲 区管理)(申请内核缓冲区队列)-->把内核的缓冲区队列映射到用户空间-> 循环采集数据-> 关闭设备。

open打开设备
检查和设置设备属性
设置属性
mmap内存映射
mmap
start capture

创建一个线程在loop, 执行函数指针

设置的回调函数
热力图的图片需要使用opencv的库,yuv-->jpg
温度数据得到
build

整个流程基本是参考官方的demo来操作的(https://www.linuxtv.org/downloads/v4l-dvb-apis-old/capture-example.html )

intel盒子上用到的系统命令:

sudo apt-cache search libopencv-highgui  查找库的当前版本

echo "$USER ALL=(ALL:ALL)NOPASSWD:ALL" |sudo tee /etc/sudoers.d/$USER   当前用户获取sudo 权限,不需要输入密码

sudo timedatectl set-timezone Asia/Shanghai              设置时区

echo superadmin:qN6RVzwqqwv | sudo chpasswd          修改superadmin用户的密码

 sudo adduser --system --shell /bin/bash --group superadmin          修改用户权限组                                                                                                   sudo usermod -aG sudo superadmin                                                                                                                                                                           sudo usermod -aG adm superadmin

! dpkg -s openssh-server | grep Status: | grep -i installed   &&  sudo apt install -y -q openssh-server 判断软件是否安装

if ! sudo iptables -t filter -C INPUT -p tcp --dport 22 -j ACCEPT ; then

  sudo iptables -A INPUT -p tcp --dport 22 -j ACCEPT

  sudo service netfilter-persistent save   保存规则

fi   打开22端口

sudo mii-tool eth0    查看网口eth0是否插了网线

添加全局dns

echo "@reboot cue /home/name/on_boot.sh" |sudo tee /etc/cron.d/sh1         添加定时crontab定时任务执行

echo "*/10 * * * * cue /home/name/on_boot.sh" |sudo tee /etc/cron.d/sh1

sudo systemctl restart cron.service

sudo dpkg -i xxx.deb

sudo dpkg -P xxx   删除 & 配置

sudo sysctl -q -w net.core.wmem_max=851968    修改tcp的发送缓冲区大小为8511968

sudo sed -i -e 's/User=www-data/User=cue/' -e 's/Group=www-data/Group=cue/' -e 's/\[Service\]/[Service]\nRestart=always/' $FCGI_CFG 修改fcgi使用cue用户启动

sudo systemctl daemon-reload

sudo /etc/init.d/fcgiwrap restart

安装ntp service
添加一个路由,相机ip 1.160, 盒子本地静态ip 1.30

遇到问题:

红外测温一体机,盒子系统从ubuntu18.04--->20.04。配合飞利浦电视使用,一起断电和上电,ubuntu系统没有声音,声卡状态正常

解决措施:

1. sudo apt install 5.10.0-1057-oem   降低内核版本 到5.10

2. 需要停止录屏进程。强制驱动重新检测声卡

停录屏进程

sleep 5     这时间需要长点,进程停了,但是声卡可能还没有完全释放

sudo -H -u pi bash -c "export DISPLAY=0:0 && xset dmps force off"

sync && sleep 2

sudo -H -u pi bash -c "export DISPLAY=0:0 && xset dmps force on"

起录屏进程

echo off |sudo tee /sys/class/drm/card*/status 

sync

sleep 2                  

echo on |sudo tee /sys/class/drm/card*/status  但是这种方式,黑屏的时间要12s左右

恢复脚本:是放在系统桌面起来后,自动执行

在/etc/xdg/autostart目录下加个desktop文件,exec执行一个脚本就可以

继续更新。。。。。。

你可能感兴趣的:(intel边缘计算盒子--系统程序)