I have a Xamarin Android app that has a feature for taking snapshots of external cameras. Until now we were using some models that provided us access from HTTP with CGI for this. However, these models were discontinuated and we are forced to change for models that provide ONVIF protocol.
I created an additional ClassLibrary project in my solution (once it is not possible to add Services References directly in Xamarin Android projects) to handle this function. And in this project I added a Service Reference to ONVIF wsdl (http://www.onvif.org/onvif/ver10/media/wsdl/media.wsdl).
So, I created the following function:
public string GetSnapshotUri(string cameraIPAddress, string username, string password)
{
try
{
var messageElement = new TextMessageEncodingBindingElement()
{
MessageVersion = MessageVersion.CreateVersion(EnvelopeVersion.Soap12, AddressingVersion.None)
};
HttpTransportBindingElement httpBinding = new HttpTransportBindingElement()
{
AuthenticationScheme = AuthenticationSchemes.Basic
};
CustomBinding bind = new CustomBinding(messageElement, httpBinding);
var mediaClient = new MediaClient(bind, new EndpointAddress($"http://{ cameraIPAddress }/onvif/Media"));
mediaClient.ClientCredentials.UserName.UserName = username;
mediaClient.ClientCredentials.UserName.Password = password;
Profile[] profiles = mediaClient.GetProfiles();
string profileToken = profiles[0].token;
MediaUri mediaUri = mediaClient.GetSnapshotUri(profileToken);
return mediaUri.Uri;
}
catch (WebException ex)
{
return ex.Message;
}
catch (Exception ex)
{
return ex.Message;
}
}
But when the function is called and the mediaClient.GetProfiles() method is reached, an error is thrown:
**
System.Net.WebException: 'There was an error on processing web request: Status code 400(BadRequest): Bad Request'
I've tried to search for any related problem, but everything I've tried didn't work.
Any suggestions?
Link related: ONVIF api capture image in C#
Thanks!
After a long time, I finally had success. Here is the final solution:
public Byte[] GetSnapshotBytes(string ip, string user, string password)
{
try
{
if (string.IsNullOrEmpty(ip)) return null;
var snapshotUri = string.Format("http://{0}:80/onvifsnapshot/media_service/snapshot?channel=1&subtype=0", ip);
NetworkCredential myCredentials = new NetworkCredential(user, password);
WebRequest myWebRequest = WebRequest.Create(snapshotUri);
myWebRequest.Credentials = myCredentials.GetCredential(new Uri(snapshotUri), "");
using (HttpWebResponse lxResponse = (HttpWebResponse)myWebRequest.GetResponse())
{
using (BinaryReader reader = new BinaryReader(lxResponse.GetResponseStream()))
{
Byte[] lnByte = reader.ReadBytes(1 * 1024 * 1024 * 10);
return lnByte;
}
}
}
catch (Exception)
{
throw;
}
}