HEXA开发日志目录
上一篇 HEXA娱乐开发日志技术点004——一步到位的推流
前言
距离上一次发文快4周了,不过我没有偷懒,技术上确实遇到了点困难,反正情况变成了下面这样,讲完干货再说。
这些折腾充分体现了技术视野对开发的重要性。
干货
很遗憾,上次的工作成果又被暂时抛弃了,这次我用
Gstreamer
。
一切原因后面再解释,先说说搞出了啥、咋搞的和为啥这么搞。
搞出了啥
成功使用Gstreamer实现了推流,从网页上看的性能,fps16左右,分辨率320x200,h264编码,虽然参数惨不忍赌,但也比之前的fps不到4强了。目前还没有整合到skill里面,只是用binary执行文件测试,源码在github上。
咋搞的
- 登陆机器人
- 挂载优盘(优盘里有gst-plugins-good的git库)
- 编译+安装gst-plugins-good
- 替换机器人身上的v4l2 gstreamer插件
- 编译我写的测试程序,生成binary执行文件simple
- 执行
./simple <你的rtmp url>
为啥这么搞
下面逐条解释一下上面步骤
- 登陆机器人
我之前好像提到过进到机器人身体里之类的动作,指的就是这个。操作方法是在手机APP上的Skill商店里打开高级开发模式,同时会看到ssh登陆命令,登陆后别忘了用passwd命令改一下初始密码。一般终端都支持ssh,都可以直接登陆。
ssh root@<机器人IP地址>
- 挂载优盘
挂载优盘的原因是,机器人身上的空间不够大,后面的编译动作会占空间。如果不出意外,并且优盘是FAT32文件系统的话,挂载命令就是下面这个,然后/mnt/sda1就等同优盘的根目录了。
mkdir /mnt/sda1
mount -t vfat dev/sda1 /mnt/sda1
- 编译+安装gst-plugins-good并替换机器人身上的v4l2 gstreamer插件
为啥要自己编译这个东西呢?因为不弄的话,gstreamer程序会陷入死循环,为啥死循环呢,因为这机器人的kernel的v4l2驱动没有按照官方标准实现,或者这版本的kernel这块就是有问题的。他们这kernel不开源,我就只好从用户层想办法,所以就改了gst-plugins-good里面的v4l2相关代码。
编译不麻烦,只是有几个坑。
执行./autogen.sh
就会发现,有依赖的系统库没有装,缺啥装啥就行了,用apt命令解决,先执行apt search <缺少库的名字>
找到缺少库的完整名字,然后apt install <缺少库的完整名字>
就行了。
最后卡住的是gstreamer的版本问题,要把gst-plugins-good切换到tag1.2.0才能通过,生成Makefile,当然,这之前要apt install git
装一下git,或者在别处切好tag。
在编译和安装完成后再替换一下系统原来的v4l2 gstreamer库就可以了。
这小节全部过程和命令如下
cd /mnt/sda1/gst-plugins-good
git checkout tags/1.2.0
git submodule init
git submodule update
./autogen.sh
报错,形如fail...need ...xxx
apt search xxx
找到形如xxx-yyy
apt install xxx-yyy
./autogen.sh
再次执行,没有报错
make
make install
mv /usr/local/lib/gstreamer-1.0/libgstvideo4linux2.so /usr/lib/arm-linux-gnueabihf/gstreamer-1.0/libgstvideo4linux2.so
这之后可以考虑make uninstall
卸掉它,因为需要的库已经换完了,也没必要占用空间。
疑似kernel的问题
有兴趣的小伙伴可以去了解一下这个版本官方的的v4l2的VIDIOC_ENUMSTD ioctl返回值是不是有问题。机器人的kernel版本是下面这样的
uname -a
Linux hexa 3.10.17_1.0.0_mb9000+ #35 SMP PREEMPT Thu Jan 18 07:08:48 UTC 2018 armv7l armv7l armv7l GNU/Linux
-
我写的测试程序
关于这个步骤没什么好解释的,一个make
,然后执行以下看看Usage就搞定。更需要说明的是为什么改用Gstreamer,至于这个程序大概怎么写出来的,看Gstreamer的官方英文文档是最好的,下面来讲讲为什么改用Gstreamer。
解惑
为什么改用Gstreamer
因为官方推荐
故事是这样的,在上次的总结中有这样一个问题:
下位机推流还有点问题,可以在播放端看到,似乎是推流的速度不够,出现了视频网站那种放一会儿就要缓冲一下的现象,具体原因有待分析
我针对这个问题研究了一番,发现官方的GO语言接口获取一张图像的时间是200多毫秒,大概是每秒4帧不到的样子,后来我看到官方论坛上有提到用v4l2驱动直接访问/dev/video0
设备文件的方式,我试了发现,1280x720的图就是每张200多毫秒,然后我向官方咨询,就被安利了Gstreamer和他们集成到机器人身上的一个VPU硬件编码模块和基于它的Gstreamer插件。
这之后我就开始在Gstreamer和ffmpeg之间徘徊不前。
- 一方面是因为我想不到还有什么比直接调用ioctl更直接的东西来获得摄像头的实际性能,这一方面在我偶然用网上的一个测试摄像头的程序测试时发现了问题。这问题就是我一直测试的是1280x720尺寸的帧率,我在论坛上没提到过我用的什么尺寸,结果我改成640x480后,就可以达到25帧了。我这一点结论还没有得到官方的回复。
- 另一方面因为搜索Gstreamer获得的中文信息弄得我一头雾水,越看越懵,所以还是想要延续原来的方案,想把官方安利的硬件编码模块搞成ffmpeg的一个编码器,或者至少在较上层把他们对接起来,但是动起手来还是感觉很麻烦。最后下定决心,开始看Gstreamer的官方英文文档,这下头上的雾水没了,一路搞下来才有今天这篇文章。
有趣的事
如果你不搞嵌入式,也许不会发现这件事很特别,那就是我的编译是在机器人上完成的。经典的嵌入式开发套路是这样的
上位机编译,下位机运行
这个机器人违反了这个套路,它身上的开发环境一应俱全,只要不嫌编译慢,它就既是上位机,又是下位机。
另一件有趣的事情是,机器人被我搞死一次。
那天我是把gstreamer工程(为啥编译它?在这文章背后,我走的弯路多了。有人能岁月静好,是因为有人在背后负重前行)放到机器人身上(不在优盘里)编译,结果空间不够了,我就删了点东西,因为它总是报告/tmp目录下创建东西不成功,我就把下面东西删了,然后把优盘挂载到了/tmp,结果第二天我再开机就起不来了。后来我找到了说明书上重置的方法,要用6根线,把机器人背上的管脚按照说明书接一下,最后我到公司找了6根线把它救活了。
在清空/tmp时,下面有一个套接字文件,我比较怀疑是删了它导致了机器人的死亡,但是我暂时不想验证这个结论。
srwxr-xr-x 1 root root 0 May 8 2017 wpa_ctrl_698=
总结
- 用Gstreamer实现了推流,暂时抛弃了ffmpeg
- 发现机器人可以同时做上/下位机
- 搞死一次机器人,重置救活
- 音频先不管,它不自带话筒,一般的话筒它不能用,还得专门买,这事后面再研究吧
- 目前推流的性能不是很好,不过先暂且如此吧,可以先整合进skill,然后研究一下怎么对视频做图像处理吧
- 这些事情的草还没发芽,包括弹幕命令集、机器人命名等
- 也许会写一篇关于Gstreamer的文章吧