May 17, 2021

Secure your account in 3 easy steps

WMSPanel cloud control panel provides extended control over your Nimble Streamer server instances. Softvelum customers utilize Nimble extensively to build their media delivery networks and streaming infrastructure, and they use WMSPanel to perform the setup easily via both web UI and API.

Web services have a lot of upside like convenience of operations. However there is a downside to it as well: if you compromise your account credentials, an abuser may take control over your assets and do significant damage.

Besides evil intentions, people just make mistakes sometimes, so you need to improve your account security to avoid them.

Here are some general practices which we highly recommend for all of WMSPanel accounts and users to improve security and robustness of your account.

1. Users management: admins vs. non-admins

First, let's check what you can do on a company account and user level.

There are two types of users in WMSPanel: admins and non-admins.

Admins can do the following.

  • Install servers and register them in WMSPanel.
  • Add and change all Nimble Streamer settings on all servers.
  • View all stats for all servers.
  • Enable and disable statistical metrics.
  • Create and change subscriptions and view invoices.
  • Add, change and remove users.
  • Track users' activities log.
When you create an account in WMSPanel, your login becomes an admin user.

Non-admins cannot do much unless you allow them to:

  • They only view the stats in the data slices where they are assigned by admins.
  • Admins can grant non-admins specific permissions for specific servers, e.g. change live streaming settings only on a designated Nimble Streamer server instance. This article explains how it works.
  • Admins may also assign a group of non-admins to control a separate group of servers using data slices. This article describes the approach and its setup.

As you can see, there is no need to make some people the admin users while you can make them non-admins and grant only some limited permissions.

The rule of thumb is: don't grant too many permissions unless you really need to do that.

2. Two-factor authentication: a must-have

Being a user with WMSPanel login, you have to make sure your credentials are not exposed to anyone else. Doesn't matter if you are a full-scale admin or a non-admin who wants to view stats. However, if your credentials are obtained by malware or as a result of some sophisticated targeted attack, you need the second line of defense.

So you must enable two-factor authentication for your WMSPanel user. This is a modern de-facto standard for operations on the Internet so you must be familiar with it. So read this article to learn more about enabling 2FA.

Or just go to Settings menu, open Security tab and follow the instructions there.

3. Nimble config cloud backups: "undoing" mistakes

If you use a Nimble Streamer instance, one of your most valuable assets is its streaming settings. This is what you do as a streaming infrastructure architect and engineer: set up Nimble, test it with your source streams or files, launch it in products and make changes to those settings if necessary.

However, people make mistakes. Whatever you do to secure the users, those users can accidentally remove a server, erase some setting or make some experiment which would ruin the setup. You need to be able to overturn events like that.

We created Cloud backups of Nimble Streamer configuration to cover this use case. It allows making both manual and automated "snapshots" of server instance configuration which is then stored in WMSPanel cloud infrastructure. The key feature is that those backups cannot be erased or changed by any end user - admin or non-admin. When the backup is set and enabled for a specific server, those backups will allow restoring the state of settings of that server.

Cloud backups cost just 1 USD per month per backup.

These are simple rules to make your WMSPanel experience more secure and reliable.

Let us know if you have any questions.

May 13, 2021

KLV metadata in Nimble Streamer

KLV is a standard used for embedding meta information, usually into video feeds. Some of our customers use it for their use cases so they've been asking us for its support.

So now Nimble Streamer supports KLV metadata passthrough. It works for the following protocols:

  • MPEG-TS-based input: MPEG-TS over UDP and over HTTP, SRT and RIST.
  • Supported outputs are MPEG-TS over HTTP/UDP, SRT and RIST.

So if your MPEGTS input has KLV streams in it, you'll be able to pass them through.

To enable this feature, you need to add max_forwarded_klv_streams parameter into Nimble config file to set the maximum number of expected streams.


Don't forget to re-start Nimble instance to make it work.

You can use ffprobe to see how many KLV streams there are in your input MPEGTS streams.

Let us know if you have any questions and if you have any specific cases for KLV.

Related documentation

Nimble Streamer MPEGTS feature set

Advertizer per-session ads insertion and stats

Nimble Advertizer is a wide feature set for server-side ads insertion for Nimble Streamer software media server. It allows adding pre-roll and mid-roll ads into live and VOD streams according to customer business logic.

Dynamic ads can be inserted into HLS, RTMP, SLDP and Icecast outgoing live streams, along with HLS VOD output.

Previously the Advertizer allowed setting rules for ads insertion per application, per stream, as well as define per-user rules based on pay-per-view framework of Nimble Streamer.

With recent update it's now possible to apply Advertizer to more use cases:

  1. Make per-session ads insertion for each individual user by using customer-side session handler.
  2. Get per-session statistics to accumulate ads insertion metrics for advertisers' confidence.

In current article we'll focus on per-session mechanics without going into common details of Advertizer functionality like pre-requisites or general config grammar. You can find full set of details about Advertizer set setup and usage in Advertizer tech spec. You can also take a look Advertizer demo page showing the playback of all supported protocols with inserted ads.

Notice that per-session ads insertion is available for HLS, SLDP and Icecast outgoing live streams and for HLS VOD output. RTMP output is not supported for per-session scenarios.

1. Workflow

Let's see how Advertizer works with regular workflow and how it can be adjusted with per-session approach.

In a regular workflow the steps are straight-forward:

  1. Nimble Advertizer calls ads handler web application to get a business logic description.
  2. Advertising handler returns ads content description and applicability rules of what ads need to be inserted in which streams.
  3. Nimble Streamer gets the ads files and inserts their content them into output streams according to.

