flutter 音视频通话项目的那点事儿

开篇

  • 今天这篇文章,从flutter出发,杂谈下我对整个移动端开发的一些感触.
  • 原生开发这么久,哪些技术类型的APP开发难度最高呢,在我的认知内,一类是图形学APP开发,3D交互等等,比如贝壳VR房屋交互等,一类复杂程度很高工具类APP,比如teamviewer操作其他APP等(这东西我甚至不知道他的原理),也有那种定制化原生,比如京东,饿了么的地图定制化开发等,总而言之,越少人研究,公开blog越少的功能,基本都是越难的功能.而我自己所经历过,音视频通讯类APP开发,只能算是其中比较复杂的一种. 前面所说的前提是业务型APP,toB的三方服务型SDK不包含其中.
  • 为什么打开各种教学网站,慕课,网易云等等,看到的都是清一色美团,饿了么,b站,电商类等项目实战课程(电商类,除开直播外,难度基本在于后端),而关于音视频社交类的项目基本没有,原因是这些项目能很快的展示一个框架项目整体基础的技术要点,这些是入门的开发者所需要的(其实电商类做到后期确实也十分的复杂),而音视频通话项目,需要频繁的后端对接,IM等socket协议,三方音视频框架对接等磨人的过程,不适合做教学类项目,所以市面上的项目实战十分的少.
业务型
  • 什么是业务型,在我看来,就是专注于业务功能,整体APP开发维护的,社交类APP,核心必然是音视频通话,im,但是那么对于一个音视频通讯类APP来说,推流编码,拉流解码,真的是核心功能吗?
  • 整个社交类APP开发还有非常多的音视频业务,前置的im拨打,超时,接听,挂断,拒接,音频通话,视频通话,多人音视频通话,语音直播,视频直播,远近大小窗切换,小窗模式,多人语音直播,视频连麦推流,弹幕,礼物队列,公屏消息,房间成员管理(上麦,禁麦,管理员等权限维护),更不用说其他的杂七杂八各类简单的社交系统(师徒,圈子,好友,关注,黑名单,粉丝,礼物背包,cp,排行榜,情侣等等).
  • 在我看来,推拉流完全不算是核心功能,我也建议,非超大型公司,不要尝试自己去自建编解码库.出于公司的安全防御性考虑,如果公司项目没有稳定的情况下,任何人都是有可能离职的,而对于中小型公司来说,一个核心库的开发阶段,少了一个核心人员,就是一个毁灭打击.而使用三方服务,把推拉流抽象到服务中,有专门的技术人员跟你对接,可以保证这个基础库不会"烂尾",对于我所做的音视频项目来说,推拉流,美颜框架,完全没有必要公司自己去做,真的得不偿失,这一部分的钱是真的有必要花的,
  • agora的最新版本,甚至做好了跟相芯(FaceU)对接的插件化,美颜集成到了自己的音视频库中,而这之前,我们APP本身是自定义视频流,手动获取到相机捕获的视频帧,手动进行相芯的美颜渲染,然后推流到agora.顺便提一句,插件化确实是有必要的,否则,flutter_agora版本的美颜集成,将会完全阻塞.
  • 为什么会开发flutter音视频项目,最主要的原因是,公司同意.在这之前我做了非常多的技术调研,agora的flutter端SDK技术测试,我们公司自己改造的im通讯框架smart_fox的flutter化,都实现了(仅有的一个小问题,就是当时flutter_agora没有实现插件化,阻塞了三方美颜的使用,因为flutter_agora封死了摄像头的使用).在公司允许以及前期技术调研成功的两个因素下,我开始了公司APPflutter化的开发.
  • 从最基本的框架设计,路由,网络,工具库,UI组件封装, 页面编写,json to model, build runner脚本, 到最新的rtm flutter, iOS端通信封装, 音视频UI,agora flutter端SDK接入,我也算是对flutter稍稍入门了.我也稍稍介绍下我个人对flutter的看法,以及想要做好一个flutter音视频项目所需掌握的各项知识.

