Skip to main content

Build an ACAP application that consume scene metadata

This guide provides steps on how to build a simple ACAP application that consumes Track Consolidation output and/or Fusion Tracker output scene metadata using the Device Data Hub API.

Prerequisites

  1. An Axis device that supports AXIS Scene Metadata
  2. Docker
    • For Windows and macOS, use the automatically upgradable Docker desktop stable
    • For Linux, use Docker Engine version 23.0.0 or later
  3. Git

Overview

The guide contains the following steps:

  1. Cloning the ACAP Native SDK Examples repository containing the application source code
  2. Build the application
  3. Install and start the application

Lets get started!

Step 1: Cloning the repository

Execute the following command from a Git terminal to clone the repository containing the ACAP Native SDK Examples.

Clone the ACAP Native SDK Examples repository
git clone https://github.com/AxisCommunications/acap-native-sdk-examples.git

Navigate to the device-data-hub > consume-scene-metadata folder where you should be able to find a directory called app. That directory contains the consume_scene_metadata.c application source code which can be compiled and run on the target device.

Step 2: Build the application

Standing in your working directory run the following commands:

info

Depending on the network your local build machine is connected to, you may need to add proxy settings for Docker. See Proxy in build time.

docker build --tag <APP_IMAGE> .

APP_IMAGE is the name to tag the image with, e.g., consume_scene_metadata:1.0

info

Default architecture is armv7hf. To build for aarch64 it's possible to update the ARCH variable in the Dockerfile or to set it in the docker build command via build argument:

docker build --build-arg ARCH=aarch64 --tag <APP_IMAGE> .

Copy the result from the container image to a local directory build:

docker cp $(docker create <APP_IMAGE>):/opt/app ./build

The working directory now contains a build folder with the following files:

consume-scene-metadata
├── app
│ ├── consume_scene_metadata.c
│ ├── LICENSE
│ ├── Makefile
│ └── manifest.json
├── build
│ ├── consume_scene_metadata
│ ├── consume_scene_metadata_1_0_0_armv7hf.eap
│ ├── consume_scene_metadata_1_0_0_LICENSE.txt
│ ├── consume_scene_metadata.c
│ ├── debug
│ │ └── consume_scene_metadata
│ ├── LICENSE
│ ├── Makefile
│ ├── manifest.json
│ ├── package.conf
│ ├── package.conf.orig
│ └── param.conf
├── Dockerfile
└── README.md
  • build/manifest.json - Defines the application and its configuration.
  • build/package.conf - Defines the application and its configuration.
  • build/param.conf - File containing application parameters.
  • build/consume_scene_metadata - Application executable binary file.
  • build/consume_scene_metadata_1_0_0_armv7hf.eap - Application package .eap file.
  • build/consume_scene_metadata_1_0_0_LICENSE.txt - Copy of LICENSE file.

Step 3: Install and start the application

Browse to the application page of the Axis device:

http://<AXIS_DEVICE_IP>/index.html#apps
  • Click on the tab Apps in the device GUI
  • Enable Allow unsigned apps toggle
  • Click (+ Add app) button to upload the application file
  • Browse to the newly built ACAP application, depending on architecture:
    • consume_scene_metadata_1_0_0_aarch64.eap
    • consume_scene_metadata_1_0_0_armv7hf.eap
  • Click Install
  • Run the application by enabling the Start switch

Inspect the generated output

The application log can be found at

http://<AXIS_DEVICE_IP>/axis-cgi/admin/systemlog.cgi?appname=consume_scene_metadata

----- Contents of SYSTEM_LOG for 'consume_scene_metadata' -----


