onvifserver_web_logo

OnvifServer C++ library

v2.0.2

Table of contents

Overview

OnvifServer is a C++ library that provides an implementation of the ONVIF server. The library supports Linux only. The library is designed to be used in applications that require ONVIF server functionality, such as video surveillance systems, IP cameras, and other devices that support the ONVIF standard. OnvifServer library has dependencies: nlohmann JSON library (source code included in the library), zlib (linked, ZLIB license), and openssl (linked, Apache 2.0 license). The library repository include template for full support of Onvif Profile S. The library was tested for full support of Onvif Profile S. Profile S template requires additional dependencies: VStreamerMediaMtx (Provides RTSP video server. Source code included), CppHttpLib (Provides HTTP server required for ONVIF Profile S, v3.14.0 source code included, MIT license), and ChildProcess (Provides function tu run external processes). This dependencies provide full functional video management and streaming capabilities of Onvif Profile S template. The library manages ONVIF requests and responses by using a callback mechanism. The user defines a global callback and the library invokes this callback with request/response type parameter. Also, configuration of OnvifServer is done by JSON string. The OnvifServer library is supported on Linux only and requires C++17 standard.

Versions

Table 1 - Library versions.

Version Release date What’s new
1.0.0 15.12.2024 - First version.
1.1.0 23.07.2025 - Profile S compliance support added.
2.0.0 23.07.2025 - Interface updated. </br> - Profile S template added.
2.0.1 27.07.2025 - VStreamerMediaMtx submodule update in example.
2.0.2 10.08.2025 - VStreamerMediaMtx submodule update in example.

Library files

The library is supplied only by source code. The user is given a set of files in the form of a CMake project (repository). The repository structure is shown below:

CMakeLists.txt --------------- Main CMake file of the library.
src -------------------------- Folder with library source code.
    CMakeLists.txt ----------- CMake file of the library.
    OnvifServer.cpp ---------- C++ implementation file.
    OnvifServer.h ------------ Main library header file.
    OnvifServerVersion.h ----- Header file with library version.
    OnvifServerVersion.h.in -- CMake service file to generate version file.
    nlohmann_json.hpp -------- Header file with nlohmann JSON library.
    OnvifXmlConverter.hpp ---- Header file with XML converter.
    OnvifMessageTypes.h ------ Header file with ONVIF message types.
    ... ---------------------- Other ONVIF backend files.
example ---------------------- Folder for example application files.
    CMakeLists.txt ----------- CMake file of example application.
    main.cpp ----------------- Source C++ file of example application.
    DefaultConfigContent.h --- Header file with default configuration content.
profileSTemplate ------------- Folder for Profile S template files.
    3rdparty ----------------- Folder with third-party libraries.
        CMakeLists.txt ------- CMake file to include third-party libraries.
        VStreamerMediaMtx ---- Folder with VStreamerMediaMtx source code.
        CppHttpLib ----------- Folder with CppHttpLib source code.
        ChildProcess --------- Folder with ChildProcess library source code.
    images ------------------- Folder with images for snapshots.
    CMakeLists.txt ----------- CMake file of Profile S template.
    DefaultConfigContent.h --- Header file with default configuration content.
    main.cpp ----------------- Source C++ file of Profile S template application.
    OnvifServer.json --------- Example JSON configuration file.
    OnvifServerCallback.cpp -- Source C++ file with ONVIF server callback example.
    Config.h ----------------- Header file with ONVIF server configuration.
    Ptz.cpp ------------------ Source C++ file with PTZ example.
    Ptz.hpp ------------------ Header file with PTZ example.
    utils.cpp ---------------- Source C++ file with utils functions.
    utils.hpp ---------------- Header file with utils functions.

OnvifServer class description

OnvifServer class declaration

The OnvifServer class is declared in the OnvifServer.h file. Class declaration:

namespace cr
{
namespace onvif
{
/// ONVIF server class.
class OnvifServer
{
public:

    /// Type definition for the ONVIF message handler callback function.
    using onvif_handler_t = ONVIF_RET (*)(ONVIF_DEVICE *, ONVIF_MSG_TYPE, ...);

    /// Get string of current library version.
    static std::string getVersion();

    /// Initialize the ONVIF server with the JSON configuration string
    /// and a global handler callback.
    bool init(const std::string& jsonConfig, onvif_handler_t callback);

