智能设备App开发实践——视频直播篇

达芬奇密码2018-07-19 12:33

在上一篇文章智能设备App开发实践——设备配置篇,介绍了智能设备添加的几种方式。在本章,主要介绍在开发青果摄像机App的时候,为了提升用户体验而做的直播优化方案。

青果视频直播,我们碰到了下面几个问题:

  1. 点击播放视频,loading很久才出现画面
  2. 请求播放视频,失败的概率较高
  3. 视频播放如何处理防盗链机制,确保播放流畅
  4. 播放经常出现卡顿现象
  5. 直播过程中,随着时间推移,延时越来越大

以上的几个问题,又可归结为如下三个问题:

  • 如何做到直播秒开
  • 如何做到直播流畅
  • 如何做到直播实时

可以说这几个问题,在视频直播的时候是不得不面对的问题。以下是我们对这些问题,从App出发,所采用的方案。

如何做到直播秒开

直播视频首次打开的速度,是很影响体验的。系统架构和视频Group of Picture(GOP)设置,对视频打开的速度都会有影响。架构和GOP的优化,不在本文讨论的范围内。
一次完整的视频播放流程:

  1. App向服务器发送播放请求
  2. 服务器接收请求,向摄像机push推流命令,同时生成播放链接返回给App
  3. 摄像机开始推流,App获取链接开始请求播放

每次播放,都需要向摄像机发送指令控制硬件向服务器推流,App需要等待推流成功才能正常播放,这是很耗时的。因此,我们做了如下优化:

  • 预先推流
    进入摄像机页面,App会立即给服务端发一次推流请求。不出意外的话,此时摄像机已经向服务端推流了。这时再点击播放按钮,服务器就不需要再向摄像机push指令了,而是直接将播放链接返回给App。App获取链接即可正常播放,节省了等待推流的时间,播放速度得到了提升。

  • Wi-Fi下自动播放
    虽然已经有了预推流,但是如果用户在发送推流请求一段时间后还没有请求播放,摄像机会停止推流。又或者用户停止播放后,再点击重新播放。以上两种情况,视频播放就又回到了最初的情况,需要loading很久才播放成功。考虑到用户很多的使用场景是Wi-Fi环境下,因此针对Wi-Fi情况下,我们还做了如下优化:

    • Wi-Fi环境下,进入摄像机页面,后台直接请求链接播放视频。此时视频是静音在后台播放,当用户点击播放按钮时候,隐藏播放器上面的截图,调整视频播放音量到正常。这时,对于用户来说,视频是立即就播出来了,达到“秒播”效果。
    • Wi-Fi环境下,点击停止播放,并不是真正停止。只是将视频静音在后天播,上面盖上截图。如此当用户又点击播放时,可以立即播放画面,达到“秒播”效果。

以上的秒播逻辑优化方案,在实际使用中较好提升了直播播放体验。但是也存在一定问题,如增加了服务端的压力,后台播放还加快了手机耗电等。实际项目中,大家可以根据情况选择是否使用。

如何做到直播流畅

请求视频播放,主要分为两个步骤。

  • 第一步:请求播放链接
  • 第二步:播放器通过链接请求视频流
    优化分别从这两部分入手:

  1. 获取链接优化
    获取链接加入失败重新请求机制,重试次数最大3次。因为服务器与设备通信,是一个单向的过程,可能存在失败的情况。为了加大请求的成功率,我们在请求失败和超时的时候重新请求,加大获取链接的成功率。
  2. 播放增加重试机制
    播放过程中开启重连检测检测定时器,固定时间检测播放进度。如果播放时间进度小于设置的阈值,则判断当次播放失败。这个时候不停止播放提示用户(画面loading提示用户正在缓冲),而是自动请求链接(此处没有链接获取重试机制)并进行播放。

如何做到直播实时

视频传输导致的延时是不可避免的,但是对于网络抖动或者手机性能导致视频数据积压,这部分我们是可以从逻辑上优化的。为了使播放流畅,播放器设置了一个缓存buffer用于存放视频数据,视频渲染都是从buffer中获取的数据。刚开始buffer设置得比较大,这也导致了在网络抖动和手机性能较差时候,延时越来越大。网络抖动时候,可能在某一瞬间来了很多视频数据,手机处理速度时恒定的,此时数据就在buffer中堆积。又或者手机处理速度很慢,接收数据量大于渲染处理的数据量,则数据也会在buffer中堆积,导致播放延时越来越大。 针对以上问题,我们的直播实时处理方案是:

  • 减小buffer大小
    我们发现,buffer越大,最终导致的延时就越长。因此通过测试,在不影响播放流畅性的情况下,我们将buffer的值调小。
  • 加入清buffer机制
    当前播放器的机制是buffer满了之后就不再接收数据了。所以在将buffer调小的基础上,我们加入清buffer机制。当buffer数据满了之后,我们将buffer清空,用以接收新数据,从而保证播放器播放的都是最新的数据。

存在问题思考

正如我们上面方案中所提到,基于清缓存机制提升了直播的实时性。此方案在网络稳定的时候可以做到较好的实时性,但是当网络抖动很厉害的时候,因为一次性来了很多的视频数据。播放器基本都在做清缓存的操作了,表现在效果上就是视频一卡一卡,根本看不了。
如何处理好低延时和抗抖动之间的平衡,这是我们需要思考的问题。目前我们设想的是基于反馈动态设置buffer的大小。即在视频的播放过程中,统计之前固定一段时间内播放loading的次数,根据loading次数的多少,动态去设置buffer的大小。如下表所示(参数只是举例,无实际意义):

缓冲次数 buffer大小
0~5 1M
6~10 2M
>11 4M

本文来自网易实践者社区,经作者郑睿授权发布。