Flutter实时音视频通信插件volc_engine_rtc的使用

发布于 1周前 作者 wuwangju 来自 Flutter

Flutter实时音视频通信插件volc_engine_rtc的使用

火山引擎实时音视频 SDK 的 Flutter 插件包

此 Flutter 插件是对 火山引擎实时音视频 SDK 的包装。

如何使用

设备权限

火山引擎实时音视频 SDK 需要获取 相机麦克风 权限来开始视频通话。

iOS

打开 Info.plist 文件并且添加:

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

如果启用了后台模式,则应用程序在切换到后台时仍可以运行语音呼叫。在 Xcode 中选择应用目标,单击 Capabilities 选项卡,启用 Background Modes,然后选中 Audio, AirPlay, and Picture in Picture

更改 Podfile 来设置 火山引擎实时音视频 SDK 的仓库源:

source 'https://github.com/volcengine/volcengine-specs.git'

Android

VolcEngineRTC 已经声明了必要的权限,会合并到 AndroidManifest.xml 中。

代码许可

本项目遵守 MIT license

示例代码

以下是一个简单的示例,展示了如何使用 volc_engine_rtc 插件创建一个基本的实时音视频通信应用。

项目结构

lib/
├── main.dart
└── login_page.dart

main.dart

// Copyright (c) 2022 Beijing Volcano Engine Technology Ltd.
// SPDX-License-Identifier: MIT

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

void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) => MaterialApp(
        theme: ThemeData(
          primarySwatch: Colors.blue,
        ),
        home: const LoginPage(),
      );
}

login_page.dart

// Copyright (c) 2022 Beijing Volcano Engine Technology Ltd.
// SPDX-License-Identifier: MIT

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

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

  @override
  _LoginPageState createState() => _LoginPageState();
}

class _LoginPageState extends State<LoginPage> {
  final TextEditingController _roomController = TextEditingController();
  final TextEditingController _tokenController = TextEditingController();

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('登录'),
      ),
      body: Padding(
        padding: const EdgeInsets.all(16.0),
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            TextField(
              controller: _roomController,
              decoration: const InputDecoration(labelText: '房间号'),
            ),
            TextField(
              controller: _tokenController,
              decoration: const InputDecoration(labelText: 'Token'),
            ),
            ElevatedButton(
              onPressed: () async {
                String room = _roomController.text;
                String token = _tokenController.text;

                if (room.isNotEmpty && token.isNotEmpty) {
                  await VolcEngineRTC().joinRoom(room, token);
                  Navigator.pushReplacement(
                    context,
                    MaterialPageRoute(builder: (context) => const RoomPage(room: room)),
                  );
                } else {
                  ScaffoldMessenger.of(context).showSnackBar(
                    const SnackBar(content: Text('请输入房间号和Token')),
                  );
                }
              },
              child: const Text('加入房间'),
            ),
          ],
        ),
      ),
    );
  }
}

room_page.dart

// Copyright (c) 2022 Beijing Volcano Engine Technology Ltd.
// SPDX-License-Identifier: MIT

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

class RoomPage extends StatefulWidget {
  final String room;

  const RoomPage({Key? key, required this.room}) : super(key: key);

  @override
  _RoomPageState createState() => _RoomPageState();
}

class _RoomPageState extends State<RoomPage> {
  late VolcEngineRTC _volcEngineRTC;

  @override
  void initState() {
    super.initState();
    _volcEngineRTC = VolcEngineRTC();
    _volcEngineRTC.setEventHandler(VolcEngineRTCEventHandler(
      onUserJoined: (userId) {
        setState(() {
          // 更新UI
        });
      },
      onUserLeft: (userId) {
        setState(() {
          // 更新UI
        });
      },
    ));
  }

  @override
  void dispose() {
    _volcEngineRTC.leaveRoom();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('房间 ${widget.room}'),
      ),
      body: Center(
        child: ElevatedButton(
          onPressed: () {
            _volcEngineRTC.leaveRoom();
            Navigator.pop(context);
          },
          child: const Text('离开房间'),
        ),
      ),
    );
  }
}

说明

  1. main.dart: 这是应用的入口点,创建了一个 MyApp 小部件,设置了主题并显示了登录页面。
  2. login_page.dart: 登录页面包含两个输入框,分别用于输入房间号和 Token。点击“加入房间”按钮后,会调用 VolcEngineRTC().joinRoom 方法加入房间,并导航到房间页面。
  3. room_page.dart: 房间页面显示当前房间的信息,并提供一个按钮用于离开房间。在 initState 方法中,设置了 VolcEngineRTC 的事件处理器,以便在用户加入或离开房间时更新 UI。

