# Streaming webcam via websocket performance issues (Code included)

I finally figured out, how I can stream my webcam, but I'm getting not the best performance. In low resolutions it's working fine, but as soon as I turn the resolution up, the performance gets worse. I think Unity can't handle the decoding in that quality and speed so that the game is getting slowed down. Here is my Code :

Texture2D screenshot = new Texture2D(Screen.width, Screen.height, TextureFormat.ARGB32, false);
screenshot.Apply();
ws.Send(System.Convert.ToBase64String(screenshot.EncodeToJPG(quality)));


Hopefully there is something to improve.

• That's no miracle. You aren't encoding a proper video-stream, you are encoding it frame-by-frame to jpeg. That results in far more bandwidth than a proper video codec would create. Try creating a proper video stream (depending on the webcam there might be an API which exposes the video input as one) and then use a movie texture on the Unity side. – Philipp Jun 9 '16 at 11:35
• Makes sense to me, I got the webcam on a Texture, which is created by Vuforia... And I don't know how to stream a video via websocket, like I'm doing now with simple Base64. So I'm kinda lost in this video decoding section :/ – TobiasW Jun 9 '16 at 12:41
• If you're making this for Web, you might want to look into WebRTC as a possible solution. There's a Unity package here that might help: assetstore.unity3d.com/en/#!/content/47846 and also a package mentioned here: forum.unity3d.com/threads/… – hobnob Jun 9 '16 at 13:27
• It's cross-platform from Unity-Android to non-Unity-WebInterface via WebSocket. But I would be happy if it would work Unity to Unity via whatever :D – TobiasW Jun 9 '16 at 13:29

There are 2 things that I think might make this run faster:

1) Limit the number of images you're attempting to send (e.g. the FPS) (Unity is single threaded, so everything you do has an impact on performance)

2) Make the resulting JPG smaller by scaling the image before Base64 encoding it

There are a number of ways to reduce the frame rate, but possibly the easiest is to use a Coroutine. If you also use WaitForSeconds then you'll be able to limit the frame rate to whatever you need. Something like the following will give you a stream of about 30FPS:

IEnumerator SendScreenshot()
{
// Change this to affect frame rate
yield return new WaitForSeconds(0.33f);

Texture2D screenshot = new Texture2D(Screen.width, Screen.height, TextureFormat.ARGB32, false);

• Thanks! I will try that, I already got it in a coroutine but in a slightly other way : yield return new WaitForEndOfFrame(); – TobiasW Jun 9 '16 at 11:50