开发环境

微信小程序

业务功能

多人视屏通话,小程序的界面应该满足:有多少用户就显示对应数量的九宫格子。并且在用户开启了视频或者语音的权限之后正常显示画面或者播放声音。

问题1:

现象描述

  1. 多人视频通话的过程中,其中有用户关闭了摄像头和话筒的权限但是未退出房间,其他人就无法在画面上看到用户的进入状态,即画面上会少一个视频格子。

    问题评估

  2. 开启摄像头权限的小程序的用户是否能主动推送流信息到其他的客户端,并被其他用户监听。

  3. 小程序收到流信息的推送后如果更新了界面,界面元素是否能够重新渲染。

问题解析

针对上述问题做出初步评估,总结为要分析的原因有三点:

  1. 小程序的媒体推送机制
  2. 小程序的模板的更新机制

针对以上总结的问题,做出以下的实践分析:
在控制台中设置打印streamList的推送日志,观察在用户主动开启或者关闭设备(语音或者视频)权限后streamList栈中的记录:
image.png
打印后发现,若用户关闭权限进入之后streamList中不存在该用户的媒体流对象信息,而在用户主动开启之后streamlist中的流媒体被推入一条流信息。总结第一条分析原因:小程序在视屏通话时,会主动监听用户的开启/关闭权限,推送给所有的视频参会与者以更新界面的信息状态,导致了视频通话宫格的减少。

验证了第一点后,继续分析第二点。既然小程序会及时在每个与会者的终端上更新推送流媒体信息,那么小程序的渲染时机是否有问题。我们可以通过实验来验证这个问题:更新数组的长度,看界面是否会正常渲染出来正确的结果:
image.png
通过给数组增加列子项,界面会及时更新。总结第二条分析原因:小程序的模板更新机制和预期的一致,在streamList这种数组类型的数据发生长度上的变化后,会及时渲染更新界面。

解决方案

通过对消息视频通话模块的分析发现:小程序会在用户的关闭和开启操作触发两个时间:hasVideo和hasAudio。这两个状态发生了变化的话会通知streamList进行更新(开启入栈,关闭出栈)的操作。从而导致了界面的渲染数量发生了变化。因此有了一下两种解决方案:
通过userList的方式去渲染界面的列表。因为userList的数量是和用户数量保持一致的,不会随用户的权限变化而变化。因此用这个列表来渲染界面可以保证格子数量和与会者数量一致。
修改streamList的更新逻辑。在源码中修改hasVideo和hasAudio两个权限的通知逻辑,即:不再因为两者的变化而去更新streamList的长度。
image.png

问题2:

现象描述

在修改了通知逻辑之后,发现格子的数量是保持了一致,但是如果之前的用户重新开启视频权限的话,界面上的格子里面无法出现视频画面。

问题评估

小程序的live-play是否会跟随模板一起更新,还是有自己的一套更新机制。

问题分析

针对上面的问题,我们需要求证的是小程序组件live-play的更新机制:是在初始化的时候更新一次,还是每次都会随着模板界面的更新而更新。
为了验证这一点我们在模板中加入属性变化的操作。观察live-play是否会保持初始化时的状态。

通过实践分析发现:live-play这个组件只会在第一次被渲染出来的的时候初始化自己的状态,其他的情况的变化不会再引起他自身的改变。

解决方案

针对live-play的这种渲染机制,我们在渲染这个组件的时候添加逻辑判断:无权限的时候不渲染组件,等到用户主动开启时再渲染这个组件:

  1. <view wx:for="{{streamList}}" wx:key="index">
  2. <view>
  3. <live-player wx:if="{{item.hasVideo}}"></liver-play>
  4. </view>
  5. </view>

经过检验,此种方案能够在视屏通话时监控用户操作权限的动作,并在界面上做出及时的更新。