Skip to main content
Skip table of contents

Forensic watermarking

To test this feature and view the example code, please see the Apple (FPS) SDK 5 Example Code Quick Start guide.

The Nexguard library forensic watermarking tool embeds a unique, invisible serial number onto video/audio content.

Version 2 of QuickMark watermarking can work in two different modes:

  • In pull mode, the player acquires the watermark from the configured server as necessary.
  • In push mode, the customer application acquires the watermark and provide it to the player for display.

The OTVQuickmark class abstracts the NexGuard-QuickMark library functionality that provides watermarking to the SDK.  This is contained within the OTVQuickMarkView.framework in the opy-ios-fps-<version>-quickmark.zip file delivered in the iOS SDK pack.

Prerequisites

A Watermarking server to generate the watermarked surface. Associated with this:

  • Tenant Id - you may use TEST_TENANT  during integration
  • Service endpoint URL
  • Secret key
  • API Key to authenticate with the service endpoint if required (optional)

A system to generate 24-bit Watermark IDs (contained within the token) to identify the user, session and device or both.

Swift Protobuf is needed for the OTVQuickmarkView sdk. The Swift Protobuf library can be found at: https://github.com/apple/swift-protobuf 

  • Swift Protobuf gives multiple examples of how to include the library in your project. We recommend using version 1.6.0 as this is the version we have integrated and tested ourselves.
  • The Swift Protobuf library is linked but not embedded inside OTVQuickMarkView.framework. You will need to put Swift Protbuf for your target as a dependency when linking OTVQuickMarkView.framework.

Configuration Values

OTVQuickmark requires several configuration values for push and pull mode. The table below shows which values are necessary and which are optional for the two modes.


Required configuration valuesOptional  configuration values
Pull Mode
  • token 
  • url
  • apiKey

  • signKey
  • computeSignatureCb
  • saveBlobCb

  • errorCb

  • messageCb

Push Mode
  • signKey
  • url
  • apiKey

  • token
  • computeSignatureCb

  • saveBlobCb

  • errorCb

  • messageCb


If you decide not to create your own callbacks as shown in the example code, OTVQuickMark will use its own internal callbacks. The functionality of these callbacks are:

  • computeCallback: This internal callback uses the signKey to compute the SHA-1 Signature 

  • errorCallback: This internal callback prints out the error message to the console.

  • messageCallback: This internal callback prints out the message callback to the console, which contains the debug information

  • saveblobCallback: This callback has no internal functionality. 

Pull mode example configuration

Instantiate and configure the OTVWatermark class providing all the configuration parameters.

CODE
  func setupOTVQuickmark() {
    do {
      try otvQuickmark = OTVQuickmark(token: nxgdQmSrvToken, apiKey: nxgdQmSrvApiKey, url: nxgdQmSrvUrl)
    }
    catch {}

The sign key is set with a specific method call:

CODE
    otvQuickmark?.setSignKey(signKey: nxgdQmsignKey)

The PlayerView and AVPlayerLayer must be bound together to allow the presentation of the watermark. Call bind(playerView:playerLayer:) passing references to your PlayerView and AVPlayerLayer.

CODE
    otvQuickmark?.bind(playerView: playerView, playerLayer: playerView.playerLayer)

When using TEST_TENANT  as the tenant, you should see a stub pattern displayed over your video.

Push mode example configuration

Push mode has additional requirements; two variants can provide them.  The first (simpler) is where default callbacks are provided within the OTVQuickMarkView.framework. The code snippets below will describe the second variant where the integrator needs to implement callback methods.

Instantiate and configure the OTVWatermark class providing the names of the integrators own callback methods.

CODE
  func setupOTVQuickmark() {
    do {
        try otvQuickmark = OTVQuickmark(computeSignatureCb: computeCb, saveBlobCb: saveblob, errorCb: errorCb, messageCb: messageCb)

The remaining configuration parameters need to be passed to the integrators implementation that will do the work of acquiring the watermark image.

CODE
      quickMarkNetworkService = try QuickMarkSimpleNetworkService.init(url: nxgdQmSrvUrl,
                                                                       token: nxgdQmSrvToken,
                                                                       apiKey: nxgdQmSrvApiKey,
                                                                       onMessageCb: onNetworkMessageCb,
                                                                       onErrorCb: onNetworkErrorCb,
                                                                       onBlobReceivedCb: onNetworkblobreceived)

For brevity, the full example code of the callbacks and QuickMarkSimpleNetworkService class is only provided within the opy-sdk-ios-fps-<version>-example-code.zip file.

As in the pull mode example, the setSignKey() and bind() methods must be called.

JavaScript errors detected

Please note, these errors can depend on your browser setup.

If this problem persists, please contact our support.