In per-session workflow, the second and third steps will have additional layer or activities.
  1. Your advertising handler (main handler) will now need to return the URL of per-session handler in addition to ads content description and applicability rules.
  2. Nimble Advertizer will call the per-session handler to send rules request and session info.
  3. Per-session handler gets the request and session info, and then makes the decision about who needs to watch which ads. It may also save the stats for further analysis.
  4. Per-session handler returns a set of rules specific to individual users.
  5. Nimble Advertizer serves ads according to new rules received by per-session handler, with session rules having priority over rules provided by the main handler.
Let's see how you can follow the described steps.

2. Enabling per-session handler

Per-session handler, just like main Advertizer handler, is a REST controller application which is called by Nimble Advertizer. You may use any language and framework to create it. Handler response must be a valid JSON text. Handler app must be available via HTTP/HTTPS protocol and accessible from Nimble instance.

Per-session handler URL needs to be returned in main handler's response in a new section called "session_handler" like shown below.


  "session_handler": {

    "apps": ["local", "remote", "live"],



  "contents": [

    {"id":"1","uri":"http:\/\/\/ads\/1_180.mp4", "height":"180"},

    {"id":"2","uri":"http:\/\/\/ads\/1_240.mp4", "height":"240"},

    {"id":"3","uri":"http:\/\/\/ads\/1_360.mp4", "height":"360"},

    {"id":"4","uri":"http:\/\/\/ads\/1_360.mp4", "height":"480"},



  "rules": [



This and other examples are available in Advertizer github repo, like this one.

Please note that Nimble streamer supports rendition-specific ads insertion taking the "height" parameter provided in the “contents” section which allows inserting ads with the stream’s appropriate resolution (see section 4 below).

The session_handler section may contain optional elements, here's full example:

"session_handler": {

  "url": "https://server/handler",

  "apps": ["app1", "app2"],

  "timeout": "1000",

  "onerror": "skip"


The elements mean the following:
  • url is the URL of per-session handler.
  • apps is a list of applications which are defined in Nimble Streamer, and which ads insertion will be applied to.
  • timeout is a period of time which Nimble can wait for per-session handler response. It's measured in milliseconds and it's 1000 by default.
  • onerror defines what action needs to be made is response is not received on time. It's "skip" by default which means that the playback will continue. The "stop" value means that the playback must be stopped and not processed since session handler has failed.

Let's see what happens when Nimble Streamer calls per-session handler.

3. Sending request to handler

First, open per-session-handler-request.json example from our github to illustrate the description below.

The request has two sections: session_info and rules_request. The handler is called in any of these events:

  • Each 30 seconds to send session_info part, you can use advertising_session_rules_request_interval to set it.
  • On each new connection, to send rules_request part. Also session_info can be sent with collected session information if available.
  • Each request_interval time slot, as defined in section 4.

Let's see what each section provides.

session_info is included in the request to show the statistics of ads viewership.

It has subsections for all sessions served by Advertizer since the last handler call, each session has its subsection. Here are the elements of each session:

  • session is a session ID.
  • app and stream show the stream which was served.
  • client_ip is the IP of a viewer.
  • user_agent is a data from viewer's User Agent header.
  • state is either active or inactive.
  • views contain data about ad viewership. It has 3 subelements: rule has ID of an ads rule applied, content has ID of ads content shown and uri is a URL of content applied.
  • userif you use pay-per-view framework, you will get user element which indicates viewer's user ID.

rules_request is included in requests to get response about what Nimble must do for sessions. Each session has individual section. It has the following elements.

  • session is s session ID.
  • protocol is a protocol type of a stream. This can be "hls", "sldp" or "icecast".
  • app and stream show the stream which is being served.
  • client_ip is the IP of a viewer.
  • user_agent is a data from viewer's User Agent header.
  • stream_time is a duration of a session prior to the moment when the request was sent

With these two sections, your per-session handler can make decisions about the ads content to be shown to your viewers.

Here's what per-session handler is expected to return to Nimble Advertizer.

4. Getting response from session handler

Take a look at response example below.

      "time_offset": 0,
      "time_sync": "stream",
      "type": "session",
      "id": 101,
      "contents": [{"id": ["1", "2", "3", "4"]}]
      "rules": [101],
      "session": 5,
      "request_interval": 10

You may also find it in Advertizer github.

Per-session handler response has two sections.

rules section defines rules for ads insertion which will be applied to sessions from rules_response section. The grammar for this section is the same as for main handler response describe in Advertizer spec. The only difference is that "type" element must always be "session".

These rules are also appended to the rules from the main handler response, so you may combine both per-session and default approaches to ads insertion. If there are per-session and main handler rules with the same rule ID, then session rule will be applied as it has priority.

Note that content IDs for resolution-specific ads insertion are provided in the rule as an array of ids, like "contents": [{"id": ["1", "2", "3", "4"]}] while these content ids and the respective content URLs are defined in the in main handler's response previously (see section 2 above).

rules_response section describes which ads insertion rules need to be applied to a particular session.

  • rules is the list of ads rules to be applied.
  • session is the ID of the session where rules are applied
  • request_interval defines how often after that Nimble Advertizer needs to request rules for this session.

The rules from response will be applied to current session once it's received by Advertizer. Some delay is possible in case of HLS just because of chunks download time and player reaction.

If you have any questions about Advertizer or per-session ads insertion, let us know.

Related documentation

Nimble AdvertizerNimble Advertizer spec, github repo for Advertizer,