Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Cross platform not working #281

Closed
BhavyKoshti9spl opened this issue Mar 23, 2021 · 37 comments
Closed

Cross platform not working #281

BhavyKoshti9spl opened this issue Mar 23, 2021 · 37 comments
Assignees
Labels
waiting for customer response waiting for customer response, or closed by no-reponse bot

Comments

@BhavyKoshti9spl
Copy link

BhavyKoshti9spl commented Mar 23, 2021

while i create stream from the android it will be visible from the android device but not on the ios device.
same as if i create stream from the ios device then it is not visible from the android device but visible from ios device.

so mainly its not working on cross platform.
Please help.

however i am receiving all the messages from rtm but rtc seems not working on cross platform or i am missing something.

I have used this as code and implemented it.

@LichKing-2234
Copy link
Contributor

maybe you use the same uid, and another one will be kicked out.

@BhavyKoshti9spl
Copy link
Author

BhavyKoshti9spl commented Mar 24, 2021

i don't think so, but even if this is the case why its working for android-android and ios-ios ?

AgoraRtcEngine.onJoinChannelSuccess = (
      String channel,
      int uid,
      int elapsed,
    ) async {
      final documentId = widget.channelName;
      channelName = documentId;
     
      print("UID    :   $uid");
      sendStartCallNotification(uid); //for notification to other users

      await Wakelock.enable();
      // This is used for Keeping the device awake. Its now enabled
    };

see after this i am sending a notification to other user's so that they can join the same channel.

if something is missing or you need anything else then please let me know.

@LichKing-2234
Copy link
Contributor

which version of SDK you used. maybe you can provide the SDK log, you can refer to the setLogFile method.

@BhavyKoshti9spl
Copy link
Author

we are using plugin version of

agora_rtc_engine: ^1.0.13
agora_rtm: ^0.9.11

@LichKing-2234
Copy link
Contributor

this version is too old, pls upgrade it.

@BhavyKoshti9spl
Copy link
Author

now i changed the agora_rtc_engine 3.3.2 now i am able to start stream from android and join in iOS its not working.

i have checked the stream id i am passing its perfect also my android - android working & iOS- iOS not tested yet.

you might encounter something i am missing or what ?

@LichKing-2234
Copy link
Contributor

could pls share your code about our SDK?

@BhavyKoshti9spl
Copy link
Author

for host :

@override
  void initState() {
    super.initState();
    // initialize agora sdk
    initialize();
    userMap = {widget.channelName: widget.image};
    _createClient();
    WidgetsBinding.instance.addObserver(
      new LifecycleEventHandler(suspendingCallBack: () {
        endStream();
        return;
      }),
    );
  }
Future<void> initialize() async {
    await _initAgoraRtcEngine();
    _addAgoraEventHandlers();
    await _engine.enableWebSdkInteroperability(true);
    if (widget.streamType == 2) {
      await _engine.disableVideo();
    } else {
      await _engine.enableVideo();
    }
    await _engine.setParameters(
        '''{\"che.video.lowBitRateStreamParameter\":{\"width\":640,\"height\":360,\"frameRate\":15,\"bitRate\":400}}''');
    await _engine.joinChannel(null, widget.channelName, null, 0);
  }
/// Add agora event handlers
  void _addAgoraEventHandlers() {
    _engine?.setEventHandler(RtcEngineEventHandler(joinChannelSuccess: (
      String channel,
      int uid,
      int elapsed,
    ) async {
      final documentId = widget.channelName;
      channelName = documentId;
      print("UID    :   $uid");
      myUid = uid;
      sendStartCallNotification(uid);
      // The above line create a document in the firestore with username as documentID

      await Wakelock.enable();
      // This is used for Keeping the device awake. Its now enabled
    }, leaveChannel: (stats) {
      setState(() {
        _users.clear();
      });
    }, userJoined: (int uid, int elapsed) {
      setState(() {
        _users.add(uid);
      });
    }, userOffline: (int uid, UserOfflineReason reason) {
      if (uid == guestID) {
        setState(() {
          accepted = false;
        });
      }
      setState(() {
        _users.remove(uid);
      });
    }));
  }
