c# – 使用新的Unity 5.1传输层API流式传输WebCamTexture

正如问题所述,我一直在尝试将WebCamTexture从带有网络摄像头的客户端流式传输到服务器.双方(客户端和服务器)都在Unity中.之后,客户端将部署到Android,服务器将成为桌面应用程序.

目前我正在使用以下方法获取纹理的像素:

tex.GetPixels32();

并使用自定义序列化程序对它们进行序列化(以优化其大小).我目前有一个未压缩的字节数组,每帧大约3,5MB,可以发送.我知道它很大,但我希望在开始之前将其传输到压缩部分和实时部分.

该过程的最后一部分应该是使用新的Unity NetworkTransport静态类发送它.自从我上次使用套接字以来已经很长时间了,我真的很烂.目前我无法让它工作.

这是我的服务器端代码(为清晰起见省略了序列化代码):

void Start()
{
    webcamTexture = new WebCamTexture();
    Background.texture = webcamTexture;
    Background.material.mainTexture = webcamTexture;
    webcamTexture.Play();

    if (!_isStarted)
    {
        _isStarted = true;

        NetworkTransport.Init();
        m_Config = new ConnectionConfig();
        m_CommunicationChannel  = m_Config.AddChannel(QosType.ReliableFragmented);
        HostTopology topology = new HostTopology(m_Config, 12);
        m_GenericHostId = NetworkTransport.AddHost(topology, 0);
        byte error;
        m_ConnectionId = NetworkTransport.Connect(m_GenericHostId, ip, port, 0, out error);
    }
}

void Update()
{
    if (!_isStarted)
        return;

    NetworkEventType recData = NetworkTransport.Receive(out recHostId, out connectionId, out channelId, recBuffer, bufferSize, out dataSize, out error);

    switch (recData)
    {
        case NetworkEventType.Nothing:         //1
            break;
        case NetworkEventType.ConnectEvent:    //2
            Debug.Log("Received connection confirmation");
            _readyToSend = true;
            break;
        case NetworkEventType.DataEvent:       //3

            break;
        case NetworkEventType.DisconnectEvent: //4
            //one of the established connection has been disconnected
            Debug.Log(String.Format("Disconnect from host {0} connection {1}", recHostId, connectionId));

            break;
    }

    if (_readyToSend)
    {
        _readyToSend = false; // To send just the first frame

        byte[] colourArray = SerializeObject(MakeSerializable(GetRenderTexturePixels(webcamTexture))); // Serialize the webcam texture

        // Sending total size
        byte[] sizeToSend = BitConverter.GetBytes(colourArray.Length);
        NetworkTransport.Send(m_GenericHostId, m_ConnectionId, m_CommunicationChannel, sizeToSend, sizeToSend.Length, out error);

        byte[] bytes = new byte[bufferLenght];
        int remainingBytes = colourArray.Length;
        int index = 0;
        int i = 1;

        while (remainingBytes >= bufferLenght)
        {
            System.Buffer.BlockCopy(colourArray, index, bytes, 0, bufferLenght);
            NetworkTransport.Send(m_GenericHostId, m_ConnectionId, m_CommunicationChannel, bytes, bytes.Length, out error);
            remainingBytes -= bufferLenght;
            Debug.Log(i++ + "Remaining bytes: " + remainingBytes + " - Error: "+error);
            index += bufferLenght;
        }

        if (remainingBytes > 0) // Send the last fragment below bufferLenght bytes
        {
            System.Buffer.BlockCopy(colourArray, index, bytes, 0, remainingBytes);
            NetworkTransport.Send(m_GenericHostId, m_ConnectionId, m_CommunicationChannel, bytes, remainingBytes, out error);
            Debug.Log("Error: "+error);
        }
    }
}

这是客户方:

void Start()
{
    if (!_isStarted)
    {
        _isStarted = true;

        NetworkTransport.Init();

        m_Config = new ConnectionConfig();

        m_CommunicationChannel  = m_Config.AddChannel(QosType.ReliableFragmented);

        HostTopology topology = new HostTopology(m_Config, 12);

        m_GenericHostId = NetworkTransport.AddHost(topology, port, null);
    }
}

void Update()
{
    if (!_isStarted)
        return;

    int recHostId; 
    int connectionId; 
    int channelId; 
    byte[] recBuffer = new byte[bufferLenght]; 
    int bufferSize = bufferLenght;
    int dataSize;
    byte error;

    NetworkEventType recData = NetworkTransport.Receive(out recHostId, out connectionId, out channelId, recBuffer, bufferSize, out dataSize, out error);

    switch (recData)
    {
        case NetworkEventType.Nothing:         //1
            break;

        case NetworkEventType.ConnectEvent:    //2

                //somebody else connect to me
            Log.text += string.Format("Connect from host {0} connection {1}\n", recHostId, connectionId);
            break;

        case NetworkEventType.DataEvent:       //3

            if (!sizeReceived)
            {
                sizeReceived = true;

                if (dataSize == 2)
                {
                    bytesToReceive = BitConverter.ToInt16(recBuffer, 0);
                }
                else if (dataSize == 4)
                {
                    bytesToReceive = BitConverter.ToInt32(recBuffer, 0);
                }

                Debug.Log("We will receive: "+bytesToReceive);
            }
            else
            {
                Log.text = string.Format("Received event host {0} connection {1} channel {2} message length {3}\n", recHostId, connectionId, channelId, dataSize);

                Log.text += "Received " + bufferSize + " bytes\n";
                bytesToReceive -= bufferSize;
                Log.text += "Remaining " + bytesToReceive + " bytes\n";
            }
            break;

        case NetworkEventType.DisconnectEvent: //4

            break;

    }
}

