Vision开发日志4

  今天搞了一下午加一个晚上,没有完成任何东西,可恶。

  本来昨天在测试将树莓派的视频流传输到Unity上的时候,几乎要成功了。我都在Unity的页面上看到树莓派摄像头拍下的我的脸一闪而过,虽然传输很不连贯,断断续续的并且有大量的乱码,但是至少我看到希望了。

  因此,我以为今天马上就要完成视频流传输了。结果折腾了一个下午都没有成功。原先我的方案是这样的:树莓派的Python端实时捕捉摄像头画面,为每一帧加上4个字节的帧头,然后通过udp传输至Unity,Unity在接收到4字节的帧头后预测帧长,然后开始接收分片的帧数据,在接收的帧数据达到预测帧长的时候就说明接收完一帧了,那么Unity就可以开始渲染这一帧的画面,渲染完成后开始接受下一帧的帧头,如此循环往复。

  这个想法虽然看起来很美好,但是存在一些问题。首先是Unity端渲染一帧的数据和树莓派端发送一帧的数据是不同步的,这就会导致当Unity渲染完成这一帧之后,理应要接收到下一帧的4字节帧头,却接收到了树莓派发来的1024字节的帧分片。如此就会让Unity端的算法无法正确执行,所以算法需要有帧同步的机制。但是即使在有了帧同步的机制后,这种算法在视频流传输上的效率是很低的,受限于带宽和树莓派的处理性能以及网络环境,基本上帧率只有个位数,这对于Vision来说是很糟糕的。

  于是我开始寻求其它的解决办法,我尝试让树莓派端不再使用Python进行视频流的捕获,而是直接使用rpicam-vid和ffmpeg来进行视频流的h.264编码然后推流至我的阿里云ecs服务器,再在Unity端尝试使用ffmpeg进行h.264解码然后显示画面。

  这个想法同样也很美好,但是实现起来就遭遇了诸多困难。首先是如何在Unity中使用ffmpeg来对视频流进行解码的问题。我找遍了很多地方,都没有找到关于这个问题的确切解决方案,我只能自己摸索这前进。当我把FFmpeg.AutoGen的引用成功导进我的Unity工程中后,发现ai给出的代码又有问题,不能使用。于是我开始找文档,又发现看不懂。几经尝试,最终放弃,决定换一种解决方案。

  根据ai提供的信息,我可以在Unity端直接使用videoplayer组建来播放rtsp的视频流,这样依然需要让树莓派端将摄像头捕获的视频推流至我的ecs服务器上。此外还需要在我的服务器上配置mediamtx的服务器,这样Unity通过mediamtx来进行视频画面的显示了。但是在实现的过程中第一关就给我卡住了,在服务器上下载mediamtx要下两个小时,卧靠这也太慢了,牛魔的阿里云就不能多给我点带宽吗,难道就因为我是试用吗。我一度想要充钱了,不过好在之后下载速度变快了。在成功下载好后,开始写入配置文件。我始终搞不清楚在stream那一个项目中究竟要填写什么信息,网上也没有可用的参考。我只能跟着配置文件里的注释和ai给的意见一点一点尝试。

  搞了好久好久,又是udp,又是tcp,又是rstp,又是rtp,七七八八的协议和端口把我搞的晕头转向。最终我认输了,决定返璞归真,直接使用配置文件里面的默认设置,然后启动mediamtx服务器,没想到成功启动了,而且能够正确接收树莓派端发来的视频流。那么接下来的任务就是让Unity端显示画面了。

  没想到这一环境依旧折磨。首先是我在Unity上写好接收视频流的代码,开始运行报错:对应URL中的是空数据。也就是说根本没有视频流,我靠真是服了。我在浏览器中输入这个URL测试,明明能显示树莓派摄像头的画面啊,姑且先不管延迟的问题。明明有数据为什么Unity的videoplayer播放不了呢。很是奇怪。由于快要熄灯了,我也来不及找这个问题的解决方案了,只能悻悻收拾东西准备关机了。

  好,现在再说回延迟的问题。当我在浏览器输入视频流的URL时候,电脑打开potplayer开始播放,这让我喜出望外。但是两秒之后我发现不对劲,这尼玛延迟也太大了,我在摄像头上挥动下手指,两秒后才给出反应。我估计这要是在Unity端显示的话延迟也会很大,太可恶了,这个方案虽然解决了帧率低的问题,但是这延迟根本接受不了啊。

  看来我又得另求方法了。或许借鉴微信视频聊天是一个不错的尝试。可惜接下来b事有点多,Vision的研发得先放一边了,shit!