void _createClient() async {
  _client = await AgoraRtmClient.createInstance(Constant.AGORA_APP_ID);
  _client.onMessageReceived = (AgoraRtmMessage message, String peerId) {
    _log(user: peerId, info: message.text, type: 'message');
  };
  _client.onConnectionStateChanged = (int state, int reason) {
    if (state == 5) {
      _client.logout();
      //_log('Logout.');
      setState(() {
        _isLogin = false;
      });
    }
  };
  await _client.login(null, widget.channelName);
  _channel = await _createChannel(widget.channelName);
  await _channel.join();
}
Future<AgoraRtmChannel> _createChannel(String name) async {
    channel = await _client.createChannel(name);
    channel.onMemberJoined = (AgoraRtmMember member) async {
      setState(() {
        userList.add(
            new User(username: member.userId, name: member.userId, image: ''));
        if (userList.length > 0) anyPerson = true;
      });
      // }
      var len;
      _channel.getMembers().then((value) {
        len = value.length;
        setState(() {
          userNo = len - 1;
        });
      });

      print("USER JOINTED : " + member.userId.toString());
      _log(info: 'Member joined: ', user: member.userId, type: 'join');
    };
    channel.onMemberLeft = (AgoraRtmMember member) {
      var len;

      print("USER LEFT : " + member.userId.toString());
      setState(() {
        userList.removeWhere((element) => element.username == member.userId);
        if (userList.length == 0) anyPerson = false;
      });

      _channel.getMembers().then((value) {
        len = value.length;
        setState(() {
          userNo = len - 1;
        });
      });
      _log(info: 'Member left: ', user: member.userId, type: 'left');
    };
    channel.onMessageReceived =
        (AgoraRtmMessage message, AgoraRtmMember member) {
      _log(user: member.userId, info: message.text, type: 'message');
    };
    return channel;
  }

for view on host :

Widget _viewRows() {
    final views = _getRenderViews();

    switch (views.length) {
      case 1:
        return Container(
            child: Column(
          children: <Widget>[_videoView(views[0])],
        ));
      case 2:
        return Container(
            child: Column(
          children: <Widget>[
            _expandedVideoRow([views[0]]),
            _expandedVideoRow([views[1]])
          ],
        ));
    }
    return Container();
  }
List<Widget> _getRenderViews() {
    final list = [
      RtcLocalView.SurfaceView(),
    ];
    return list;
  }

  /// Video view wrapper
  Widget _videoView(view) {
    return Expanded(child: ClipRRect(child: view));
  }

  /// Video view row wrapper
  Widget _expandedVideoRow(List<Widget> views) {
    final wrappedViews = views.map<Widget>(_videoView).toList();
    return Expanded(
      child: Row(
        children: wrappedViews,
      ),
    );
  }

@BhavyKoshti9spl
Copy link
Author

for jointed user :

@override
  void initState() {
    super.initState();
    // initialize agora sdk
    initialize();
    userMap = {widget.username: widget.userImage};
    _createClient();
  }
Future<void> initialize() async {
    await _initAgoraRtcEngine();
    _addAgoraEventHandlers();
    await _engine.enableWebSdkInteroperability(true);
    await _engine.setParameters(
        '''{\"che.video.lowBitRateStreamParameter\":{\"width\":640,\"height\":360,\"frameRate\":15,\"bitRate\":400}}''');
    await _engine.joinChannel(null, widget.channelName, null, 0);
  }
/// Create agora sdk instance and initialize
  Future<void> _initAgoraRtcEngine() async {
    _engine = await RtcEngine.createWithConfig(
        RtcEngineConfig(Constant.AGORA_APP_ID));
    await _engine.enableVideo();
    await _engine.muteLocalAudioStream(true);
    await _engine.enableLocalAudio(false);
    // await AgoraRtcEngine.enableLocalVideo(!muted);
  }
