Skip to main content
If your use case doesn’t require DRM, you can follow the same steps provided below, omit the DRM configuration part, and follow our video storage structure guide, which describes how to access your Bunny Stream videos programmatically.

What you’ll need

Before you dive in, make sure you have the following prerequisites in place:

Setting up Bitmovin player

Bitmovin offers an HTML web player that can be embedded into your site using JavaScript. You can read official Bitmovin documentation on how to get started with the player or copy the code sample below.
You are required to use your own license key for the player to ensure domain whitelisting for production environments.
The demo code provided below can be run in localhost without issues.The JavaScript changes below are required to ensure compatibility with our license endpoints.

HTML configuration

Incorporate the following HTML code into your web page:
<html lang="en">
  <head>
    <link
      rel="stylesheet"
      type="text/css"
      href="https://cdn.jsdelivr.net/npm/bitmovin-player@8/bitmovinplayer-ui.css"
    />
    <title>Bitmovin Player Demo</title>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="text/html; charset=utf-8" />
    <script
      type="text/javascript"
      src="https://cdn.jsdelivr.net/npm/bitmovin-player@8/bitmovinplayer.js"
    ></script>
  </head>
  <body>
    <div class="player-wrapper">
      <div id="player"></div>
    </div>
  </body>
</html>

JavaScript configuration

Replace [ENTER_YOUR_BITMOVIN_KEY] with your actual Bitmovin license key. The JavaScript configuration below includes necessary modifications to ensure compatibility with the license endpoints, as well as DRM configurations for both Widevine and FairPlay:
var conf = {
  key: "[ENTER_YOUR_BITMOVIN_KEY]", // change key here
  logs: {
    level: "debug",
  },
  network: {
    preprocessHttpRequest: function (type, request) {
      if (type === "drm/license/fairplay") {
        request.headers["Content-Type"] = "application/json";
      }
      return Promise.resolve(request);
    },
    preprocessHttpResponse: function (type, response) {
      switch (type) {
        case "drm/certificate/fairplay":
          const obj = JSON.parse(new TextDecoder().decode(response.body));
          const { certificate } = obj;
          response.body = base64ToArrayBuffer(certificate);
          break;
        case "manifest/hls/variant":
          response.body = response.body.replace(
            /.*KEYFORMAT="com.apple.streamingkeydelivery"\n/,
            "",
          );
          break;
        default:
          break;
      }
      return Promise.resolve(response);
    },
  },
};

var source = {
  title: "New Dashboard",
  hls: "{{playlistUrl}}",
  drm: {
    widevine: {
      LA_URL:
        "https://video.bunnycdn.com/WidevineLicense/{{videoLibraryId}}/{{videoId}}",
      maxCertificateRequestRetries: 0,
      maxLicenseRequestRetries: 0,
    },
    fairplay: {
      LA_URL:
        "https://video.bunnycdn.com/FairPlayLicense/{{videoLibraryId}}/{{videoId}}",
      certificateURL:
        "https://video.bunnycdn.com/FairPlayLicense/{{videoLibraryId}}/{{videoId}}",
      maxCertificateRequestRetries: 0,
      maxLicenseRequestRetries: 0,
      useUint16InitData: true,
      licenseResponseType: "json",
      prepareContentId: (url) => {
        return url.substring(url.indexOf("skd://"));
      },
      prepareLicense: (license) => {
        return license.ckc;
      },
      prepareMessage: (event, session) => {
        const obj = JSON.stringify({
          spc: btoa(String.fromCharCode.apply(null, event.message)),
        });
        return obj;
      },
    },
  },
};

function base64ToArrayBuffer(base64) {
  var binary_string = window.atob(base64);
  var len = binary_string.length;
  var bytes = new Uint8Array(len);
  for (var i = 0; i < len; i++) {
    bytes[i] = binary_string.charCodeAt(i);
  }
  return bytes.buffer;
}

const player = new bitmovin.player.Player(
  document.getElementById("player"),
  conf,
);
player.load(source);

Finalizing integration

After embedding the HTML and JavaScript code into your web application, the Bitmovin Player should load and be capable of playing DRM-protected content from Bunny Stream. Test the setup in various environments to ensure compatibility and performance across different devices and browsers.