欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

如何快速构建一个Flutter互动直播应用

程序员文章站 2022-06-10 13:44:33
...

跨平台开发的热度持续上升,为此,即构科技基于Express SDK封装了 Zego Express Engine Flutter SDK ,开发者可以在 Flutter 应用中快速实现稳定、可靠的实时音视频通话、互动直播应用。只需简单的5步,就能构建一个简单的移动跨平台互动直播应用。

一、集成

1、准备环境

请确保开发环境满足以下技术要求:

  • Flutter 1.12 或以上版本,参考 Flutter Get
    Started(https://flutter.dev/docs/get-started/install
  • iOS 8.0或以上版本且支持音视频的 iOS 设备或模拟器(推荐使用真机)
  • Android 版本不低于 4.0.3 且支持音视频的 Android
    设备或模拟器(推荐使用真机),如果是真机,请开启“允许调试”选项。
  • iOS / Android 设备已经连接到 Internet

配置开发环境:

  • Android Studio: Preferences -> Plugins,搜索 Flutter 插件进行下载,在插件中配置第一步下载好的 Flutter SDK 路径。
  • VS Code: 在应用商店中搜索 Flutter 扩展并下载。

以上任一开发环境配置好 Flutter 环境之后,命令行(终端)执行 flutter doctor,根据提示内容补全相关未下载的依赖项。

2、集成SDK

打开工程中的 pubspec.yaml,添加 zego_express_engine 依赖

  • 以 pub 形式依赖(推荐)
dependencies:
  flutter:
  sdk: flutter

  zego_express_engine: ^0.9.0
  • 以 git 形式依赖
dependencies:
  flutter:
  sdk: flutter

  zego_express_engine:
    git:
      url: git://github.com/zegoim/zego-express-flutter-sdk.git
      ref: master

保存文件后,命令行执行 flutter pub get

3、添加权限

Android

打开 app/src/main/AndroidManifest.xml 文件,添加如下内容:
如何快速构建一个Flutter互动直播应用

<!-- SDK 必须使用的权限 -->
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.RECORD_AUDIO" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.BLUETOOTH" />
<uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />

<!-- App 需要使用的部分权限 -->
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.WAKE_LOCK" />

<uses-feature
    android:glEsVersion="0x00020000"
    android:required="true" />

<uses-feature android:name="android.hardware.camera" />
<uses-feature android:name="android.hardware.camera.autofocus" />

请注意:因为 Android 6.0 在一些比较重要的权限上要求必须申请动态权限,不能只通过 AndroidMainfest.xml 文件申请静态权限。因此还需要参考执行如下代码( requestPermissions 是 Activity 的方法)

String[] permissionNeeded = {
        "android.permission.CAMERA",
        "android.permission.RECORD_AUDIO"};

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
    if (ContextCompat.checkSelfPermission(this, "android.permission.CAMERA") != PackageManager.PERMISSION_GRANTED ||
        ContextCompat.checkSelfPermission(this, "android.permission.RECORD_AUDIO") != PackageManager.PERMISSION_GRANTED) {
        requestPermissions(permissionNeeded, 101);
    }
}

iOS

选择项目 TARGETS -> Info -> Custom iOS Target Properties
如何快速构建一个Flutter互动直播应用

点击 + 添加按钮,添加摄像头和麦克风权限。

1.Privacy - Camera Usage Description

2.Privacy - Microphone Usage Description

添加权限完成后如图所示:
如何快速构建一个Flutter互动直播应用

二、初始化

集成 SDK 完成后,要想使用 SDK 的功能,需要先 创建引擎 Engine ,再进一步调用 Engine 提供的各项 API。