    /// Initialize the ONVIF server with the function pointers to initialize
    /// the supported analytics rules and modules. This method is OPTIONAL.
    void initAnalytics(void (*rulesInit)(onvif_SupportedRules *),
                       void (*modulesInit)(onvif_SupportedAnalyticsModules *));

    /// Start the ONVIF server.
    bool start();

    /// Stop the ONVIF server.
    bool stop();

    /// Set the streaming capabilities of server device that onvif server will use.
    void setStreamingCapabilities(bool rtpMulticast, bool rtpRtspTcp);
};
}
}

getVersion method

The getVersion() method returns a string of the current class version. Method declaration:

static std::string getVersion();

Method can be used without OnvifServer class instance:

cout << "OnvifServer version: " << OnvifServer::getVersion();

Console output:

OnvifServer version: 2.0.0

init method

The init(…) method initializes the ONVIF server. Method declaration:

bool init(const std::string& jsonConfig, onvif_handler_t callback);
Parameter Value
jsonConfig JSON string with configuration for the ONVIF server.
callback Callback function to handle ONVIF requests. See Callback mechanism for more details.

Returns: TRUE if initialization is successful or FALSE if not.

initAnalytics method

The initAnalytics(…) method initializes ONVIF analytics. Analytics functionality is not required by Profile S, it is an optional feature. It should be used for Profile M compliant server. Method declaration:

void initAnalytics(void (*rulesInit)(onvif_SupportedRules *),
                   void (*modulesInit)(onvif_SupportedAnalyticsModules *));
Parameter Value
rulesInit Function to initialize ONVIF supported rules.
modulesInit Function to initialize ONVIF supported analytics modules.

start method

The start() method starts internal HTTP and WebSocket servers, runs different message parsers and processes. The method returns the result of the operation. Method declaration:

bool start();

Returns: TRUE if the server started successfully or FALSE if not.

stop method

The stop() method stops the operation of internal HTTP and WebSocket servers, different message parsers and processes, and frees used resources. Method declaration:

bool stop();

Returns: TRUE if the server stopped successfully or FALSE if not.

setStreamingCapabilities method

The setStreamingCapabilities(…) method sets the streaming capabilities of the ONVIF server. Method declaration:

void setStreamingCapabilities(bool rtpMulticast, bool rtpRtspTcp);
Parameter Value
rtpMulticast Enable or disable RTP multicast streaming.
rtpRtspTcp Enable or disable RTP over RTSP over TCP streaming.

JSON Configuration String

The OnvifServer library uses a JSON configuration string to initialize the ONVIF server. The JSON string contains the configuration for the ONVIF server, including device information, supported services, and capabilities. The JSON string is passed to the init(…) method of the OnvifServer class. By using a JSON configuration string, the user can define different configurations such as the number of cameras, their names, and other parameters. It is difficult to provide a complete template for the JSON configuration string because it depends on the specific use case and the features that are required. However, the profileSTemplate/OnvifServer.json file contains an example of a JSON configuration string that can be used to initialize the ONVIF server with 2 cameras and 1 PTZ controller. This configuration provides a Profile S compliant ONVIF server.

Simple form of JSON configuration string is shown below:

{
  "config": {
    "log_enable": 1,
    "log_level": 0,
    "device": [
      {
        "server_ip": "",
        "http_enable": 1,
        "http_port": 10000,
        "https_enable": 0,
        "https_port": 1443,
        "cert_file": "ssl.ca",
        "key_file": "ssl.key",
        "http_max_users": 16,
        "need_auth": 0,
        "EndpointReference": "urn:uuid:endpoint-1",
        "information": {
          "Manufacturer": "YourCompany",
          "Model": "IPCamera",
          "FirmwareVersion": "2.4",
          "SerialNumber": "123456",
          "HardwareId": "1.0"
        },
        "user": [
          {
            "username": "admin",
            "password": "admin",
            "userlevel": "Administrator"
          },
          {
            "username": "user",
            "password": "123456",
            "userlevel": "User"
          }
        ],
        "RemoteUser": [
          {
            "username": "remote_user",
            "password": "remote_password",
            "UseDerivedPassword": false
          }
        ],
        "SystemDateTime": {
          "TimeZone": {
            "TZ": "UTC"
          },
          "DateTimeType": "NTP",
          "DaylightSavings": false
        },
        "network": {
          "NetworkProtocols": [
            {
              "Name": "HTTP",
              "Enabled": true,
               "Port": [80, 8080, 10000]
            },
            {
              "Name": "HTTPS",
              "Enabled": true,
              "Port": [443, 8443]
            },
            {
              "Name": "RTSP",
              "Enabled": true,
              "Port": [554, 8554]
            }
          ],
          "DNSInformation": {
            "FromDHCP": false,
            "SearchDomain": [
              "example.com",
              "example.org"
            ],
            "DNSManual": [
              {
                "Type": "IPv4",
                "IPv4Address": "10.10.10.4"
              },
              {
                "Type": "IPv4",
                "IPv4Address": "10.10.10.5"
              },
              {
                "Type": "IPv4",
                "IPv4Address": "10.10.10.6"
              },
              {
                "Type": "IPv4",
                "IPv4Address": "10.10.10.7"
              }
            ]
          },
          "NTPInformation": {
            "FromDHCP": false,
            "NTPManual": [
              {
                "Type": "IPv4",
                "IPv4Address": "192.168.1.1"
              },
              {
                "Type": "IPv4",
                "IPv4Address": "192.168.1.2"
              },
              {
                "Type": "DNS",
                "DNSname": "time.example.com"
              },
              {
                "Type": "DNS",
                "DNSname": "time.example.org"
              }
            ]
          },
          "HostnameInformation": {
            "FromDHCP": false,
            "RebootNeeded": false
          },
          "NetworkGateway": {
            "IPv4Address": [
              "192.168.1.1",
              "192.168.1.2"
            ]
          },
          "DiscoveryMode": "Discoverable",
          "DynamicDNSInformation": {
            "Type": "NoUpdate",
            "Name": "example.com",
            "TTL": 3600
          },
          "ZeroConfiguration": {
            "InterfaceToken": "eth0",
            "Enabled": true
          }
        },
        "HashingAlgorithm": {
          "@md5": 1,
          "@sha256": 1
        },
        "VideoSources": [
          {
            "@token": "camera1",
            "Framerate": 30.0,
            "Resolution": {
              "Width": 1920,
              "Height": 1080
            },
            "VideoSourceModes": {
              "@token": "camera1_VSMode1",
              "@Enabled": true,
              "MaxFramerate": 30.0,
              "MaxResolution": {
                "Width": 1920,
                "Height": 1080
              },
              "Encodings": "H264",
              "Reboot": false,
              "Description": "Default Mode"
            },
            "ImagingSettings": {
              "Brightness": 50.0,
              "Focus": {
                "AutoFocusMode": "AUTO",
                "DefaultSpeed": 0.5,
                "NearLimit": 0.0,
                "FarLimit": 5.0,
                "Smoothing": true
              }
            },
            "ImagingOptions": {
              "Brightness": {
                "Min": 0.0,
                "Max": 100.0
              },
              "Focus": {
                "AutoFocusMode": [
                  "AUTO",
                  "MANUAL"
                ],
                "DefaultSpeed": {
                  "Min": 0.0,
                  "Max": 1.0
                },
                "NearLimit": {
                  "Min": 0.0,
                  "Max": 5.0
                },
                "FarLimit": {
                  "Min": 0.0,
                  "Max": 5.0
                }
              }
            },
            "CurrentPresetToken": "imgPreset1",
            "ThermalSupport": true,
            "ThermalConfiguration": {
              "ColorPalette": {
                "@token": "palette1",
                "@Type": "Rainbow",
                "@Name": "RainbowPalette"
              },
              "Polarity": "WhiteHot",
              "NUCTable": {
                "@token": "nucTable1",
                "@LowTemperture": -30.0,
                "@HighTemperture": 50.0,
                "@Name": "NUCTable1"
              },
              "Cooler": {
                "Enabled": true,
                "RunTime": 24.0
              }
            },
            "RadiometryConfiguration": {
              "RadiometryGlobalParameters": {
                "ReflectedAmbientTemperature": 20.0,
                "Emissivity": 0.95,
                "DistanceToObject": 1.0,
                "RelativeHumidity": 50.0,
                "AtmosphericTemperature": 20.0,
                "ExtOpticsTemperature": 20.0,
                "ExtOpticsTransmittance": 0.95
              }
            }
          }
        ],
        "VideoSourceConfigurations": [
          {
            "@token": "camera1_config",
            "Name": "camera1_config",
            "SourceToken": "camera1",
            "Bounds": {
              "@width": 1920,
              "@height": 1080,
              "@x": 0,
              "@y": 0
            }
          }
        ],
        "VideoEncoderConfigurations": [
          {
            "@token": "camera1_video_encoder",
            "@GovLength": 30,
            "@AnchorFrameDistance": 1,
            "@Profile": "High",
            "@GuaranteedFrameRate": 30,
            "Name": "camera1_video_encoder",
            "Encoding": "H264",
            "Resolution": {
              "Width": 1920,
              "Height": 1080
            },
            "RateControl": {
              "@ConstantBitRate": true,
              "FrameRateLimit": 30,
              "BitrateLimit": 2048
            },
            "Multicast": {},
            "Quality": 5,
            "SessionTimeout": "PT10S",
            "EncodingInterval": 1
          }
        ],
        "profile": [
          {
            "@token": "Camera1Stream1",
            "fixed": true,
            "Name": "Camera1Stream1",
            "VideoSourceConfiguration": {
              "@token": "camera1_config"
            },
            "VideoEncoderConfiguration": {
              "@token": "camera1_video_encoder"
            },
            "stream_uri": {
              "@append_params": 0,
              "#text": ""
            },
            "PTZConfiguration": {
              "@token": "ptz1"
            },
            "Presets": [
              {
                "@token": "preset1",
                "Name": "MainPosition",
                "PTZPosition": {
                  "PanTilt": {
                    "@x": 3,
                    "@y": 3
                  },
                  "Zoom": {
                    "@x": 1
                  }
                }
              },
              {
                "@token": "preset2",
                "Name": "SecondPosition",
                "PTZPosition": {
                  "PanTilt": {
                    "@x": 5,
                    "@y": 5
                  },
                  "Zoom": {
                    "@x": 2
                  }
                }
              }
            ],
            "PresetTours": [
              {
                "@token": "tour1",
                "Name": "Tour1",
                "Status": {
                  "State": "Idle"
                },
                "AutoStart": true,
                "StartingCondition": {
                  "@RandomPresetOrder": false,
                  "RecurringTime": "60",
                  "RecurringDuration": "PT1M30S",
                  "Direction": "Forward"
                },
                "TourSpot": [
                  {
                    "PresetDetail": {
                      "PresetToken": "preset1",
                      "Home": true,
                      "PTZPosition": {
                        "PanTilt": {
                          "@x": 0,
                          "@y": 0
                        },
                        "Zoom": {
                          "@x": 0
                        }
                      }
                    },
                    "Speed": {
                      "PanTilt": {
                        "@x": 0.5,
                        "@y": 0.5
                      },
                      "Zoom": {
                        "@x": 1
                      }
                    },
                    "StayTime": "PT2S"
                  }
                ]
              }
            ]
          }
        ],
        "PTZNodes": [
          {
            "@token": "ptzNode1",
            "@FixedHomePosition": true,
            "@GeoMove": true,
            "Name": "PTZNode1",
            "SupportedPTZSpaces": {
              "AbsolutePanTiltPositionSpace": {
                "XRange": {
                  "Min": -5.0,
                  "Max": 6.0
                },
                "YRange": {
                  "Min": -9.0,
                  "Max": 10.0
                }
              },
              "AbsoluteZoomPositionSpace": {
                "XRange": {
                  "Min": 0.0,
                  "Max": 3.0
                }
              },
              "ContinuousPanTiltVelocitySpace": {
                "XRange": {
                  "Min": -20.0,
                  "Max": 20.0
                },
                "YRange": {
                  "Min": -30.0,
                  "Max": 30.0
                }
              },
              "ContinuousZoomVelocitySpace": {
                "XRange": {
                  "Min": -15.0,
                  "Max": 15.0
                }
              },
              "PanTiltSpeedSpace": {
                "XRange": {
                  "Min": 0.0,
                  "Max": 4.0
                }
              },
              "ZoomSpeedSpace": {
                "XRange": {
                  "Min": 0.0,
                  "Max": 7.0
                }
              }
            },
            "MaximumNumberOfPresets": 100,
            "HomeSupported": true,
            "Extension": {
              "SupportedPresetTour": {
                "MaximumNumberOfPresetTours": 10,
                "PTZPresetTourOperation": [
                  "Start",
                  "Stop",
                  "Pause",
                  "Extended"
                ]
              }
            },
            "AuxiliaryCommands": [
              "Wiper start",
              "Wiper stop"
            ]
          }
        ],
        "PTZConfigurations": [
          {
            "@token": "ptz1",
            "@MoveRamp": 1,
            "@PresetRamp": 2,
            "@PresetTourRamp": 3,
            "Name": "PTZCfg1",
            "NodeToken": "ptzNode1",
            "UseCount": 0,
            "DefaultPTZSpeed": {
              "PanTilt": {
                "@x": 0.5,
                "@y": 0.5
              },
              "Zoom": {
                "@x": 0.5
              }
            },
            "DefaultPTZTimeout": "PT5S",
            "PanTiltLimits": {
              "Range": {
                "XRange": {
                  "Min": -13,
                  "Max": 13
                },
                "YRange": {
                  "Min": -14,
                  "Max": 14
                }
              }
            },
            "ZoomLimits": {
              "Range": {
                "XRange": {
                  "Min": -9,
                  "Max": 9
                }
              }
            },
            "Extension": {
              "PTControlDirection": {
                "EFlip": {
                  "Mode": "ON"
                },
                "Reverse": {
                  "Mode": "AUTO"
                }
              }
            }
          }
        ],
        "replay_session_timeout": 60,
        "scope": [
          "onvif://www.onvif.org/location/country/PL",
          "onvif://www.onvif.org/type/video_encoder",
          "onvif://www.onvif.org/name/IP-Camera",
          "onvif://www.onvif.org/hardware/YourHardwareId"
        ],
        "event": {
          "renew_interval": 60,
          "simulate_enable": 1
        }
      }
    ]
  }
}

