ONVIF Analytics Overlays Not Showing in Smart Client Despite AI Bridge Receiving and Forwarding Data (v2.0.0)

Hello Milestone Community,

I am working on integrating an AI Bridge (version

v2.0.0

) with our Milestone XProtect VMS, specifically to display ONVIF analytics overlays on live video streams in the Smart Client. I’ve successfully set up the data flow, but the overlays are not appearing, and I’m hoping to get some insights into what might be going wrong.

My Setup:

  • Milestone XProtect VMS Version: (Please insert your specific XProtect version here, e.g., 2024 R1, 2023 R2, etc. If unsure, state “a recent version”).
  • **AI Bridge Version:**v2.0.0
  • (as per GraphQL query).
  • Video Source: GStreamer simulation, sending an RTSP stream to
  • rtsp://127.0.0.1:554/video1

gst-launch-1.0 videotestsrc is-live=true do-timestamp=true ! tsoffset offset=-60000000000 ! nvvideoconvert ! nvv4l2h264enc ! rtspclientsink protocols=tcp location=rtsp://127.0.0.1:554/video1

Metadata Sender: A Python script (provided below) sends ONVIF analytics XML data via REST POST requests to the AI Bridge.

AI Bridge Metadata Topic: The AI Bridge exposes an

ONVIF_ANALYTICS

topic for objects.

graphQL response

{
  "data": {
    "about": {
      "version": "v2.0.0"
    },
    "metadataTopics": [
      {
        "topicName": "objects",
        "metadataFormat": "ONVIF_ANALYTICS",
        "topicAvailability": {
          "rest": "http://aivs-serv-2:8382/metadata/05f3aa90-2316-4286-a0a9-97f70b0d77db/objects/onvif_analytics",
          "kafka": "metadata.05f3aa90-2316-4286-a0a9-97f70b0d77db.objects.onvif_analytics",
          "grpc": "grpc://AIVS-Serv-2:8383"
        }
      }
    ]
  }
}

python sender to bridge

import requests
import time
from datetime import datetime, timezone, timedelta
 
# --- Configuration ---
METADATA_URL = "http://10.5.1.230:8382/metadata/05f3aa90-2316-4286-a0a9-97f70b0d77db/objects/onvif_analytics"
SEND_INTERVAL_SECONDS = 0.1
SOURCE_STREAM_ID = "6f9f6042-7ece-4e99-8e9b-b65f603d2418/28dc44c3-079e-4c94-8ec9-60363451eb40"
 
def generate_onvif_metadata_xml():
    current_utc_now = datetime.now(timezone.utc)
    # The UtcTime is set to current UTC time for the purpose of this post,
    # though I've also tested with a 1-minute offset to match the GStreamer pipeline.
    utc_time_str = current_utc_now.isoformat(timespec='milliseconds') + '+00:00'
 
    xml_content = f"""<?xml version="1.0" encoding="UTF-8"?>
<tt:MetadataStream xmlns:tt="http://www.onvif.org/ver10/schema">
    <tt:VideoAnalytics>
        <tt:Frame UtcTime="{utc_time_str}" SourceStreamID="{SOURCE_STREAM_ID}">
            <tt:Object ObjectId="1">
                <tt:Appearance>
                    <tt:Class>
                        <tt:ClassCandidate>
                            <tt:Type>Vehicle</tt:Type>
                            <tt:Likelihood>0.86</tt:Likelihood>
                        </tt:ClassCandidate>
                    </tt:Class>
                    <tt:VehicleInfo>
                        <tt:Type>Car</tt:Type>
                        <tt:Brand>Ford</tt:Brand>
                        <tt:Model>Mustang</tt:Model>
                    </tt:VehicleInfo>
                    <tt:Shape>
                        <tt:BoundingBox bottom="0.46875" right="0.321875" top="0.515625" left="0.275"/>
                        <tt:CenterOfGravity y="0.298" x="0.492"/>
                    </tt:Shape>
                </tt:Appearance>
            </tt:Object>
        </tt:Frame>
    </tt:VideoAnalytics>
</tt:MetadataStream>"""
    return xml_content.encode('utf-8')
 
def send_metadata_loop():
    print(f"Starting ONVIF metadata sender to {METADATA_URL}")
    print(f"Sending every {SEND_INTERVAL_SECONDS * 1000} ms...")
 
    while True:
        try:
            xml_data = generate_onvif_metadata_xml()
            headers = {'Content-Type': 'application/xml'}
            response = requests.post(METADATA_URL, data=xml_data, headers=headers, timeout=5)
            print(f"[{datetime.now().isoformat(timespec='milliseconds')}] Status Code: {response.status_code}, Response: {response.text.strip()}")
            response.raise_for_status()
        except requests.exceptions.RequestException as e:
            print(f"[{datetime.now().isoformat(timespec='milliseconds')}] Error: {e}")
        time.sleep(SEND_INTERVAL_SECONDS)
 
if __name__ == "__main__":
    send_metadata_loop()

Observations:

The Python script consistently receives HTTP 200 OK responses from the AI Bridge, indicating successful delivery of the XML metadata.

The AI Bridge logs show that the metadata is being received and forwarded to the VPS (Video Processing Service). An example log line:

