0

Q1) how I can add more then one person to make conference with them ?

I success to make one person call to other but if person NO.3 want login in conference person NO.3 can't login even person NO.2 get out from conference.

and I have same channel ,ever user have name and uid ,have AppiToken from agora and I send them by FCM notification with them to get token and other

1-this is code (Screen Main) of Host user who make Conference :-

// ignore_for_file: deprecated_member_use

import 'dart:async';

import 'package:agora_rtc_engine/rtc_engine.dart';
import 'package:agora_rtm/agora_rtm.dart';
import 'package:broadcasting/modules/buttom.dart';
import 'package:broadcasting/shared/components/component.dart';
import 'package:firebase_messaging/firebase_messaging.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
// import 'package:livestream/HomePage/homepage.dart';

import '../../cubit_main/cubit.dart';
import '../../cubit_main/states.dart';
import '../../model/FcmModel.dart';
import '../../network/end_points.dart';
// import '../constant/constant.dart';
import 'package:agora_rtc_engine/rtc_local_view.dart' as RtcLocalView;
import 'package:agora_rtc_engine/rtc_remote_view.dart' as RtcRemoteView;
import 'package:agora_rtc_engine/rtc_remote_view.dart' as RtcRemoteView2;


import 'dart:math' as math;

import '../../shared/styles/colores.dart';

// import '../constant/heartanim.dart';

class Host_5 extends StatefulWidget {
  final String? channelName;
  final String? userId;
  const Host_5({Key? key, required this.channelName, required this.userId})
      : super(key: key);

  @override
  State<Host_5> createState() => _Host_5State();
}

class _Host_5State extends State<Host_5> {
  late RtcEngine _engine;
  late int streamId;
  bool muted = false;
  List messages = [''];
  List names = [userh]; //get user name
  List images = [image]; //get image
  bool heart = false;
  double height = 0.5;
  bool visable = false;
  bool msgFCM = false;
  int _remoteUid = 0;
  int _remoteUid2 = 0;

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

  @override
  void dispose() {
    _engine.leaveChannel();
    _engine.destroy();
    super.dispose();
  }

  Future<void> initializeAgora() async {
    _engine = await RtcEngine.createWithContext(RtcEngineContext(appId));
    await _engine.enableVideo();

    await _engine.setChannelProfile(ChannelProfile.LiveBroadcasting);
    await _engine.setClientRole(ClientRole.Broadcaster);
    streamId = (await _engine.createDataStream(false, false))!;
    _engine.setEventHandler(RtcEngineEventHandler(
      rejoinChannelSuccess: (channel, uid, elapsed) {
        if (kDebugMode) {
          print("onREJoinChannel: $channel, uid: $uid");
        }
      },
      joinChannelSuccess: (channel, uid, elapsed) {
        if (kDebugMode) {
          print("onJoinChannel: $channel, uid: $uid");
        }
      },
      leaveChannel: (stats) {
        if (kDebugMode) {
          print("channel left");
        }
      },
      userJoined: (uid, elapsed) {
        print("UserJoined: $uid");
        setState(() {
          _remoteUid2 = uid;
          _remoteUid = uid;
        });
      },
      userOffline: (uid, elapsed) {
        if (kDebugMode) {
          print("Useroffline: $uid");
          setState(() {
            _remoteUid = 0;
            _remoteUid2 = 0;
 
          });
        }
      },
    ));
    await _engine.joinChannel(null, widget.channelName!, null, 0);
  }

 