/// Add agora event handlers
  void _addAgoraEventHandlers() {
    _engine?.setEventHandler(RtcEngineEventHandler(joinChannelSuccess: (
      String channel,
      int uid,
      int elapsed,
    ) async {
      await Wakelock.enable();
    }, userJoined: (int uid, int elapsed) {
      setState(() {
        _users.add(uid);
      });
    }, userOffline: (int uid, UserOfflineReason reason) {
      if (uid == widget.channelId) {
        setState(() {
          completed = true;
          endStream();
          Future.delayed(const Duration(milliseconds: 1500), () async {
            await Wakelock.disable();
            // Navigator.pop(context);
            GameRoomsModel gameRoomsModel = new GameRoomsModel(0, 4);

            if (widget.isFromNotification) {
              MyApp.navKey.currentState.pushNamedAndRemoveUntil(
                  RouteGenerator.home_screen, (Route<dynamic> route) => false,
                  arguments: gameRoomsModel);
            } else {
              Navigator.pop(context);
            }
          });
        });
      }
      _users.remove(uid);
    }));
  }

for view :

Widget _viewRows() {
   final views = _getRenderViews();

   switch (views.length) {
     case 1:
       return (loading == true) && (completed == false)
           ?
           //LoadingPage()
           CircularProgressIndicator()
           : Container(
               child: Column(
               children: <Widget>[_videoView(views[0])],
             ));
     case 2:
       return (loading == true) && (completed == false)
           ?
           //LoadingPage()
           CircularProgressIndicator()
           : Container(
               child: Column(
               children: <Widget>[
                 _expandedVideoRow([views[0]]),
                 _expandedVideoRow([views[1]])
               ],
             ));
   }
   return Container();
 }
/// Helper function to get list of native views
  List<Widget> _getRenderViews() {
    final List<RtcRemoteView.SurfaceView> list = [];
    //user.add(widget.channelId);
    _users.forEach((int uid) {
      if (uid == widget.channelId) {
        list.add(RtcRemoteView.SurfaceView(
          uid: uid,
        ));
      }
    });
    /*if (accepted == true) {
      list.add(AgoraRenderWidget(0, local: true, preview: true));
    }*/
    if (list.isEmpty) {
      setState(() {
        loading = true;
      });
    } else {
      setState(() {
        loading = false;
      });
    }

    return list;
  }

  /// Video view wrapper
  Widget _videoView(view) {
    return Expanded(child: ClipRRect(child: view));
  }

  /// Video view row wrapper
  Widget _expandedVideoRow(List<Widget> views) {
    final wrappedViews = views.map<Widget>(_videoView).toList();
    return Expanded(
      child: Row(
        children: wrappedViews,
      ),
    );
  }

  /// Video layout wrapper
  Widget _viewRows() {
    final views = _getRenderViews();

    switch (views.length) {
      case 1:
        return (loading == true) && (completed == false)
            ?
            //LoadingPage()
            CircularProgressIndicator()
            : Container(
                child: Column(
                children: <Widget>[_videoView(views[0])],
              ));
      case 2:
        return (loading == true) && (completed == false)
            ?
            //LoadingPage()
            CircularProgressIndicator()
            : Container(
                child: Column(
                children: <Widget>[
                  _expandedVideoRow([views[0]]),
                  _expandedVideoRow([views[1]])
                ],
              ));
    }
    return Container();
  }

@LichKing-2234
Copy link
Contributor

await _client.login(null, widget.channelName);

why login with the channelName? the param need be uid.

@LichKing-2234
Copy link
Contributor

pls refer to our example, it must work on different platforms.

@BhavyKoshti9spl
Copy link
Author

await _client.login(null, widget.channelName);

why login with the channelName? the param need be uid.

it is uid. and its working for Android - Android

@BhavyKoshti9spl
Copy link
Author

pls refer to our example, it must work on different platforms.

i have referred the example and changed my old code to the new latest 3.3.2. there is class changes as well as video view is also changed.

@LichKing-2234
Copy link
Contributor

pls refer to our example, it must work on different platforms.

i have referred the example and changed my old code to the new latest 3.3.2. there is class changes as well as video view is also changed.

