You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

270 lines
5.4 KiB

using EC.Onvif.Common;
using EC.Onvif.Device;
using EC.Onvif.Imaging;
using EC.Onvif.Media;
using EC.Onvif.PTZ;
using System;
using System.Threading.Tasks;
using Capabilities = EC.Onvif.Common.Capabilities;
namespace EC.Onvif
{
public class OnvifClient
{
#region Attr
public string Hostname { get; private set; }
public string Username { get; private set; }
public string Password { get; private set; }
public static float atomDist { get; private set; } = 0.01f;
public static float atomSpeed { get; private set; } = 0.1f;
#endregion Attr
#region Client Attr
private DeviceClient Device { get; set; }
private MediaClient Media { get; set; }
private PTZClient PTZ { get; set; }
private ImagingClient Imaging { get; set; }
private Capabilities Caps { get; set; }
#endregion Client Attr
#region Settings Attr
private string profileToken { get; set; }
private string videoSourceToken { get; set; }
#endregion Settings Attr
public OnvifClient(string hostname, string username, string password)
{
Hostname = hostname;
Username = username;
Password = password;
}
public async Task Init()
{
try
{
Device = await OnvifClientFactory.CreateDeviceClientAsync(Hostname, Username, Password);
Media = await OnvifClientFactory.CreateMediaClientAsync(Hostname, Username, Password);
PTZ = await OnvifClientFactory.CreatePTZClientAsync(Hostname, Username, Password);
Imaging = await OnvifClientFactory.CreateImagingClientAsync(Hostname, Username, Password);
var profiles = await Media.GetProfilesAsync();
var videoSources = await Media.GetVideoSourcesAsync();
foreach (var profile in profiles.Profiles)
{
if (string.IsNullOrEmpty(profileToken))
{
profileToken = profile.token;
break;
}
}
foreach (var source in videoSources.VideoSources)
{
if (string.IsNullOrEmpty(videoSourceToken))
{
videoSourceToken = source.token;
break;
}
}
Caps = (await Device.GetCapabilitiesAsync(new CapabilityCategory[] { CapabilityCategory.All })).Capabilities;
}
catch (Exception)
{
throw;
}
}
#region DeviceClient
public bool IsDeviceContected()
{
return Device != null;
}
#endregion DeviceClient
#region MediaClient
public bool IsMediaContected()
{
bool ret = IsDeviceContected();
return ret;
}
private StreamSetup RtspStreamSetup { get; } = new()
{
Stream = StreamType.RTPUnicast,
Transport = new() { Protocol = TransportProtocol.RTSP }
};
public async Task<string> GetStreamUri()
{
MediaUri mediaUri = await Media.GetStreamUriAsync(RtspStreamSetup, profileToken);
return mediaUri.Uri;
}
public async Task<string> GetSnapshotUri()
{
MediaUri mediaUri = await Media.GetSnapshotUriAsync(profileToken);
return mediaUri.Uri;
}
#endregion MediaClient
#region PTZClient
public bool IsPTZContected()
{
bool ret = IsDeviceContected() && (PTZ != null) && !string.IsNullOrEmpty(profileToken);
return ret;
}
/// <summary>
/// 绝对移动
/// </summary>
/// <param name="pan"></param>
/// <param name="tilt"></param>
/// <param name="zoom"></param>
/// <returns></returns>
public async Task AbsoluteMove(float pan, float tilt, float zoom)
{
await PTZ.AbsoluteMoveAsync(profileToken, new PTZVector
{
PanTilt = new Vector2D
{
x = pan,
y = tilt
},
Zoom = new Vector1D
{
x = zoom
}
}, null);
}
/// <summary>
/// 相对移动
/// </summary>
/// <param name="pan"></param>
/// <param name="tilt"></param>
/// <param name="zoom"></param>
public async Task RelativeMove(float pan, float tilt, float zoom)
{
await PTZ.RelativeMoveAsync(profileToken, new PTZVector
{
PanTilt = new Vector2D
{
x = pan,
y = tilt
},
Zoom = new Vector1D
{
x = zoom
}
}, null);
}
/// <summary>
/// 持续移动
/// </summary>
/// <param name="pan">0~100</param>
/// <param name="tilt">0~100</param>
/// <param name="zoom">0~100</param>
public async Task ContinuousMove(float pan, float tilt, float zoom)
{
await PTZ.ContinuousMoveAsync(profileToken, new PTZSpeed
{
PanTilt = new Vector2D
{
x = pan,
y = tilt
},
Zoom = new Vector1D
{
x = zoom
}
}, null);
}
public async Task StopMove()
{
await PTZ.StopAsync(profileToken, true, true);
}
public async Task<PTZStatus> GetStatus()
{
return await PTZ.GetStatusAsync(profileToken);
}
#endregion PTZClient
#region ImagingClient
public bool IsImagingContected()
{
bool ret = IsDeviceContected();
return ret;
}
public async Task FocusAbsoluteMove(float position)
{
await Imaging.MoveAsync(videoSourceToken, new FocusMove
{
Absolute = new AbsoluteFocus
{
Position = position,
//Speed = 1f,
//SpeedSpecified = true
}
});
}
public async Task FocusRelativeMove(float distance)
{
await Imaging.MoveAsync(videoSourceToken, new FocusMove
{
Relative = new RelativeFocus
{
Distance = distance,
//Speed = 1f,
//SpeedSpecified = true
}
});
}
public async Task FocusContinuousMove(float speed)
{
await Imaging.MoveAsync(videoSourceToken, new FocusMove
{
Continuous = new ContinuousFocus
{
Speed = speed
}
});
}
public async Task FocusStopMove()
{
await Imaging.StopAsync(videoSourceToken);
}
#endregion ImagingClient
}
}