Flutter音频通信插件dolbyio_comms_sdk_flutter的使用

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

Flutter音频通信插件 dolbyio_comms_sdk_flutter 的使用

Dolby.io Communications SDK for Flutter 允许创建高质量的视频会议应用程序。通过Flutter,您可以编写单一代码库,并在多个平台上本地编译和使用这些代码来构建、测试和部署应用程序。当前,Flutter SDK支持为iOS和Android设备创建应用程序。

快速开始

您可以在GitHub上访问Flutter SDK的发布版本。为了快速入门,请遵循GitHub上的入门项目指南。这个入门项目解释了如何为移动设备创建一个基本的仅限音频的会议应用,并为您的解决方案(如事件、协作、教育或直播)提供了基础。

如果您需要Flutter开发的帮助,请参阅Flutter文档

前提条件

确保您已准备好以下内容:

  • 一个Dolby.io账户。如果没有账户,可以免费注册
  • iOS或Android设备或模拟器
  • Flutter SDK 3.0.3或更高版本,配置为可在iOS和Android上工作
  • Android Studio用于Android开发
  • Xcode和CocoaPods用于iOS开发
  • Dolby.io仪表板复制的客户端访问令牌

要检查是否需要安装任何额外的依赖项以完成设置,请使用flutter doctor命令(macOSWindows)。

有关iOS SDK和Android SDK的要求,请参阅支持环境文档。

示例代码

下面是一个完整的示例demo,展示了如何使用dolbyio_comms_sdk_flutter插件实现音频会议功能。

import 'package:permission_handler/permission_handler.dart';
import 'package:dolbyio_comms_sdk_flutter/dolbyio_comms_sdk_flutter.dart';
import 'package:flutter/material.dart';
import 'package:collection/collection.dart';
import 'dart:async';
import 'dart:math';

void main() {
  runApp(const MaterialApp(home: FlutterScreen()));
}

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

  [@override](/user/override)
  State<FlutterScreen> createState() => _FlutterScreenState();
}

class _FlutterScreenState extends State<FlutterScreen> {
  final dolbyioCommsSdk = DolbyioCommsSdk.instance;
  TextEditingController usernameController = TextEditingController();
  TextEditingController conferenceNameController = TextEditingController();
  String accessToken = ''; // 替换为您自己的Dolby.io访问令牌

  bool isLeaving = false;
  bool isJoining = false;
  bool isInitializedList = false;
  List<Participant> participants = [];

  StreamSubscription<Event<ConferenceServiceEventNames, Participant>>?
      onParticipantsChangeSubscription;
  StreamSubscription<Event<ConferenceServiceEventNames, StreamsChangeData>>?
      onStreamsChangeSubscription;

  [@override](/user/override)
  void initState() {
    super.initState();
    [
      Permission.bluetoothConnect,
      Permission.microphone,
      Permission.camera,
    ].request();

    initializeSdk();
    openSession();

    onParticipantsChangeSubscription =
        dolbyioCommsSdk.conference.onParticipantsChange().listen((params) {
      updateParticipantsList();
    });

    onStreamsChangeSubscription =
        dolbyioCommsSdk.conference.onStreamsChange().listen((params) {
      updateParticipantsList();
    });
  }

  [@override](/user/override)
  void dispose() {
    onParticipantsChangeSubscription?.cancel();
    onStreamsChangeSubscription?.cancel();
    super.dispose();
  }

  [@override](/user/override)
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('Flutter SDK'), centerTitle: true),
      body: Padding(
        padding: const EdgeInsets.all(16),
        child: !isInitializedList
            ? Column(
                children: [
                  TextField(controller: usernameController, readOnly: true),
                  const SizedBox(height: 12),
                  TextField(decoration: const InputDecoration(hintText: 'Conference name'), controller: conferenceNameController),
                  const SizedBox(height: 12),
                  ElevatedButton(
                    onPressed: () async {
                      await joinConference();
                    },
                    child: isJoining ? const Text('Joining...') : const Text('Join the conference'),
                  ),
                  const Divider(thickness: 2),
                  const Text("Join the conference to see the list of participants.")
                ],
              )
            : Column(children: [
                Text('Conference name: ${conferenceNameController.text}', style: const TextStyle(fontWeight: FontWeight.w400, fontSize: 16)),
                const SizedBox(height: 16),
                Expanded(
                  child: Column(children: [
                    const Align(alignment: Alignment.centerLeft, child: Text('List of participants:', style: TextStyle(color: Colors.blue, fontWeight: FontWeight.w600))),
                    const SizedBox(height: 16),
                    Expanded(
                      child: ListView.separated(
                        separatorBuilder: (BuildContext context, int index) {
                          return const SizedBox(height: 5);
                        },
                        shrinkWrap: true,
                        itemCount: participants.length,
                        itemBuilder: (context, index) {
                          var participant = participants[index];
                          return Padding(
                            padding: const EdgeInsets.all(4),
                            child: Row(children: [
                              Expanded(
                                flex: 1,
                                child: SizedBox(
                                  height: 150,
                                  width: 150,
                                  child: VideoView.withMediaStream(
                                    participant: participant,
                                    mediaStream: participant.streams?.firstWhereOrNull((s) => s.type == MediaStreamType.camera),
                                    key: ValueKey('video_view_tile_${participant.id}'),
                                  ),
                                ),
                              ),
                              Expanded(
                                flex: 1,
                                child: Column(mainAxisAlignment: MainAxisAlignment.center, children: [
                                  Text("${participant.info?.name.toString()}"),
                                  Text("status: ${participant.status?.name}")
                                ]),
                              ),
                            ]),
                          );
                        },
                      ),
                    ),
                  ]),
                ),
                const SizedBox(height: 16),
                ElevatedButton(
                  style: ElevatedButton.styleFrom(primary: Colors.red),
                  onPressed: () async {
                    await leaveConference();
                  },
                  child: isJoining ? const Text('Leaving...') : const Text('Leave the conference'),
                )
              ]),
      ),
    );
  }

  Future<void> initializeSdk() async {
    await dolbyioCommsSdk.initializeToken(accessToken, () async {
      return accessToken;
    });
  }

  Future<void> openSession() async {
    int randomNumber = Random().nextInt(1000);
    usernameController.text = "user-$randomNumber";
    var participantInfo = ParticipantInfo(usernameController.text, null, null);
    await dolbyioCommsSdk.session.open(participantInfo);
  }

  Future<void> joinConference() async {
    setState(() => isJoining = true);

    var params = ConferenceCreateParameters();
    params.dolbyVoice = true;
    var createOptions = ConferenceCreateOption(conferenceNameController.text, params, 0);

    var joinOptions = ConferenceJoinOptions();
    joinOptions.constraints = ConferenceConstraints(true, true);

    var conference = await dolbyioCommsSdk.conference.create(createOptions);
    conference = await dolbyioCommsSdk.conference.join(conference, joinOptions);

    if (conference.status == ConferenceStatus.joined) {
      setState(() => isJoining = false);
      print('Joined to conference.');
    } else {
      print('Cannot join to conference.');
    }
  }

  Future<void> leaveConference() async {
    setState(() => isLeaving = true);
    await dolbyioCommsSdk.conference.leave(options: null);
    setState(() => isInitializedList = false);
    setState(() => isLeaving = false);
  }

  Future<void> updateParticipantsList() async {
    try {
      var conference = await dolbyioCommsSdk.conference.current();
      var participantsList = await dolbyioCommsSdk.conference.getParticipants(conference);
      final availableParticipants = participantsList.where((element) => element.status != ParticipantStatus.left);

      setState(() {
        participants = availableParticipants.toList();
        isInitializedList = true;
      });
    } catch (error) {
      print("Error during initializing participant list.");
    }
  }
}

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