The provided JSON string configures the ONVIF server with a single camera, single stream, and one PTZ controller. This configuration can be used as a base template to create your ONVIF configuration with different cameras and streams.

In order to add a new camera, the following steps should be performed:

  1. Add a new entry to the VideoSources array with the camera token, resolution, framerate, and imaging settings.
  2. Add a new entry to the VideoSourceConfigurations array with the camera token and bounds.
  3. Add a new entry to the VideoEncoderConfigurations array with the camera token, encoding settings, and resolution.
  4. Add a new entry to the profile array with the camera token, video source configuration, and video encoder configuration.

Callback mechanism

The OnvifServer class provides a callback mechanism to handle ONVIF requests. The callback function should match the following signature:

ONVIF_RET onvif_global_handler(ONVIF_DEVICE *p_device, ONVIF_MSG_TYPE msg_type, ...);

The callback function will be called for each ONVIF request received by the server. The msg_type parameter indicates the type of the request, and the variable arguments can be used to pass additional data related to the request.

// Example callback function
ONVIF_RET onvif_cb(ONVIF_DEVICE *p_device, ONVIF_MSG_TYPE msg_type, ...)
{
    va_list args;
    va_start(args, msg_type);

    // Handle the ONVIF request based on the msg_type
    switch (msg_type)
    {
        case GetImagingSettings:
            // Handle GetImagingSettings request
            auto vsl = va_arg(args, VideoSourceList *);
            auto req = va_arg(args, img_GetImagingSettings_REQ *);
            // Use vsl and req to get the imaging settings for the requested video source
            break;
        case SetImagingSettings:
            // Handle SetImagingSettings request
            auto vsl = va_arg(args, VideoSourceList *);
            auto req = va_arg(args, img_SetImagingSettings_REQ *);
            // Use vsl and req to set the imaging settings for the requested video source
            break;
        // Add more cases for other message types
    }

    va_end(args);
    return ONVIF_OK;
}

