Flutter视频会议插件oa_agora_video的使用

Flutter视频会议插件oa_agora_video的使用

oa_agora_videocall 插件是一个用于将视频通话功能集成到 Flutter 应用程序中的包。它提供了一个简单且可定制的解决方案,用于添加视频通话功能到您的 Flutter 应用程序中。该插件包括如静音音频/视频、查看参与者以及向正在进行的通话中添加新参与者等功能。

特性

  • 将视频通话功能集成到您的 Flutter 应用程序中。
  • 根据您的应用程序设计自定义视频通话界面。
  • 在通话期间静音/取消静音音频。
  • 在通话期间暂停/播放视频。
  • 查看参与者的视频流。
  • 向正在进行的通话中添加新的参与者。

开始使用

AndroidManifest.xml 文件中,确保包含以下权限:

<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.READ_PHONE_STATE"/>
<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_WIFI_STATE" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />

<!-- 如果用户使用蓝牙设备,Agora SDK 需要蓝牙权限 -->
<uses-permission android:name="android.permission.BLUETOOTH" />
<!-- 对于 Android 12 及以上设备,还需要以下权限 -->
<uses-permission android:name="android.permission.BLUETOOTH_CONNECT" />

对于 iOS/macOS:

打开 Info.plist 并添加:

Privacy - Microphone Usage Description,并在 Value 列中添加描述。
Privacy - Camera Usage Description,并在 Value 列中添加描述。

pubspec.yaml 文件中添加依赖项:

dependencies:
  oa_agora_videocall: ^x.x.x
  agora_rtc_engine: ^x.x.x
  permission_handler: ^x.x.x

替换 ^x.x.x 为最新版本的包。

使用示例

import 'package:flutter/material.dart';
import 'package:oa_agora_video/oa_agora_video.dart';
import 'package:agora_rtc_engine/agora_rtc_engine.dart';
import 'package:permission_handler/permission_handler.dart';

class VideoPackage extends StatefulWidget {
  const VideoPackage({Key? key}) : super(key: key);

  [@override](/user/override)
  State<VideoPackage> createState() => _VideoPackageState();
}

const appId = "Your app id";
const gettoken = "Your token";
const channelname = "Your channel name";

class _VideoPackageState extends State<VideoPackage> {
  int? _remoteUid;
  bool _localUserJoined = false;
  bool _muteLocalAudio = false;
  bool _muteLocalVideo = false;
  late RtcEngine _engine;

  [@override](/user/override)
  void initState() {
    super.initState();
    initAgora();
  }

  Future<void> initAgora() async {
    await [Permission.microphone, Permission.camera].request();

    _engine = createAgoraRtcEngine();
    await _engine.initialize(const RtcEngineContext(
      appId: appId,
      channelProfile: ChannelProfileType.channelProfileLiveBroadcasting,
    ));

    _engine.registerEventHandler(
      RtcEngineEventHandler(
        onJoinChannelSuccess: (RtcConnection connection, int elapsed) {
          debugPrint("Host ${connection.localUid} joined");
          setState(() {
            _localUserJoined = true;
          });
        },
        onUserJoined: (RtcConnection connection, int remoteUid, int elapsed) {
          debugPrint("New user $remoteUid joined");
          setState(() {
            _remoteUid = remoteUid;
          });
        },
        onUserOffline: (RtcConnection connection, int remoteUid, UserOfflineReasonType reason) {
          debugPrint("New user $remoteUid left channel");
          setState(() {
            _remoteUid = null;
          });
        },
        onTokenPrivilegeWillExpire: (RtcConnection connection, String token) {
          debugPrint('[onTokenPrivilegeWillExpire] connection: ${connection.toJson()}, token: ${gettoken}');
        },
      ),
    );

    await _engine.setClientRole(role: ClientRoleType.clientRoleBroadcaster);
    await _engine.enableVideo();
    await _engine.startPreview();

    await _engine.joinChannel(
      token: gettoken,
      channelId: channelname,
      uid: 0,
      options: const ChannelMediaOptions(),
    );
  }

  [@override](/user/override)
  void dispose() {
    super.dispose();
    _dispose();
  }

  Future<void> _dispose() async {
    await _engine.leaveChannel();
    await _engine.release();
  }

  void _toggleMuteLocalAudio() {
    setState(() {
      _muteLocalAudio = !_muteLocalAudio;
    });
    _engine.muteLocalAudioStream(_muteLocalAudio);
  }

  void _toggleMuteLocalVideo() {
    setState(() {
      _muteLocalVideo = !_muteLocalVideo;
    });

    if (_muteLocalVideo) {
      _engine.enableLocalVideo(false);
    } else {
      _engine.enableLocalVideo(true);
    }
  }