1 回复

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


当然,下面是一个关于如何在Flutter项目中使用dolbyio_comms_sdk_flutter插件进行音频通信的示例代码。请注意,实际使用中可能需要根据具体需求进行调整,并且确保你已经按照官方文档完成了插件的安装和配置。

1. 添加依赖

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

dependencies:
  flutter:
    sdk: flutter
  dolbyio_comms_sdk_flutter: ^最新版本号  # 请替换为实际发布的最新版本号

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

2. 配置Dolby.io

在Dolby.io开发者门户创建一个应用并获取必要的凭证(API Key, API Secret, Room ID等)。确保你已经正确配置了这些凭证。

3. 初始化SDK并加入房间

下面是一个基本的示例,展示如何初始化Dolby.io Comms SDK并加入一个通信房间:

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

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

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

class _MyAppState extends State<MyApp> {
  late DolbyIOCommsClient _dolbyIOClient;
  late Room _room;
  bool _isConnected = false;

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

  Future<void> initDolbyIO() async {
    // 替换为你的API Key和API Secret
    final String apiKey = 'YOUR_API_KEY';
    final String apiSecret = 'YOUR_API_SECRET';

    _dolbyIOClient = DolbyIOCommsClient(apiKey: apiKey, apiSecret: apiSecret);

    try {
      // 替换为你的Room ID
      final String roomId = 'YOUR_ROOM_ID';
      _room = await _dolbyIOClient.joinRoom(roomId: roomId);
      _isConnected = true;
      print('Joined room: $roomId');

      // 监听音频事件
      _room.onRemoteAudioStarted.listen((event) {
        print('Remote audio started: ${event.participantId}');
      });

      _room.onRemoteAudioStopped.listen((event) {
        print('Remote audio stopped: ${event.participantId}');
      });

      // 其他事件监听可以根据需要添加

    } catch (e) {
      print('Failed to join room: $e');
    }
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: Text('Dolby.io Comms SDK Flutter Example'),
        ),
        body: Center(
          child: _isConnected
              ? Text('Connected to room')
              : Text('Connecting to room...'),
        ),
        floatingActionButton: FloatingActionButton(
          onPressed: () async {
            if (_isConnected) {
              await _room.leave();
              _isConnected = false;
              setState(() {});
            } else {
              // 如果需要重新连接,可以在这里调用initDolbyIO或相应逻辑
            }
          },
          tooltip: _isConnected ? 'Leave Room' : 'Reconnect',
          child: Icon(_isConnected ? Icons.exit_to_app : Icons.refresh),
        ),
      ),
    );
  }

  @override
  void dispose() {
    // 离开房间并释放资源
    if (_isConnected) {
      _room.leave();
    }
    _dolbyIOClient.dispose();
    super.dispose();
  }
}

4. 运行应用

确保你已经按照Dolby.io的文档完成了必要的配置,然后运行你的Flutter应用。这个示例展示了如何初始化Dolby.io Comms SDK,加入一个通信房间,并监听远程音频事件。

注意事项

  • 确保你的Dolby.io凭证和Room ID是有效的。
  • 根据你的需求,你可能需要添加更多的事件监听和处理逻辑,比如处理视频流、聊天消息等。
  • 在生产环境中,务必处理好错误和异常情况,以提供良好的用户体验。

这个示例提供了一个基本的框架,你可以在此基础上根据具体需求进行扩展和定制。

回到顶部