背景

历时7个小时,总算在 CentOS 7(32位)上安装好了 Shinobi,整个编译过程遇到无数问题,然而最终还是被头铁的我逐一解决,我简直太难了,特此记录!

先说 Shinobi,这是一个基于 Nodejs 开发的 完全开源的视频流管理软件,之前有过博文提到我在捣鼓一个 萤石(EZVIZ) C6CN 网络摄像头,在该文中提到我出于安全考虑打算禁用该摄像头接入公网,并且改用第三方手段来录制和存储录像视频,而 Shinobi 就是最终的选择,我已经提前在一台 CentOS 7(64位) 的VPS上进行过一次预装和体验,该软件的功能完全符合我的需求,因此这才准备开始在我的NAS上进行实际安装。

由于我那台 NAS 的CPU不支持64位,最终安装了 CentOS 7(32位),最终导致了本次我疯狂踩坑的悲惨经历……

万事开头难

但是这个第一步也太难了啊!!!

首先,Shinob安装要求 如下:

1
Node.js (12+), FFmpeg (3.3+), and MariaDB (10.4+) are the main components that Shinobi needs.

然而 Nodejs下载页面并没有32-bit的版本,经过深思熟虑我决定直接下载源码进行本机编译:

源码方式编译最新版本nodejs

1
2
3
4
5
wget https://nodejs.org/dist/v12.16.2/node-v12.16.2.tar.gz
tar zxvf node-v12.16.2.tar.gz
cd node-v12.16.2
./configure
make

在我这颗上古奔腾4单核CPU上足足跑了3个多小时后,以失败告终;看着 make 出来的一堆堆 ERROR 报错,欲哭无泪。

寻找支持32位的最新版本nodejs

冷静下来后我想了想,nodejs 早期是有32位版本支持的,那么我直接找到支持32位的最后一个版本不就行了?

说干就干,进入Nodejs Release Download,然后按照版本号倒序挨个点进去:

  • latest-v12.x/
  • latest-v11.x/
  • latest-v10.x/
  • latest-v9.x/

找到了 node-v9.11.2-linux-x86.tar.gz,然后根据 How to install Node.js via binary archive on Linux? 对二进制包进行解压,并且设置环境变量,测试成功:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
[root@private Shinobi]# node -v
v9.11.2

[root@private Shinobi]# npm version
{ npm: '6.14.4',
ares: '1.13.0',
cldr: '33.0',
http_parser: '2.8.0',
icu: '61.1',
modules: '59',
napi: '3',
nghttp2: '1.32.0',
node: '9.11.2',
openssl: '1.0.2o',
tz: '2018c',
unicode: '10.0',
uv: '1.19.2',
v8: '6.2.414.46-node.23',
zlib: '1.2.11' }

[root@private Shinobi]# npx -v
6.14.4

第二只拦路虎:FFmpeg

CentOS 7 上安装 FFmpeg 最简单的方法是通过 Nux Dextop 仓库的方式安装:

