Skip to main content

Bitmovin Player pre-integrated bundle

To automate embedding Bitmovin Player on your website the methods from Publish tab in Streaming module might not be flexible enough. For that scenarios we prepared a Bitmovin Player pre-integrated bundle in two variants.

The bundle includes Bitmovin Player and Cloud Video Kit integration software. It allows you to stream content created in Cloud Video Kit using one of the best video players on the market. To use the bundle, you need a Cloud Video Kit account and a Player License Key from console. Once the player is created, you can customize it to your needs by following the Player UI customization guide.


Before integration

Before starting the integration, you need the following four elements for initializing player:

  • key - your "@CLOUD_VIDEO_KIT_BITMOVIN_PLAYER_KEY" (from Cloud Video Kit)
  • url - endpoint which returns addresses to manifests and DRM info (from Cloud Video Kit)
  • token - JWT token, which contains information about the tenantid and assetid of the material you want to play in the payload

The token should be generated by your backend application. Token generation is explained in details below in Token section. Token generated on backend protects your signingKey. This process adds an extra layer of security and makes life harder for anyone who wants to steal your content.


Integration approaches

JavaScript bundle over CDN

Probably the easiest way to start using pre-integrated Bitmovin Player in your app is by adding link to files hosted over Content Delivery Network. Here are the steps to integrate the JavaScript bundle:

  1. In the head section of the page, attach the bundled JS file: <script src="https://cdn.jsdelivr.net/npm/@cloud-video-kit/bitmovin-player@1.0.1/dist/browser/secured/min/index.min.js"></script> and bitmovin player <script src="https://cdn.bitmovin.com/player/web/8/bitmovinplayer.js"></script>
  2. In a script tag, create a new player instance: var player = new bitmovin.player.CvkBitmovinPlayer(document.getElementById("player"), config);
  3. Initialize player await player.initialize()
  4. Call the sourceConfig method, with the endpoint url and the JWT token as the call parameter (read more about token generation and source config)

Example code:

<html>
<head>
<script src="https://cdn.bitmovin.com/player/web/8/bitmovinplayer.js"></script>
<script src="https://cdn.jsdelivr.net/npm/@cloud-video-kit/bitmovin-player@1.0.1/dist/browser/secured/min/index.min.js"></script>
</head>
<body>
<div id="player"></div>
<script>
(async () => {
var playerConfig = {
// get @cloud-video-kit/bitmovin-player key from https://console.videokit.cloud/dashboard/streaming/configuration#licenses
key: "@CLOUD_VIDEO_KIT_BITMOVIN_PLAYER_KEY",
};

var playerInstance = new bitmovin.player.CvkBitmovinPlayer(
document.getElementById("player"),
playerConfig
);

await playerInstance.initialize(bitmovin.player.Player);

// sourceConfig call - with success response the player is ready to play
// get source config url from https://console.videokit.cloud/dashboard/streaming/configuration#integration-parameters
playerInstance
.sourceConfig("SOURCE-COFIG-URL", "JWT-TOKEN")
.then(
function () {
console.log("Successfully loaded source"); // Success!
},
function () {
console.log("Error while loading source"); // Error!
}
);
})();
</script>
</body>
</html>

NPM package

For more advanced integration, we recommend installing via npm. Please follow these steps:

  1. Install the package by running npm i @cloud-video-kit/bitmovin-player
  2. Import CvkBitmovinPlayer into your code using import { CvkBitmovinPlayer } from "@cloud-video-kit/bitmovin-player";
  3. Create a new player instance using const playerInstance = new CvkBitmovinPlayer(containerElement, config);
  4. Initialize player await player.initialize()
  5. Call the sourceConfig method and provide the endpoint URL and JWT token as parameters (read more about token generation and source config)
  • url - endpoint that returns addresses to manifests and DRM info
  • token - JWT token that contains information about the tenantid and assetid of the material you want to play in the payload.

Example code:

import { CvkBitmovinPlayer } from "@cloud-video-kit/bitmovin-player";
import { UIFactory } from "bitmovin-player-ui";
import "bitmovin-player-ui/dist/css/bitmovinplayer-ui.css";
import { Player } from "bitmovin-player";

const playerConfig: PlayerConfig = {
// get your @cloud-video-kit/bitmovin-player key and Bitmovin Analytics License key from https://console.videokit.cloud/dashboard/streaming/configuration#licenses
key: "@CLOUD_VIDEO_KIT_BITMOVIN_PLAYER_KEY",
analytics: { // optional if you want to use Analytics feature
key: "BITMOVIN_ANALYTICS_LICENSE_KEY",
}
};

const playerContainer = document.getElementById('player');
const playerInstance = new CvkBitmovinPlayer(playerContainer, playerConfig);

