WCF 和 Onvif 简单示例

WCF and Onvif simple example

有人有使用 WCF 发现 Onvif 相机的简单示例吗? 或者使用 WCF 使用 Onvif 标准向相机发送命令的任何其他示例? 我知道 Onvif DM、Onvif 设备测试工具和 Onvif 编程指南。 但是不知道怎么实现。

谢谢

添加 System.ServiceModelSystem.ServiceModel.Discovery 程序集。 这是代码:

    // perform the onvif search (this is the MAIN)
    public static IEnumerable<EndpointDiscoveryMetadata> SearchOnvifDevices()
    {
        // object used to define the search criteria to find onvif device on the network
        var findCriteria = new FindCriteria();

        // what device type to find? this is required
        var contractTypeName = "NetworkVideoTransmitter";  // the other possible value is 'Device'
        var contractTypeNamespace = "http://www.onvif.org/ver10/network/wsdl";
        // those parametes are defined by onvif standard
        findCriteria.ContractTypeNames.Add(new XmlQualifiedName(contractTypeName, contractTypeNamespace));

        // you can canfigure the search with TimeOut, MaxResults, Scope, DeviceType, MaxResponseDelay, TransportSettings.TimeToLive, ...
        findCriteria.MaxResults = 100;
        findCriteria.Duration = new TimeSpan(10000);
        // ...

        //// you can specify scopes to restrict the search
        //SetScopes(findCriteria, new[] { "onvif://www.onvif.org/type/ptz" });


        // object used to search the devices using the FindCriteria.
        var discoveryClient = new DiscoveryClient(new UdpDiscoveryEndpoint(DiscoveryVersion.WSDiscoveryApril2005));

        // search
        var findResponse = discoveryClient.Find(findCriteria);
        return findResponse.Endpoints;
    }

    // set scopes to find devices that only match the specifieds scopes
    public static void SetScopes(FindCriteria findCriteria, IEnumerable<string> scopes)
    {
        findCriteria.ScopeMatchBy = FindCriteria.ScopeMatchByExact;
        if (scopes != null)
        {
            foreach (var item in scopes)
                findCriteria.Scopes.Add(new Uri(item));
        }


        // for example:
        // a device can have set the following scopes:
        // onvif://www.onvif.org/type/ptz
        // onvif://www.onvif.org/hardware/D1-566
        // onvif://www.onvif.org/location/country/china
        // onvif://www.onvif.org/location/city/bejing
        // onvif://www.onvif.org/name/ARV-453

        // then if you perform the search with the scope 'onvif://www.onvif.org/location/country/china' it will resolve the device
        // but if the search include the scope 'onvif://www.onvif.org/hardware/D1' then it will not.
    }

    // you can use this method to get parse endpoints to device
    public static IEnumerable<Device> GetDevices(IEnumerable<EndpointDiscoveryMetadata> endpoints)
    {
        var result = new List<Device>();

        var id = 0;
        foreach (var endpoint in endpoints)
        {
            foreach (var listenUri in endpoint.ListenUris)
            {
                var newDevice = new Device
                {
                    Id = id,
                    ListenUri = listenUri,
                    EndpointDiscoveryMetadata = endpoint
                };
                result.Add(newDevice);
                id++;
            }
        }

        return result;
    }

    // class used to identify a Device
    public class Device
    {
        // id to identify the device
        public int Id;

        // uri where the device is listening
        public Uri ListenUri;

        // endpoint where the device was founded
        public EndpointDiscoveryMetadata EndpointDiscoveryMetadata;
    }

你可以这样使用它:

  // discover endpoints
  var endpoints = SearchOnvifDevices();

  // if you want, parse to devices
  var devices = GetDevices(endpoints);

拜托,我手边没有任何设备,因此无法测试,但此代码必须有效。有任何建议或错误,请评论。

修改

    #region SearchOnvifDev-Proba1
    private static void SearchOnvifDev()
    {
        ServicePointManager.Expect100Continue = false;

        var contractTypeName = "Device";  // the other possible value is 'Device' or 'NetworkVideoTransmitter'
        var contractTypeNamespace = "http://www.onvif.org/ver10/network/wsdl";

        var endPoint = new UdpDiscoveryEndpoint(DiscoveryVersion.WSDiscoveryApril2005);

        var discoveryClient = new DiscoveryClient(endPoint);

        FindCriteria findCriteria = new FindCriteria();
        //visak ispod
        findCriteria.ContractTypeNames.Add(new XmlQualifiedName(contractTypeName, contractTypeNamespace));
        findCriteria.Duration = TimeSpan.MaxValue;
        findCriteria.MaxResults = 1000000;
        discoveryClient.FindAsync(findCriteria);
        //events
        discoveryClient.FindProgressChanged += discoveryClient_FindProgressChanged;
        discoveryClient.FindCompleted += discoveryClient_FindCompleted;

        Console.ReadKey();

    } 
    #endregion

    #region endEvent for discovery client
    static void discoveryClient_FindCompleted(object sender, FindCompletedEventArgs e)
    {
        Console.WriteLine("the end");
    } 
    #endregion

    #region changeEvent for discovery client
    static void discoveryClient_FindProgressChanged(object sender, FindProgressChangedEventArgs e)
    {
        var lines = "\r\n--------" + DateTime.Now.ToString() + "\r\n" + e.EndpointDiscoveryMetadata.Address.Uri.AbsoluteUri.ToString();
        Console.WriteLine("\r\n--------" + DateTime.Now.ToString() + "\r\n" + e.EndpointDiscoveryMetadata.Address.Uri.AbsoluteUri.ToString());

        using (System.IO.StreamWriter file = new System.IO.StreamWriter(@"info.txt", true))
        {
            file.WriteLine(lines);
        }

        foreach (var item in e.EndpointDiscoveryMetadata.ListenUris)
        {
            string uri = item.OriginalString;

            Console.WriteLine(uri.ToString());

            //this camera isnt found :(
            if (uri.Contains("http://192.168.4.230/"))
            {
                Console.WriteLine("BINGO");
            }
        }
    } 
    #endregion