'How to extract a file from a large Stream and broadcast it?
Im trying to get with the result from 2 days ago and nothing till today.
First in the same stream i need to connect to the server via TCP after I sent a XML format with the credentials to the server.
Read the response from the server to know if the connection was made successfully and if its authenticated.
Send the XML to get the camera video in a multipart imag format. The response is in HTTP format and there is the file that I want.
I tried getting the image partially like frame per frame and writing each frame in a Stream and using a PushStreamContent to response but only show the first frame when i GET from a <img src="/api/sample"/> in a Chrome Browser.
Really I tried a lot of way to do it and every are wrong... I'm in a point where I don't know what to do. This is not my enviroment and obviosly need help.
public HttpResponseMessage Get([FromUri] string serverHost, string cameraId, string username, string password)
{
SystemAccess _sysInfo = new SystemAccess();
_sysInfo.Connect(serverHost, username, password);
LoginInfo loginInfo = _sysInfo.LoginInfo;
_sysInfo._basicConnection.GetConfiguration(loginInfo.Token);
Uri webServer = new Uri("http://localhost/");
foreach (ServerCommandService.RecorderInfo recorder in _sysInfo._basicConnection.ConfigurationInfo.Recorders)
{
foreach (ServerCommandService.CameraInfo cameraInfo in recorder.Cameras.Where(x => x.DeviceId == Guid.Parse(cameraId)))
{
webServer = new Uri(recorder.WebServerUri);
}
}
//The top code is to get camera information
ImageServerConnection imgSvr = new ImageServerConnection(webServer, cameraId, 75);
imgSvr.SetCredentials(_sysInfo, username, password); //Auth
imgSvr.PlaybackStartTime = 1648587605015;
imgSvr.PlaybackEndTime = 1648587614925;
var response = new HttpResponseMessage();
response.Content = new PushStreamContent((stream, content, context) => imgSvr.Playback(stream));
response.StatusCode = HttpStatusCode.OK;
return response;
}
public void Playback(Stream imageContent)
{
Stream networkStream = null;
try
{
networkStream = ConnectToImageServer();
if (networkStream == null) return;
_playback = true;
int maxbuf = 1024 * 64;
string sendBuffer = FormatConnect();
Byte[] bytesSent = Encoding.Default.GetBytes(sendBuffer);
networkStream.Write(bytesSent, 0, bytesSent.Length);
Byte[] bytesReceived = new Byte[maxbuf];
int bytes = RecvUntil(networkStream, bytesReceived, 0, maxbuf);
string page = Encoding.UTF8.GetString(bytesReceived, 0, bytes);
bool authenticated = false;
XmlDocument doc = new XmlDocument();
doc.LoadXml(page);
XmlNodeList nodes = doc.GetElementsByTagName("connected");
foreach (XmlNode node in nodes)
{
if (node.InnerText.ToLower() == "yes")
{
authenticated = true;
}
}
if (!authenticated)
{
return;
}
int count = 1;
_playbackTime = PlaybackStartTime;
int curBufSize = maxbuf;
int qual = _quality;
if (_quality < 1 || _quality > 104)
{
qual = 100;
}
//Request to get the video
sendBuffer = string.Format(
"<?xml version=\"1.0\" encoding=\"utf-8\"?>" +
"<methodcall>" +
"<requestid>{0}</requestid>" +
"<methodname>goto</methodname>" +
"<time>{1}</time>" +
"<compressionrate>{2}</compressionrate>" +
"<keyframesonly>no</keyframesonly>" +
"</methodcall>\r\n\r\n",
++count, _playbackTime, qual);
bytesSent = Encoding.UTF8.GetBytes(sendBuffer);
networkStream.Write(bytesSent, 0, bytesSent.Length);
page = Encoding.UTF8.GetString(bytesReceived, 0, bytes); //The headers from the page
}
catch (Exception e)
{
//...
}
finally
{
networkStream?.Dispose();
}
}
private static int RecvUntil(Stream stream, byte[] buf, int offset, int size)
{
int miss = size;
int got = 0;
int bytes = 0;
int ended = 4;
int i = 0;
while (got < size && ended > 0)
{
i = offset + got;
bytes = stream.Read(buf, i, 1);
if (buf[i] == '\r' || buf[i] == '\n')
{
ended--;
}
else
{
ended = 4;
}
got += bytes;
miss -= bytes;
}
if (got > size)
{
throw new Exception("Buffer overflow");
}
if (ended == 0)
{
return got;
}
return -got;
}
private string XmlEscapeGt127(string raw)
{
string str = "";
foreach (char c in raw)
{
if (c < 128)
{
str += c;
}
else
{
str += string.Format("&#{0};", Convert.ToUInt32(c));
}
}
return str;
}
private string FormatConnect()
{
string sendBuffer;
if (_token == "BASIC")
{
sendBuffer = string.Format(
"<?xml version=\"1.0\" encoding=\"utf-8\"?>" +
"<methodcall>" +
"<requestid>0</requestid>" +
"<methodname>connect</methodname>" +
"<username>{0}</username>" +
"<password>{1}</password>" +
"<cameraid>{2}</cameraid>" +
"<clientcapabilities>" +
"<multipartdata>yes</multipartdata>" +
"</clientcapabilities>" +
"</methodcall>\r\n\r\n",
XmlEscapeGt127(_user), XmlEscapeGt127(_pwd), _cameraGuid);
}
else
{
sendBuffer = string.Format(
"<?xml version=\"1.0\" encoding=\"utf-8\"?>" +
"<methodcall>" +
"<requestid>0</requestid>" +
"<methodname>connect</methodname>" +
"<username>a</username>" +
"<password>a</password>" +
"<cameraid>{0}</cameraid>" +
"<transcode>" +
"<allframes>yes</allframes>" +
"</transcode>" +
"<clientcapabilities>" +
"<multipartdata>yes</multipartdata>" +
"</clientcapabilities>" +
"<connectparam>" +
"id={1}&connectiontoken={2}" +
"</connectparam>" +
"</methodcall>\r\n\r\n",
_cameraGuid, _cameraGuid, _token);
}
return sendBuffer;
}
private Stream ConnectToImageServer()
{
Stream networkStream = null;
String oper = "";
try
{
IPAddress ipAddress;
oper = "new Socket";
Socket sock = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
try
{
oper = "IPAddress.Parse " + _imageServer;
ipAddress = IPAddress.Parse(_imageServer.Host);
}
catch
{
oper = "ConnInfo.ToIpv4 " + _imageServer;
ipAddress = ConnInfo.ToIpv4(_imageServer.Host);
}
oper = "new IPEndPoint " + ipAddress;
IPEndPoint ipe = new IPEndPoint(ipAddress, _imageServer.Port);
sock.Connect(ipe);
oper = "NetworkStream";
networkStream = new NetworkStream(sock, true);
if (String.Equals(_imageServer.Scheme, Uri.UriSchemeHttps, StringComparison.OrdinalIgnoreCase))
{
oper = "SslStream";
SslStream sslStream = new SslStream(networkStream, false);
networkStream = sslStream;
sslStream.AuthenticateAsClient(_imageServer.Host);
}
networkStream.ReadTimeout = 10000;
networkStream.WriteTimeout = 2000;
}
catch (AuthenticationException ae)
{
// Tell the application I'm done
if (OnConnectionStoppedMethod != null)
{
string errMsg = $"SSL error {ae.Message}.";
OnConnectionStoppedMethod.Invoke(new ConnInfo(IscErrorCode.NoConnect, errMsg));
}
networkStream?.Dispose();
networkStream = null;
}
catch (IOException ioe)
{
// Tell the application I'm done
if (OnConnectionStoppedMethod != null)
{
string errMsg = $"NetworkStream error {ioe.Message}.";
OnConnectionStoppedMethod.Invoke(new ConnInfo(IscErrorCode.NoConnect, errMsg));
}
networkStream?.Dispose();
networkStream = null;
}
catch (SocketException se)
{
// Tell the application I'm done
if (OnConnectionStoppedMethod != null)
{
string errMsg = $"Socket error {se.ErrorCode}. Win32 error {se.NativeErrorCode}";
OnConnectionStoppedMethod.Invoke(new ConnInfo(IscErrorCode.NoConnect, errMsg));
}
networkStream?.Dispose();
networkStream = null;
}
catch (Exception)
{
// Tell the application I'm done
if (OnConnectionStoppedMethod != null)
{
OnConnectionStoppedMethod.Invoke(new ConnInfo(IscErrorCode.NoConnect, oper));
}
networkStream?.Dispose();
networkStream = null;
}
return networkStream;
}
Wireshark Capture - Only a part.
For more code can check: Sample in Github
My code is a implementation of the ImageServerConnection.cs playback.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|