(注:Shinobi 官方自动化安装脚本是也是采用该仓库进行安装,下面的代码摘自 Shinobi源码的 INSTALL/centos.sh

1
2
3
4
5
6
#Install EPEL Repo
sudo yum install epel-release -y
#Enable Nux Dextop repo for FFMPEG
sudo rpm --import http://li.nux.ro/download/nux/RPM-GPG-KEY-nux.ro
sudo rpm -Uvh http://li.nux.ro/download/nux/dextop/el7/x86_64/nux-dextop-release-0-1.el7.nux.noarch.rpm
sudo yum install ffmpeg ffmpeg-devel -y

然而实际情况是,http://li.nux.ro/download/nux/dextop/el7/ 下只有 x86_64,嗯……

头铁不信邪的我,打算试试 CentOS 6(32位) 版本的安装包是否能够安装,结果当然是失败的,过程就不贴了,太愚蠢了。


时来运转,我在FFmpeg 官网下载页面 发现了有32-bitLinux Static Build,抱着试试的心态开搞:

1
2
3
wget https://johnvansickle.com/ffmpeg/releases/ffmpeg-release-i686-static.tar.xz
tar xvf ffmpeg-release-i686-static.tar.xz
sudo mv ffmpeg-4.2.2-i686-static/ffmpeg ffmpeg-4.2.2-i686-static/ffprobe /usr/bin/

搞定,测试可用:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
[root@private Shinobi]# ffmpeg
ffmpeg version 4.2.2-static https://johnvansickle.com/ffmpeg/ Copyright (c) 2000-2019 the FFmpeg developers
built with gcc 8 (Debian 8.3.0-6)
configuration: --enable-gpl --enable-version3 --enable-static --disable-debug --disable-ffplay --disable-indev=sndio --disable-outdev=sndio --cc=gcc --enable-fontconfig --enable-frei0r --enable-gnutls --enable-gmp --enable-libgme --enable-gray --enable-libfribidi --enable-libass --enable-libfreetype --enable-libmp3lame --enable-libopencore-amrnb --enable-libopencore-amrwb --enable-libopenjpeg --enable-librubberband --enable-libsoxr --enable-libspeex --enable-libsrt --enable-libvorbis --enable-libopus --enable-libtheora --enable-libvidstab --enable-libvo-amrwbenc --enable-libvpx --enable-libwebp --enable-libx264 --enable-libx265 --enable-libxml2 --enable-libxvid --enable-libzimg
libavutil 56. 31.100 / 56. 31.100
libavcodec 58. 54.100 / 58. 54.100
libavformat 58. 29.100 / 58. 29.100
libavdevice 58. 8.100 / 58. 8.100
libavfilter 7. 57.100 / 7. 57.100
libswscale 5. 5.100 / 5. 5.100
libswresample 3. 5.100 / 3. 5.100
libpostproc 55. 5.100 / 55. 5.100
Hyper fast Audio and Video encoder
usage: ffmpeg [options] [[infile options] -i infile]... {[outfile options] outfile}...

Use -h to get full help or, even better, run 'man ffmpeg'

正式安装 Shinobi

从Git仓库拉源码,然后搞配置文件:

1
2
3
4
5
6
7
8
yum install git -y

cd /home
git clone https://gitlab.com/Shinobi-Systems/Shinobi.git Shinobi

cd Shinobi
cp conf.sample.json conf.json
cp super.sample.json super.json
  • vi conf.json,修改端口port,视频存储路径addStorage,事务密匙cron.key 这三项。
  • vi super.json,修改超级管理员帐号密码 mailpass

执行 CentOS 安装脚本:

1
chmod +x INSTALL/centos.sh && INSTALL/centos.sh

根据安装指引,分别完成以下安装步骤:

  • Install Node.js 检查及安装,因为我们前面已经安装了 9.x 版本,这里会直接显示版本号。
  • Install FFMPEG 检查及安装,这里我选择了 npm 方式安装。(这里有个坑,后面会提到)
  • Install MariaDB 检查及安装,常规的数据库安装流程,根据提示安装即可。
  • Shinobi - Database Installation 初始化 Shinobi 数据库。(这里有一个报错,但不是每个人都会遇到,跟你的数据库版本有关,需要手动处理,后面会提到)
  • Install NPM Libraries 自动完成,无需干涉。
  • Install PM2 自动完成,无需干涉。

接下来询问是否开机启动,选择Y后会自动启动Shinobi并且设置开机启动。

安装过程到此结束,我们看看运行状态:

1
2
3
4
5
6
7
[root@private Shinobi]# sudo pm2 list
┌─────┬───────────┬─────────────┬─────────┬─────────┬──────────┬────────┬──────┬───────────┬──────────┬──────────┬──────────┬──────────┐
│ id │ name │ namespace │ version │ mode │ pid │ uptime │ ↺ │ status │ cpu │ mem │ user │ watching │
├─────┼───────────┼─────────────┼─────────┼─────────┼──────────┼────────┼──────┼───────────┼──────────┼──────────┼──────────┼──────────┤
│ 0 │ camera │ default │ 2.0.0 │ fork │ 2838 │ 2h │ 2 │ online │ 0.7% │ 77.6mb │ root │ disabled │
│ 1 │ cron │ default │ 2.0.0 │ fork │ 2844 │ 2h │ 2 │ online │ 0.4% │ 34.4mb │ root │ disabled │
└─────┴───────────┴─────────────┴─────────┴─────────┴──────────┴────────┴──────┴───────────┴──────────┴──────────┴──────────┴──────────┘

无法访问?

访问 http://127.0.0.1:8080 失败,然后看下端口监听:

1
[root@private Shinobi]# netstat -anop | grep node | grep LISTEN

居然没有任何监听,发生了什么?只能查看系统日志:

1
2
3
4
5
6
7
8
[root@private Shinobi]# cd /home/Shinobi
./INSTALL/shinobi logs

/root/.pm2/logs/camera-out.log last 100 lines:
0|camera | Shinobi is Exiting...
0|camera | ffbinaries : Downloading FFmpeg. Please Wait...
0|camera | 2020-04-24T14:18:40+08:00 Current Version : c2b393b86de5511d6d2d60dfe5548fe0f2889793
0|camera |

可是我明明装好了FFmpeg了呀?只能看Shinobi源码了,先看camera.js

1
33 loadLib('ffmpeg')(s,config,lang,function(ffmpeg){

继续看libs/ffmpeg.js

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
48     //check node module : ffbinaries
49 ffmpeg.checkForFfbinary = function(failback){
50 try{
51 ffbinaries = require('ffbinaries')
52 var ffbinaryDir = s.mainDirectory + '/ffmpeg/'
53 var downloadFFmpeg = function(){
54 downloadingFfmpeg = true
55 console.log('ffbinaries : Downloading FFmpeg. Please Wait...');
56 ffbinaries.downloadBinaries(['ffmpeg', 'ffprobe'], {
57 destination: ffbinaryDir,
58 version : '3.4'
59 },function () {
60 config.ffmpegDir = ffbinaryDir + 'ffmpeg'
61 console.log('ffbinaries : FFmpeg Downloaded.');
62 ffmpeg.completeCheck()
63 })
64 }
65 if (!fs.existsSync(ffbinaryDir + 'ffmpeg')) {
66 downloadFFmpeg()
67 }else{
68 config.ffmpegDir = ffbinaryDir + 'ffmpeg'
69 }
70 }catch(err){
71 console.log('No "ffbinaries". Continuing.')
72 console.log('Run "npm install ffbinaries" to get this static FFmpeg downloader.')
73 failback()
74 }
75 }

这下明白了,在 /home/Shinobi/ffmpeg/ 下没有找到ffmpeg这个二进制文件,所以ffbinaries开始下载,然而下载速度又奇慢无比,所以导致后续代码无法执行,因此整个程序没有起来,知道原因就简单了,我们之前不是下载过编译好的静态 ffmpeg 二进制文件么?直接拷过来:

1
cp -f /usr/bin/ffmpeg /home/Shinobi/ffmpeg/

数据库初始化时的问题

前面提到在执行安装脚本初始化数据库的时候有一个报错:

1
ERROR 1293 (HY000): Incorrect table definition; there can be only one TIMESTAMP column with CURRENT_TIMESTAMP in DEFAULT or ON UPDATE clause

错误是执行sql/framework.sql这个数据库初始化sql文件时产生的,具体行数是41行。

解决方法参见:MySQL错误TIMESTAMP column with CURRENT_TIMESTAMP的解决方法

所以解决起来就很简单了,把end字段移到time字段之前:

1
2
3
4
5
6
7
8
9
10
-- Dumping structure for table ccio.Timelapses
CREATE TABLE IF NOT EXISTS `Timelapses` (
`ke` varchar(50) NOT NULL,
`mid` varchar(50) NOT NULL,
`details` longtext,
`date` date NOT NULL,
`end` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
`time` timestamp NOT NULL,
`size` int(11) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

然后手动单独执行这个表创建代码即可。

结束

最后,Shinobi 终于安装完成并且正常工作了,这波成就感拉满了;
后面有机会的话我来写一写Shinobi的使用体验,网上貌似很少有人分享。