  Widget build(BuildContext context) {
    double w = MediaQuery.of(context).size.width;
    double h = MediaQuery.of(context).size.height;
    double hp = WidgetsBinding.instance.window.physicalSize.height;
    double wp = WidgetsBinding.instance.window.physicalSize.width;
    return BlocConsumer<Main_Cubit, Main_states>(
        listener: (context, state) {},
        builder: (context, state) {

          return Scaffold(
            body: Stack(
              children: [
                Container(
                  height: h,
                  width: w,
                  color: Colors.green,
                  child: _broadcastView(),  //====>  MY LIVE Person NO.1 Master
                ),
                 Align(
                   alignment: Alignment.topLeft,
                   child: Container(
                     color: Colors.amber,
                
                     width: 100,
                     height: 250,
                     margin: const EdgeInsets.only(left: 30, top: 40),
                     child: _renderRemoteView_out(),//====>  come from out Person NO.2 can login
                   ),
                 ),
                Align(
                    alignment: Alignment.topRight,
                    child: Container(
                      color: Colors.purple,
                
                      width: 100,
                      height: 250,
                      margin: const EdgeInsets.only(left: 30, top: 40),
                      child: _renderRemoteView_out2() ,//====>  come from out Person NO.3 and can't login
                    ),
                  ),
                Column(
                  crossAxisAlignment: CrossAxisAlignment.center,
                  mainAxisAlignment: MainAxisAlignment.start,
                  children: [
                    SizedBox(height: 20),
                    RowHead(),
        
                  ],
                ),
                Column(
                  crossAxisAlignment: CrossAxisAlignment.start,
                  mainAxisAlignment: MainAxisAlignment.end,
                  children: [
                     Visibility(
                      visible: msgFCM,
                      child: Padding(
                        padding: const EdgeInsets.all(10.0),
                        child: Container(
                          height: 100,
                          width: 350,
                          color: Colors.black.withOpacity(0.5),
                          child: Column(
                            crossAxisAlignment: CrossAxisAlignment.center,
                            mainAxisAlignment: MainAxisAlignment.center,
                            children: [
                              txt(size: 15, txt: 'Note Message'),
                              const SizedBox(height: 15),
                              Row(
                                    crossAxisAlignment: CrossAxisAlignment.center,
                                    mainAxisAlignment: MainAxisAlignment.center,
                                    children: [
                                      ElevatedButton(onPressed: (){
                                        setState(() {
                                          visable=true;
                                          msgFCM=false;
                      
                                          // Navigator.of(context).pop();
                                        });
                                      }, child: txt(size: 12, txt: 'Ok',colors: Colors.white)),
                                      const SizedBox(width: 15),
                                      ElevatedButton(onPressed: (){
                                        setState(() {
                                        // Navigator.of(context).pop();
                                        msgFCM=false;
                                        });
                                      }, child: txt(size: 12, txt: 'Cancel',colors: Colors.white)),
                                    ],
                                  ),
                            ],
                          ),),
                      ),
                    ),
                    _toolbar(),
                    // SizedBox(height: 55),
                  ],
                )
              ],
            ),
          );
        });
    // }
  }

  
  //BroadCast host=======================================================
  Widget _broadcastView() {
    not_fcm();
    return const RtcLocalView.SurfaceView();
  }
  //to get user name and Email from Person no.2 or no.3
  void not_fcm()  {
    FirebaseMessaging.onMessage.listen((event) {
      FcmModel? userModel;
      userModel = FcmModel.fromJson(event.data);
      // print('*************//////**************************');
      // print(userModel.email);
      // print(userModel.tokenFCM);
      // print('*************//////**************************');
      setState(() {
        msgFCM=true;
      });
   
    }).onError((error) {
      print(error);
    });
  }
  //remot host=======================================================
  //to get person no.1
  Widget _renderRemoteView_out() {
    if (_remoteUid != 0 && visable==true) {
      // muted=true;
    showTost(txt: 'Guses is ${userh}', state: ToastStates.SUCCESS);
      return RtcRemoteView.SurfaceView(
        uid: _remoteUid,
        channelId: widget.channelName!,
      );
      
    } else {
      // muted=false;

      return  txt(size: 12,txt: 'Waiting for other user to join',colors: Colors.white);
    }
  }
  //to get person no.2
  Widget _renderRemoteView_out2() {
    if (_remoteUid2 != 0) {
      return RtcRemoteView2.SurfaceView(
        uid: _remoteUid2,
        channelId: widget.channelName!,
      );
    } else {
      return const Text("Waiting for other user to join");
    }
  }
  void _onToggleMute() {
    setState(() {
      muted = !muted;
    });
    _engine.muteLocalAudioStream(muted);
  }
  void _onCallEnd() {
    _engine.leaveChannel().then((value) {
      // checkExist();
      Navigator.push(
          context, MaterialPageRoute(builder: (context) => bottom()));
    });
  }
    void _onSwitchCamera() {
    _engine.switchCamera();
  }
  Widget RowHead() => Row(
        crossAxisAlignment: CrossAxisAlignment.center,
        mainAxisAlignment: MainAxisAlignment.center,
        children: [
          RawMaterialButton(
            onPressed: () {
              _onCallEnd();
              // _onScrollDown();
            },
            shape: const CircleBorder(),
            padding: const EdgeInsets.all(5),
            elevation: 2.0,
            fillColor: Colors.black.withOpacity(0.50),
            child: const Icon(
              Icons.close_rounded,
              color: Colors.white,
              size: 30,
            ),
          ),
          Spacer(),
          Container(
            margin: EdgeInsets.only(left: 20, top: 30, right: 20),
            padding: EdgeInsets.all(5),
            decoration: BoxDecoration(
                border: Border.all(color: Colors.blueAccent),
                borderRadius: BorderRadius.circular(20),
                color: Colors.black.withOpacity(0.2)),
            child: Row(
              crossAxisAlignment: CrossAxisAlignment.start,
              mainAxisAlignment: MainAxisAlignment.end,
              children: [
                CircleAvatar(
                  backgroundColor: circle_avtar_color,
                  radius: 20,
                  child: CircleAvatar(
                    // backgroundImage: AssetImage('assets/image/doctor.png'),
                    backgroundImage: NetworkImage(imageProfile!),

                    radius: 20,
                    backgroundColor: circle_avtar_color,
                  ),
                ),
                SizedBox(width: 10),
                Column(children: [
                  txt(size: 12, txt: userProfile!, colors: Colors.white),
                  txt(size: 12, txt: 'Livel 20', colors: Colors.pink)
                ]),
              ],
            ),
          )
        ],
      );
      Widget _toolbar() {
    return Container(
      alignment: Alignment.bottomCenter,
      margin: const EdgeInsets.only(bottom: 30),
      child: Row(
        mainAxisAlignment: MainAxisAlignment.center,
        children: [
          RawMaterialButton(
            onPressed: () {
              _onToggleMute();
            },
            shape: const CircleBorder(),
            padding: const EdgeInsets.all(5),
            elevation: 2.0,
            fillColor: (muted) ? Colors.blue : Colors.white,
            child: Icon(
              (muted) ? Icons.mic_off : Icons.mic,
              color: muted ? Colors.white : Colors.blue,
              size: 40,
            ),
          ),
         
          RawMaterialButton(
            onPressed: () {
              _onSwitchCamera();
            },
            shape: const CircleBorder(),
            padding: const EdgeInsets.all(5),
            elevation: 2.0,
            fillColor: Colors.white,
            child: const Icon(
              Icons.switch_camera,
              color: Colors.blue,
              size: 40,
            ),
          )
        ],
      ),
    );
  }
}