For the requests that require additional parameters (which can be information about the request or response), the callback function can use va_arg to retrieve the parameters from the variable argument list. The parameters are defined in the ONVIF specification for each message type. For example, for the SetImagingSettings message type, the parameters can include a pointer to the VideoSourceList and a pointer to the img_SetImagingSettings_REQ structure.

case SetImagingSettings:
{
    auto vsl = va_arg(args, VideoSourceList *);
    auto req = va_arg(args, img_SetImagingSettings_REQ *);
}

The req parameter will contain the request data that the ONVIF client sent, so you can use it to apply settings to your camera. For example:

yourCameraBrightness = req->ImagingSettings.Brightness;
yourCameraContrast = req->ImagingSettings.Contrast;
yourCameraColorSaturation = req->ImagingSettings.ColorSaturation;

The requests that require a response instead of an action also work the same way. For example, for the GetImagingSettings message type, the parameters can include a pointer to the VideoSourceList and a pointer to the img_GetImagingSettings_REQ structure. The response can be set by modifying the ImagingSettings field of the VideoSourceList.

case GetImagingSettings:
{
    auto vsl = va_arg(args, VideoSourceList *);
    auto req = va_arg(args, img_GetImagingSettings_REQ *);
}

This time req parameter will contain data related to request for example camera token. You can use this token to figure out which camera onvif client requested settings for. After that you can set response data to vsl->ImagingSettings. For example:

