今天要開始在Flutter的專案內使用Agora
flutter pub add agora_rtc_engine
flutter pub add permission_handler
android 設定
開啟android->build.gradle
allprojects {
repositories {
maven { url 'https://www.jitpack.io' }
}
}
開啟android->app->src->main->AndroidManifest.xml
<uses-permission android:name="android.permission.READ_PHONE_STATE"/>
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.RECORD_AUDIO" />
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<!-- The Agora SDK requires Bluetooth permissions in case users are using Bluetooth devices.-->
<uses-permission android:name="android.permission.BLUETOOTH" />
ios 設定
開啟ios->Runner->info.plist
<key>NSCameraUsageDescription</key>
<string>This app requires permission to access camera to scan qrcode</string>
<key>NSMicrophoneUsageDescription</key>
<string>This app requires permission to access microphone</string>
取得appId
設定臨時的channel及token
建立agora_screen.dart
我在這邊有特別將uid改為random的數值,讓大家能夠方便同時執行兩隻實體機有接通的畫面
import 'dart:math';
import 'package:agora_rtc_engine/agora_rtc_engine.dart';
import 'package:flutter/material.dart';
import 'package:permission_handler/permission_handler.dart';
const appId = "請輸入appId";
const token = "請輸入token";
const channel = "請輸入channel";
class AgoraScreen extends StatefulWidget {
const AgoraScreen({Key? key}) : super(key: key);
@override
State<AgoraScreen> createState() => _AgoraScreenState();
}
class _AgoraScreenState extends State<AgoraScreen> {
int? _remoteUid;
bool _localUserJoined = false;
late RtcEngine _engine;
@override
void initState() {
super.initState();
initAgora();
}
Future<void> initAgora() async {
// retrieve permissions
await [Permission.microphone, Permission.camera].request();
//create the engine
_engine = createAgoraRtcEngine();
await _engine.initialize(const RtcEngineContext(
appId: appId,
channelProfile: ChannelProfileType.channelProfileLiveBroadcasting,
));
_engine.registerEventHandler(
RtcEngineEventHandler(
onJoinChannelSuccess: (RtcConnection connection, int elapsed) {
debugPrint("local user ${connection.localUid} joined");
setState(() {
_localUserJoined = true;
});
},
onUserJoined: (RtcConnection connection, int remoteUid, int elapsed) {
debugPrint("remote user $remoteUid joined");
setState(() {
_remoteUid = remoteUid;
});
},
onUserOffline: (RtcConnection connection, int remoteUid, UserOfflineReasonType reason) {
debugPrint("remote user $remoteUid left channel");
setState(() {
_remoteUid = null;
});
},
onTokenPrivilegeWillExpire: (RtcConnection connection, String token) {
debugPrint('[onTokenPrivilegeWillExpire] connection: ${connection.toJson()}, token: $token');
},
),
);
await _engine.setClientRole(role: ClientRoleType.clientRoleBroadcaster);
await _engine.enableVideo();
await _engine.startPreview();
Random random = Random();
int uid = random.nextInt(100);
await _engine.joinChannel(
token: token,
channelId: channel,
uid: uid,
options: const ChannelMediaOptions(),
);
}
// Create UI with local view and remote view
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Agora Video Call'),
),
body: Stack(
children: [
Center(
child: _remoteVideo(),
),
Align(
alignment: Alignment.topLeft,
child: SizedBox(
width: 100,
height: 150,
child: Center(
child: _localUserJoined
? AgoraVideoView(
controller: VideoViewController(
rtcEngine: _engine,
canvas: const VideoCanvas(uid: 0),
),
)
: const CircularProgressIndicator(),
),
),
),
],
),
);
}
// Display remote user's video
Widget _remoteVideo() {
if (_remoteUid != null) {
return AgoraVideoView(
controller: VideoViewController.remote(
rtcEngine: _engine,
canvas: VideoCanvas(uid: _remoteUid),
connection: const RtcConnection(channelId: channel),
),
);
} else {
return const Text(
'Please wait for remote user to join',
textAlign: TextAlign.center,
);
}
}
}
執行的時候要記得用實體機去跑,iPhone虛擬器無法模擬、Android的模擬器上會有奇怪的圖案
未接通Agora畫面
成功接通Agora畫面
兩支手機接通畫面