【问题标题】:Agora.io - When other user leave channel and rejoin, the video stream of the other user hanged/stopped updatingAgora.io - 当其他用户离开频道并重新加入时,其他用户的视频流挂起/停止更新
【发布时间】:2020-06-15 10:39:31
【问题描述】:

我尝试使用 Unity 制作视频流应用程序,我已成功连接两个用户,并且能够进行视频聊天和共享屏幕。现在的问题是当另一个/第二个用户按下离开频道并再次重新加入时,第一个用户将看到第二个用户屏幕刚刚停止在最后一帧。目前唯一的处理方法是退出 Unity 播放模式并重新进入。下面是代码:

    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();
    }

我在代码中遗漏了什么吗?

编辑

我怀疑这是 Agora API 的错误,当在运行时更改 UID 时,视频表面将不会继续流式传输视频。这解释了当同一个用户离开并重新加入时,他每次重新加入都会得到不同的 uid。视频表面需要将 UID 设置为另一个数字,这会导致视频表面停止流式传输。

解决方案

我使用统一实例化解决了这个问题,以便在连接到频道时实时实例化视频表面,并在离开频道时销毁视频表面游戏对象。

【问题讨论】:

  • 我也面临同样的问题,我想将我的大原始图像交换为一个较小的原始图像,分别代表远程和本地用户。如果我使用 SetForUser() 方法,原始图像会冻结并且 tmpi 总是返回 -1

标签: c# visual-studio unity3d video-streaming agora.io


【解决方案1】:

首先,好名字! ;)

很高兴您能够找到解决方案。 您可以尝试的另一种技术是调用: yourVideoSurface.SetForUser(yourNewUID);

看起来您已经在 playerOne.Set(0) 通话中隐含地这样做了,但我想我会提到它以防万一。

【讨论】:

  • 我在我的 VideoSurface 上呼叫 SetForUser(),当其他用户离开并重新加入时,视频仍然冻结。看起来videoRender.UpdateVideoRawData() 在使用更新的 uid 调用时返回 -1,这导致 VideoSurface.Update() 在修改其纹理之前中止。有什么想法吗?
  • @Jeremy 我的猜测是您正在使用旧的 UID 调用 SetForUser()。当用户离开/重新加入时,他们会使用新的唯一 UID 加入。我建议每当有新用户加入时删除并重新实例化图像。这是一个link to a github project you can use as reference,允许玩家随意离开/加入。希望对您有所帮助!
  • 不,我在日志中打印 UID,每次肯定都不一样。重新加入甚至不是特例。我在任何人加入之前预先制作了一个表面,并将其 UID 设置为最近加入的人。第一次工作而不是第二次。看起来很像 VideoSurface 根本不支持更改用户(即使界面暗示它支持)。
【解决方案2】:

我在 Unity 中遇到了同样的问题。 tmp 返回-1。在 VideoSurface.cs 的更新循环中,如果发生这种情况,更新循环将停止。

if (tmpi == -1)
return;

我同意 Jeremy 的观点,Agora VideoSurface 不支持更改用户。我在 VideoSurface 上手动设置了 UID,它解决了这个问题。我也同意 sdk 暗示它会改变——这是误导和令人沮丧的。

我认为可能会出现此问题,因为 VideoSurface.cs 在更新循环中设置了 uint uid = mUid;,因此在 Unity 场景启动时将其设置为默认 ID,然后当用户在 TestHelloUnityVideo 调用 videoSurface.SetForUser(uid); 时出错加入。

【讨论】:

    猜你喜欢
    • 2021-02-07
    • 1970-01-01
    • 2015-10-27
    • 1970-01-01
    • 2021-11-19
    • 1970-01-01
    • 1970-01-01
    • 2020-07-19
    • 1970-01-01
    相关资源
    最近更新 更多