vsl->ImagingSettings.Brightness = 25.0f; // Example value, replace with actual camera settings.
vsl->ImagingSettings.Contrast = 50.0f; // Example value, replace with actual camera settings.
vsl->ImagingSettings.ColorSaturation = 75.0f; // Example value, replace with actual camera settings.

The callback function should return an ONVIF_RET value indicating the result of the operation. The possible return values are defined in the ONVIF specification and include ONVIF_OK, ONVIF_ERR_InvalidToken, and other error codes. Please refer to file /src/OnvifMessageTypes.h for the full list of message types their parameters and return values.

/profileSTemplate/OnvifServerCallback.cpp file contains an example of the callback function that handles ONVIF requests that provides Profile S compliance. Please note that Profile S compliance requires additional features such as real video streaming, Ptz control, http server for system restore, and RTSP over HTTP tunneling. These features are implemented in the Profile S template application and are not part of the OnvifServer library functionality. The callback function in the Profile S template handles ONVIF requests related to video streaming, PTZ control, and other Profile S specific features.

Simple example

The application bellow shows simplest usage of OnvifServer. The application create OnvifServer object and initialize it with a simple callback.

#include <iostream>
#include <string>
#include <thread>
#include <chrono>
#include "OnvifImage.h"
#include "OnvifServer.h"
#include "OnvifGlobalHandler.h"
#include "DefaultConfigContent.h"

/// ONVIF callback function. This function handles ONVIF messages.
ONVIF_RET onvifCallback(ONVIF_DEVICE *p_device, ONVIF_MSG_TYPE msg_type, ...)
{
    va_list args;
    va_start(args, msg_type);

    // Unless request is rejected explicitly, better to return ONVIF_OK
    // for many requests for test tool compatibility.
    ONVIF_RET ret = ONVIF_OK;

    // Check the message type and handle it accordingly.
    switch (msg_type)
    {
        // Handle SetImagingSettings request.
        case SetImagingSettings:
        {
            auto vsl = va_arg(args, VideoSourceList *);
            auto req = va_arg(args, img_SetImagingSettings_REQ *);

            // Get token. Camera token is defined in config file.
            std::string cameraName(vsl->VideoSource.token);

            // Some logic depends on camera name if we have multiple cameras.

            // Apply these settings to your camera. 
            req->ImagingSettings.Brightness;
            req->ImagingSettings.Contrast;
            req->ImagingSettings.ColorSaturation;
            break;
        }
        // Handle GetImagingSettings request.
        case GetImagingSettings:
        {
            auto vsl = va_arg(args, VideoSourceList *);
            auto req = va_arg(args, img_GetImagingSettings_REQ *);

            // Get token. Camera token is defined in config file.
            std::string cameraName(vsl->VideoSource.token);

            // Some logic depends on camera name if we have multiple cameras.

            // Fill image settings.
            auto imageSettings = &vsl->ImagingSettings;
            imageSettings->Brightness = 25.0f;      // Example value.
            imageSettings->Contrast = 50.0f;        // Example value.
            imageSettings->ColorSaturation = 75.0f; // Example value.
            break;
        }

        // ... Other cases for handling different ONVIF messages ...
    }

    va_end(args);

    // Return the result of the operation.
    return ret;
}

/// Entry point.
int main(int argc, char **argv)
{
    // Create ONVIF server object.
    cr::onvif::OnvifServer onvifServer;

    // Init ONVIF server with the JSON configuration and callback function.
    if (!onvifServer.init(g_defaultConfigContent, onvifCallback))
        return -1;

    // Start ONVIF server.
    if (!onvifServer.start())
        return -1;

    // Wait key press to stop the server.
    std::cout << "ONVIF server started. Press Enter to stop..." << std::endl;
    std::cin.get();

    onvifServer.stop();

    return 0;
}