2025-08-06T14:42:55Z Forwarding metadata in onvif_analytics format from source 6f9f6042-7ece-4e99-8e9b-b65f603d2418/28dc44c3-079e-4c94-8ec9-60363451eb40 to VPS connection stopped after 46130 frames (did not get data for 13.727018311s)

(The “connection stopped” message is expected as a timeout if no new data is sent for a period, which happens between bursts of metadata).

I have verified that the “Overlays” option is enabled in the Milestone Smart Client view item.

The SourceStreamID used in the metadata XML matches the camera’s ID in Milestone.

I have ensured that the UtcTime in the XML is correctly formatted and aligns with the video stream’s timestamp (both by trying current UTC time and a 1-minute offset).

The XML includes tt:BoundingBox with left, top, right, bottom coordinates, which should allow for drawing.

The Problem:

Despite all these confirmations, no overlays (like bounding boxes for the “Vehicle” object) are visible on the video feed in the Milestone Smart Client.

Questions for the Community:

What are the common reasons for ONVIF analytics overlays not appearing in the Smart Client, even when the AI Bridge confirms successful forwarding to the VPS and returns 200 OK?

Are there any specific, less obvious settings in the Milestone Management Client or Smart Client that need to be configured for ONVIF analytics overlays to render?

Could there be a subtle issue with the UtcTime synchronization or format that is accepted by the AI Bridge but causes rendering issues in the Smart Client?

Are there any known compatibility issues with AI Bridge v2.0.0 and specific Milestone XProtect versions regarding ONVIF analytics rendering?

What debugging steps can I take within Milestone (e.g., specific logs, diagnostics tools) to understand why the overlays aren’t being drawn?

Any guidance or suggestions would be greatly appreciated. Thank you in advance for your help!

Same happens in the connectivitysample goland app as well, not able to see any overlays or events, shown when simulating.

Hi,

Let me try answer…:

What are the common reasons for ONVIF analytics overlays not appearing in the Smart Client, even when the AI Bridge confirms successful forwarding to the VPS and returns 200 OK?

  • The 200 indicates it is successfully posted to the AI Bridge, that then will take care of the further handling

Are there any specific, less obvious settings in the Milestone Management Client or Smart Client that need to be configured for ONVIF analytics overlays to render?

  • The metadata device must be added to the Camera device’s Related metadata (in the Client tab)
  • This is taken care of when you subscribe to the topic in the Camera device’s Processing Server tab

Could there be a subtle issue with the UtcTime synchronization or format that is accepted by the AI Bridge but causes rendering issues in the Smart Client?

  • you can only add metadata with a timestamp that is higher that is already in the database, for the device.

Are there any known compatibility issues with AI Bridge v2.0.0 and specific Milestone XProtect versions regarding ONVIF analytics rendering?

  • none known

What debugging steps can I take within Milestone (e.g., specific logs, diagnostics tools) to understand why the overlays aren’t being drawn?

  • check the DeviceHandling.log, I think you have done that
  • the preview icon on the metadata device will show an animation with 0 and 1 when metadata is received
  • you can use the Metadata Playback Viewer (sample) to check the metadata in the metadata database
  • Center of gravity can be hard to calculate right, and isn’t needed in XProtect, so you can try omit the CenterOfGravity tag
  • Verify if overlays shows up in playback, in the Smart Client, potentially at unexpected video-time

Excellent!!

I am getting this in DeviceHandling.log

2025-08-07 16:52:32.231+03:00 [ 107] ERROR - 83ce20d8-f86c-4356-a803-e6fb88686a69 Universal 1 channel driver (10.5.1.230) - Camera 1 [objects-onvif_analytics] - Metadata (onvif_analytics) Unable to add one or more frames to the frame collector (Logged only once a minute). Error code = 5

preview icon on the metadata device is not showing any animation

I will check other things and get back,

Thanks for the help!!

Hi @Hans Kierulff

Eventhough I send metadata, and getting same log in the DeviceHandling.log.

I dont see anything in this window. Please help to find the reason, if it is not shown here.

This is what I see in Playback metadata player

Hi @Hans Kierulff​ ,

Kindly let me know if there is anything I can do. This is a big blocker for us.

Hi @ofer apitz​,

This “error 5” usually is produced by a time warp problem, the frame time does not fit within the stream.

To narrow down the problem and troubleshoot it together, I have some suggestions for you to check, to decrease the complexity of your setup:

  • Remove the GStreamer simulation camera: Try to setup a real camera on the VMS or try using the StableFPS driver to simulate it - this .
  • Remove AI Bridge for the setup: Using the Bounding Box Metadata Provider to check if there is nothing broken on the bounding boxes regular behaviour.

If after this you can see bouding boxes on Smart Client, try to send the metadata from AI Bridge to the real camera/StableFPS camera.

Please, share your finding when you have them, we will make it work.

Hello again @ofer apitz​,

I forgot to mention something, whenever you have Smart Client open and you add a new metadata device related to any camera, remember to restart (close and open) or refresh the Smart Client server configuration (you can check the answer on this post) to have the new harware related and ready to receive and show metadata.

Regards,

Fer

Actually restarting the entire service, solved the issue.