通过以上步骤,您可以快速搭建一个基于 volc_engine_rtc 插件的实时音视频通信应用。希望这对您有所帮助!


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

1 回复

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


当然,以下是一个关于如何在Flutter项目中集成和使用volc_engine_rtc插件来实现实时音视频通信的示例代码。这个插件通常用于实现类似于视频会议或即时通讯应用中的音视频通话功能。

1. 添加依赖

首先,你需要在你的pubspec.yaml文件中添加volc_engine_rtc依赖。

dependencies:
  flutter:
    sdk: flutter
  volc_engine_rtc: ^最新版本号  # 请替换为实际可用的最新版本号

2. 导入插件

在你的Dart文件中,导入volc_engine_rtc插件。

import 'package:volc_engine_rtc/volc_engine_rtc.dart';

3. 初始化RTC引擎

在应用的入口文件(通常是main.dart)中初始化RTC引擎。

void main() async {
  WidgetsFlutterBinding.ensureInitialized();
  await VolcEngineRtc.init({
    'appKey': '你的AppKey',  // 请替换为你的实际AppKey
  });
  runApp(MyApp());
}

4. 创建RTC房间并加入

在你的应用逻辑中,创建并加入RTC房间。

class MyApp extends StatefulWidget {
  @override
  _MyAppState createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  VolcEngineRtcEngine? _engine;
  String _roomId = 'test_room';

  @override
  void initState() {
    super.initState();
    initEngine();
  }

  void initEngine() async {
    _engine = await VolcEngineRtcEngine.create(config: {
      'appId': '你的AppId',  // 通常与AppKey相关
      'channelProfile': VolcEngineRtcChannelProfile.Communication,  // 通信模式
    });

    _engine!.onJoinChannelSuccess = (channel, uid, elapsed) {
      print("Joined channel: $channel, uid: $uid");
    };

    _engine!.onUserJoined = (uid, elapsed) {
      print("User joined: $uid");
    };

    // 其他回调可以根据需要添加

    await _engine!.joinChannel(
      token: '',  // 如果有token认证,请填写
      channelId: _roomId,
      uid: 0,  // 用户ID,通常是从服务器获取的
      options: VolcEngineRtcJoinChannelOptions()
    );
  }

  @override
  void dispose() {
    _engine?.destroy();
    _engine = null;
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: Text('Flutter RTC Demo'),
        ),
        body: Center(
          child: Text('Joining channel: $_roomId'),
        ),
      ),
    );
  }
}

5. 处理音视频数据

你可以根据需要处理音视频数据,例如渲染远程视频流。以下是一个简单的例子,展示如何在Flutter中渲染远程视频。

import 'package:flutter/material.dart';
import 'package:volc_engine_rtc_ui/volc_engine_rtc_ui.dart';  // 假设有一个UI插件来处理渲染

// ...

class VideoCallScreen extends StatefulWidget {
  @override
  _VideoCallScreenState createState() => _VideoCallScreenState();
}

class _VideoCallScreenState extends State<VideoCallScreen> {
  final Map<int, RTCVideoView?> remoteViews = {};

  @override
  void initState() {
    super.initState();
    _engine!.onRemoteVideoStateChanged = (uid, state, reason, elapsed) {
      if (state == VolcEngineRtcRemoteVideoStateState.Started) {
        // 创建RTCVideoView来渲染远程视频
        RTCVideoView? view = RTCVideoView();
        _engine!.setupRemoteVideo(view: view, uid: uid);
        setState(() {
          remoteViews[uid] = view;
        });
      } else if (state == VolcEngineRtcRemoteVideoStateState.Stopped) {
        setState(() {
          remoteViews.remove(uid);
        });
      }
    };
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Stack(
        children: [
          // 本地视频渲染(如果有)
          // 你可以使用RTCVideoView来渲染本地视频流
          // ...

          // 远程视频渲染
          ...remoteViews.values.map((view) =>
            Positioned(
              top: 0,
              left: 0,
              child: Container(
                width: double.infinity,
                height: double.infinity,
                child: view!,
              ),
            )
          ).toList(),
        ],
      ),
    );
  }
}

请注意,上面的RTCVideoViewvolc_engine_rtc_ui是假设存在的UI插件,实际使用时你可能需要自己实现UI渲染逻辑或使用其他现有的UI库。

总结

以上代码展示了如何在Flutter项目中集成volc_engine_rtc插件,并进行基本的RTC初始化、房间加入和远程视频渲染。实际应用中,你可能需要处理更多的回调和逻辑,比如音频管理、用户管理、网络状态管理等。建议详细阅读volc_engine_rtc的官方文档和API参考,以充分利用其功能。

回到顶部