美文网首页
Unity3D开发技术研究(FMETP STREAM)实时画面传

Unity3D开发技术研究(FMETP STREAM)实时画面传

作者: TonyWan_AR | 来源:发表于2021-10-06 23:28 被阅读0次

    一、框架视图





    二、关键代码

    FMNetworkManager

    using UnityEngine;
    using UnityEngine.UI;
    using System;
    
    
    using System.Net;
    using System.Net.Sockets;
    using System.Net.NetworkInformation;
    
    public enum FMNetworkType { Server, Client }
    public enum FMSendType { All, Server, Others, TargetIP }
    public struct FMPacket
    {
        public byte[] SendByte;
        public string SkipIP;
        public FMSendType SendType;
        public string TargetIP;
    }
    public struct FMNetworkTransform
    {
        public Vector3 position;
        public Quaternion rotation;
        public Vector3 localScale;
    }
    
    public class FMNetworkManager : MonoBehaviour
    {
        public string LocalIPAddress()
        {
            string localIP = "0.0.0.0";
            //ssIPHostEntry host;
            //host = Dns.GetHostEntry(Dns.GetHostName());
    
            foreach (NetworkInterface ni in NetworkInterface.GetAllNetworkInterfaces())
            {
                if (ni.NetworkInterfaceType == NetworkInterfaceType.Wireless80211 || ni.NetworkInterfaceType == NetworkInterfaceType.Ethernet)
                {
                    foreach (UnicastIPAddressInformation ip in ni.GetIPProperties().UnicastAddresses)
                    {
                        if (ip.Address.AddressFamily == AddressFamily.InterNetwork)
                        {
                            if (ip.IsDnsEligible)
                            {
                                try
                                {
                                    if (ip.AddressValidLifetime / 2 != int.MaxValue)
                                    {
                                        localIP = ip.Address.ToString();
                                        break;
                                    }
                                    else
                                    {
                                        //if didn't find any yet, this is the only one
                                        if (localIP == "0.0.0.0") localIP = ip.Address.ToString();
                                    }
                                }
                                catch (Exception e)
                                {
                                    localIP = ip.Address.ToString();
                                    //Debug.Log("LocalIPAddress(): " + e.ToString());
                                    break;
                                }
                            }
                        }
                    }
                }
            }
            return localIP;
        }
    
        private string _localIP;
        public string ReadLocalIPAddress
        {
            get
            {
                if(_localIP == null) _localIP = LocalIPAddress();
                if (_localIP.Length <= 3) _localIP = LocalIPAddress();
                return _localIP;
            }
        }
    
        public static FMNetworkManager instance;
        public bool AutoInit = true;
    
        [HideInInspector]
        public bool Initialised = false;
    
        [Tooltip("Initialise as Server or Client")]
        public FMNetworkType NetworkType;
    
        [HideInInspector]
        public FMServer Server;
        [HideInInspector]
        public FMClient Client;
    
        [System.Serializable]
        public class FMServerSettings
        {
            public int ServerListenPort = 3333;
    
            [Tooltip("(( on supported devices only ))")]
            public bool UseAsyncListener = false;
    
            [Tooltip("(( suggested for low-end mobile, but not recommend for streaming large data ))")]
            public bool UseMainThreadSender = true;
            public int ConnectionCount;
        }
    
        [System.Serializable]
        public class FMClientSettings
        {
            public int ClientListenPort = 3334;
    
            [Tooltip("(( suggested for low-end mobile, but not recommend for streaming large data ))")]
            public bool UseMainThreadSender = true;
    
            [Tooltip("(( true by default ))")]
            public bool AutoNetworkDiscovery = true;
            [Tooltip("(( only applied when Auto Network Discovery is off ))")]
            public string ServerIP;
            public bool IsConnected;
        }
    
        [Tooltip("Network Settings for Server")]
        public FMServerSettings ServerSettings;
        [Tooltip("Network Settings for Client")]
        public FMClientSettings ClientSettings;
    
    
        public bool ShowLog = true;
        [TextArea(1, 10)]
        public string Status;
        public Text UIStatus;
    
        public UnityEventByteArray OnReceivedByteDataEvent;
        public UnityEventString OnReceivedStringDataEvent;
        public UnityEventByteArray GetRawReceivedData;
    
        #region Network Objects Setup
        [Header("[ Sync ] Server => Client")]
        [Tooltip("Sync Transformation of Network Objects. # Both Server and Clients should have same number of NetworkObjects")]
        public GameObject[] NetworkObjects;
        FMNetworkTransform[] NetworkTransform;
    
        //[Tooltip("Frequency for sync (second)")]
        float SyncFrequency = 0.05f;
        [Range(1f, 60f)]
        public float SyncFPS = 20f;
        float SyncTimer = 0f;
    
        float LastReceivedTimestamp = 0f;
        float TargetTimestamp = 0f;
        float CurrentTimestamp = 0f;
    
        void Action_SendNetworkObjectTransform()
        {
            if (NetworkType == FMNetworkType.Server)
            {
                byte[] Timestamp = BitConverter.GetBytes(Time.realtimeSinceStartup);
    
                byte[] Data = new byte[NetworkObjects.Length * 10 * 4];
                byte[] SendByte = new byte[Timestamp.Length + Data.Length];
    
                int index = 0;
                Buffer.BlockCopy(Timestamp, 0, SendByte, index, Timestamp.Length);
                index += Timestamp.Length;
    
                foreach (GameObject obj in NetworkObjects)
                {
                    byte[] TransformByte = EncodeTransformByte(obj);
                    Buffer.BlockCopy(TransformByte, 0, SendByte, index, TransformByte.Length);
                    index += TransformByte.Length;
                }
                Server.Action_AddNetworkObjectPacket(SendByte, FMSendType.Others);
            }
        }
    
        byte[] EncodeTransformByte(GameObject obj)
        {
            byte[] _byte = new byte[40];
            Vector3 _pos = obj.transform.position;
            Quaternion _rot = obj.transform.rotation;
            Vector3 _scale = obj.transform.localScale;
    
            float[] _float = new float[]
            {
                _pos.x,_pos.y,_pos.z,
                _rot.x,_rot.y,_rot.z,_rot.w,
                _scale.x,_scale.y,_scale.z
            };
            Buffer.BlockCopy(_float, 0, _byte, 0, _byte.Length);
            return _byte;
        }
    
        float[] DecodeByteToFloatArray(byte[] _data, int _offset)
        {
            float[] _transform = new float[10];
            for (int i = 0; i < _transform.Length; i++)
            {
                _transform[i] = BitConverter.ToSingle(_data, i * 4 + _offset);
            }
    
    
            return _transform;
        }
    
        //float LastReceiveTime = 0f;
        //public int _fps = 0;
        public void Action_SyncNetworkObjectTransform(byte[] _data)
        {
            //_fps = (int)((1f / (Time.realtimeSinceStartup - LastReceiveTime)));
            //LastReceiveTime = Time.realtimeSinceStartup;
            //Debug.Log(_fps);
    
            float Timestamp = BitConverter.ToSingle(_data, 0);
            int meta_offset = 4;
    
            if (Timestamp > LastReceivedTimestamp)
            {
                LastReceivedTimestamp = TargetTimestamp;
                TargetTimestamp = Timestamp;
                CurrentTimestamp = LastReceivedTimestamp;
    
                for (int i = 0; i < NetworkObjects.Length; i++)
                {
                    float[] _transform = DecodeByteToFloatArray(_data, meta_offset + i * 40);
                    NetworkTransform[i].position = new Vector3(_transform[0], _transform[1], _transform[2]);
                    NetworkTransform[i].rotation = new Quaternion(_transform[3], _transform[4], _transform[5], _transform[6]);
                    NetworkTransform[i].localScale = new Vector3(_transform[7], _transform[8], _transform[9]);
                }
            }
    
    
        }
        #endregion
    
        public void Action_InitAsServer()
        {
            NetworkType = FMNetworkType.Server;
            Init();
        }
    
        public void Action_InitAsClient()
        {
            NetworkType = FMNetworkType.Client;
            Init();
        }
    
        void Init()
        {
            if (NetworkType == FMNetworkType.Server)
            {
                Server = this.gameObject.AddComponent<FMServer>();
                Server.Manager = this;
    
                Server.ServerListenPort = ServerSettings.ServerListenPort;
                Server.ClientListenPort = ClientSettings.ClientListenPort;
    
                Server.UseAsyncListener = ServerSettings.UseAsyncListener;
                Server.UseMainThreadSender = ServerSettings.UseMainThreadSender;
            }
            else
            {
                Client = this.gameObject.AddComponent<FMClient>();
                Client.Manager = this;
    
                Client.ServerListenPort = ServerSettings.ServerListenPort;
                Client.ClientListenPort = ClientSettings.ClientListenPort;
    
                Client.UseMainThreadSender = ClientSettings.UseMainThreadSender;
                Client.AutoNetworkDiscovery = ClientSettings.AutoNetworkDiscovery;
                if (ClientSettings.ServerIP == "") ClientSettings.ServerIP = "127.0.0.1";
                if (!Client.AutoNetworkDiscovery) Client.ServerIP = ClientSettings.ServerIP;
    
                NetworkTransform = new FMNetworkTransform[NetworkObjects.Length];
                for (int i = 0; i < NetworkTransform.Length; i++)
                {
                    NetworkTransform[i] = new FMNetworkTransform();
                    NetworkTransform[i].position = Vector3.zero;
                    NetworkTransform[i].rotation = Quaternion.identity;
                    NetworkTransform[i].localScale = new Vector3(1f, 1f, 1f);
                }
            }
    
            Initialised = true;
        }
    
        void Awake()
        {
            Application.runInBackground = true;
            if (instance == null) instance = this;
        }
    
        //void Awake()
        //{
        //    if (instance == null)
        //    {
        //        instance = this;
        //        this.gameObject.transform.parent = null;
        //        DontDestroyOnLoad(this.gameObject);
        //    }
        //    else
        //    {
        //        Destroy(this.gameObject);
        //    }
        //}
    
        // Use this for initialization
        void Start()
        {
            if (AutoInit) Init();
        }
    
        // Update is called once per frame
        void Update()
        {
            if (Initialised == false) return;
    
            //====================Sync Network Object============================
            #region Sync Network Objects
            if (NetworkType == FMNetworkType.Server)
            {
                //on Server
                if (Server.ConnectionCount > 0)
                {
                    if (NetworkObjects.Length > 0)
                    {
                        SyncFrequency = 1f / SyncFPS;
                        SyncTimer += Time.deltaTime;
                        if (SyncTimer > SyncFrequency)
                        {
                            Action_SendNetworkObjectTransform();
                            SyncTimer = SyncTimer % SyncFrequency;
                        }
                    }
                }
                Server.ShowLog = ShowLog;
            }
            else
            {
                //on Client
                if (Client.IsConnected)
                {
                    if (NetworkObjects.Length > 0)
                    {
                        for (int i = 0; i < NetworkObjects.Length; i++)
                        {
                            CurrentTimestamp += Time.deltaTime;
                            float step = (CurrentTimestamp - LastReceivedTimestamp) / (TargetTimestamp - LastReceivedTimestamp);
                            step = Mathf.Clamp(step, 0f, 1f);
                            NetworkObjects[i].transform.position = Vector3.Slerp(NetworkObjects[i].transform.position, NetworkTransform[i].position, step);
                            NetworkObjects[i].transform.rotation = Quaternion.Slerp(NetworkObjects[i].transform.rotation, NetworkTransform[i].rotation, step);
                            NetworkObjects[i].transform.localScale = Vector3.Slerp(NetworkObjects[i].transform.localScale, NetworkTransform[i].localScale, step);
                        }
                    }
                }
                Client.ShowLog = ShowLog;
            }
            #endregion
            //====================Sync Network Object============================
    
            //====================Update Debug Text============================
            #region Debug Status
            string _status = "";
            _status += "Thread: " + Loom.numThreads + " / " + Loom.maxThreads + "\n";
            _status += "Network Type: " + NetworkType.ToString() + "\n";
            _status += "Local IP: " + ReadLocalIPAddress + "\n";
    
            if (NetworkType == FMNetworkType.Server)
            {
                ServerSettings.ConnectionCount = Server.ConnectionCount;
    
                _status += "Connection Count: " + ServerSettings.ConnectionCount + "\n";
                _status += "Async Listener: " + ServerSettings.UseAsyncListener + "\n";
                _status += "Use Main Thread Sender: " + ServerSettings.UseMainThreadSender + "\n";
    
                foreach (FMServer.ConnectedClient _cc in Server.ConnectedClients)
                {
                    if (_cc != null)
                    {
                        _status += "connected ip: " + _cc.IP + "\n";
    
                        _status += "last seen: " + _cc.LastSeenTimeMS + "\n";
                        _status += "last send: " + _cc.LastSentTimeMS + "\n";
                    }
                    else
                    {
                        _status += "Connected Client: null/unknown issue" + "\n";
                    }
                }
            }
            else
            {
                ClientSettings.IsConnected = Client.IsConnected;
    
                _status += "Is Connected: " + ClientSettings.IsConnected + "\n";
                _status += "Use Main Thread Sender: " + ClientSettings.UseMainThreadSender + "\n";
    
                _status += "last send: " + Client.LastSentTimeMS + "\n";
                _status += "last received: " + Client.LastReceivedTimeMS + "\n";
            }
    
            Status = _status;
            if (UIStatus != null) UIStatus.text = Status;
            #endregion
            //====================Update Debug Text============================
        }
    
        #region SENDER MAPPING
        public void Send(byte[] _byteData, FMSendType _type){Send(_byteData, _type, null);}
        public void Send(string _stringData, FMSendType _type){Send(_stringData, _type, null);}
    
        public void SendToAll(byte[] _byteData){Send(_byteData, FMSendType.All, null);}
        public void SendToServer(byte[] _byteData){Send(_byteData, FMSendType.Server, null);}
        public void SendToOthers(byte[] _byteData){Send(_byteData, FMSendType.Others, null);}
    
        public void SendToAll(string _stringData){Send(_stringData, FMSendType.All, null);}
        public void SendToServer(string _stringData){Send(_stringData, FMSendType.Server, null);}
        public void SendToOthers(string _stringData){Send(_stringData, FMSendType.Others, null);}
    
        public void SendToTarget(byte[] _byteData, string _targetIP)
        {
            if (_targetIP == ReadLocalIPAddress || _targetIP == "127.0.0.1" || _targetIP == "localhost")
            {
                OnReceivedByteDataEvent.Invoke(_byteData);
            }
            else
            {
                Send(_byteData, FMSendType.TargetIP, _targetIP);
            }
        }
        public void SendToTarget(string _stringData, string _targetIP)
        {
            if (_targetIP == ReadLocalIPAddress || _targetIP == "127.0.0.1" || _targetIP == "localhost")
            {
                OnReceivedStringDataEvent.Invoke(_stringData);
            }
            else
            {
                Send(_stringData, FMSendType.TargetIP, _targetIP);
            }
        }
    
        private void Send(byte[] _byteData, FMSendType _type, string _targetIP)
        {
            if (!Initialised) return;
            if (NetworkType == FMNetworkType.Client && !Client.IsConnected) return;
    
            switch (_type)
            {
                case FMSendType.All:
                    if (NetworkType == FMNetworkType.Server)
                    {
                        Server.Action_AddPacket(_byteData, _type);
                        OnReceivedByteDataEvent.Invoke(_byteData);
                    }
                    else
                    {
                        Client.Action_AddPacket(_byteData, _type);
                    }
                    break;
                case FMSendType.Server:
                    if (NetworkType == FMNetworkType.Server)
                    {
                        OnReceivedByteDataEvent.Invoke(_byteData);
                    }
                    else
                    {
                        Client.Action_AddPacket(_byteData, _type);
                    }
                    break;
                case FMSendType.Others:
                    if (NetworkType == FMNetworkType.Server)
                    {
                        Server.Action_AddPacket(_byteData, _type);
                    }
                    else
                    {
                        Client.Action_AddPacket(_byteData, _type);
                    }
                    break;
                case FMSendType.TargetIP:
                    if (NetworkType == FMNetworkType.Server)
                    {
                        if(_targetIP.Length > 4) Server.Action_AddPacket(_byteData, _targetIP);
                    }
                    else
                    {
                        if (_targetIP.Length > 4) Client.Action_AddPacket(_byteData, _targetIP);
                    }
                    break;
            }
        }
    
        private void Send(string _stringData, FMSendType _type, string _targetIP)
        {
            if (!Initialised) return;
            if (NetworkType == FMNetworkType.Client && !Client.IsConnected) return;
    
            switch (_type)
            {
                case FMSendType.All:
                    if (NetworkType == FMNetworkType.Server)
                    {
                        Server.Action_AddPacket(_stringData, _type);
                        OnReceivedStringDataEvent.Invoke(_stringData);
                    }
                    else
                    {
                        Client.Action_AddPacket(_stringData, _type);
                    }
                    break;
                case FMSendType.Server:
                    if (NetworkType == FMNetworkType.Server)
                    {
                        OnReceivedStringDataEvent.Invoke(_stringData);
                    }
                    else
                    {
                        Client.Action_AddPacket(_stringData, _type);
                    }
                    break;
                case FMSendType.Others:
                    if (NetworkType == FMNetworkType.Server)
                    {
                        Server.Action_AddPacket(_stringData, _type);
                    }
                    else
                    {
                        Client.Action_AddPacket(_stringData, _type);
                    }
                    break;
                case FMSendType.TargetIP:
                    if (NetworkType == FMNetworkType.Server)
                    {
                        if (_targetIP.Length > 6) Server.Action_AddPacket(_stringData, _targetIP);
                    }
                    else
                    {
                        if (_targetIP.Length > 6) Client.Action_AddPacket(_stringData, _targetIP);
                    }
                    break;
            }
        }
    
        #endregion
    
        public void Action_ReloadScene()
        {
            UnityEngine.SceneManagement.SceneManager.LoadScene(UnityEngine.SceneManagement.SceneManager.GetActiveScene().name);
        }
    
    }
    
    
    

    FMNetwork_Demo

    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;
    using System.Text;
    using UnityEngine.UI;
    
    public class FMNetwork_Demo : MonoBehaviour {
    
        public Text ServerText;
        public Text ClientText;
    
        public void Action_ProcessStringData(string _string)
        {
            if(FMNetworkManager.instance.NetworkType == FMNetworkType.Server)
            {
                if (ServerText != null) ServerText.text = "Server Received : " + _string;
            }
            else
            {
                if (ClientText != null) ClientText.text = "Client Received : " + _string;
            }
        }
    
        public void Action_ProcessByteData(byte[] _byte)
        {
            if (FMNetworkManager.instance.NetworkType == FMNetworkType.Server)
            {
                if (ServerText != null) ServerText.text = "Server Received byte[] : " + _byte.Length;
            }
            else
            {
                if (ClientText != null) ClientText.text = "Client Received byte[]: " + _byte.Length;
            }
        }
    
        public void Action_ShowRawByteLength(byte[] _byte)
        {
            Debug.Log("get byte length: " + _byte.Length);
        }
    
        // Use this for initialization
        void Start () {
            if (Box1 != null) StartPosBox1 = Box1.transform.position;
            if (Box2 != null) StartPosBox2 = Box2.transform.position;
        }
    
        public GameObject Box1;
        public GameObject Box2;
        public Vector3 StartPosBox1;
        public Vector3 StartPosBox2;
        public Toggle toggle;
    
        public LargeFileEncoder LFE;
        public Text LFE_text;
    
        [Space]
        [Header("[New] Send To Target IP")]
        public string TargetIP = "127.0.0.1";
        public void Action_SetTargetIP(string _targetIP) { TargetIP = _targetIP; }
    
        public void Action_SendRandomLargeFile()
        {
            LFE.Action_SendLargeByte(new byte[(int)(1024f * 1024f * ((int)Random.Range(2, 4)))]);
        }
        public void Action_DemoReceivedLargeFile(byte[] _data)
        {
            //LFE_text.text = (float)_data.Length/(float)(1024*1024) + " MB";
        }
    
        private void Update()
        {
            if (FMNetworkManager.instance.NetworkType == FMNetworkType.Server)
            {
                if (toggle.isOn)
                {
                    if (Box1 != null && Box2 != null)
                    {
                        Box1.transform.Rotate(new Vector3(0f, Time.deltaTime * 15f, 0f));
                        Box1.transform.position = new Vector3(Mathf.Sin(Time.realtimeSinceStartup), 0f, 0f) + StartPosBox1;
                        Box1.transform.localScale = new Vector3(1f, 1f, 1f) * (1f + 0.5f * Mathf.Sin(Time.realtimeSinceStartup * 3f));
    
                        Box2.transform.Rotate(new Vector3(0f, Time.deltaTime * 30f, 0f));
                        Box2.transform.position = new Vector3(Mathf.Sin(Time.realtimeSinceStartup * 0.5f), 0f, -1f) + StartPosBox2;
                        Box2.transform.localScale = new Vector3(1f, 1f, 1f) * (1f + 0.5f * Mathf.Sin(Time.realtimeSinceStartup * 2f));
                    }
                }
            }
        }
    
        public void Action_SendByteToAll(int _value)
        {
            FMNetworkManager.instance.SendToAll(new byte[_value]);
        }
        public void Action_SendByteToServer(int _value)
        {
            FMNetworkManager.instance.SendToServer(new byte[_value]);
        }
        public void Action_SendByteToOthers(int _value)
        {
            FMNetworkManager.instance.SendToOthers(new byte[_value]);
        }
        public void Action_SendByteToTarget(int _value)
        {
            FMNetworkManager.instance.SendToTarget(new byte[_value], TargetIP);
        }
    
        public void Action_SendTextToAll(string _value)
        {
            FMNetworkManager.instance.SendToAll(_value);
        }
        public void Action_SendTextToServer(string _value)
        {
            FMNetworkManager.instance.SendToServer(_value);
        }
        public void Action_SendTextToOthers(string _value)
        {
            FMNetworkManager.instance.SendToOthers(_value);
        }
        public void Action_SendTextToTarget(string _value)
        {
            FMNetworkManager.instance.SendToTarget(_value, TargetIP);
        }
    
        public void Action_SendRandomTextToAll()
        {
            string _value = Random.value.ToString();
            FMNetworkManager.instance.SendToAll(_value);
        }
        public void Action_SendRandomTextToServer()
        {
            string _value = Random.value.ToString();
            FMNetworkManager.instance.SendToServer(_value);
        }
        public void Action_SendRandomTextToOthers()
        {
            string _value = Random.value.ToString();
            FMNetworkManager.instance.SendToOthers(_value);
        }
        public void Action_SendRandomTextToTarget()
        {
            string _value = Random.value.ToString();
            FMNetworkManager.instance.SendToTarget(_value, TargetIP);
        }
    }
    
    

    LargeFileEncoder

    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;
    using System;
    
    public class LargeFileEncoder : MonoBehaviour {
    
        public bool Sending = false;
    
        [Tooltip("smaller number: take longer time to send \nTry to reduce the number if the file cannot be sent successfully")]
        [Range(1,60)]
        public int AddDelayEveryPacket = 4;
    
        public UnityEventByteArray OnDataByteReadyEvent;
    
        [Header("Pair Encoder & Decoder")]
        public int label = 8001;
        int dataID = 0;
        int maxID = 1024;
        int chunkSize = 8096; //32768;
    
        public int dataLength;
    
        void Start()
        {
            Application.runInBackground = true;
        }
    
        public void Action_SendLargeByte(byte[] _data)
        {
            StartCoroutine(SenderCOR(_data));
        }
    
        IEnumerator SenderCOR(byte[] dataByte)
        {
            yield return null;
            if (!Sending)
            {
                Sending = true;
    
                dataLength = dataByte.Length;
                int _length = dataByte.Length;
                int _offset = 0;
    
                byte[] _meta_label = BitConverter.GetBytes(label);
                byte[] _meta_id = BitConverter.GetBytes(dataID);
                byte[] _meta_length = BitConverter.GetBytes(_length);
    
                int chunks = Mathf.FloorToInt(dataByte.Length / chunkSize);
                for (int i = 0; i <= chunks; i++)
                {
                    int SendByteLength = (i == chunks) ? (_length % chunkSize + 16) : (chunkSize + 16);
                    byte[] _meta_offset = BitConverter.GetBytes(_offset);
                    byte[] SendByte = new byte[SendByteLength];
    
                    Buffer.BlockCopy(_meta_label, 0, SendByte, 0, 4);
                    Buffer.BlockCopy(_meta_id, 0, SendByte, 4, 4);
                    Buffer.BlockCopy(_meta_length, 0, SendByte, 8, 4);
    
                    Buffer.BlockCopy(_meta_offset, 0, SendByte, 12, 4);
    
                    Buffer.BlockCopy(dataByte, _offset, SendByte, 16, SendByte.Length - 16);
                    OnDataByteReadyEvent.Invoke(SendByte);
                    _offset += chunkSize;
                }
    
                dataID++;
                if (dataID > maxID) dataID = 0;
    
                Sending = false;
            }
        }
    
        void OnDisable()
        {
            StopAll();
        }
        void OnApplicationQuit()
        {
            StopAll();
        }
        void OnDestroy()
        {
            StopAll();
        }
    
        void StopAll()
        {
            StopAllCoroutines();
        }
    }
    
    

    LargeFileDecoder

    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;
    using System;
    
    public class LargeFileDecoder : MonoBehaviour {
    
        public UnityEventByteArray OnReceivedByteArray;
    
        // Use this for initialization
        void Start()
        {
            Application.runInBackground = true;
        }
    
        bool ReadyToGetFrame = true;
    
        [Header("Pair Encoder & Decoder")]
        public int label = 8001;
        int dataID = 0;
        //int maxID = 1024;
        int dataLength = 0;
        int receivedLength = 0;
    
        byte[] dataByte;
    
        public void Action_ProcessData(byte[] _byteData)
        {
            if (_byteData.Length <= 8) return;
    
            int _label = BitConverter.ToInt32(_byteData, 0);
            if (_label != label) return;
            int _dataID = BitConverter.ToInt32(_byteData, 4);
            //if (_dataID < dataID) return;
    
            if (_dataID != dataID) receivedLength = 0;
    
            dataID = _dataID;
            dataLength = BitConverter.ToInt32(_byteData, 8);
            int _offset = BitConverter.ToInt32(_byteData, 12);
    
            if (receivedLength == 0) dataByte = new byte[dataLength];
            receivedLength += _byteData.Length - 16;
    
            Buffer.BlockCopy(_byteData, 16, dataByte, _offset, _byteData.Length - 16);
            if (ReadyToGetFrame)
            {
                if (receivedLength == dataLength) StartCoroutine(ProcessData(dataByte));
            }
        }
    
        IEnumerator ProcessData(byte[] _byteData)
        {
            ReadyToGetFrame = false;
            OnReceivedByteArray.Invoke(_byteData);
            ReadyToGetFrame = true;
            yield return null;
        }
    
        private void OnDisable()
        {
            StopAllCoroutines();
        }
    }
    
    

    三、效果展示

    相关文章

      网友评论

          本文标题:Unity3D开发技术研究(FMETP STREAM)实时画面传

          本文链接:https://www.haomeiwen.com/subject/zlranltx.html