您当前的位置是:  首页 > 新闻 > 国内 >
 首页 > 新闻 > 国内 >

Flutter + WebRTC:Agora Flutter SDK 设计实践

2019-02-20 09:24:37   作者:郝阳,声网Agora Web工程师   来源:CTI论坛   评论:0  点击:


  应开发者们的需求,我们在上周推出了 Agora Flutter SDK,它以Flutter Plugin的形式为Flutter App增添实时音视频能力。考虑到Flutter对于部分开发者来讲,仍是个新鲜事物。所以,我们也分享了来自RTC开发者社区作者的Flutter开发经验。其实,在开发AgoraFlutterSDK之初,我们的技术团队也就如何基于Flutter实现实时音视频,深入做过一番调研。本文将就调研的过程和成果,为大家分享一些我们的经验。
  Flutter如何调用原生代码
  我们要做的是在Flutter上实现实时音视频。那么在开始具体的工作之前,首先需要了解Flutter是如何调用诸如“获取媒体设备”这类原生平台API的。
  上方来自官方的架构图已经足够清晰了,Flutter通过MethodChannel发起某一方法的调用,然后原生平台收到消息后执行相应的实现(Java/Kotlin/Swift/Object-C)并异步地返回结果,以getUserMedia为示例,首先在Flutter层中声明这一方法,具体实现则是通过MethodChannel发送一条携带调用方法名和相应参数的信息。
  Future表示一个异步的调用,类似Javascript的Promise;async/await类似,在一个async函数中,会类似同步地按顺序去执行await方法,尽管await后面的是异步方法。
  当平台在MainActivity中同样注册MethodChannel,通过MethodChannel收到方法调用的消息和参数后,基于本平台实现相应逻辑,并返回执行结果,此处仅以Android平台为例:

  更多详细的信息可以参考Flutter官方示例与解释:
  https://flutter.io/docs/development/platform-integration/platform-channels
  实现音视频SDK的思路
  了解上述Flutter调用原生平台方法的原理后,我们就有两种思路来实现一个音视频SDK。
  1.先在原生平台实现音视频SDK,后Flutter通过MethodChannel直接调用SDK提供的方法。
  具体的方案为直接通过MethodChannel调用已有的声网AgoraSDK,并在Flutter层抹去可能存在的差异,诸如参数不同、部分方法名不同。
  这种做法的主要优点在于可以最大程度复用已有的SDK,类似于建立了一层桥接。
  2.先基于原生平台实现WebRTC标准,然后在Flutter层通过MethodChannel调用WebRTC接口,再实现音视频SDK逻辑。
  这种方案先利用原生平台实现WebRTC标准(前一节实现的getUserMedia就是此标准的一部分),然后在Flutter层注册为WebRTCPlugin。在这个FlutterWebRTCPlugin的基础上参照声网音视频SDK,连接到AgoraSD-RTN?全球虚拟通讯网络。
  这种方案相比前一点,相当于实现一个全新的Dart语言的SDK,需要用到更多Dart的标准库(诸如math、io、convert之类)与第三方生态(如(flutter_webrtc)。假设要支持更多的平台时(比如Windows),只需要该平台实现WebRTC标准就可以直接使用。
  熟悉WebRTC的同学们可能知道在实现浏览器WebRTC应用的时候有一个Adapter的概念,目的就是为了掩藏几大主流浏览器WebRTC接口的些许差异,和本方案的思路是类似的,只不过适配的平台从Firefox/Chrome/Safari变为了Windows/iOS/Android等。
  最终出于调研的目的,同时也是为了更加迎合Flutter一套代码,多平台通用的思想(理论上SDK就是一层设计完备的客户端逻辑,在WebRTC受良好支持的情况下,工作的内容就变为:如何使用Dart语言在WebRTC的标准上实现音视频通信逻辑),我们选择采用这个方案,因此读者可能会发现这个FlutterSDK整体上不少概念上更接近于声网Web平台的音视频SDK一些。
  3.SDK的结构
  SDK的主要功能大致包含了音视频采集与播放,与AgoraGateway建立P2P连接并管理,以及与Gateway之间的消息交换和处理。
  虽然Flutter社区相对较新,但是Dart的标准库可以算得上是非常完备了,同时也已经有不少优秀的第三方Plugin。
  代码可以主要拆分为以下模块:
  基于dart:io中Websocket相关的方法实现与Gateway之间的消息通信(比如publish/subscribe这类消息和回复)
  基于开源社区的flutter_webrtc项目实现音视频采集以及p2p连接等WebRTC相关功能
  基于dartStream对象或是简单的Map来实现EventEmitter这些SDK所需的辅助类(当然也可以直接采用Dart的Stream/Sink概念进行替代)。
  这些模块完成后,在此之上就可以实现类似声网WebSDK中的Client与Stream对象。
  其中值得一说的是视频流的播放,可以借助flutter_webrtcplugin中的RTCVideoView对象来实现,想要深入了解具体原理的可以学习一下Flutter外接纹理(Texture)相关概念。
  到此SDK就已经基本形成了,之后便是UI层的开发,Flutter这一部分很大程度上受到了React框架的启发,熟悉该框架的Web开发者可以基于此SDK轻松的实现一个可运行在Android/iOS平台的视频通话App。我们此前分享过的demo已经成功和已有的声网Android/iOS/WebSDK进行互通,相应的代码也许将在不久未来进行开源。
  4.总结
  尽管Flutter社区仍然很年轻,但是已经逐渐有不少优秀的第三方插件涌现出来,加上Dart相对全面的标准库,实现这样一个音视频SDK或是类似的功能并不需要自己大量地去造轮子,加上Flutter本身环境搭建/构建/调试都非常的方便,因此整个开发过程中几乎没有遇到什么坑。
  此外在应用层的开发过程中,风格非常接近于使用React进行Web开发,加上Flutter亚秒级的HotReload等特性,在开发体验与效率上相比原生开发确实有着不小的优势。
  再考虑到逐渐完善的跨平台特性(桌面端的flutter-desktop-embedding项目与浏览器端的hummingbird项目)以及可能会到来的谷歌新操作系统Fuchsia,对于无论是想要接触到原生开发的Web开发者,还是追求更高的开发效率和更好的开发体验的原生开发者来说,Flutter都是一个非常适宜的切入角度,值得在新的一年里加入自己的技术栈中。
【免责声明】本文仅代表作者本人观点,与CTI论坛无关。CTI论坛对文中陈述、观点判断保持中立,不对所包含内容的准确性、可靠性或完整性提供任何明示或暗示的保证。请读者仅作参考,并请自行承担全部责任。

专题

CTI论坛会员企业