This guide explains how to embed recorded videos into external websites using the Fermion SDK.
The Fermion SDK is open source and available on GitHub: github.com/fermion-app/sdk

Prerequisites

  • Video ID from your Fermion dashboard
  • Fermion API key (only if you disable public embeds)
  • Access to your website’s codebase
  • Your website domain (for origin whitelisting - optional but recommended)

Step 1: Enable Video Library and Get Video ID

First, go to Manage features tab on your instructor dashboard and enable Video library: After that, go to Video library and upload a video if you haven’t: Each video on Fermion has a unique identifier (e.g., 6779080e80ec97e953a17971). You’ll need this ID for embedding.

Step 2: Configure Origin Whitelisting (Optional)

For enhanced security, you can configure origin whitelisting to control which domains are allowed to embed your videos. This is especially useful for public embeds to prevent unauthorized usage.

Per-Video Origin Whitelisting

You can set a whitelisted origin for individual videos:
  1. Go to your video settings
  2. In the Video Settings section, find the Whitelisted origin (optional) field
  3. Enter the domain where you want to embed the video (e.g., https://example.com)
  4. Make sure Allow public embeds is enabled if you want the video to be publicly embeddable
If you specify a whitelisted origin, only that domain will be allowed to embed your video. Leave empty to allow all origins. Domain restrictions do not apply when using JWT signed tokens - signed embeds will always work regardless of origin whitelisting settings.

Global Origin Whitelisting

You can also set a default whitelisted domain for all your videos:
  1. Click on Modify global settings for videos
  2. In the Global video settings modal, enter your domain in the Whitelisted domain for embedding videos externally (optional) field
  3. Click Save Changes
If specified, this domain will be used as the default whitelisted origin for all videos that don’t have a specific whitelisted origin set. Leave empty to allow all origins by default. Note: JWT signed tokens always bypass domain restrictions.

Step 3: Install the SDK

npm install @fermion-app/sdk
# or
yarn add @fermion-app/sdk
# or
pnpm add @fermion-app/sdk

Step 4: Basic Video Embedding

Public Video Embedding

For public videos, you can use the following code:
import { FermionRecordedVideo } from '@fermion-app/sdk/recorded-video'

// Create a video instance
const video = new FermionRecordedVideo({
	videoId: 'your-video-id',
	websiteHostname: 'your-domain.fermion.app',
})

// Get the embed code
const publicEmbed = video.getPubliclyEmbedPlaybackIframeCode()
console.log(publicEmbed.iframeHtml)
When using public embeds with origin whitelisting enabled, make sure your website domain matches the whitelisted origin you configured in Step 2. If there’s a mismatch, the video embed will not work.

Private Video Embedding

If your video is not public, you’ll need to generate a JWT token for authentication:
import jwt from 'jsonwebtoken'

const payloadObject = {
	type: 'external-embed',
	videoId: 'your-video-id',
	userId: 'unique-user-id',
}

const jwtToken = jwt.sign(payloadObject, 'FERMION_API_KEY', {
	expiresIn: '10h',
})
Important notes: - Replace FERMION_API_KEY with your actual API key - Provide a unique user ID for each viewer - Recommended token validity is 10h-20h
Then use the token to embed the video:
const privateEmbed = video.getPrivateEmbedPlaybackIframeCode({
	jwtToken: 'your-jwt-token',
})
console.log(privateEmbed.iframeHtml)
JWT signed embeds work from any domain, regardless of origin whitelisting settings. This makes private embeds more flexible than public embeds when it comes to domain restrictions.

Step 5: Controlling Video Playback

Once the video is embedded, you can control its playback programmatically using the play() and pause() methods.
import { FermionRecordedVideo } from '@fermion-app/sdk/recorded-video'

const video = new FermionRecordedVideo({
	videoId: 'your-video-id',
	websiteHostname: 'your-domain.fermion.app',
})

// Assuming you have added the iframe to your DOM
// For example:
// const embed = video.getPubliclyEmbedPlaybackIframeCode();
// document.getElementById('video-container').innerHTML = embed.iframeHtml;

// You can now control the video
video.play() // to play the video
video.pause() // to pause the video
The SDK automatically assigns a unique ID to the iframe when you use getPubliclyEmbedPlaybackIframeCode or getPrivateEmbedPlaybackIframeCode. This allows play() and pause() to find the iframe automatically without you passing the iframe element.
If you have multiple videos or a custom iframe setup, you can pass the iframe element directly to the methods:
const iframeElement = document.querySelector('#my-custom-iframe-id')
video.play(iframeElement)
video.pause(iframeElement)

Step 6: Add Event Listeners (Optional)

Track video playback events using the SDK’s event system:
const video = new FermionRecordedVideo({
	videoId: 'your-video-id',
	websiteHostname: 'your-domain.fermion.app',
})

// Setup event listeners
const events = video.setupEventListenersOnVideo()

// Listen for video events
events.onVideoPlay((data) => {
	console.log('Video started playing at', data.durationAtInSeconds, 'seconds')
})

events.onVideoPaused((data) => {
	console.log('Video paused at', data.durationAtInSeconds, 'seconds')
})

events.onTimeUpdated((data) => {
	console.log('Current playback time:', data.currentTimeInSeconds, 'seconds')
})

events.onVideoEnded(() => {
	console.log('Video playback ended')
})

// When done, clean up the listeners
events.dispose()
Event listeners only work when using the Fermion video player through getPubliclyEmbedPlaybackIframeCode or getPrivateEmbedPlaybackIframeCode. They are not available when using manual M3U8 playback.

Advanced: Custom M3U8 Playback

For security, all Fermion videos are encrypted using AES-128 (clearkey) encryption. The Fermion video player, embedded via the iframe methods, handles the decryption process seamlessly. We highly recommend using the default Fermion player as it is robust, production-ready, and provides a user-friendly experience out of the box. However, for advanced use cases where you need to integrate the video into your own custom video player (like HLS.js, Video.js, etc.), you can get the M3U8 playback URL. The getM3U8PlaybackUrl method fetches the M3U8 manifest, patches it with the necessary decryption key, and returns a blob URL that your player can use.
DRM-protected videos can only be played using the Fermion iframe embed. The custom M3U8 playback method does not support DRM at this time.
const video = new FermionRecordedVideo({
	videoId: 'your-video-id',
	websiteHostname: 'your-domain.fermion.app',
})

// Get M3U8 playback URL
const m3u8Url = await video.getM3U8PlaybackUrl({
	origin: 'https://cdn-storage.fermion.app',
	m3u8Pathname: '/path/to/your/playlist.m3u8',
	decryptionKey: '6815d8748df5297181862d32',
	signedUrlSearchParams: '?verify=signature_here',
})

// Use this URL with your custom HLS player
To get the playback options (origin, m3u8Pathname, decryptionKey, signedUrlSearchParams), you need to call the get-signed-url-data-for-recorded-video-playback API endpoint from your backend server with your Fermion API key. Refer to API Reference for more information.