我目前正在使用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上运行并且受其他法规的限制。
提前谢谢!