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