Replies: 3 comments 8 replies
-
|
This automatically generated reply acts as a friendly reminder. Answers to your questions will most often come from the community, from developers like yourself. You will, from time to time, find that Axis employees answers some of the questions, but this is not a guarantee. Think of the discussion forum as a complement to other support channels, not a replacement to any of them. If your question remains unanswered for a period of time, please revisit it to see whether it can be improved by following the guidelines listed in Axis support guidelines. |
Beta Was this translation helpful? Give feedback.
-
|
Bro that's a lot you ask, did you not check any docs or so hehe Metadata via websockets is possible: https://developer.axis.com/vapix/network-video/event-streaming-over-websocket/ We have an ACAP hat can post metadata to an webserver. You can also write your own, subscribe to axevent topic for kind of metadata you want and use curl for sending to your webserver. Either wss or https Transport are both TLS so what's your question about security ? If you want test our acap I can provide you a demo license. (c.acs@commend.at) |
Beta Was this translation helpful? Give feedback.
-
|
Hi @seemanthk ,
Build an ACAP application that consume scene metadata
Project files:consume-scene-metadata-1166.zip Changes in consume-scene-metadata example:DockerfileARG ARCH=
ARG VERSION=12.6.0
ARG UBUNTU_VERSION=24.04
ARG REPO=axisecp
ARG SDK=acap-native-sdk
FROM ${REPO}/${SDK}:${VERSION}-${ARCH}-ubuntu${UBUNTU_VERSION}
# Set arguments used in build of both libraries
ARG ARCH=armv7hf
ARG PEM_CERT_FILE=cacert.pem
# (Optional) Get more verbose logging when running the application
ARG APP_DEBUG
ENV APP_DEBUG ${APP_DEBUG}
#-------------------------------------------------------------------------------
# Prepare build environment
#-------------------------------------------------------------------------------
WORKDIR /opt/app
COPY ./app .
#-------------------------------------------------------------------------------
# Get CA certificate for the web server we want to transfer data from
#-------------------------------------------------------------------------------
# Use the 'openssl' tool from the Ubuntu container to get a CA certificate from
# the web server of interest. Why not use the compiled 'openssl' binary to do
# this? It's cross compiled and will not run on a standard desktop.
SHELL ["/bin/bash", "-o", "pipefail", "-c"]
# (Optional) If the network has a proxy
ARG BUILD_PROXY
# PROXY_SETTING needs to be split, ignore hadolint error
# hadolint ignore=SC2086
RUN PROXY_SETTING= ; \
[ -z "$BUILD_PROXY" ] || PROXY_SETTING="-proxy $BUILD_PROXY" ; \
echo quit | openssl s_client \
-showcerts \
-servername api.openobserve.ai \
-connect api.openobserve.ai:443 \
$PROXY_SETTING \
> ${PEM_CERT_FILE}
#-------------------------------------------------------------------------------
# Finally build the ACAP application
#-------------------------------------------------------------------------------
RUN . /opt/axis/acapsdk/environment-setup* && \
acap-build . -a ${PEM_CERT_FILE}consume_scene_metadata.c/**
* Copyright (C) 2024 Axis Communications AB, Lund, Sweden
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* <http://www.apache.org/licenses/LICENSE-2.0>
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* This example creates a Message Broker subscriber for the
* analytics_scene_description topic. Streamed messages are received in the
* Analytics Data Format (ADF) and is logged to syslog.
*/
#include <signal.h>
#include <stdio.h>
#include <string.h>
#include <sys/syslog.h>
#include <syslog.h>
#include <time.h>
#include <unistd.h>
#include <mdb/connection.h>
#include <mdb/error.h>
#include <mdb/subscriber.h>
#include <curl/curl.h>
#include <openssl/err.h>
#include <openssl/ssl.h>
typedef struct channel_identifier {
char* topic;
char* source;
} channel_identifier_t;
static void on_connection_error(const mdb_error_t* error, void* user_data) {
(void)user_data;
syslog(LOG_ERR, "Got connection error: %s, Aborting...", error->message);
abort();
}
static void on_message(const mdb_message_t* message, void* user_data) {
const struct timespec* timestamp = mdb_message_get_timestamp(message);
const mdb_message_payload_t* payload = mdb_message_get_payload(message);
channel_identifier_t* channel_identifier = (channel_identifier_t*)user_data;
CURL *curl;
CURLcode res;
curl = curl_easy_init();
if(curl) {
struct curl_slist *headers = NULL;
headers = curl_slist_append(headers, "Content-Type: application/json");
// --- Replace these with your real values ---
const char *url = "https://api.openobserve.ai/api/XXXXXXXXXXXXXXXXXXXXXXXXXXX/default/_json";
const char *userpwd = "xxxxx.xxxxx@axis.com:XXXXXXXXXXXXXXXX";
// --- Build ISO8601 timestamp ---
time_t t = timestamp->tv_sec;
struct tm tm;
gmtime_r(&t, &tm);
char iso_time[64];
strftime(iso_time, sizeof(iso_time), "%Y-%m-%dT%H:%M:%SZ", &tm);
// --- Prepare final JSON payload for OpenObserve ---
// Wrap the original ADF data inside a single-element JSON array
char json_buf[32768];
snprintf(json_buf, sizeof(json_buf),
"[{\"level\":\"info\","
"\"camera\":\"axis-001\","
"\"topic\":\"%s\","
"\"source\":\"%s\","
"\"timestamp\":\"%s\","
"\"log\":%.*s}]",
channel_identifier->topic,
channel_identifier->source,
iso_time,
(int)payload->size,
(char*)payload->data);
// --- Initialize cURL and send ---
curl_easy_setopt(curl, CURLOPT_URL, url);
curl_easy_setopt(curl, CURLOPT_USERPWD, userpwd);
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);
curl_easy_setopt(curl, CURLOPT_POSTFIELDS, json_buf);
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L); // same as -k
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0L);
res = curl_easy_perform(curl);
if(res != CURLE_OK) {
syslog(LOG_ERR, "Failed to send to OpenObserve: %s", curl_easy_strerror(res));
}
curl_slist_free_all(headers);
curl_easy_cleanup(curl);
}
}
static void on_done_subscriber_create(const mdb_error_t* error, void* user_data) {
if (error != NULL) {
syslog(LOG_ERR, "Got subscription error: %s, Aborting...", error->message);
abort();
}
channel_identifier_t* channel_identifier = (channel_identifier_t*)user_data;
syslog(LOG_INFO,
"Subscribed to %s (%s)...",
channel_identifier->topic,
channel_identifier->source);
}
static void sig_handler(int signum) {
(void)signum;
// Do nothing, just let pause in main return.
}
int main(void) {
syslog(LOG_INFO, "Subscriber started...");
// For com.axis.analytics_scene_description.v0.beta source corresponds to the
// video channel number.
channel_identifier_t channel_identifier = {.topic =
"com.axis.consolidated_track.v1.beta",
.source = "1"};
mdb_error_t* error = NULL;
mdb_subscriber_config_t* subscriber_config = NULL;
mdb_subscriber_t* subscriber = NULL;
mdb_connection_t* connection = mdb_connection_create(on_connection_error, NULL, &error);
if (error != NULL) {
goto end;
}
subscriber_config = mdb_subscriber_config_create(channel_identifier.topic,
channel_identifier.source,
on_message,
&channel_identifier,
&error);
if (error != NULL) {
goto end;
}
subscriber = mdb_subscriber_create_async(connection,
subscriber_config,
on_done_subscriber_create,
&channel_identifier,
&error);
if (error != NULL) {
goto end;
}
// Add signal handler to allow for cleanup on ordered termination.
(void)signal(SIGTERM, sig_handler);
pause();
end:
if (error != NULL) {
syslog(LOG_ERR, "%s", error->message);
}
mdb_error_destroy(&error);
mdb_subscriber_config_destroy(&subscriber_config);
mdb_subscriber_destroy(&subscriber);
mdb_connection_destroy(&connection);
syslog(LOG_INFO, "Subscriber closed...");
}MakefilePROG1 = $(shell jq -r '.acapPackageConf.setup.appName' manifest.json)
OBJS1 = $(PROG1).c
PROGS = $(PROG1)
DEBUG_DIR = debug
PKGS = openssl libcurl mdb
CFLAGS += $(shell PKG_CONFIG_PATH=$(PKG_CONFIG_PATH) pkg-config --cflags $(PKGS))
LDLIBS += $(shell PKG_CONFIG_PATH=$(PKG_CONFIG_PATH) pkg-config --libs $(PKGS))
# Set warning flags
CFLAGS += -Wall \
-Wextra \
-Wformat=2 \
-Wpointer-arith \
-Wbad-function-cast \
-Wstrict-prototypes \
-Wmissing-prototypes \
-Winline \
-Wdisabled-optimization \
-Wfloat-equal \
-W \
-Werror
# Pre-process debug setting if it's set in the Dockerfile
ifneq ($(strip $(APP_DEBUG)),)
CFLAGS += -DAPP_DEBUG="\"$(APP_DEBUG)\""
endif
all: $(PROGS)
$(PROG1): $(OBJS1)
install -d $(DEBUG_DIR)
$(CC) $^ $(CFLAGS) $(LIBS) $(LDFLAGS) -lm $(LDLIBS) -o $(DEBUG_DIR)/$@
cp $(DEBUG_DIR)/$@ .
$(STRIP) $@
clean:
rm -rf $(PROGS) *.o *.eap* *_LICENSE.txt package.conf* param.conf tmp* cacert.pem $(DEBUG_DIR)
Tried testing with AXIS Q1656-DLE Radar-Video Fusion Camera: AXIS OS version 12.6.104 form AXIS Virtual Loan Tool but due to the Network Restriction it failed to connect with OpenObserve webhook(Curl log data source).
After adding local syslog dump of json_bufif (res != CURLE_OK)
{
if (res == CURLE_COULDNT_RESOLVE_HOST)
{
syslog(LOG_WARNING,
"Failed to send to OpenObserve: Could not resolve hostname. Logging payload locally:\n%s",
json_buf);
}
else
{
syslog(LOG_ERR,
"Failed to send to OpenObserve: %s. Logging payload locally:\n%s",
curl_easy_strerror(res),
json_buf);
}
}
else
{
syslog(LOG_INFO, "Sent ADF frame to OpenObserve successfully.");
}Do let me know in case if the above ACAP sample code worked for you with your own HTTP webhook after changes. 😉
EDIT:Tested with AXIS Q1728 Block Camera (AXIS OS version 12.6.97):
|
Beta Was this translation helpful? Give feedback.












Uh oh!
There was an error while loading. Please reload this page.
-
Need real-time per-track id, speed, bbox, direction, timestamp from Q1656-DLE. RTSP & MQTT are not acceptable. Can the camera:
expose VAPIX/HTTP JSON for current tracks; OR
push TrackCreated/TrackUpdated via WebSocket (wss) with JSON; OR
run an ACAP that exposes HTTPS JSON or POSTs to my HTTPS webhook?
Please include exact endpoints / subscribe patterns / minimal ACAP example. Security: TLS & NTP suggestions appreciated.
Beta Was this translation helpful? Give feedback.
All reactions