flutterjanus / flutter_janus_client

A plugin that allows the flutter app to communicate with a Janus server using different transport mechanisms, such as WebSocket and HTTP(rest). It features a developer-friendly api to interact with various WebRTC Janus Plugins. Hence, it can be considered as a swiss-knife for WebRTC solutions.
MIT License
132 stars 76 forks source link

UI freeze when attaching JanusSession #125

Closed rtviwe closed 1 year ago

rtviwe commented 1 year ago

I am using this package in Flutter web and this line of code janusSession.attach<JanusVideoCallPlugin>(); makes UI to freeze for 1-2 seconds. How can I fix it?

shivanshtalwar0 commented 1 year ago

Which version are you using and which flutter version? Coz this shouldn't freeze ui maybe you are using it in throttled network condition either way its hard to comment without reproducing your issue

rtviwe commented 1 year ago

Version of janus_client is 2.2.14, flutter is 3.10.0. There is how I use it

Future<void> initJanus(RTCVideoRenderer remoteRender) async {
    janusClient = JanusClient(
      refreshInterval: 10,
      transport: WebSocketJanusTransport(url: Constants.janusSocket),
      withCredentials: true,
      apiSecret: Constants.janusApiSecret,
      iceServers: [
        RTCIceServer(
          urls: Constants.stunServer,
          username: Constants.stunUser,
          credential: Constants.stunPassword,
        )
      ],
    );
    session = await janusClient.createSession();
    videoCallPlugin = await session.attach<JanusVideoCallPlugin>();
    final userid = settings.userId;
    final name = settings.fullUserName;
    await remoteRender.initialize();
    await videoCallPlugin.register('${userid!}///$name');
    temp = await createLocalMediaStream('remoteVideoStream');
    await initAudioBridge();

    videoCallPlugin.remoteTrack?.listen(
      (event) async {
        if (event.track != null && event.flowing == true) {
          temp?.addTrack(event.track!);
          remoteRender.srcObject = temp;
          remoteRender.muted = false;
          // this is done only for web since web api are muted by default for local tagged mediaStream
        } else {
          temp?.removeTrack(event.track!);
        }
      },
    );

    videoCallPlugin.typedMessages?.listen(
      (event) async {
        await videoCallPlugin.handleRemoteJsep(event.jsep);
        Object data = event.event.plugindata?.data;
        if (data is VideoCallRegisteredEvent) {
          callState.add(CallState.ready());
        }
        if (data is VideoCallIncomingCallEvent) {
          callState.add(CallState.incoming(message: '', callerName: data.result!.username!, jsep: event.jsep!));
        }
        if (data is VideoCallAcceptedEvent) {
          callState.add(CallState.inCall(type: CallType.single));
        }
        if (data is VideoCallCallingEvent) {
          callState.add(CallState.outgoing(message: 'Call'));
        }
        if (data is VideoCallHangupEvent) {
          callState.add(CallState.hangup());
        }
      },
    );
  }
shivanshtalwar0 commented 1 year ago

Are you calling initJanus from ui tree itself?

rtviwe commented 1 year ago

Not directly. From ui I call presenter method and then presenter calls this initJanus

  @override
  Widget build(BuildContext context, WidgetRef ref) {
    final webRtcPresenter = ref.watch(webRTCPresenterProvider.notifier);

    useEffect(
      () {
        Future.delayed(
          Duration.zero,
          () => webRtcPresenter.load(),
        );

        return () {};
      },
      const [],
    );
shivanshtalwar0 commented 1 year ago

Why you calling expensive and uncertain operation in the build method in the first place try moving initJanus in didDepedencyChanged hook and you will no longer have ui freezes its not an issue with library itself, its something you need to keep in mind while developing flutter application never put api call or i/o operations in build method closing this.