How to run JIT with Accurate Player SDK
This is a step-by-step tutorial that covers how to build a JIT frontend application using the Accurate Player SDK.
The source code for this tutorial is available for download in the Accurate Player SDK Examples repository
Prerequisites
First, you need the Node.js JavaScript runtime installed. If you don't have it installed already, go to How to install Node.js and follow the instructions.
Verify that you have a recent version of node installed, we recommend that you use the latest LTS version of node
. Type this to get the node
version printed in your terminal:
node -v
The installation of node also includes npm
, a package manager for Node.js. We will use npm
to install the packages required to run the JIT frontend application.
To install Accurate Player's SDK packages, you will need a username and password to Codemill's npm
repository. Your sales representative can provide you with these. Once you have these, login to Codemill's npm
repository by running this command in your terminal:
npm login --auth-type=legacy --registry=https://codemill.jfrog.io/codemill/api/npm/accurate-video/ --scope=@accurate-player
This will make npm
use the Codemill npm
repository for all packages whose name starts with @accurate-player
. After a successful command, your access token will be stored in your user config. The user config location can be found by running:
npm config get userconfig
Finally, this tutorial requires a JIT backend service running on localhost.
Building the application
Basic Player
We will use Vite, a frontend build tool, to create the frontend application.
To scaffold your project run:
npm create vite@latest
You will be prompted some information about the project:
Need to install the following packages:
create-vite@5.2.3
Ok to proceed? (y) y
✔ Project name: … jit-frontend
✔ Select a framework: › Vanilla
✔ Select a variant: › TypeScript
Scaffolding project in jit/tutorials/quick-start/jit-frontend...
Done. Now run:
cd jit-frontend
npm install
npm run start
Follow the instructions to get the development server up and running.
Next, you need a license key for Accurate Player JIT. If you don't have one, talk to your sales representative. In the jit-frontend
directory, create a file called license-key.js
:
window.LICENSE_KEY = "<YOUR LICENSE KEY>";
Next, include your license key in the application:
...
<head>
...
<script src="/license-key.js"></script>
...
</head>
Now we need to install the AP SDK libraries we will use in this tutorial. In the jit-frontend
project run:
npm install -d @accurate-player/accurate-player-core
npm install -d @accurate-player/accurate-player-jit
npm install -d @accurate-player/accurate-player-plugins
npm install -d @accurate-player/accurate-player-controls
Next, delete everything already in src/main.ts
, then add imports and declare the player:
import './style.css'
import {JITPlayer} from "@accurate-player/accurate-player-jit";
import {
Player,
PlayerEventType,
} from "@accurate-player/accurate-player-core";
let player: Player;
Next, in src/main.ts
, let's add a button, video, and a status container to the page:
const applicationContainer = document.querySelector<HTMLDivElement>('#app')!;
applicationContainer.innerHTML = `
<button id="loadbutton">Load video</button>
<div id="status">Idle</div>
<div class="video-container" >
<video id="videomaster" autoplay></video>
</div>
`;
The autoplay
attribute on the <video>
element is important here as we want the WebRTC stream to start as soon as we start receiving it.
Locate the button and add an event listener for click
:
const loadButton: HTMLButtonElement = document.querySelector("#loadbutton")!;
loadButton.addEventListener("click", () => {
initPlayer();
loadVideo();
});
There needs to be user activation on the page before the browser allows us to start watching the WebRTC video stream (because of autoplay
).
We already added the calls to initPlayer
and loadVideo
. Let's look at those functions next.
function initPlayer() {
const videoMaster: HTMLVideoElement = document.querySelector("#videomaster")!;
const statusDiv: HTMLDivElement = document.querySelector("#status")!;
player = new JITPlayer(videoMaster, window.LICENSE_KEY, {
jitBackend: "http://localhost:8080",
iceServers: [{
urls: [
"stun:stun.l.google.com:19302",
"stun:stun1.l.google.com:19302",
"stun:stun2.l.google.com:19302",
"stun:stun3.l.google.com:19302",
"stun:stun4.l.google.com:19302",
]
}],
});
player.on(PlayerEventType.Loading, () => {
statusDiv.innerText = "Loading (this may take a while)...";
});
player.on(PlayerEventType.Loaded, () => {
statusDiv.innerText = "Loaded";
player.api.play();
});
}
When we create the JITPlayer
we need to provide:
- the video element that we added earler
- the license key that you got from your sales rep
and settings that specify:
- the location of the JIT Backend and,
- STUN/TURN servers. Here is a list of some free alternatives for STUN/TURN. You can also use a local STUN/TURN server if you started one when following the backend tutorial.
We also added some event listeners to get callbacks when the player is loading (PlayerEventType.Loading
) and is finished loading (PlayerEventType.Loaded
) to update the status text on the page.
Next we load a video file:
function loadVideo() {
player.api.loadVideoFile({
src: "https://accurate-player-static.s3.eu-central-1.amazonaws.com/Sintel/sintel-2048-timecode-6ch.mp4",
frameRate: {
numerator: 24,
denominator: 1
}
});
}
And now we have a functioning player!
JIT Parameters
When loading a file with JIT, we can append a number of parameters. Read more about JitVideoFile and JitParameters in the docs. Below are a few common examples.
src
can be a URL as above. It can also be a local file path, accessible on the host machine running the backend. That would look something like this instead:
...
src: "file:///media/video.mp4",
...
Another example would be to scale down 4k to HD to be able to stream without lagging/buffering. Scaling down the example file by half would look something like this:
import { JITVideoFile } from "@accurate-player/accurate-player-jit";
function loadVideo() {
let jitVideoFile: JITVideoFile = {
src: "https://s3.eu-central-1.amazonaws.com/accurate-player-demo-assets/timecode/sintel-2048-timecode-stereo.mp4",
}
jitVideoFile.frameRate = {
numerator: 24,
denominator: 1,
};
jitVideoFile.jit = {};
jitVideoFile.jit.resolution = {
width: 2048 / 2,
height: 872 / 2
};
jitVideoFile.jit.lowres = 1;
player.api.loadVideoFile(jitVideoFile);
}
Accurate Player Controls
To make it a little more usable, we want to add Accurate Player Controls. Start with importing the package:
import "@accurate-player/accurate-player-controls";
Then alter the html
like this:
applicationContainer.innerHTML = `
<button id="loadbutton">Load video</button>
<div id="status">Idle</div>
<div class="video-container" >
<video id="videomaster" autoplay></video>
<apc-controls class="apc-video"></apc-controls>
</div>
And init the controls in initPlayer
:
const apControls = document.querySelector("apc-controls") as any;
apControls.init(videoMaster, player);
And, to restrict apc-controls to the video container, add this to style.css
:
.video-container {
position: relative;
}
And now you have video controls, so that you can play, pause, search, change playback speed, etc!
Accurate Player Hotkeys
To activate keyboard hotkeys, import the plugin:
import { HotkeyPlugin } from "@accurate-player/accurate-player-plugins";
and initialize it in the initPlayer
function:
new HotkeyPlugin(player);
Quality slider
Default, JIT sets the streaming quality automatically. To be able to set it manually, we want a slider. Add this to the html
element:
<input type="range" id="quality-input-el" class="quality-input" min="1" max="100" value="50" disabled>
<div>
<label for="override-quality-el">Override quality manually</label>
<input type="checkbox" id="override-quality-el" class="override-quality">
</div>
Now we have a slider and a checkbox to toggle to setting the quality manually. Let's create references to them:
const overrideQualityCheckbox = document.getElementById("override-quality-el") as HTMLAudioElement;
const qualityInput = document.getElementById("quality-input-el") as HTMLAudioElement;
And, in initPlayer
, add some event listeners to update both quality and related elements, for the automatic and the manual case:
overrideQualityCheckbox.checked = false;
overrideQualityCheckbox.addEventListener('change', function() {
qualityInput.disabled = !overrideQualityCheckbox.checked;
updateManualQuality();
});
qualityInput.addEventListener('change', function() {
updateManualQuality();
});
player.on(PlayerEventType.StatusChanged, () => {
if (!overrideQualityCheckbox.checked) {
qualityInput.value = player.api.reportedQuality;
}
});
And, finally, create the handler that actually sets the quality:
function updateManualQuality()
{
let value = Math.round(qualityInput.value as number);
if (overrideQualityCheckbox.checked && value && value >= 1 && value <= 100)
{
player?.api.setQuality(value);
}
else
{
player?.api.setQuality(null);
}
}
Result
That's it. You can inspect the final file jit-frontend/src/main.ts
This is the bare minimum to get you started. You can add extra functionality to your player / application by loading more Plugins or by following any of our other tutorials in the Accurate Player SDK Examples repository.