2-this is code person NO.2 OR NO.3 to login in Conference (sub Screen )

// ignore_for_file: deprecated_member_use

import 'dart:async';

import 'package:agora_rtc_engine/rtc_engine.dart';
import 'package:agora_rtm/agora_rtm.dart';
import 'package:broadcasting/modules/buttom.dart';
import 'package:broadcasting/shared/components/component.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
// import 'package:livestream/HomePage/homepage.dart';

import '../../cubit_main/cubit.dart';
import '../../cubit_main/states.dart';
import '../../network/end_points.dart';
// import '../constant/constant.dart';
import 'package:agora_rtc_engine/rtc_local_view.dart' as RtcLocalView;
import 'package:agora_rtc_engine/rtc_remote_view.dart' as RtcRemoteView;
import 'package:agora_rtc_engine/rtc_remote_view.dart' as RtcRemoteView2;
import '../../shared/styles/colores.dart';

class Audience_5 extends StatefulWidget {
  final String? channelName;
  final String? userId;
  const Audience_5({Key? key, required this.channelName, required this.userId})
      : super(key: key);
  @override
  State<Audience_5> createState() => _Audience_5State();
}
class _Audience_5State extends State<Audience_5> {
  late RtcEngine _engine;
  late int streamId;
  bool muted = false;
  late AgoraRtmClient _client;
  late AgoraRtmChannel _channel;
  List messages = [''];
  List names = [userProfile]; //get user name
  List images = [imageProfile]; //get image
  final ScrollController _scrollController = ScrollController();
  double height = 0.5;
  int _remoteUid = 0;
  int _remoteUid2 = 0;
  @override
  void initState() {
    super.initState();
    initializeAgora();
  }

  @override
  void dispose() {
    _engine.leaveChannel();
    _engine.destroy();
    super.dispose();
  }