// Create the UI
UIFactory.buildDefaultUI(playerInstance);

await playerInstance.initialize(Player);

// sourceConfig call - with success response the player is ready to play
// get your source config url from https://console.videokit.cloud/dashboard/streaming/configuration#integration-parameters
playerInstance.sourceConfig('SOURCE-CONFIG-URL', 'JWT-TOKEN')
.then(
() => {
console.log("Successfully loaded source");
},
() => {
console.log("Error while loading source");
}
);

// HTML
<body>
<div id="player"></div>
</body>

SourceConfig method

Description

The sourceConfig method returns the URLs to the Dash and HLS manifests. In the case of DRM-protected materials, the response will also contain fields pointing the player to the addresses of Playready / Widevine / Fairplay license servers.

Method definition

sourceConfig(url: string, token: string, init?: RequestInit): Promise<void>;

Required

  • url - The endpoint that returns addresses to manifests and DRM info. Parameter example https://tenant.streaming.videokit.cloud/v1/sourceconfig.
  • token - A JWT token that contains information about the tenantid, userid and assetid of the material you want to play in the payload. For more information about tokens, visit https://jwt.io/introduction

Optional

  • init - Contains network request properties used to modify an HTTP request. For more information, visit RequestInit

Token generation

Instead of passing the tenantID, assetID, and userID directly as parameters for the method, the API expects a token. This mechanism adds an extra layer of security as the tokens are signed using a secretKey. Token generation should occur on the backend to secure the secretKey from being exposed.

Token access protection can be disabled per tenant or per asset. It will make your integration easier, but your content will be less secure.

In our case, the token in the payload section contains the following information:

  • tenantid=[string] - The tenantid in Cloud Video Kit is a unique string that identifies your account.
  • assetid=[string] - The ID of the material you want to open in the player. It's a unique identifier of an asset created in VOD, Recorder or Live module. You can find it in the table of contents, or on asset’s detail page in Cloud Video Kit web console
  • userid=[string] - userid of the end user who wants to play the material. This parameter is optional and is used for limitting concurrent sessions per user
  • exp=[number] - Expiration time of the JWT token, in the form of a Unix timestamp. We recommend keeping it short-lived, for example, 60 seconds.

Example token payload:

{
"tenantid": "fed119a4-6bad-49c4-a53a-25a4c1a0b49c",
"assetid": "b95005b5-a6aa-4ccf-a850-b745ff1c1513",
"userid": "user123",
"exp": 1676981532
}

"5EEwZcVIlDTTmg2yUl56g+8lUE/yyah1XrJrUQBWpbU=" is a secretKey used in below examples. Your value of this parameter will be provided by Insys.

Examples

Below, you will find sample token generation code for various programming languages.

  using Microsoft.IdentityModel.Tokens;
using System.IdentityModel.Tokens.Jwt;
using System.Security.Claims;

namespace dotnet
{
internal static class JwtToken
{
private static readonly string Key = "5EEwZcVIlDTTmg2yUl56g+8lUE/yyah1XrJrUQBWpbU=";

public static string CreateToken()
{
var expiration = DateTime.Now.AddSeconds(60);
JwtPayload payload = new JwtPayload(null, null, new List<Claim>(), null, expiration);
payload.Add("tenantid", "fed119a4-6bad-49c4-a53a-25a4c1a0b49c");
payload.Add("assetid", "b95005b5-a6aa-4ccf-a850-b745ff1c1513");
payload.Add("userid", "user123");

var keyBytes = Convert.FromBase64String(Key);
var signingKey = new SymmetricSecurityKey(keyBytes);
SigningCredentials signing = new SigningCredentials(signingKey, SecurityAlgorithms.HmacSha256);
JwtHeader header = new JwtHeader(signing);

JwtSecurityToken token = new JwtSecurityToken(header, payload);
var handler = new JwtSecurityTokenHandler();
var tokenString = handler.WriteToken(token);
return tokenString;
}

public static bool ValidateToken(string token)
{
var keyBytes = Convert.FromBase64String(Key);
var signingKey = new SymmetricSecurityKey(keyBytes);
var tokenHandler = new JwtSecurityTokenHandler();

try
{
tokenHandler.ValidateToken(
token,
new TokenValidationParameters
{
ValidateIssuerSigningKey = true,
IssuerSigningKey = signingKey,
ValidateAudience = false,
ValidateIssuer = false,
ValidAlgorithms = new List<string> { SecurityAlgorithms.HmacSha256 },
RequireExpirationTime = true,
RequireSignedTokens = true,
ValidateLifetime = true,
},
out SecurityToken validatedToken);
}
catch
{
return false;
}
return true;
}
}
}