Minimal Call using IMediaNetwork

using Byn.Media;
using Byn.Net;
using UnityEngine;

namespace Byn.Unity.Examples
{
    /// <summary>
    /// This example results in the same behavior as MinimalCall but
    /// uses instead the MinimalMediaNetwork interface.
    /// While the ICall interface isn't yet completed you can use the 
    /// IMediaNetwork interface to gain access to some additional features 
    /// such as sending byte[] reliable / unreliable and creating custom 
    /// typologies. 
    /// IMediaNetwork is not aware of network topologies at all and is simply
    /// a collection of peer connections. StartServer will allocate an address 
    /// via the Signaling Server and thus allow incoming connections and 
    /// Connect() will create a new outgoing connection. 
    /// MediaConfig will be set for all peers e.g. if video and audio is 
    /// set to active it will stream it to all incoming and outgoing connections.
    /// 
    /// You can IMediaNetwork for example to create a server / client structure 
    /// where one user streams to multiple users or for conference calls where
    /// each connection can be controlled manually. 
    /// 
    /// Note that IMediaNetwork is mainly for internal purposes. It might
    /// behave differently on different platforms and change in further updates.
    /// </summary>
    public class MinimalMediaNetwork : MonoBehaviour
    {
        IMediaNetwork sender;
        private bool mSenderConfigured = false;
        IMediaNetwork receiver;
        private bool mReceiverConfigured = false;

        private NetworkConfig netConf;
        private string address;

        void Start()
        {
            //STEP1: instance setup

            if (UnityCallFactory.Instance == null)
            {
                //if it is null something went terribly wrong
                Debug.LogError("UnityCallFactory missing. Platform not supported / dll's missing?");
                return;
            }
            address = Application.productName + "_MinimalMediaNetwork";

            netConf = new NetworkConfig();
            netConf.SignalingUrl = ExampleGlobals.Signaling;
            netConf.IceServers.Add(new IceServer(ExampleGlobals.TurnUrl));
            SetupReceiver();
        }

        private void SetupReceiver()
        {
            //STEP2: Setup the receiver. See UpdateReceiver() for event handling
            Debug.Log("receiver setup");
            MediaConfig mediaConf1 = new MediaConfig();
            //first one only receives
            mediaConf1.Video = false;
            mediaConf1.Audio = false;

            receiver = UnityCallFactory.Instance.CreateMediaNetwork(netConf);
            receiver.Configure(mediaConf1);
        }

        private void UpdateReceiver()
        {
            //STEP3: Updating the receiver. Will be called ever frame
            //IMediaNetwork uses polling instead of events
            receiver.Update();

            //check if the configuration state changed
            if (receiver.GetConfigurationState() == MediaConfigurationState.Failed)
            {
                //did configuration fail? error
                Debug.Log("receiver configuration failed " + receiver.GetConfigurationError());
                receiver.ResetConfiguration();
            }
            else if (receiver.GetConfigurationState() == MediaConfigurationState.Successful
                && mReceiverConfigured == false)
            {
                //configuration successful.
                mReceiverConfigured = true;
                //StartServer corresponds to ICall.Listen
                receiver.StartServer(address);
            }

            //Dequeue network events
            NetworkEvent evt;
            while (receiver.Dequeue(out evt))
            {
                
                if (evt.Type == NetEventType.ServerInitialized)
                {
                    //triggered if StartServer completed
                    Debug.Log("receiver: server initialized.");
                    //receiver is ready -> create sender
                    SenderSetup();
                }
                else if (evt.Type == NetEventType.ServerInitFailed)
                {
                    //either network problem or address in use
                    Debug.LogError("receiver: server init failed");
                }
                else if (evt.Type == NetEventType.NewConnection)
                {
                    //triggered if a new connection is established
                    Debug.Log("receiver: New connection with id " + evt.ConnectionId);
                }
            }
            receiver.Flush();
        }
        private void SenderSetup()
        {
            //STEP4: receiver is ready -> start the sender 
            Debug.Log("sender setup");
            sender = UnityCallFactory.Instance.CreateMediaNetwork(netConf);
            MediaConfig mediaConf2 = new MediaConfig();
            mediaConf2.Video = false;
            mediaConf2.Audio = true;
            sender.Configure(mediaConf2);
        }


        private void UpdateSender()
        {
            //STEP5: Sender update loop. Same as receiver but is calling Connect
            //once configure completed.
            sender.Update();

            NetworkEvent evt;

            if (sender.GetConfigurationState() == MediaConfigurationState.Failed)
            {
                //did configuration fail? error
                Debug.Log("sender configuration failed " + sender.GetConfigurationError());
                sender.ResetConfiguration();
            }
            else if (sender.GetConfigurationState() == MediaConfigurationState.Successful
                && mSenderConfigured == false)
            {
                mSenderConfigured = true;

                //connecting to to the receiver
                sender.Connect(address);
            }

            while (sender.Dequeue(out evt))
            {
                if (evt.Type == NetEventType.NewConnection)
                {
                    Debug.Log("sender: New connection with id " + evt.ConnectionId);
                }
                else if (evt.Type == NetEventType.ConnectionFailed)
                {
                    Debug.LogError("sender: connection failed");
                }
            }
            sender.Flush();
        }


        private void OnDestroy()
        {
            if (receiver != null)
            {
                receiver.Dispose();
                receiver = null;
            }
            if (sender != null)
            {
                sender.Dispose();
                sender = null;
            }
        }


        // Update is called once per frame
        void Update()
        {
            if (receiver != null)
                UpdateReceiver();

            if (sender != null)
                UpdateSender();
        }
    }
}

Leave a Reply