Agora.io - When other user leave channel and rejoin, the video stream of the other user hanged/stopped updating

Viewed 1036

I tried to do a video streaming application with Unity and I have successfully connect two user and are able to video chat & sharescreen. The problem is now when the other/second user press leave channel and rejoin again, first user will see the second user screen just stopped at the last frame. Only way to deal with it right now is to exit Unity play mode and re-enter again. Below are the code:

    void LoadEngine()
    {
        print("Loading Engine...");

        if (engine != null)
        {
            print("Engine already exists. Please unload it first!");
            return;
        }

        engine = IRtcEngine.GetEngine(appId);
        engine.SetLogFilter(LOG_FILTER.DEBUG);
    }

    void UnloadEngine()
    {
        print("Unloading Engine...");

        if (engine != null)
        {
            IRtcEngine.Destroy();
            engine = null;
        }
    }

    void EnableVideo(bool yes)
    {
        engine.DisableAudio();
        if (yes)
        {
            engine.EnableVideo();
            engine.EnableVideoObserver();
        }
        else
        {
            engine.DisableVideo();
            engine.DisableVideoObserver();
        }
    }

    private void JoinChannel()
    {
        print("Joining Channel...");

        EnableVideo(true);

        // add our callback to handle Agora events
        engine.OnJoinChannelSuccess += OnJoinChannelSuccess;
        engine.OnUserJoined += OnUserJoined;
        engine.OnUserOffline += OnUserLeave;
        engine.OnLeaveChannel += OnLeaveChannel;

        button_Join.onClick.RemoveListener(JoinChannel);
        button_Join.onClick.AddListener(LeaveChannel);
        button_Join.GetComponentInChildren<Text>().text = "Leave Channel";

        if (string.IsNullOrEmpty(channelName))
        {
            return;
        }

        engine.JoinChannel(channelName, null, 0);
    }

    private void LeaveChannel()
    {
        print("Leaving Channel...");

        button_Join.onClick.RemoveListener(LeaveChannel);
        button_Join.onClick.AddListener(JoinChannel);
        button_Join.GetComponentInChildren<Text>().text = "Join Channel";

        playerOne.Clear();
        playerTwo.Clear();

        engine.LeaveChannel();
        EnableVideo(false);

        engine.OnJoinChannelSuccess -= OnJoinChannelSuccess;
        engine.OnUserJoined -= OnUserJoined;
        engine.OnUserOffline -= OnUserLeave;
        engine.OnLeaveChannel -= OnLeaveChannel;
    }

    private void OnJoinChannelSuccess(string channelName, uint uid, int elapsed)
    {
        print("Joined with uid " + uid);
        myId = uid;
        playerOne.Set(0);
    }

    private void OnUserJoined(uint uid, int elapsed)
    {
        string userJoinedMessage = string.Format("onUserJoined callback uid {0} with elapsed {1}", uid, elapsed);
        print(userJoinedMessage);

        playerTwo.Set(uid);
    }

    private void OnUserLeave(uint uid, USER_OFFLINE_REASON reason)
    {
        string userLeaveMessage = string.Format("onUserOffline callback uid {0} with reason {1}", uid, reason);
        print(userLeaveMessage);

        playerTwo.Clear();
    }

    private void OnLeaveChannel(RtcStats stats)
    {
        playerTwo.Clear();
    }

    private void OnApplicationQuit()
    {
        UnloadEngine();
    }

Is there anything I missed out in the code?

Edit

I suspect this is Agora API bugs where the video surface will not continue to stream the video when the UID was being changed in the runtime. This explained when the same user leave and rejoin, he will get different uid everytime he rejoin. The video surface will need to set UID to another number which causes the video surface stopped streaming.

Solution

I solved it using unity instantiate to real time instantiate the video surface when connected to channel and destroy the video surface game object when leaving a channel.

2 Answers

first of all, great name! ;)

I'm glad that you were able to work out a solution. Another technique you can try, is calling: yourVideoSurface.SetForUser(yourNewUID);

It looks like you're already implicitly doing that in your playerOne.Set(0) call, however I'd figure I'd mention it just in case.

I had the same issue in Unity. The tmp was returning -1. In the Update loop of VideoSurface.cs if this occurs, the update loop stops.

if (tmpi == -1)
return;

I agree with Jeremy, the Agora VideoSurface doesn't support changing users. I set the UID on the VideoSurface manually and it fixed the issue. I also agree that the sdk implies that it would change- which is misleading and frustrating.

I believe the issue may occur because VideoSurface.cs sets uint uid = mUid; in the update loop, so it is set to the default ID when the Unity scene starts then errors out when videoSurface.SetForUser(uid); is called by TestHelloUnityVideo when a user joins.

Related