LLicenseManager Reference Manual & Licensing Guide
The LLicenseManager class is the central licensing validation engine of the now2sdk framework, defined in the now2sdk namespace. It provides a modular licensing strategy where individual premium components (such as LReplay, LAnimation, LSwitcher, or LStinger) are validated independently.
If a module is not licensed or its support contract has expired, LLicenseManager enforces licensing policies by rendering a visual watermark directly onto video frames in memory.
1. Architectural Concepts & Licensing Flow
graph TD
A[Client Application] -->|initialize license block| B(LLicenseManager)
B --> C{Verify License?}
C -->|No| D[Unlicensed Mode]
C -->|Yes| E{SDK Build Date <= License Expiration?}
E -->|No: Expired Support Contract| D
E -->|Yes: Valid License| F[Unlocks Module]
G[Playout / Render Loop - LReplay / LAnimation] --> H{isLicensed?}
H -->|Yes| I[Transmit Clean Feed]
H -->|No| J[applyWatermark]
J --> K[Render now2sdk overlay on AVFrame]
Key Licensing Mechanisms:
- License Verification: Validates the license string details. The verification process checks module names and expiration metadata against the SDK compile parameters to ensure the license is valid.
- Update Expiration Enforcement: Prevents clients from using new SDK builds with old support contracts. The manager compares the SDK's release date with the license's
License.UpdateExpirationparameter. If the SDK compile release date is newer than the support contract date, the license is invalidated for that version. - Luma-Channel Watermark Overlay: When watermarking is triggered,
LLicenseManager::applyWatermarkmodifies the frame'sAVFrameY (Luma) plane. It draws the text"now2sdk"in the center of the frame as an overlay.
2. License Block Configuration (INI Format)
Licenses are represented as INI blocks. Multiple blocks can be concatenated in a single string to license multiple modules simultaneously:
[now2sdk]
License.Module=LReplay
License.IssuedTo=Deyan Automation
License.UpdateExpiration=2026-12-15
License.Signature=950d5a5600d1e7bd36be31fb2b97582cb7e7b9208965161892b23b6271e779ee
[now2sdk]
License.Module=LAnimation
License.IssuedTo=Deyan Automation
License.UpdateExpiration=2026-12-15
License.Signature=d2c67efbc56722d36fa89c0919de15ba78e63b62b1b369c0d1e1fa62bcf819ea
Parameter Explanations:
License.Module: The specific class name to unlock (e.g.,"LReplay","LAnimation","LSwitcher","LStinger").License.IssuedTo: The name of the client/organization.License.UpdateExpiration: The support contract end date (YYYY-MM-DD). The SDK release date must be equal or older than this date.License.Signature: Signature string verifying block integrity.
3. API Reference & Methods
📌 Static Methods
static void initialize(const std::string& licenseData);
Clears previous license registrations, parses the concatenated INI blocks, verifies their validity, checks the support contract boundaries, and registers valid modules.
static bool isLicensed(const std::string& moduleName);
Checks if the specified module has a valid, active license. Returns true if valid, and false otherwise.
static std::string getUpdateExpirationDate(const std::string& moduleName);
Returns the update expiration date string ("YYYY-MM-DD") for the registered module.
static std::string getIssuedTo(const std::string& moduleName);
Returns the licensee name for the registered module.
static void applyWatermark(AVFrame* frame);
Renders the semi-transparent "now2sdk" watermark overlay directly onto the AVFrame's luma channel.
4. Single-Module Playout License Activation
To activate a license for a single specific module, developers have two options:
Option A: Using the Instance API (Recommended)
Every premium class (e.g. LReplay, LAnimation, LSwitcher, LStinger) exposes a public setLicense() helper method. This is the simplest way to configure a single module:
#include "LReplay.h"
#include <iostream>
void initializeSingleReplayInstance() {
LReplay* replayEngine = new LReplay();
// Pass the INI block for LReplay directly to the class instance
bool success = replayEngine->setLicense(R"(
[now2sdk]
License.Module=LReplay
License.IssuedTo=Deyan Automation
License.UpdateExpiration=2026-12-15
License.Signature=950d5a5600d1e7bd36be31fb2b97582cb7e7b9208965161892b23b6271e779ee
)");
if (success && replayEngine->isLicensed()) {
std::cout << "Replay engine licensed and ready." << std::endl;
} else {
std::cout << "Replay engine is running in unlicensed DEMO mode (Watermarked)." << std::endl;
}
}
Option B: Using the Global Manager API
Developers can initialize the licensing details globally for a single module name at the beginning of the program:
#include "LLicenseManager.h"
#include "LAnimation.h"
#include <iostream>
void initializeSingleModuleGlobally() {
// 1. Define the single module license block
std::string animLicense = R"(
[now2sdk]
License.Module=LAnimation
License.IssuedTo=Deyan Automation
License.UpdateExpiration=2026-12-15
License.Signature=d2c67efbc56722d36fa89c0919de15ba78e63b62b1b369c0d1e1fa62bcf819ea
)";
// 2. Initialize the global manager
now2sdk::LLicenseManager::initialize(animLicense);
// 3. Verify specifically for LAnimation
if (now2sdk::LLicenseManager::isLicensed("LAnimation")) {
std::cout << "LAnimation has been successfully unlocked." << std::endl;
}
}
5. Multi-Module SDK Initialization on Application Startup
This example demonstrates how to parse and register multiple module licenses during application initialization.
#include "now2sdk.h"
#include "LLicenseManager.h"
#include <iostream>
int main() {
// 1. Concatenated license blocks
std::string licenseString = R"(
[now2sdk]
License.Module=LReplay
License.IssuedTo=Deyan Automation
License.UpdateExpiration=2026-12-15
License.Signature=950d5a5600d1e7bd36be31fb2b97582cb7e7b9208965161892b23b6271e779ee
[now2sdk]
License.Module=LAnimation
License.IssuedTo=Deyan Automation
License.UpdateExpiration=2026-12-15
License.Signature=d2c67efbc56722d36fa89c0919de15ba78e63b62b1b369c0d1e1fa62bcf819ea
)";
// 2. Initialize the License Manager
now2sdk::LLicenseManager::initialize(licenseString);
// 3. Verify module validation states
if (now2sdk::LLicenseManager::isLicensed("LReplay")) {
std::cout << "LReplay has been successfully unlocked for client: "
<< now2sdk::LLicenseManager::getIssuedTo("LReplay") << std::endl;
} else {
std::cout << "WARNING: LReplay is running in unlicensed DEMO mode!" << std::endl;
}
if (now2sdk::LLicenseManager::isLicensed("LAnimation")) {
std::cout << "LAnimation has been successfully unlocked. Support contract valid until: "
<< now2sdk::LLicenseManager::getUpdateExpirationDate("LAnimation") << std::endl;
}
return 0;
}
6. Integration Inside Custom Processing Loops
This example shows how a custom player or replay engine applies watermarking policies to its output frames before distributing them to downstream sinks.
#include "now2sdk.h"
#include "LLicenseManager.h"
class CustomPlayoutEngine : public LObject {
public:
void setLicense(const std::string& licenseData) {
now2sdk::LLicenseManager::initialize(licenseData);
}
bool isLicensed() const {
return now2sdk::LLicenseManager::isLicensed("CustomPlayoutEngine");
}
protected:
void processingLoop(AVFrame* decodedFrame) {
// ... frame decoding logic ...
// Apply watermark policies if unlicensed
if (!isLicensed()) {
now2sdk::LLicenseManager::applyWatermark(decodedFrame);
}
// Distribute frame to registered sinks
distributeVideoFrame(decodedFrame);
}
};