  Future<void> initializeAgora() async {
    _engine = await RtcEngine.createWithContext(
        RtcEngineContext(appId)); //goto constant.dart file
    await _engine.enableVideo();
    await _engine.setChannelProfile(ChannelProfile.LiveBroadcasting);
    await _engine.setClientRole(ClientRole.Broadcaster);
    streamId = (await _engine.createDataStream(false, false))!;
    _engine.setEventHandler(RtcEngineEventHandler(
      joinChannelSuccess: (channel, uid, elapsed) {
        if (kDebugMode) {
          print("onJoinChannel: $channel, uid: $uid");
        }
      },
      leaveChannel: (stats) {
        if (kDebugMode) {
          print("channel left");
        }
      },
      userJoined: (uid, elapsed) {
        print("UserJoined: $uid");
        setState(() {
          _remoteUid = uid;
          _remoteUid2 = uid;
        });
      },
      userOffline: (uid, elapsed) {
        if (kDebugMode) {
          print("Useroffline: $uid");
          setState(() {
            _remoteUid = 0;
           _remoteUid2 = 0;
          });
        }
      },
    ));
    await _engine.joinChannel(null, widget.channelName!, null, 0);
  }

  Widget build(BuildContext context) {
    double w = MediaQuery.of(context).size.width;
    double h = MediaQuery.of(context).size.height;
    double hp = WidgetsBinding.instance.window.physicalSize.height;
    double wp = WidgetsBinding.instance.window.physicalSize.width;
    return BlocConsumer<Main_Cubit, Main_states>(
        listener: (context, state) {},
        builder: (context, state) {
          var cubit = Main_Cubit.get(context);

          return Scaffold(
            body: Stack(
              children: [
                Container(
                  height: h,
                  width: w,
                  color: Colors.green,
                  child: _renderRemoteView_out(),//=====>out from No1

                ),
                Align(
                  alignment: Alignment.topLeft,
                  child: Container(
                    color: Colors.amber,
                    width: 100,
                    height: 250,
                    margin: const EdgeInsets.only(left: 30, top: 40),
                    child: _broadcastView(),//=============which make stream
                  ),
                ),
                 Align(
                  alignment: Alignment.topRight,
                  child: Container(
                    color: Colors.purple,
                    width: 100,
                    height: 250,
                    margin: const EdgeInsets.only(left: 30, top: 40),
                    child: _renderRemoteView_out2(), //==================Out from NO2
                  ),
                ),
                Column(
                  crossAxisAlignment: CrossAxisAlignment.center,
                  mainAxisAlignment: MainAxisAlignment.start,
                  children: [
                    SizedBox(height: 20),
                    RowHead(),
                  ],
                ),
                Column(
                  crossAxisAlignment: CrossAxisAlignment.start,
                  mainAxisAlignment: MainAxisAlignment.end,
                  children: [
                    Container(
                      alignment: Alignment.center,
                      height: h / 4,
                      // width: w,
                      width: 200,

                      child: Padding(
                        padding: const EdgeInsets.all(0.0),
                        child: ListView.builder(
                            itemCount: names.length,
                            // scrollDirection: Axis.vertical,
                            physics: const BouncingScrollPhysics(),
                            controller: _scrollController,
                            itemBuilder: (BuildContext context, int index) {
                              return Container(
                                decoration: BoxDecoration(
                                  border: Border.all(color: Colors.black12),
                                  borderRadius: BorderRadius.circular(20),
                                  color: Colors.black.withOpacity(0.10),
                                ),
                                // color: Colors.black.withOpacity(0.20),
                                // width: 150,
                                child: index == 0
                                    ? null
                                    : ListTile(
                                        leading: CircleAvatar(
                                          backgroundImage:
                                              NetworkImage(images[index]),
                                        ),
                                        subtitle: txt(
                                            size: 15,
                                            txt: messages[index],
                                            colors: Colors.white),
                                        title: txt(
                                            size: 18,
                                            txt: names[index],
                                            colors: Colors.black),
                                        //
                                      ),
                              );
                            }),
                      ),
                    ),
                    _toolbar(),
                    // SizedBox(height: 55),
                  ],
                )
              ],
            ),
          );
        });
    // }
  }

  
  //BroadCast host=======================================================

  Widget _broadcastView() {
    return const RtcLocalView.SurfaceView();
  }

