You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Delphi中通过ONVIF接收IP摄像机事件的实现方案咨询

解决方案:Delphi下实现ONVIF事件订阅与接收

一、原生SOAP调用实现核心逻辑

ONVIF基于SOAP协议,Delphi自带SOAP工具链,可自行实现事件订阅流程:

  • 第一步,获取目标摄像机的ONVIF WSDL文件,通常设备服务入口为http://[相机IP]/onvif/device_service,事件服务入口为/onvif/events
  • 用Delphi的WSDL Importer(路径:Tools -> WSDL Importer)导入事件服务WSDL,自动生成SOAP客户端单元
  • 实现WS-Security鉴权:在THTTPRio的OnBeforeExecute事件中,添加包含用户名密码的Digest认证头,符合ONVIF的鉴权标准
  • 选择订阅模式:
    • 回调模式:搭建本地HTTP服务(推荐用TIdHTTPServer),调用Subscribe方法指定回调地址,摄像机触发事件时会主动推送SOAP消息到该地址
    • 拉取模式:调用CreatePullPointSubscription创建拉取订阅,定时调用PullMessages主动获取事件数据
  • 解析事件:从SOAP响应中提取事件类型,越线检测对应RuleEngine/LineCrossing、移动侦测对应RuleEngine/MotionDetection,根据业务需求处理告警逻辑

二、第三方组件简化开发

如果不想从头封装SOAP逻辑,可选用成熟的Delphi ONVIF组件:

  • ONVIF Delphi Component Suite:封装了设备发现、事件订阅、媒体流管理等全量ONVIF功能,通过组件的Subscribe方法即可完成事件订阅,触发时通过组件回调接收告警
  • 自定义Indy封装:基于Indy的HTTP组件手动构造SOAP请求,适合需要高度定制协议细节的场景

三、与TVideograbber的整合方案

结合你已在用的TVideograbber实现联动:

  • 事件触发时,利用TVideograbber.Overlay功能在视频画面上叠加告警标识,比如绘制红框、告警文字
  • 触发时刻调用TVideograbber.SaveFrameToBitmap保存当前帧,关联事件日志展示
  • 将事件信息写入界面日志列表,实现视频与告警的同步追踪

关键代码示例

1. 拉取模式订阅事件(基于自动生成的SOAP客户端)

var
  EventService: EventPortType;
  PullPoint: PullPointSubscription;
  MsgList: NotificationMessageList;
  I: Integer;
begin
  // 初始化事件服务客户端
  EventService := GetEventPortType(false, 'http://192.168.1.100/onvif/events', nil);
  // 添加WS-Security鉴权
  (EventService as THTTPRio).OnBeforeExecute := procedure(const MethodName: string; SOAPRequest: TStream)
  var
    SecHeader: TSecurityHeader;
  begin
    SecHeader := TSecurityHeader.Create;
    try
      SecHeader.UsernameToken.Username := 'admin';
      SecHeader.UsernameToken.Password := 'your_password';
      SecHeader.UsernameToken.PasswordType := 'http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordDigest';
      // 注意:实际需按ONVIF标准生成Nonce和Created时间戳,此处为简化示例
      (EventService as THTTPRio).SOAPHeaders.Send(SecHeader);
    finally
      SecHeader.Free;
    end;
  end;

  // 创建拉取订阅
  PullPoint := EventService.CreatePullPointSubscription('', '', 60);
  // 定时拉取消息(建议用TTimer触发,间隔不超过订阅超时时间)
  MsgList := EventService.PullMessages(PullPoint.SubscriptionReference.Address.Value, 10, 60);
  
  // 解析事件
  if Assigned(MsgList.NotificationMessage) then
  begin
    for I := 0 to Length(MsgList.NotificationMessage) - 1 do
    begin
      if MsgList.NotificationMessage[I].Message._Type.Contains('LineCrossing') then
      begin
        // 处理越线告警
        TVideograbber1.OverlayText('越线检测触发', 10, 10, clRed);
      end
      else if MsgList.NotificationMessage[I].Message._Type.Contains('MotionDetection') then
      begin
        // 处理移动侦测告警
        TVideograbber1.OverlayText('移动侦测触发', 10, 30, clYellow);
      end;
    end;
  end;
end;

2. 回调模式本地HTTP服务(基于Indy)

procedure TMainForm.IdHTTPServer1CommandGet(AContext: TIdContext;
  ARequestInfo: TIdHTTPRequestInfo; AResponseInfo: TIdHTTPResponseInfo);
var
  EventXML: TXMLDocument;
  EventTypeNode: IXMLNode;
begin
  // 解析摄像机推送的SOAP事件消息
  EventXML := TXMLDocument.Create(nil);
  try
    EventXML.LoadFromStream(ARequestInfo.PostStream);
    EventXML.Active := True;
    // 通过XPath定位事件类型节点(需引入XMLIntf单元)
    EventTypeNode := EventXML.DocumentElement.SelectNode('//tt:Message/tt:Type');
    if Assigned(EventTypeNode) then
    begin
      if EventTypeNode.Text.Contains('LineCrossing') then
        Synchronize(procedure begin TVideograbber1.OverlayText('越线告警', 10, 10, clRed); end)
      else if EventTypeNode.Text.Contains('MotionDetection') then
        Synchronize(procedure begin TVideograbber1.OverlayText('移动侦测', 10, 30, clYellow); end);
    end;
    // 返回SOAP响应确认
    AResponseInfo.ResponseNo := 200;
    AResponseInfo.ContentText := '<s:Envelope xmlns:s="http://www.w3.org/2003/05/soap-envelope"><s:Body><wsnt:SubscribeResponse xmlns:wsnt="http://docs.oasis-open.org/wsn/b-2"><wsnt:SubscriptionReference><wsa:Address xmlns:wsa="http://www.w3.org/2005/08/addressing">http://192.168.1.50:8080/onvif-callback</wsa:Address></wsnt:SubscriptionReference></wsnt:SubscribeResponse></s:Body></s:Envelope>';
    AResponseInfo.ContentType := 'application/soap+xml';
  finally
    EventXML.Free;
  end;
end;

内容的提问来源于stack exchange,提问作者Shraga Milon

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.28 01:27:44