1、申请 AppID 与 AppSign
登录 即构管理控制台(https://console.zego.im/account/login) 申请创建引擎需要的 AppID 和 AppSign

2、创建Engine

// 导入
import 'package:zego_express_engine/zego_express_engine.dart';

int appID = ;  // 请通过官网注册获取,格式为:1234567890
String appSign = ;  //请通过官网注册获取,格式为:'0123456789012345678901234567890123456789012345678901234567890123'(共64个字符)

// 创建引擎,使用测试环境,通用场景接入
ZegoExpressEngine.createEngine(appID, appSign, true, ZegoScenario.General);

3、关注事件回调
以根据场景需要,在初始化后监听想要关注的事件通知,比如远端用户加入房间,设备异常事件,音视频首帧等。

调用示例
事件回调皆为 Function 类型的静态属性,直接赋值为一个自己的函数即可收到回调。

// 举例:监听房间内流数量变更的通知
ZegoExpressEngine.onRoomStreamUpdate = (String roomID, ZegoUpdateType updateType, List<ZegoStream> streamList) {
  // ······
};

三、登录房间
完成了创建引擎,在开始音视频通话前,需要先登录房间。

1、登录/登出房间
调用示例:

// 创建用户对象
ZegoUser user = ZegoUser.id('user1');

// 开始登陆房间
ZegoExpressEngine.instance.loginRoom('room1', user);

// 登出房间
ZegoExpressEngine.instance.logoutRoom('room1');

注意:
1.需保证 roomID 信息的全局唯一。
2.userID 与 userName 不能为 null 否则会导致登录房间失败。
3.ZegoUser 的构造方法 ZegoUser.id 会将 userName 设为与传的参数 userID 一样。
4.每个 userID 必须唯一,建议设置成一个有意义的值,开发者可将 userID 与自己业务账号系统进行关联。

2、监听房间相关事件回调
调用示例:

// 以下为常用的房间相关回调

ZegoExpressEngine.onRoomStateUpdate = (String roomID, ZegoRoomState state, int errorCode, Map<String, dynamic> extendedData) {
  // 房间状态更新回调,登陆房间后,当房间连接状态发生变更(如出现房间断开,登陆认证失败等情况),SDK会通过该回调通知
};

ZegoExpressEngine.onRoomUserUpdate = (String roomID, ZegoUpdateType updateType, List<ZegoUser> userList) {
  // 用户状态更新,登陆房间后,当房间内有用户新增或删除时,SDK会通过该回调通知
};

ZegoExpressEngine.onRoomStreamUpdate = (String roomID, ZegoUpdateType updateType, List<ZegoStream> streamList) {
  // 流状态更新,登陆房间后,当房间内有用户新推送或删除音视频流时,SDK会通过该回调通知
};

四、推流
不论是在多人通话还是在秀场直播中,首先都需要推送自己的音视频画面到 ZEGO 云端服务上,对端再通过从 ZEGO 云端服务上拉流,才可以获取到自己的视频画面。

1、开始/停止推流
通过调用开始推流接口 startPublishingStream ,可以向远端用户发送本端的音视频流。如果不需要继续推流,请调用 stopPublishingStream 停止推流。

调用示例:

// 开始推流
ZegoExpressEngine.instance.startPublishingStream('stream1');

// 停止推流
ZegoExpressEngine.instance.stopPublishingStream();

注意:开始推流前,建议开发者在开始推流前对推流参数、本地预览视图进行设置。

ZEGO Express SDK支持丰富的推流参数配置,主要包含:视频帧率/码率/分辨率、音频码率、手机方向、美颜参数、滤镜参数、视频镜像、使用前后置摄像头等等。如果不进行配置,SDK将采用默认配置。

2、启用/停止本地预览(可选)
用户如果希望看到自己本端的画面,可通过调用如下接口设置预览视图,并启动/停止本地预览。

  • 首先需要创建一个预览用的 TextureRenderer(外接纹理)
void createPreviewRenderer() {
     // Create a Texture Renderer
     ZegoExpressEngine.instance.createTextureRenderer(widget.screenWidthPx, widget.screenHeightPx).then((textureID) {

         _previewViewID = textureID;

         setState(() {
             // Create a Texture Widget
             _previewViewWidget = Texture(textureId: textureID);
         });

         // Start preview using texture renderer
         startPreview(textureID);
     });
 }
  • 将上一步得到的 TextureRenderer 的 textureID 作为 viewID 创建一个 ZegoCanvas 对象,开始预览
void startPreview(int viewID) {

     // Set the preview canvas
     ZegoCanvas previewCanvas = ZegoCanvas.view(viewID);

     // Start preview
     ZegoExpressEngine.instance.startPreview(canvas: previewCanvas);
 }

3、使用 PlatformView 预览(可选)
如果希望使用 PlatformView 来渲染预览视图,首先请在创建引擎时设置 enablePlatformView 参数为 true

  • 创建引擎时开启 PlatformView
// 创建引擎,使用测试环境,通用场景接入,开启 PlatformView
 ZegoExpressEngine.createEngine(appID, appSign, true, ZegoScenario.General, enablePlatformView: true);

注意:开启 PlatformView 后,在销毁引擎之前,都只能使用 PlatformView 而不能使用 TextureRenderer,反之亦然。

  • 创建一个 PlatformView
Widget previewViewWidget = ZegoExpressEngine.instance.createPlatformView((viewID) {

     _previewViewID = viewID;

     // Start preview using platform view
     startPreview(viewID);
 });
  • 通过上一步得到的 PlatformView 的 viewID 创建一个 ZegoCanvas 对象,开始预览
void startPreview(int viewID) {

     // Set the preview canvas
     ZegoCanvas previewCanvas = ZegoCanvas.view(viewID);

     // Start preview
     ZegoExpressEngine.instance.startPreview(canvas: previewCanvas);
 }

Flutter 的 PlatformView 占用资源相比外接纹理的方式要高一些,并且不够稳定,但鲁棒性随着 Flutter 版本的迭代也在不断提高,请开发者酌情考虑使用何种渲染方式。目前 SDK 的默认渲染方式为 TextureRenderer(外接纹理)

4、监听推流相关事件通知
示例:

ZegoExpressEngine.onPublisherStateUpdate = (String streamID, ZegoPublisherState state, int errorCode, Map<String, dynamic> extendedData) {
    // 调用推流接口成功后,当推流器状态发生变更,如出现网络中断导致推流异常等情况,SDK在重试推流的同时,会通过该回调通知
};

五、拉流
不论是在多人通话还是在秀场直播中,需要通过拉流功能在 ZEGO 服务上进行拉流,如此才能获取到远端主播推送的音视频画面。

1、开始/停止拉流
调用 startPlayingStream 进行拉流,如果不需要继续拉流,请调用 stopPlayingStream 停止拉流。

  • 首先创建一个显示拉流画面用的 TextureRenderer(外接纹理)
// Create a Texture Renderer
 ZegoExpressEngine.instance.createTextureRenderer(widget.screenWidthPx, widget.screenHeightPx).then((textureID) {

     _playViewID = textureID;

     setState(() {
         // Create a Texture Widget
         _playViewWidget = Texture(textureId: textureID);
     });

     // Start playing stream using texture renderer
     startPlayingStream(textureID, streamID);
 });
  • 将上一步得到的 TextureRenderer 的 textureID 作为 viewID 创建一个 ZegoCanvas 对象,开始拉流
void startPlayingStream(int viewID, String streamID) {
     setState(() {

         // Set the play canvas
         _playCanvas = ZegoCanvas.view(viewID);

         // Start playing stream
         ZegoExpressEngine.instance.startPlayingStream(streamID, canvas: _playCanvas);
     });
 }

注意:
1.流名需要在整个 AppID 内全局唯一。
2.远端用户推送的 streamID 可以从 onRoomStreamUpdate 回调中获得。

2、使用 PlatformView 渲染拉流画面(可选)
如果希望使用 PlatformView 来渲染拉流画面,首先请在创建引擎时设置 enablePlatformView 参数为 true

  • 创建引擎时开启 PlatformView
// 创建引擎,使用测试环境,通用场景接入,开启 PlatformView
 ZegoExpressEngine.createEngine(appID, appSign, true, ZegoScenario.General, enablePlatformView: true);

注意:开启 PlatformView 后,在销毁引擎之前,都只能使用 PlatformView 而不能使用 TextureRenderer,反之亦然。

  • 创建一个 PlatformView
Widget playViewWidget = ZegoExpressEngine.instance.createPlatformView((viewID) {

     _playViewID = viewID;

     // Start playing stream using platform view
     startPlayingStream(viewID, streamID);
 });
  • 通过上一步得到的 PlatformView 的 viewID 创建一个 ZegoCanvas 对象,开始拉流
void startPlayingStream(int viewID, String streamID) {
     setState(() {

         // Set the play canvas
         _playCanvas = ZegoCanvas.view(viewID);

         // Start playing stream
         ZegoExpressEngine.instance.startPlayingStream(streamID, canvas: _playCanvas);
     });
 }

Flutter 的 PlatformView 占用资源相比外接纹理的方式要高一些,并且不够稳定,但鲁棒性随着 Flutter 版本的迭代也在不断提高,请开发者酌情考虑使用何种渲染方式。目前 SDK 的默认渲染方式为 TextureRenderer(外接纹理)

3、监听拉流相关事件通知(可选)
示例:

ZegoExpressEngine.onPlayerStateUpdate = (String streamID, ZegoPlayerState state, int errorCode, Map<String, dynamic> extendedData) {
    // 调用拉流接口成功后,当拉流器状态发生变更,如出现网络中断导致推流异常等情况,SDK在重试拉流的同时,会通过该回调通知
};

通过上面的五步,就可以基于 ZEGO SDK来快速构建一个简单的移动跨平台互动直播应用。点击下方链接,可以下载示例源码:https://github.com/zegoim/zego-express-flutter-sdk