  [@override](/user/override)
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('OASolutions Video Call'),
        backgroundColor: Colors.blue, // 更改背景颜色
      ),
      body: Column(
        crossAxisAlignment: CrossAxisAlignment.stretch,
        children: [
          Expanded(
            child: 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),
                              ),
                            )
                          : CircularProgressIndicator(),
                    ),
                  ),
                ),
              ],
            ),
          ),
          Padding(
            padding: const EdgeInsets.all(16.0),
            child: Row(
              mainAxisAlignment: MainAxisAlignment.spaceEvenly,
              children: [
                // 查看参与者详情
                IconButton(
                  icon: Icon(Icons.person),
                  onPressed: () {
                    // 添加参与者详情功能
                  },
                ),

                // 向通话中添加新参与者
                IconButton(
                  icon: Icon(Icons.add_box),
                  onPressed: () {
                    // 添加添加新参与者的功能
                  },
                ),

                IconButton(
                  icon: Icon(_muteLocalAudio ? Icons.mic_off : Icons.mic),
                  onPressed: _toggleMuteLocalAudio,
                ),
                IconButton(
                  icon: Icon(_muteLocalVideo ? Icons.pause : Icons.play_arrow), // 更改图标
                  onPressed: _toggleMuteLocalVideo,
                ),
              ],
            ),
          ),
        ],
      ),
    );
  }

  Widget _remoteVideo() {
    if (_remoteUid != null) {
      return AgoraVideoView(
        controller: VideoViewController.remote(
          rtcEngine: _engine,
          canvas: VideoCanvas(uid: _remoteUid),
          connection: RtcConnection(channelId: channelname),
        ),
      );
    } else {
      return const Center(
        child: Text(
          '等待其他用户加入',
          textAlign: TextAlign.center,
        ),
      );
    }
  }
}

更多关于Flutter视频会议插件oa_agora_video的使用的实战教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter视频会议插件oa_agora_video的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


oa_agora_video 是一个基于 Agora 视频 SDK 的 Flutter 插件,用于在 Flutter 应用中实现视频会议功能。以下是如何使用 oa_agora_video 插件的详细步骤。

1. 添加依赖

首先,在 pubspec.yaml 文件中添加 oa_agora_video 插件的依赖:

dependencies:
  flutter:
    sdk: flutter
  oa_agora_video: ^1.0.0  # 请使用最新版本

然后运行 flutter pub get 以安装依赖。

2. 初始化 Agora SDK

在使用 oa_agora_video 插件之前,需要初始化 Agora SDK。通常,你需要在应用的启动时进行初始化。

import 'package:oa_agora_video/oa_agora_video.dart';

void initializeAgora() async {
  await OaAgoraVideo.initialize(appId: 'YOUR_AGORA_APP_ID');
}

3. 加入频道

在初始化之后,你可以通过调用 joinChannel 方法来加入一个视频会议频道。

void joinChannel() async {
  await OaAgoraVideo.joinChannel(
    token: 'YOUR_AGORA_TOKEN',
    channelName: 'YOUR_CHANNEL_NAME',
    uid: 0, // 用户 ID,0 表示自动分配
  );
}

4. 显示本地和远程视频

oa_agora_video 插件提供了 AgoraVideoView 组件,用于显示本地和远程视频。

import 'package:flutter/material.dart';
import 'package:oa_agora_video/oa_agora_video.dart';

class VideoCallScreen extends StatelessWidget {
  [@override](/user/override)
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Video Call'),
      ),
      body: Column(
        children: [
          // 显示本地视频
          Expanded(
            child: AgoraVideoView(
              uid: 0, // 本地用户的 UID
            ),
          ),
          // 显示远程视频
          Expanded(
            child: AgoraVideoView(
              uid: 1, // 远程用户的 UID
            ),
          ),
        ],
      ),
    );
  }
}

5. 离开频道

当用户想要退出视频会议时,可以调用 leaveChannel 方法。

void leaveChannel() async {
  await OaAgoraVideo.leaveChannel();
}

6. 处理事件

oa_agora_video 插件还提供了一些事件监听器,例如用户加入、离开频道等。

OaAgoraVideo.onUserJoined = (int uid) {
  print('User joined: $uid');
};

OaAgoraVideo.onUserOffline = (int uid) {
  print('User left: $uid');
};

7. 权限配置

确保在 AndroidManifest.xmlInfo.plist 中添加必要的权限配置。

AndroidManifest.xml:

<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" />

Info.plist:

<key>NSCameraUsageDescription</key>
<string>需要访问摄像头以进行视频通话</string>
<key>NSMicrophoneUsageDescription</key>
<string>需要访问麦克风以进行音频通话</string>

8. 释放资源

在应用退出时,释放 Agora SDK 的资源。

void disposeAgora() async {
  await OaAgoraVideo.dispose();
}

9. 完整示例

以下是一个完整的示例,展示了如何使用 oa_agora_video 插件实现一个简单的视频会议功能。

import 'package:flutter/material.dart';
import 'package:oa_agora_video/oa_agora_video.dart';

void main() async {
  WidgetsFlutterBinding.ensureInitialized();
  await OaAgoraVideo.initialize(appId: 'YOUR_AGORA_APP_ID');
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  [@override](/user/override)
  Widget build(BuildContext context) {
    return MaterialApp(
      home: VideoCallScreen(),
    );
  }
}

class VideoCallScreen extends StatefulWidget {
  [@override](/user/override)
  _VideoCallScreenState createState() => _VideoCallScreenState();
}

class _VideoCallScreenState extends State<VideoCallScreen> {
  [@override](/user/override)
  void initState() {
    super.initState();
    joinChannel();
  }

  void joinChannel() async {
    await OaAgoraVideo.joinChannel(
      token: 'YOUR_AGORA_TOKEN',
      channelName: 'YOUR_CHANNEL_NAME',
      uid: 0,
    );
  }

  void leaveChannel() async {
    await OaAgoraVideo.leaveChannel();
  }

  [@override](/user/override)
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Video Call'),
      ),
      body: Column(
        children: [
          Expanded(
            child: AgoraVideoView(
              uid: 0,
            ),
          ),
          Expanded(
            child: AgoraVideoView(
              uid: 1,
            ),
          ),
        ],
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: leaveChannel,
        child: Icon(Icons.call_end),
      ),
    );
  }

  [@override](/user/override)
  void dispose() {
    OaAgoraVideo.dispose();
    super.dispose();
  }
}
回到顶部