  //remot host=======================================================
  //person NO.1 who make Coneferance
  Widget _renderRemoteView_out() {
    if (_remoteUid != 0) {
      return RtcRemoteView.SurfaceView(
        uid: _remoteUid,
        channelId: widget.channelName!,
      );
    } else {
      return const Text("Waiting for other user to join");
    }
  }
  //person NO.3 
  Widget _renderRemoteView_out2() {
    if (_remoteUid2 != 0) {
      return RtcRemoteView2.SurfaceView(
        uid: _remoteUid2,
        channelId: widget.channelName!,
      );
    } else {
      return const Text("Waiting for other user to join");
    }
  }
  void _onToggleMute() {
    setState(() {
      muted = !muted;
    });
    _engine.muteLocalAudioStream(muted);
  }

  void _onCallEnd() {
    _engine.leaveChannel().then((value) {
      // checkExist();
      Navigator.push(
          context, MaterialPageRoute(builder: (context) => bottom()));
    });
  }

  void _call_host() {
    Main_Cubit.get(context).PostFCM_to_otherM(
      tokenFCM_host: tokenFCMCall!,
      uId_host: uidCall!,
      email_host: emailCall!,
      name_host: nameCall!,
    );
  }
  void _onSwitchCamera() {
    _engine.switchCamera();
  }

  
  Widget RowHead() => Row(
        crossAxisAlignment: CrossAxisAlignment.center,
        mainAxisAlignment: MainAxisAlignment.center,
        children: [
          RawMaterialButton(
            onPressed: () {
              _onCallEnd();
              // _onScrollDown();
            },
            shape: const CircleBorder(),
            padding: const EdgeInsets.all(5),
            elevation: 2.0,
            fillColor: Colors.black.withOpacity(0.50),
            child: const Icon(
              Icons.close_rounded,
              color: Colors.white,
              size: 30,
            ),
          ),
          Spacer(),
          Container(
            margin: EdgeInsets.only(left: 20, top: 30, right: 20),
            padding: EdgeInsets.all(5),
            decoration: BoxDecoration(
                border: Border.all(color: Colors.blueAccent),
                borderRadius: BorderRadius.circular(20),
                color: Colors.black.withOpacity(0.2)),
            child: Row(
              crossAxisAlignment: CrossAxisAlignment.start,
              mainAxisAlignment: MainAxisAlignment.end,
              children: [
                CircleAvatar(
                  backgroundColor: circle_avtar_color,
                  radius: 20,
                  child: CircleAvatar(
                    // backgroundImage: AssetImage('assets/image/doctor.png'),
                    backgroundImage: NetworkImage(image!),

                    radius: 20,
                    backgroundColor: circle_avtar_color,
                  ),
                ),
                SizedBox(width: 10),
                Column(children: [
                  txt(size: 12, txt: userh!, colors: Colors.white),
                  txt(size: 12, txt: 'Livel 20', colors: Colors.pink)
                ]),
              ],
            ),
          )
        ],
      );
      Widget _toolbar() {
    return Container(
      alignment: Alignment.bottomCenter,
      margin: const EdgeInsets.only(bottom: 30),
      child: Row(
        mainAxisAlignment: MainAxisAlignment.center,
        children: [
          RawMaterialButton(
            onPressed: () {
              _onToggleMute();
            },
            shape: const CircleBorder(),
            padding: const EdgeInsets.all(5),
            elevation: 2.0,
            fillColor: (muted) ? Colors.blue : Colors.white,
            child: Icon(
              (muted) ? Icons.mic_off : Icons.mic,
              color: muted ? Colors.white : Colors.blue,
              size: 40,
            ),
          ),
          RawMaterialButton(
            onPressed: () {
              _onSwitchCamera();
            },
            shape: const CircleBorder(),
            padding: const EdgeInsets.all(5),
            elevation: 2.0,
            fillColor: Colors.white,
            child: const Icon(
              Icons.switch_camera,
              color: Colors.blue,
              size: 40,
            ),
          ),
           RawMaterialButton(
            onPressed: () {
              _call_host();
            },
            shape: const CircleBorder(),
            padding: const EdgeInsets.all(5),
            elevation: 2.0,
            fillColor: Colors.white,
            child: const Icon(
              Icons.wifi_calling_3_outlined,
              color: Colors.blue,
              size: 40,
            ),
          )
        ],
      ),
    );
  }
  
}

and I search in agora Documentation can't find my issue https://api-ref.agora.io/en/video-sdk/flutter/6.x/API/rtc_api_overview_ng.html thank a lot

0 Answers0