我知道它会阻止Update函数直到发送,但现在对我来说并不重要,因为我只是试图让一个帧被传输以了解这个新系统如何工作,并从那里开始.目前我在第一个包发送后收到此错误,缓冲区为32768字节:

no free events for long message
UnityEngine.Networking.NetworkTransport:Send(Int32, Int32, Int32, Byte[], Int32, Byte&)
CameraStreamer:Update() (at Assets/Scripts/Client/CameraStreamer.cs:112)

我还尝试使用1024缓冲区,显示消息只需要更长时间(超过100个成功发送包后).

根据this thread,它与发送的消息太快并填满队列有关,但所提出的解决方案都不适用于我.
我很感激任何帮助或方向,因为Unity文档真的很差.

解决方法:

即使使用Unity 5.2补丁,这个特定的测试代码/示例仍然会出现问题.

在Unity 5.3.4f1中运行代码,我能够看到错误4(NetworkError.NoResource)在大约200个数据包之后发生并且之后不久就停止发送.我认为原因是因为它是阻塞发送,因此消息队列永远不会正常刷新.

我重写了代码,以便在延迟2秒后从纹理中抓取网络摄像头图像(因为网络摄像头需要时间进行初始化,否则您会发送空白图像).

然后通过网络摄像头图像发送,每次执行Update的单个数据包现在看起来很好.可能是因为Update有时间运行并且没有被阻止.因此,发送数据包并退出Update函数,将索引和其他变量移出Update.

希望这有助于其他任何人看着这个,花了3天时间才弄明白.

编辑:对于测试,一个更简单的方法是移出阻塞发送(同时位)并将其添加到协同例程中.似乎也是这样工作的.

原文地址:https://codeday.me/bug/20190702/1359167.html

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


这篇文章将为大家详细讲解有关Unity3D中如何通过Animator动画状态机获取任意animation clip的准确播放持续时长,小编觉得挺实用的,因此分享给大家做个参考,
这篇文章主要介绍了Unity3D如何播放游戏视频,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解
这篇文章给大家分享的是有关Unity3D各平台路径是什么的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。1、Resources路径 Reso...
小编给大家分享一下Unity3D如何实现移动平台上的角色阴影,希望大家阅读完这篇文章之后都有所收获,下面让我们一起去探讨吧!由于目前主流使用Unity3.x在移动平...
如何解析基于Unity3D的平坦四叉树地形与Virtual Texture的分析,相信很多没有经验的人对此束手无策,为此本文总结了问题出现的原因和解决方法,通过这篇文章希
这篇文章主要介绍Unity3D如何实现动态分辨率降低渲染开销,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!之前项目降低分辨率我们都普...
这篇文章主要介绍了unity3d中如何使用屏幕空间改善shadowmap漏光,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编...
这篇文章主要介绍unity3d如何实现基于屏幕空间的描边,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!Outline(Based on Image Space)由...
这篇文章给大家分享的是有关unity3d中导入fbx时的Scale是什么的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。在Unity中点击GameOb...
这篇文章主要为大家展示了“unity3d中如何实现ttc转ttf及制作字体”,内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带领大家一起研究并学习
这篇文章主要介绍了unity3d中水彩风渲染有什么用,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了...
这篇文章将为大家详细讲解有关unity3d中图像压缩原理是什么,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。1 图像可压缩...
这篇文章给大家分享的是有关unity3d中光照公式有哪些的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。漫反射、高光、物理渲染(PBR...
小编给大家分享一下unity3d中光照探针的示例分析,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我...
这篇文章将为大家详细讲解有关Unity3D中Rendering Paths及LightMode的示例分析,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有
这篇文章将为大家详细讲解有关unity3d中图形学的光照原理是什么,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。首先,在...
这篇文章给大家分享的是有关unity3d中图片渲染流程是什么的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。相关名词GPU(Graphic Pr...
本篇我们来介绍一下左侧工具栏中基本绘制的应用。 一、墙体绘制直墙 & 矩形墙绘制墙体时,可以看到上方的工具栏中对墙体进行参数的设定。 弧形墙在建筑版的户...
xlua是由腾讯维护的一个开源项目,我们可以在github上下载这个开源项目并查看一些相关文档官网:https://github.com/Tencent/xLua配置文档:https://github.com/Tencent/xLua/blob/master/Assets/XLua/Doc/hotfix.md常见问题解答:https://github.com/Tencent/xLua/blob/master/Assets/
我们都知道,一个三维场景的画面的好坏,百分之四十取决于模型,百分之六十取决于贴图,可见贴图在画面中所占的重要性。在这里我将列举一些贴图,并且初步阐述其概念,理解原理的基础上制作贴图,也就顺手多了。我在这里主要列举几种UNITY3D中常用的贴图,与大家分享,希望对大家有帮助。01 首先