Profile S template

The OnvifServer library provides a template for Profile S. The template is located in the profileSTemplate folder. Profile S template requires additional dependencies: VStreamerMediaMtx (Provides RTSP video server. Source code included), CppHttpLib (Provides HTTP server required for ONVIF Profile S, v3.14.0 source code included, MIT license), and ChildProcess (Provides function tu run external processes). This dependencies provide full functional video management and streaming capabilities of Onvif Profile S template.

The most important files in the profileSTemplate folder are:

  • OnvifServerCallback.cpp - file with ONVIF server callback example. This file contains the implementation of the callback function that handles ONVIF requests.
  • OnvifServerProfileS.json - example JSON configuration file for the ONVIF server. This file contains the configuration for the ONVIF server, including device information, supported services, and capabilities.

In order to support Profile S, the OnvifServer library uses the VStreamerMediaMtx (source code included) library, which uses the MediaMTX executable to provide RTSP streaming. The mediamtx executable and mediamtx.yml configuration file should be located in the same folder as the OnvifServer executable. The mediamtx application can be obtained from MediaMTX releases. Follow the instructions from MediaMTX.

The OnvifServer library also uses the CppHttpLib library to provide HTTP server functionality for the system restore feature of Profile S. The source code of the CppHttpLib library is located in the 3rdparty/CppHttpLib folder. The CppHttpLib library is used to handle HTTP requests and responses, and to provide the necessary functionality for Profile S compliance.

Lastly, Profile S requires RTSP over HTTP tunneling support. However, the VStreamerMediaMtx library does not support RTSP over HTTP tunneling. Therefore, the OnvifServer library uses the live555ProxyServer executable to provide RTSP over HTTP tunneling support. The live555ProxyServer executable should be located in the same folder as the OnvifServer executable.

Instructions to to build live555ProxyServer :

  • Obtain live555 library source code
      git clone https://github.com/rgaufman/live555
      cd live555
    
  • Modify config file for C++ std support. So open related config file for example, config.linux-64bit. Add -DNO_STD_LIB to CPLUSPLUS_FLAGS.

  • Build live555 library
     ./genMakefiles linux-64bit
     make
    
  • live555ProxyServer executable is located in the live555/proxyServer folder. Copy live555ProxyServer executable to the same folder as the OnvifServer executable.

Test application

The OnvifServer library provides a test application located in the test folder. The test application demonstrates the usage of the OnvifServer library and provides examples of how to use the library’s features. The test application includes all features of the OnvifServer library but does not provide any RTSP streams.

In order to run the test application, the /test/onvif.json file should be located in the same folder as the test application executable. This file contains the configuration for the ONVIF server, including device information, supported services, and capabilities.

Dependencies

The OnvifServer library has the dependency on openssl and zlib. In order to install these dependencies by using package manager, you can use the following commands:

sudo apt install libssl-dev zlib1g-dev

Build and connect to your project

Typical commands to build OnvifServer library:

cd OnvifServer
mkdir build
cd build
cmake ..
make

If you want to connect the OnvifServer library to your CMake project as source code, you can follow these steps. For example, if your repository has this structure:

CMakeLists.txt
src
    CMakeList.txt
    yourLib.h
    yourLib.cpp

Create a 3rdparty folder in your repository and place the OnvifServer repository folder there. The new structure of your repository will be:

CMakeLists.txt
src
    CMakeLists.txt
    yourLib.h
    yourLib.cpp
3rdparty
    OnvifServer

Create a CMakeLists.txt file in the **3rdparty** folder. The CMakeLists.txt should contain:

