如何快速构建一个Flutter互动直播应用
跨平台开发的热度持续上升,为此,即构科技基于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 文件,添加如下内容:
<!-- 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
点击 + 添加按钮,添加摄像头和麦克风权限。
1.Privacy - Camera Usage Description
2.Privacy - Microphone Usage Description
添加权限完成后如图所示:
二、初始化
集成 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
下一篇: 引用类型之RegExp类型