脚本

  1. 本地资源文件读取,这个可用脚本插件生成,否则pub.yaml配置确实比较烦
  2. json_model化,项目肯定需要数据转模型的,flutter禁用了反射mirror库,日常使用一般都是使用json_annotation注解,build_runner脚本运行,预生成json转化文件.这种编译前的转化.如果是这样,基本没啥好说的,主要的点是,模型数据有可能不是后端发给我们的,也有可能是iOS原生,已经安卓原生通过im发送过来的,所以数据类型有可能会被原生decode,encode修改,事实上我确实碰到了这个问题,在拨打电话中,接收iOS原生发送过来的数据,有些数据类型被修改了,比如int类型被修改成了string,这里在转模型时就会抛出异常,所以我不得不手动转类型,不过,因为是采用正则全局替换,也不算什么太过麻烦的事.


状态管理

  • 数据和逻辑分离,flutter的声明式UI天生就适合做状态管理,技术调研之后,我选择了Get这个框架,网上对这个框架褒贬不一,我大致也明白其争论的点,主要是两点
  1. Get自标榜MOST LISKED的LOGO,这个有点王婆卖瓜的味道.
  2. Get弱化context以及stful的这个行为,这个应该是官方不太喜欢get的原因.
  3. Get太"好用"了,导致部分新手动不动就get,get,完全不关心原生的生命周期,原理等等,导致基础更加薄弱,有些人的无脑使得别的人对这一框架更加反感
  • 但是,我不是人云亦云的人,从iOS转过来,开发了这么多年,总归是有一些判断能力的. get在路由上的使用,非常的方便(原生的路由跳转属实有些麻烦),以及getcontroller,个人认为,iOSer关注的其实就是controller释放问题,解决这个,基本也没啥了
  • 一个小建议就是,如果不熟,建议只用GetBuilder,不要搞太多幺蛾子.

动画管理

  • flutter的动画跟iOS的动画管理有非常大的不同,更多的是和Android相近,关于动画,基础的使用大家基本都会,但是,为了写好项目的框架,建议你认真的记住flutter的显性动画,隐式动画,脑子最好有一个xmind图,分门别类的确定每个动画组件所属的显式动画



    以及隐式动画



    以及动画的差值器(Tween),当然,能够自定义一些动画组件当然更好,
    比如我在做大小窗动画时自定义的一个差值器
class SKPositionTween extends Tween {
  SKPositionTween({required SKPosition begin, required SKPosition end})
      : super(begin: begin, end: end);

  @override
  SKPosition lerp(double t) => SKPosition.lerp(begin!, end!, t);
}

以及差值动画计算SKPosition.lerp(begin!, end!, t);

原生与flutter通信,插件封装

  • 关于flutter通信,这块我在设计im的插件flutter_smart_im中有涉及,以及我在之前的flutter iap苹果内购中也介绍过,主要分为纯原生通信,以及封装原生view,我做的项目不需要封装原生view,更多的是im通信这块.至于插件封装,这块有复杂也有简单的,比如我封装的flutter_smart_im,我一开始是将其封装成三方插件,通过pub引入的,但是,开发阶段,我需要频繁改动这个库(比如增加新的im调用,音视频拨打,接收音视频拨打,发送消息等等),中途我又把这个库放回项目中,不过,开发过程中,需要注意的是,这个库的import 不要有项目中的文件(这一点不得不吐槽Swift的无import设计,真真的恶心人,一个文件,根本不知道他import了多少个文件,在项目抽库时,恶心的要死囧),后续肯定还是要抽成一个framework.
  • 而既然做插件,肯定也涉及原生的framework封装,这里就还要提及的是pod.spec管理,封三方插件,需要你自己会原生pod.spec封装,这一步可是坑不老少的,比如往里塞一个三方的framework,还有各种各样的坑,以后有时间再细说吧
Overlay层级控制

比如弹窗什么的永远要高于直播层级,可以通过权重设置每个overlay的层级



这东西有点向iOS原生window层级控制.


agora管理

三方框架永远建议自己至少封装一层,否则迭代升级会非常的痛苦.


最好能做到业务page中,不需要
import 'package:agora_rtc_engine/rtc_engine.dart';

整体框架把控

  • flutter项目的整体框架,我在之前的文章中已经提过了,这里不再讲了,这里顺便说下iOS原生项目封装,在项目初期,没有稳定的基础类库的时候,建议建立一个target的framework,从开始就做好文件的隔离,做好组件化的基础,这里稍稍给个例子



PS

  • 这篇文章,讲的很杂,我这个,想法很多,有什么就写点什么,比较不成体系,后续可能还会继续增加些杂谈的点,各位看官,图一乐即可.

你可能感兴趣的:(flutter 音视频通话项目的那点事儿)