Skip to content

Exporting Data and Events

CVEDIA-RT provides the integration for third-party applications which would consume the data such as Video Management Systems (VMSs). You can also create your exporters to consume the events generated in the CVEDIA-RT.

It's also possible to export data in various forms by clicking on Add Custom Export Options which would show you options to customize the name, data to export, format and so on.

Export settings

Click on the cog icon beside the instance name to access the Setup Window:

Instance cog icon

Then open the Export tab:

Export tab

Third-party integration

Starting from version 2023.3.0, CVEDIA-RT started supporting a standardized way of exporting events using JSON schemas.

This enabled the implementation of specialized exporters used to integrate with external systems, by guaranteeing stability in the format also in future versions of RT. Each JSON schema is versioned and the exporters can negotiate with CVEDIA-RT the version to use.

To get the schemas, visit the following page: Schemas

Integrations can be found in exporters directory.

Warning

Current exporters require Python3.6+ to run. The JSON Exporter can also support image export on disk if numpy and opencv-python packages are provided.

Each exporter has a configuration file that allows exposing the required settings in the CVEDIA-RT UI.

Integration settings

The exporters' settings are global and can be accessed from the main menu System -> Integrations:

Integration menu

Each exporter can be then enabled or disabled in the instance configuration: Enabling exporter

The JSON Exporter serves as a simple example of how to create custom integrations based on versioned JSON schemas.

Custom third-party integrations

As mentioned above, the JSON Exporter serves as an example for creating custom integrations. It is not required to write the exporter in Python, however, it is probably the easiest way of doing so.

Exporters are spawned as a separate process from the RT and communicate with RT through STDIN. Their configuration is defined in a JSON file, that is loaded by RT:

Exporter Schema Description

  • Section A: Defines which events and versions to subscribe to. Multiple versions can be selected. 0 stands for not registering (equivalent to a no line).
  • Section B: Defines the command to run from CVEDIA-RT
  • Section C: Defines additional environment variables to be set for the command execution
  • Section D: Defines the settings that will be displayed in the UI. The setting values can be used in the command.
  • Section E: Defines the name of the Exporter. Can be anything

You can use any program written in any language of your choice (Python, C++, C#, ...) that can read STDIN. Then you just change the command field value to it. Your program will then get required events as JSON strings through STDIN and you can parse it according to the available schemas. For more information about parsing the inputs, see the Schemas or jsonexport.py in the exporters directory.

Preprocessing of events

Starting from version 2023.5.1, CVEDIA-RT supports a way to filter, reorganize, or edit the events' data produced accordingly to the event schemas defined here: https://bin.cvedia.com/schema.

Users can define a command for execution within an isolated process, allowing for interaction with event data. The data is written to the process via the standard input (stdin), and the transmission of output to CVEDIA-RT passes through the standard output (stdout) of said process.

To enable the preprocessing, you can configure the pre-process command in the Export settings of the instance:

Prefilter

You can also configure the preprocess_cmd option of the Output plugin in the instance JSON file:

{
    "Output": {
        "preprocess_cmd": "./test_filter.py"
    }
}

Example of a Python script for processing data):

#!/usr/bin/env python3
import json, os, queue, threading

from psutil import pid_exists   # NOTE: `pip install psutil`
from sys import exit, stdin, stdout
from time import sleep

BUFFER_SIZE = 4096
MESSAGE_SEPARATOR = b'\0'

def is_parent_process_alive(none_is_alive=True):
        ppid = os.getppid()
        if ppid is None:
            return none_is_alive
        return pid_exists(ppid)

def process_message(bit):
    try:
        events = json.loads(bit)
    except:
        return None
    # -------- USER DATA MANIPULATION STARTS HERE --------
    if type(events) is not list:
        events = [events]
    for event in events:
        # Modify input data
        event["was_externally_modified"] = "YES"
    # -------- USER DATA MANIPULATION ENDS HERE --------
    return events

def send_messages_thread(events_queue):
    while True:
        try:
            events = events_queue.get(block=False)
        except queue.Empty:
            sleep(0.001)
            continue
        # Dump events to stdout
        stdout.write(json.dumps(events)+"\n")
        stdout.flush()

def run():
    read_buffer = b""
    loops = 0

    os.set_blocking(stdin.fileno(), False)

    writer_queue = queue.Queue(maxsize=1024)
    writer_thread = threading.Thread(target=send_messages_thread, args=(writer_queue, ))
    writer_thread.start()

    while True:
        # Check if parent process is alive
        if loops % 10 == 1:
            if not is_parent_process_alive():
                exit(0)
        loops += 1

        # Read from stdin
        try:
            read_buffer += os.read(0, BUFFER_SIZE)
        except:
            pass
        if not MESSAGE_SEPARATOR in read_buffer:
            # Sleep 10ms to prevent 100% CPU usage
            sleep(0.001)
            continue

        # Split buffer into messages
        messages = read_buffer.split(MESSAGE_SEPARATOR)
        # Reset buffer
        read_buffer = b""
        for idx, message in enumerate(messages):
            events = process_message(message)
            # If event was not json string
            if events is None:
                # If it was the last message, save it to buffer
                if idx == len(messages)-1:
                    read_buffer = message
                continue
            for _ in range(20):
                try:
                    writer_queue.put(events, block=False)
                    break
                except queue.Full:
                    # Sleep 10ms to prevent 100% CPU usage
                    sleep(0.01)
                    continue

        # Sleep 10ms to prevent 100% CPU usage
        sleep(0.01)

