使用Unity C#通过网络发送图片

时间:2020-09-30 14:57:21

标签: c# unity3d ffmpeg

我目前正在使用HoloLens,因此正在使用Unity。这个想法是使网络摄像头实时流尽可能少地延迟到另一台设备上的FFmpeg实例进行编码。但是,我遇到了一些问题。

我的第一个问题是从Color32数组到字节数组的转换。它会创建大量带宽,尤其是当我尝试以30fps和1280x720分辨率进行录制和流传输时。 这是一些代码:

IEnumerator Init()
    {
        webCam = new WebCamTexture(1280, 720, 30);
        webCam.Play();
        image.texture = webCam;
        Debug.Log("WebCam Width: " + webCam.width);
        Debug.Log("WebCam Height: " + webCam.height);
        currentTexture = new Texture2D(webCam.width, webCam.height);
        
        data = new Color32[webCam.width * webCam.height];
        listener = new TcpListener(IPAddress.Any, 10305);
        listener.Start();



        while (webCam.width < 100)
        {
            
             yield return null;
        }

        StartCoroutine("Recording");
    }

    WaitForEndOfFrame endOfFrame = new WaitForEndOfFrame();

    IEnumerator Recording()
    {

        TcpClient tcpClient = null;
        NetworkStream tcpStream = null;
        bool isConnected = false;

        Loom.RunAsync(() =>
        {
            while(!stopCapture)
            {
                tcpClient = listener.AcceptTcpClient();
                Debug.Log("Client Connected!");
                isConnected = true;
                tcpStream = tcpClient.GetStream();
            }
        });
        while(!isConnected)
        {
            yield return endOfFrame;
        }
        readyToGetFrame = true;
        byte[] messageLength = new byte[SEND_RECEIVE_COUNT];
        while(!stopCapture)
        {
            yield return endOfFrame;

            webCam.GetPixels32(data);
            byte[] webCamBytes = Utilities.Color32ArrayToByteArray(data);
                                
            readyToGetFrame = false;
            Loom.RunAsync(() => {
                tcpStream.Write(webCamBytes, 0, webCamBytes.Length);
                readyToGetFrame = true;
            });

            while (!readyToGetFrame)
            {
                yield return endOfFrame;
            }
        }
    }
public static class Utilities
{
    public static byte[] Color32ArrayToByteArray(Color32[] colors)
    {
        if (colors == null || colors.Length == 0)
        {
            return null;
        }

        int lengthOfColor32 = Marshal.SizeOf(typeof(Color32));
        int byteArrayLength = lengthOfColor32 * colors.Length;
        byte[] bytes = new byte[byteArrayLength];

        GCHandle handle = default(GCHandle);

        try
        {
            handle = GCHandle.Alloc(colors, GCHandleType.Pinned);
            IntPtr ptr = handle.AddrOfPinnedObject();
            Marshal.Copy(ptr, bytes, 0, byteArrayLength);
        }
        finally
        {
            if(handle != default(GCHandle))
            {
                handle.Free();
            }
        }

        return bytes;
    }
}

为解决此问题,我尝试改用EncodePNG和EncodeJPG。但是,还有第二个问题。如果使用这些方法,将会造成很大的性能损失。

所以代替这个

        webCam.GetPixels32(data);
        byte[] webCamBytes = Utilities.Color32ArrayToByteArray(data);

我用这个

        currentTexture.SetPixels(webCam.GetPixels());
        byte[] webCamBytes = currentTexture.EncodeToJPG();

因此,我的问题是: 有没有办法通过减少不需要的alpha值来减小带宽?还是有另一种好方法,例如转换为不同的颜色或图片格式?

因为现在我没有可用的想法,感觉有点卡住。也许只是我;-)

PS:使用外部库有点困难,因为它需要在HoloLens上运行并且受其他法规的限制。

提前谢谢!

0 个答案:

没有答案