I mean you can use our example to test on Android - iOS.

@BhavyKoshti9spl
Copy link
Author

ok will check and back to you!

@BhavyKoshti9spl
Copy link
Author

i tried with 2 android devices and it seems the example is not working for android-android audio seems playing but video is not working then i started one channel with my app and tried to join that channel from the example and that was working fine.

i am not getting anything what is the issue here?

@LichKing-2234
Copy link
Contributor

which of example you used?

@BhavyKoshti9spl
Copy link
Author

which of example you used?

https://github.com/AgoraIO/Agora-Flutter-SDK

@LichKing-2234
Copy link
Contributor

i tried with 2 android devices and it seems the example is not working for android-android audio seems playing but video is not working then i started one channel with my app and tried to join that channel from the example and that was working fine.

i am not getting anything what is the issue here?

pls use the JoinChannelVideo example.

@LichKing-2234
Copy link
Contributor

maybe you can provide the SDK log file.

@BhavyKoshti9spl
Copy link
Author

maybe you can provide the SDK log file.

what do you mean by sdk log file ?
flutter sdk logs or agora logs ?
and for my application or your example ?

also i have used the JoinChannelVideo example.

@LichKing-2234
Copy link
Contributor

LichKing-2234 commented Mar 25, 2021

you can refer to setLogFile method.

you should replicate the problem then pull the log file.

@BhavyKoshti9spl
Copy link
Author

worked on a first try but then again when i started it its the same as before.

couldn't got the log file

@LichKing-2234
Copy link
Contributor

Why couldn't get the log file?

@BhavyKoshti9spl
Copy link
Author

Sorry for late response but so far i got this and i have some issues getting log files on both devices. i dont know where are they and how to check logs.

ios-ios working

android-android working

ios(host) - Android(spectator) - working

android(host) -ios(spectator) - sometimes not working

@BhavyKoshti9spl
Copy link
Author

BhavyKoshti9spl commented Mar 30, 2021

hey if there is a function for clearCache or something like this or reseting the agora account like that would be much helpful we can try that.

so far i know that first time its working perfectly but after first check android->ios seems trubling i am thinking might be possible some cache issues related to android in hosting agora rtc.

@BhavyKoshti9spl
Copy link
Author

here are the logs on android device in which i hosted the rtc session.

although i couldn't find any log files in ios devices.

@LichKing-2234
Copy link
Contributor

@BhavyKoshti9spl Sorry for the late reply, we need the RTC SDK log too.

@florianthiel
Copy link

Is this issue going to be fixed? This currently makes Agora unusable in production. Here can you find my sdk logs: #311

@imrajeshcoder
Copy link

imrajeshcoder commented Aug 19, 2021

### host.dart

  /// Helper function to get list of native views
  List<Widget> _getRenderViews() {
    final List<StatefulWidget> list = [];
    list.add(RtcLocalView.SurfaceView());
    if (accepted == true) {
      _users.forEach((int uid) {
        if (uid != 0) {
          guestID = uid;
        }
        list.add(RtcRemoteView.SurfaceView(uid: uid));
      });
    }
    return list;
  }

### join.dart

List<Widget> _getRenderViews() {
   final List<StatefulWidget> list = [];
   _users.forEach((int uid) => list.add(RtcRemoteView.SurfaceView(uid: uid)));

   if (accepted == true) {
     list.add(RtcLocalView.SurfaceView());
   }

   if (list.isEmpty) {
     setState(() {
       loading = true;
     });
   } else {
     setState(() {
       loading = false;
     });
   }
   return list;
 }

@agora-vin
Copy link

Hi Florian,

//Form your iOS log, you enabled encryption

Agora SDK ver 3.4.2 build 76955, built on May 11 2021 13:52:27
INFO (12:18:47:169 | 0) 69643; Agora SDK git ver:6fb8aef706 and branch:release/3.4.2
WARN (12:18:47:170 | 1) 69643; CacheManager: check cache file header failed
INFO (12:18:47:170 | 0) 69643; initialize plugin manager
INFO (12:18:47:170 | 0) 69643; built-in encryption is enabled
INFO (12:18:47:176 | 6) 69643; built-in ssl is enabled
INFO (12:18:47:177 | 1) 69643; use AHPL engine
INFO (12:18:47:182 | 5) 69643; CacheManager: save cache to storage elapsed 4