if __name__ == '__main__':
    run()

Custom Export Options

By clicking the "Add Custom Export Options" button, you can add one or more exporting configurations, and enable/disable them as needed.

The first step is to choose what data to export

Data to export

Depending on the choice, a list of different formats will be listed below. Two types of data can be exported: binary (for example the output image) and metadata (detections, events, etc...).

For binary data, the supported formats are mp4, jpg, png, RTSP, and RTMP.

For metadata, the supported formats are JSON files, json over mqtt, csv, and txt.

Export format

Once a format is chosen, a few additional options will be displayed that allow to control how and where to export the data.

Upon clicking the OK button, the new exporting settings will be added to the instance.

Info

It's suggested to change the export settings while the instance is not running. In case it's already running, it's necessary to save the instance using the Instance -> Save Instance menu and restart the instance.

Save instance

JSON

The JSON format exposes the following settings:

Minify: It allows to compress the entire JSON object in a single line. When disabled, the JSON text will be formatted for easier readability.

Append Only: When enabled, CVEDIA-RT will export the data of multiple frames or events in a single file. This should be used in combination with the Minify options to create a JSON log, where each row is an entry.

Path: The path and file name where to export the data. The path is relative to the binary of CVEDIA RT. On Windows, it corresponds to the files subfolder. You can also specify an absolute path.

Note

On Windows the path must use the forward slash as a folder separator: /

The path can also contain variables or special tokens to define a dynamic folder or file name: output/zone_stats_{obj.frame_id}.json

In this example, the file name will be built using the frame id.

The obj keyword represents the object that is being exported, and it allows to access any internal value. The metadata produced by CVEDIA-RT contains at least these values: frame_id, frame_time, system_timestamp, system_date.

For more information please check Dynamic Strings.

Each solution sends one or more data streams to the output sink. These data streams are used to draw visual references in the Output and Data panels but can be used to export data in various formats and protocols.

CSV

The CSV format exposes the following settings:

Minify: See JSON settings

Separator: It allows to set the character to use as column separation.

Minify: See JSON settings. This is useful if you are not exporting tabular data (see the notes below)

Append Only: See JSON settings

Path: See JSON settings

Tip

When exporting CSV data, it's recommended to choose the tabular format from the list in Data to export.

MQTT

The MQTT format exposes the following settings:

IP: The IP where the MQTT server is running.

Port: The port that the MQTT server is using.

Topic: A name that will be used to filter the data on the server.

Tip

You can configure multiple MQTT export settings in a single instance to export different types of data by using different topic names.

Info

You can run an MQTT server using Eclipse Mosquitto MQTT Broker or one of the Python scripts available in the tools folder inside the CVEDIA-RT folder.

MP4

To export to MP4 you should select "Output stream" as Data to export, and then select "MP4" as Format.

The MP4 format exposes the following settings:

Resolution: The resolution of the exported video. It can be customized or kept the same as the input source.

FPS: The number of frames per second of the exported video. It can be customized or kept the same as the input source.

Path: See JSON settings. A dynamic path is not supported here.

JPG and PNG

To export to JPG or PNG you should select "Output stream" as Data to export, and then select "JPG" or "PNG" as Format.

Path: See JSON settings. In this case, a dynamic path is required.

RTMP

To export to RTMP you should select "Output stream" as Data to export, and then select "RTMP" as Format.

URI: It defines the GStreamer pipeline. It must include the element appsrc name=cvedia-rt as a source.

For more information please check Advanced IO with GStreamer

Example

gstreamer:///appsrc name=cvedia-rt ! videoconvert ! x264enc speed-preset=1 ! video/x-h264,profile=baseline ! flvmux latency=0 start-time-selection=1 streamable=true ! rtmpsink location='rtmp://127.0.0.1:1935/live/cam0 live=true'

RTSP

To export to RTSP you should select "Output stream" as Data to export, and then select "RTSP" as Format.

The RTSP format exposes the following settings:

Pipeline: The GStreamer pipeline. It must include the element appsrc name=cvedia-rt as a source.

Example

( appsrc name=cvedia-rt ! videoconvert ! videoscale ! x264enc ! video/x-h264,profile=high ! rtph264pay name=pay0 pt=96 )

FPS: The number of frames per second of the exported video.

IP: The IP that the RTSP server should use.

Port: The port that the RTSP server should listen to for connections.

Topic: The topic name.

HLS

To export to HLS you should select "Output stream" as Data to export, and then select "HLS" as Format.