consume_scene_metadata[5193]: Application started
consume_scene_metadata[5193]: User data: consume_scene_metadata_data
consume_scene_metadata[5193]: Received consumer-scene-metadata: {"channel_id":1,"duration":0.6,"end_time":"2026-05-28T13:09:58.740130Z","id":"05e2024f-f60e-467e-b408-b3391ee38281","parts":[{"object_track_id":"63c62160-a7d9-4431-8c95-8dd8cb941ae4"}],"path":[{"bounding_box":{"bottom":0.5985,"left":0.4247,"right":0.505,"top":0.5036},"timestamp":"2026-05-28T13:09:58.140130Z"},{"bounding_box":{"bottom":0.5985,"left":0.4256,"right":0.5112,"top":0.488},"timestamp":"2026-05-28T13:09:58.240130Z"},{"bounding_box":{"bottom":0.5964,"left":0.4247,"right":0.5181,"top":0.4849},"timestamp":"2026-05-28T13:09:58.340131Z"},{"bounding_box":{"bottom":0.5932,"left":0.4229,"right":0.5252,"top":0.4881},"timestamp":"2026-05-28T13:09:58.440130Z"},{"bounding_box":{"bottom":0.5932,"left":0.4235,"right":0.5323,"top":0.4881},"timestamp":"2026-05-28T13:09:58.540130Z"},{"bounding_box":{"bottom":0.5948,"left":0.4253,"right":0.5395,"top":0.4865},"timestamp":"2026-05-28T13:09:58.640130Z"},{"bounding_box":{"bottom":0.5943,"left":0.4229,"right":0.5484,"top":0.4849},"timestamp":"2026-05-28T13:09:58.740130Z"}],"start_time":"2026-05-28T13:09:58.140130Z"}
consume_scene_metadata[5193]: User data: consume_scene_metadata_data
consume_scene_metadata[5193]: Received consumer-scene-metadata: {"channel_id":1,"duration":0.1,"end_time":"2026-05-28T13:09:58.440130Z","id":"cb014ade-4447-414b-88ae-8f794ebff337","parts":[{"object_track_id":"e2c25529-fc6d-4fc7-9129-b2c60f6abf37"}],"path":[{"bounding_box":{"bottom":0.5068,"left":0.3193,"right":0.3497,"top":0.4235},"timestamp":"2026-05-28T13:09:58.340131Z"},{"bounding_box":{"bottom":0.5053,"left":0.3203,"right":0.3532,"top":0.4235},"timestamp":"2026-05-28T13:09:58.440130Z"}],"start_time":"2026-05-28T13:09:58.340131Z"}

The format of a detection is shown in a more readable way.

{
"channel_id": 1,
"duration": 0.6,
"end_time": "2026-05-28T13:09:58.740130Z",
"id": "05e2024f-f60e-467e-b408-b3391ee38281",
"parts": [
{
"object_track_id": "63c62160-a7d9-4431-8c95-8dd8cb941ae4"
}
],
"path": [
{
"bounding_box": {
"bottom": 0.5985,
"left": 0.4247,
"right": 0.505,
"top": 0.5036
},
"timestamp": "2026-05-28T13:09:58.140130Z"
},
{
"bounding_box": {
"bottom": 0.5985,
"left": 0.4256,
"right": 0.5112,
"top": 0.488
},
"timestamp": "2026-05-28T13:09:58.240130Z"
},
{
"bounding_box": {
"bottom": 0.5964,
"left": 0.4247,
"right": 0.5181,
"top": 0.4849
},
"timestamp": "2026-05-28T13:09:58.340131Z"
},
{
"bounding_box": {
"bottom": 0.5932,
"left": 0.4229,
"right": 0.5252,
"top": 0.4881
},
"timestamp": "2026-05-28T13:09:58.440130Z"
},
{
"bounding_box": {
"bottom": 0.5932,
"left": 0.4235,
"right": 0.5323,
"top": 0.4881
},
"timestamp": "2026-05-28T13:09:58.540130Z"
},
{
"bounding_box": {
"bottom": 0.5948,
"left": 0.4253,
"right": 0.5395,
"top": 0.4865
},
"timestamp": "2026-05-28T13:09:58.640130Z"
},
{
"bounding_box": {
"bottom": 0.5943,
"left": 0.4229,
"right": 0.5484,
"top": 0.4849
},
"timestamp": "2026-05-28T13:09:58.740130Z"
}
],
"start_time": "2026-05-28T13:09:58.140130Z"
}
info

The application outputs the result of Track Consolidation module for source 1.

If you would like to consume Fusion Tracker outout instead, you would need to modify the topic specified in the application source code file to com.axis.scene.frame.v1.