Lab
  • DRM packaging tutorialsCourse
  • 5 things you need to know about multi-DRMCourse
  • Getting started with DoveRunner Anti PiracyCourse
  • Getting started with DoveRunner Forensic WatermarkingCourse
  • Getting started with DoveRunner Mobile App SecurityCourse
  • Getting started with DoveRunner Multi-DRMCourse
  • Getting started with DoveRunner Transcoding & PackagingCourse
  • Packaging content with the DRM CLI PackagerLesson · DRM packaging tutorials
한국어

Transcoding & Packaging with the TnP API

Get a token, register storage, create a job, and poll its status with the TnP API to produce a CMAF, DRM, and Forensic Watermarking stream.

Lesson 25 min

DRM: —FWM: —Status: idle

What the TnP API does

The Transcoding & Packaging (TnP) API runs the same jobs as DoveRunner Console from your own code or scripts. One job transcodes a source video, packages it as CMAF, protects it with Multi-DRM, and preprocesses it for Forensic Watermarking, so the stream is ready for DRM playback and watermark embedding.

The flow has five calls: get a token, register input and output storage, create a job, poll its status, and check the output.

Before you start

  • DoveRunner Site ID and access key: found in DoveRunner Console
  • Two AWS S3 buckets (input and output) and an IAM user with an access key that can read and write both
  • A source MP4 uploaded to the input bucket
  • DRM and Forensic Watermarking enabled on your site
  • An HTTP client, such as curl, Postman, or your own code

All calls go to https://tnp.doverunner.com/api.

1. Get an access token

Send accountId:accessKey as Base64 in a Basic authorization header. You can encode it with the Base64 encoder / decoder under Playground > Common Tools in the Lab.

GET /api/token/{siteId}
Authorization: Basic <base64(accountId:accessKey)>

The response contains data.token. Send it as the Authorization header on every other call.

Write Basic with a capital B. The lowercase basic shown in some examples returns 401 E9001 Token value is invalid.

2. Register input and output storage

Register each bucket once with POST /api/storage/{siteId}. The response returns a storage_id; keep both.

Field Value
storage_name A name for this storage
aws_bucket The S3 bucket name
io_type input or output
access_key_id / secret_key The IAM user's access key
region The service region code (RGxxx)
description Optional note

You can list registered storages with GET /api/storage/{siteId}. The input and output buckets must be in the same region as the TnP service region.

3. Create the job

Create the job with POST /api/job/{siteId}. The request has a job name and content ID, an input section, and an output section.

{
  "job_name": "my-tutorial-job",
  "content_id": "my-content-id",
  "input": {
    "storage_id": "<input storage_id>",
    "files": [
      {
        "file_type": "multi",
        "file_path": "folder/source.mp4",
        "audios": [{ "in": { "track": 0 }, "remap": { "track": 0 } }]
      }
    ]
  },
  "output": {
    "storage_id": "<output storage_id>",
    "path": "lab-contents",
    "transcodings": [ ... ],
    "packaging": { "dash": false, "hls": false, "cmaf": true },
    "drm": { "enabled": true },
    "forensic_watermarking": { "enabled": true }
  }
}
  • content_id is the ID your player and license requests use.
  • output.path is the Output Directory Path. TnP adds the content ID below it.
  • audios maps the source audio track to the output. Without it (and the matching sources in the audio transcoding), the job fails with 400 E2141.

Transcoding

transcodings lists one entry per output rendition. Each video rendition sets track_id, track_type, codec (h264 or h265), width, height, bitrate_mode, and bitrate. The audio rendition sets codec (aac), bitrate, language, and sources.

{ "track_id": "video1", "track_type": "video", "codec": "h264",
  "width": 1920, "height": 1080, "bitrate_mode": "cbr", "bitrate": 2500000 },
{ "track_id": "video2", "track_type": "video", "codec": "h264",
  "width": 1280, "height": 720, "bitrate_mode": "cbr", "bitrate": 1200000 },
{ "track_id": "audio1", "track_type": "audio", "codec": "aac",
  "bitrate_mode": "cbr", "bitrate": 128000, "language": "en",
  "sources": [{ "track": 0 }] }

Packaging, DRM, and watermarking

Set packaging.cmaf to true to package CMAF, which serves Widevine, PlayReady, and FairPlay from one set of segments. drm and forensic_watermarking only need { "enabled": true }. Other options are optional; see DoveRunner Docs.

A successful request returns data.job_id. Failed requests return an error_code and error_message.

4. Poll the job status

GET /api/job/{siteId}/{jobId}

Read job_status from the response. The codes you see on a normal run are:

Code State
TP010 Media info checked
TP100100 Transcoding
TP300100 Packaging
TP500 Complete

TP600 means the job failed. The full list is on the status and error codes page. A job like this one takes a few minutes.

5. Check the output

When the status is TP500, the output is in the output bucket under wm-contents/<path>/<content ID>/:

wm-contents/
└── <output.path>/
    └── <content ID>/
        ├── 0/cmaf/   (stream.mpd, master.m3u8, video/, audio/)
        └── 1/cmaf/

0 and 1 are the two watermark variants (A/B). You can cross-check the job in Transcoding & Packaging > Job History in DoveRunner Console. DoveRunner also sends a notification email when a job finishes or fails.

The video above is this kind of output: CMAF, DRM, and watermark variants, played through the Lab's Session URL API. The next step is watermark embedding.