Monitor HLS.js (Web)
The FastPix Data SDK with HLS.js tracks key metrics like user engagement, playback quality, and web performance to optimize the viewing experience. It offers customizable tracking, detailed streaming insights, and secure error management for improved video delivery and performance.
Step 1: Installation and setup
To install the SDK, you can use npm or your favourite node package manager 😉:
npm install @fastpix/data-core
Initialize FastPix Data SDK
To start tracking and analyzing video performance using FastPix, you need to initialize the FastPix Data SDK with your unique Workspace key. Follow these steps:
Log into your FastPix Dashboard and go to the Workspaces section.
Once you've identified the correct workspace, copy the Workspace Key associated with it. This key is essential for client-side monitoring and should be included in the JavaScript code on every webpage where you want to track video performance and analytics.
Basic usage:
import fastpixMetrix from "fp-core-metrix";
Use the following React or JavaScript or HTML code into your application to configure HLS with FastPix:
import React, { useEffect, useRef } from "react";
import Hls from "hls.js"; // Import HLS.js library for video streaming
import fastpixMetrix from "@fastpix/data-core";
export default function VideoPlayer() {
const videoElementRef = useRef(null);
// Replace with your actual stream URL
const videoSourceUrl =
"https://stream.fastpix.io/027a90e4-f5e2-433d-81e5-b99ee864c3f6.m3u8"; // Your HLS stream URL
useEffect(() => {
let hlsInstance;
// Check if the videoElementRef.current is available before proceeding
if (videoElementRef.current) {
const videoElement = videoElementRef.current;
const playerInitTime = fastpixMetrix.utilityMethods.now(); // Get player initialization time
// Check if the video element can play HLS natively (Safari support)
if (videoElement.canPlayType("application/vnd.apple.mpegurl")) {
// For Safari, which has native HLS support
videoElement.src = videoSourceUrl;
} else if (Hls.isSupported()) {
// For other browsers, initialize Hls.js
hlsInstance = new Hls();
hlsInstance.loadSource(videoSourceUrl); // Load the video stream
hlsInstance.attachMedia(videoElement); // Attach the stream to the video element
// Custom metadata to be passed for tracking
const customData = {
workspace_id: "WORKSPACE_KEY", // Replace with your workspace key
player_name: "Main Player", // Identifier for the player instance
player_init_time: playerInitTime, // Player initialization time
// Add any additional metadata here
};
// IMPORTANT: You **must** pass both `hlsInstance` and `Hls` to the FastPix tracker for correct tracking
fastpixMetrix.tracker(videoElement, {
debug: false,
hlsjs: hlsInstance, // Pass the `hlsInstance` created above
Hls, // Pass the `Hls` constructor (imported)
data: customData,
});
}
}
// Cleanup on component unmount
return () => {
if (hlsInstance) {
hlsInstance.destroy(); // Clean up HLS.js instance when the component is unmounted
}
};
}, [videoElementRef]);
return (
<video
controls
ref={videoElementRef}
style={{ width: "100%", maxWidth: "500px" }}
/>
);
}
import Hls from "hls.js";
import fastpixMetrix from "@fastpix/data-core";
const videoElement = document.getElementById('video-player'); // Video element reference
const videoSourceUrl = "https://stream.fastpix.io/027a90e4-f5e2-433d-81e5-b99ee864c3f6.m3u8"; // Your HLS stream URL
// Ensure the video element is available
if (videoElement) {
let hlsInstance;
const playerInitTime = fastpixMetrix.utilityMethods.now(); // Get player initialization time
// Check if the video element can play HLS natively (Safari support)
if (videoElement.canPlayType("application/vnd.apple.mpegurl")) {
// For Safari, which has native HLS support
videoElement.src = videoSourceUrl;
} else if (Hls.isSupported()) {
// For other browsers, initialize Hls.js
hlsInstance = new Hls();
hlsInstance.loadSource(videoSourceUrl); // Load the video stream
hlsInstance.attachMedia(videoElement); // Attach the stream to the video element
// Custom metadata to be passed for tracking
const customData = {
workspace_id: "WORKSPACE_KEY", // Replace with your workspace key
player_name: "Main Player", // Identifier for the player instance
player_init_time: playerInitTime, // Player initialization time
// Add any additional metadata here
};
// IMPORTANT: You **must** pass both `hlsInstance` and `Hls` to the FastPix tracker for correct tracking
fastpixMetrix.tracker(videoElement, {
debug: false,
hlsjs: hlsInstance, // Pass the `hlsInstance` created above
Hls, // Pass the `Hls` constructor (imported)
data: customData,
});
}
}
<video id="my-player" controls width="660" height="380" />
<script>
const playerInitTime = Date.now(); // Track player initialization time
const videoEl = document.querySelector('#my-player'); // Select the video element
if (Hls.isSupported()) { // Check if HLS is supported in the browser
let hls = new Hls(); // Create a new HLS.js instance
hls.loadSource('https://stream.fastpix.io/027a90e4-f5e2-433d-81e5-b99ee864c3f6.m3u8'); // Load the video source (HLS stream)
hls.attachMedia(videoEl); // Attach the video element to the HLS.js instance
if (window && window.fastpixMetrix) {
// Start tracking video analytics
fastpixMetrix.tracker(videoEl, {
hlsjs: hls, // Pass the HLS.js instance to analytics
Hls: Hls, // Pass HLS.js to analytics for reference
debug: true,
data: {
workspace_id: "YOUR_WORKSPACE_KEY", // Your workspace key for analytics
player_init_time: playerInitTime, // Time when the player was initialized
video_title: "core player" // Title of the video
// ... and other metadata
},
});
}
}
</script>
PLEASE NOTE
When configuring the SDK, include both the hls instance and the Hls constructor in the options.
Step 2: Including custom metadata:
PLEASE NOTE: workspace_id is the only mandatory field, providing additional metadata can greatly enhance analytics and reporting.
Here’s how to structure your initialization:
fastpixMetrix.tracker("#my-player", {
debug: false, // Set to true for debugging information in the console
hlsjs: hls,
Hls: Hls,
data: {
workspace_id: "WORKSPACE_KEY", // Replace with your actual workspace key
viewer_id: "", // Example: '12345' - Unique identifier for the viewer
experiment_name: "", // Example: 'player_test_A' - Name of the experiment if applicable
sub_property_id: "", // Example: 'cus-1' - Identifier for the sub-property
// Player Metadata
player_name: "", // Example: 'My Main Player' - Name of the player instance
player_version: "", // Example: '1.0.0' - Version of the player
player_init_time: fastpixMetrix.utilityMethods.now(), // Use current time or specify a timestamp
// Video Metadata
video_id: "", // Example: 'abcd123' - Unique identifier for the video
video_title: "", // Example: 'My Great Video' - Title of the video
video_series: "", // Example: 'Weekly Great Videos' - Series name if applicable
video_duration: 120000, // Example: 120000 (2 minutes) - Duration in milliseconds
video_stream_type: "on-demand", // Specify 'live' or 'on-demand'
video_cdn: "", // Example: 'Fastly' or 'Akamai' - CDN used for streaming
},
});
To explore all the additional metadata options supported by the FastPix Data SDK, check out the User-Passable Metadata section.
DEVELOPMENT TIP
Keep metadata consistent across different video loads to make comparison easier in your analytics dashboard.
Step 3: Changing video streams in player
Effective video view tracking is crucial to track multiple videos in the same player in your application. You can reset tracking in two key scenarios: when loading a new source, such as in video series or episodic content, and when switching programs within a continuous live stream.
Handling new source loading
When your application plays multiple videos back-to-back in the same player, it’s essential to notify the FastPix SDK whenever a new video starts; possibly in scenarios like playlist content/ video series or any other video that user wants to play.
Emitting a videoChange
event:
To inform the FastPix SDK of a new view, emit a videoChange event immediately after loading the new video source. Include relevant metadata about the new video:
// videoElement is the HTML5 <video> element representing your video player.
const videoElement = document.getElementById("#my-player");
videoElement.fp.dispatch("videoChange", {
video_id: "NEW_SOURCE_VIDEO_ID", // Unique identifier for the new video
video_title: "NEW_SOURCE_VIDEO_TITLE", // Title of the new video
video_series: "NEW_SERIES", // Series name if applicable
// Additional metadata can be included here
});
PLEASE NOTE
Always ensure that this event is dispatched right after the new source is loaded to maintain accurate tracking.
Managing program changes in live streams
In scenarios where the program changes within a continuous stream (e.g., live broadcasts), tracking each program as its own view can provide more granular analytics.
Emitting a programChange
event:
When a program change occurs, emit a programChange event with updated metadata.
// videoElement is the HTML5 <video> element representing your video player.
const videoElement = document.getElementById("#my-player");
videoElement.fp.dispatch("programChange", {
video_id: "NEW_PROGRAM_VIDEO_ID", // Unique identifier for the new video
video_title: "NEW_PROGRAM_VIDEO_TITLE", // Title of the new video
video_series: "NEW_SERIES_SERIES", // Series name if applicable
// Additional metadata can be included here
});
PLESE NOTE
The programChange event should only be emitted when the player is not paused. Emitting this event while paused can lead to inaccurate tracking of video startup time and watch time.
Step 4: Advanced configurations with HLS.js
Enhancing your video player with advanced options can significantly improve user experience and data tracking. Below are key configurations you can implement when using the FastPix SDK with your Shaka Player instance.
1. Disable cookies:
FastPix uses cookies by default to track playback across page views. If your application is not supposed to collect cookies or if you prefer not to use cookies, you can disable this feature by setting disableCookies: true
.
// videoElement is the HTML5 <video> element representing your video player.
const videoElement = document.getElementById("#my-player");
fastpixMetrix.tracker(videoElement, {
debug: false,
hlsjs: hls,
Hls: Hls,
disableCookies: true,
data: {
workspace_id: "WORKSPACE_KEY", // Replace with your workspace key
// ... and other metadata
},
});
2. Bypass "do not track" settings
FastPix does not respect the Do Not Track setting by default. If you want to honor users' privacy preferences, enable this feature by passing respectDoNotTrack: true
.
// videoElement is the HTML5 <video> element representing your video player.
const videoElement = document.getElementById("#my-player");
fastpixMetrix.tracker(videoElement, {
debug: false,
hlsjs: hls,
Hls: Hls,
respectDoNotTrack: true,
data: {
workspace_id: "WORKSPACE_KEY", // Replace with your workspace key
// ... and other metadata
},
});
3. Configure error tracking preferences
Errors tracked by FastPix are considered fatal. If you encounter non-fatal errors that should not be captured, you can emit a custom error event to provide more context.
// videoElement is the HTML5 <video> element representing your video player.
const videoElement = document.getElementById("#my-player");
videoElement.fp.dispatch("error", {
player_error_code: 1000, // Custom error code
player_error_message: "Description of error", // Generalized error message
player_error_context: "Additional context for the error", // Instance-specific information
});
TIP
Use custom error codes and messages that are meaningful for your debugging process to streamline troubleshooting.
4. Stop automatic error tracking
For complete control over which errors are counted as fatal, consider disabling automatic error tracking by setting automaticErrorTracking: false
.
// videoElement is the HTML5 <video> element representing your video player.
const videoElement = document.getElementById("#my-player");
fastpixMetrix.tracker(videoElement, {
debug: false,
hlsjs: hls,
Hls: Hls,
automaticErrorTracking: false,
data: {
workspace_id: "WORKSPACE_KEY", // Replace with your workspace key
// ... and other metadata
},
});
Updated 15 days ago