I need to stream video from a Raspberry Pi's camera (Python server), to a C# script client (Unity, in fact).
I have successfully done this, using a Python to Python workflow, but I can't manage to make It work on C# client side.
This is my python server, where I'm sending the Stream over sockets:
Server.py:
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
s.bind(('0.0.0.0', 24000))
s.listen(1)
connection = s.accept()[0].makefile('wb')
print ('Client connected')
while True:
stream = io.BytesIO()
for foo in camera.capture_continuous(stream, 'jpeg'):
connection.write(struct.pack('<L', stream.tell()))
connection.flush()
stream.seek(0)
connection.write(stream.read())
stream.seek(0)
stream.truncate()
And this is my Python client side, which is actually working:
Client.py:
def threadLoop(self):
self.socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self.socket.connect((self.ip, self.port))
connection = self.socket.makefile('rb')
print('Recibiendo fotos')
while not self.haltSignal():
image_len, image_width, image_height = struct.unpack('<LLL', connection.read(struct.calcsize('<LLL')))
print ("L: " + str(image_len) + " W: " + str(image_width) + " H: " + str(image_height))
if not image_len:
break
image_stream = io.BytesIO()
image_stream.write(connection.read(image_len))
image_stream.seek(0)
self.callback(image_stream.getvalue(), image_width, image_height)
self.socket.close()
self.socket = None
self.thread = None
So, the question is... having this Server.py, how can I make a C# client that receives the stream and show the pictures?
I've tried to capture the received data in C#, over the socket, store It in a Byte array and convert It to a readable image, which sometimes, when It's a (very)small sized picture, works fine. I guess there must be a better way to achieve this.
Thanks!
Edit: This is what I've been trying in C#. Thanks again!
public int Connect()
{
if (_clientSocket.Connected == false)
{
_clientSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
mutexToSend = new Mutex();
mutexReceived = new Mutex();
ThreadStart ts = new ThreadStart(SendReceiveData);
threadSend = new Thread(ts);
threadSend.Start();
return 1;
}
else
return 0; //There is a socket already connected.
}
//----------------------------------------------------------
private void SendReceiveData()
{
try
{
_clientSocket.SendTimeout = 1000;
_clientSocket.ReceiveTimeout = 1000;
System.Net.IPAddress ipaddress = this.serverIP;
_clientSocket.Connect(new IPEndPoint(ipaddress, this.serverPort));
}
catch (SocketException ex)
{
//turn ex.Message;
}
_clientSocket.BeginReceive(_recieveBuffer, 0, _recieveBuffer.Length, SocketFlags.None, new AsyncCallback(ReceiveCallback), null);
}
//----------------------------------------------------------
private void ReceiveCallback(IAsyncResult AR)
{
//Check how much bytes are recieved and call EndRecieve to finalize handshake
int recieved = _clientSocket.EndReceive(AR);
if (recieved <= 0)
{
GestorCamaraSala.imgReceived = _recieveBuffer; //I copy the received data to the image texture
return;
}
//Start receiving again
_clientSocket.BeginReceive(_recieveBuffer, 0, _recieveBuffer.Length, SocketFlags.None, new AsyncCallback(ReceiveCallback), null);
}// end ReceivedCallback