A couple of thing here, I would like to check on IOS and Android sides.

  1. The AppId of createInstance should be the same among IOS and Android
    RTC -- mRtcEngine = RtcEngine.create(getApplicationContext(), getString(R.string.private_app_id), mHandler);
    RTM -- mRtmClient = RtmClient.createInstance(mContext, appID, new RtmClientListener() {
    2.The encryption algorithm should be the same among iOS and Android.
    3. Enable encryption before joining channels

For follow up if needed,
please attach BOTH iOS and android log.
Please have time stamp, channel name, uid on IOS and Android.

Regards,
..Vin

@florianthiel
Copy link

I'm using the same code to create the engine on iOS and Android. Is encryption enabled by default? Because I didn't enable it in my code. The code I'm using to create the engine:

final token = (await _genAgoraToken.call({ 'trainingId': training.id })).data['token'];
        _engine = await RtcEngine.create('xxx');
        _engine!.setEventHandler(RtcEngineEventHandler(
          joinChannelSuccess: joinChannelSuccess,
          userJoined: userJoined,
          userOffline: userOffline,
          videoSizeChanged: videoSizeChanged,
          localUserRegistered: localUserRegistered,
          networkQuality: networkQuality,
          error: (error) {
            FirebaseCrashlytics.instance.recordFlutterError(FlutterErrorDetails(
              exception: error,
              library: 'agora_rtc_engine'
            ));
            print('=== ERROR ===');
            print(error);
            print('=============');
          },
          warning: (warning) {
            print('=== WARINING ===');
            print(warning);
            print('=============');
          }
        ));

        if (Client.instance.currentUser is Trainer)
          await AgoraRtcRawdata.registerVideoFrameObserver((await _engine!.getNativeHandle())!);

        // Set Video config
        final config = VideoEncoderConfiguration();
        config.dimensions = VideoDimensions(width: 1280, height: 720);
        config.frameRate = VideoFrameRate.Fps24;
        config.bitrate = 1710;
        config.degradationPrefer = DegradationPreference.MaintainBalanced;

        await _engine!.setVideoEncoderConfiguration(config);
        await _engine!.registerLocalUserAccount('xxx', Client.instance.currentUser!.id);
        await _engine!.enableAudio();
        await _engine!.enableVideo();
        await _engine!.joinChannelWithUserAccount(token, training.id, Client.instance.currentUser!.id);

The error occurs fairly random. Sometimes it doesn't occur at all. But there are times where this happens on every call. I will post the Android and iOS logs if I catch the error again.

@agora-vin
Copy link

agora-vin commented Aug 23, 2021 via email

@florianthiel
Copy link

I don't have different config files for iOS and Android. I have one dart file which stores the AppId. So the AppId is the same on both platforms

@littleGnAl
Copy link
Collaborator

If you still face issues, please try upgrading to the new version to see if it works for you.

@littleGnAl littleGnAl added the waiting for customer response waiting for customer response, or closed by no-reponse bot label Nov 14, 2023
Copy link
Contributor

Without additional information, we are unfortunately not sure how to resolve this issue. We are therefore reluctantly going to close this bug for now. If you find this problem please file a new issue with the same description, what happens, logs and the output. All system setups can be slightly different so it's always better to open new issues and reference the related ones. Thanks for your contribution.

Copy link
Contributor

github-actions bot commented Dec 5, 2023

This thread has been automatically locked since there has not been any recent activity after it was closed. If you are still experiencing a similar issue, please raise a new issue.

@github-actions github-actions bot locked as resolved and limited conversation to collaborators Dec 5, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
waiting for customer response waiting for customer response, or closed by no-reponse bot
Projects
None yet
Development

No branches or pull requests

7 participants