```cmake
cmake_minimum_required(VERSION 3.13)

################################################################################
## 3RD-PARTY
## dependencies for the project
################################################################################
project(3rdparty LANGUAGES CXX)

################################################################################
## SETTINGS
## basic 3rd-party settings before use
################################################################################
# To inherit the top-level architecture when the project is used as a submodule.
SET(PARENT ${PARENT}_YOUR_PROJECT_3RDPARTY)
# Disable self-overwriting of parameters inside included subdirectories.
SET(${PARENT}_SUBMODULE_CACHE_OVERWRITE OFF CACHE BOOL "" FORCE)

################################################################################
## CONFIGURATION
## 3rd-party submodules configuration
################################################################################
SET(${PARENT}_SUBMODULE_ONVIF_SERVER              ON  CACHE BOOL "" FORCE)
if (${PARENT}_SUBMODULE_ONVIF_SERVER)
    SET(${PARENT}_ONVIF_SERVER                    ON  CACHE BOOL "" FORCE)
endif()

################################################################################
## INCLUDING SUBDIRECTORIES
## Adding subdirectories according to the 3rd-party configuration
################################################################################
if (${PARENT}_SUBMODULE_ONVIF_SERVER)
    add_subdirectory(OnvifServer)
endif()

OnvifServer default configuration supports profile S mandatory and optional features. For enabling/disabling other features following flags can be used in CMakeLists.txt file:

# Default configuration supports Profile S.
SET(ONVIF_HTTPD_SUPPORT                      ON  CACHE BOOL "" ${REWRITE_FORCE})
SET(ONVIF_MEDIA_SUPPORT                      ON  CACHE BOOL "" ${REWRITE_FORCE})
SET(ONVIF_IMAGE_SUPPORT                      ON  CACHE BOOL "" ${REWRITE_FORCE})
SET(ONVIF_DEVICE_IO_SUPPORT                  ON  CACHE BOOL "" ${REWRITE_FORCE})
SET(ONVIF_MEDIA2_SUPPORT                     ON  CACHE BOOL "" ${REWRITE_FORCE})
SET(ONVIF_PTZ_SUPPORT                        ON  CACHE BOOL "" ${REWRITE_FORCE})
SET(ONVIF_IP_FILTER_SUPPORT                  ON  CACHE BOOL "" ${REWRITE_FORCE})
SET(ONVIF_MPEG4_SUPPORT                      OFF CACHE BOOL "" ${REWRITE_FORCE})
SET(ONVIF_PROFILE_G_SUPPORT                  OFF CACHE BOOL "" ${REWRITE_FORCE})
SET(ONVIF_PROFILE_C_SUPPORT                  OFF CACHE BOOL "" ${REWRITE_FORCE})
SET(ONVIF_CREDENTIAL_SUPPORT                 OFF CACHE BOOL "" ${REWRITE_FORCE})
SET(ONVIF_ACCESS_RULES_SUPPORT               OFF CACHE BOOL "" ${REWRITE_FORCE})
SET(ONVIF_SCHEDULE_SUPPORT                   OFF CACHE BOOL "" ${REWRITE_FORCE})
SET(ONVIF_AUDIO_SUPPORT                      OFF CACHE BOOL "" ${REWRITE_FORCE})
SET(ONVIF_VIDEO_ANALYTICS_SUPPORT            OFF CACHE BOOL "" ${REWRITE_FORCE})
SET(ONVIF_THERMAL_SUPPORT                    OFF CACHE BOOL "" ${REWRITE_FORCE})
SET(ONVIF_RECEIVER_SUPPORT                   OFF CACHE BOOL "" ${REWRITE_FORCE})
SET(ONVIF_STORAGE_SUPPORT                    OFF CACHE BOOL "" ${REWRITE_FORCE})
SET(ONVIF_PROVISIONING_SUPPORT               OFF CACHE BOOL "" ${REWRITE_FORCE})
SET(ONVIF_GEOLOCATION_SUPPORT                OFF CACHE BOOL "" ${REWRITE_FORCE})
SET(ONVIF_DOT11_SUPPORT                      OFF CACHE BOOL "" ${REWRITE_FORCE})

The file 3rdparty/CMakeLists.txt adds the OnvifServer folder to your project and excludes the test application and examples from compiling (by default, test application and examples are excluded from compiling if OnvifServer is included as a sub-repository). Your repository’s new structure will be:

CMakeLists.txt
src
    CMakeList.txt
    yourLib.h
    yourLib.cpp
3rdparty
    CMakeLists.txt
    OnvifServer

Next you need include folder 3rdparty in main CMakeLists.txt file of your repository. Add string at the end of your main CMakeLists.txt:

add_subdirectory(3rdparty)

Next you have to include OnvifServer library in your src/CMakeLists.txt file:

target_link_libraries(${PROJECT_NAME} OnvifServer)

Done!


Table of contents