Skip to content

Commit 868ff8d

Browse files
Implement dash.js data collection and update readme.md
1 parent 13b101b commit 868ff8d

10 files changed

Lines changed: 128 additions & 89 deletions

File tree

CHANGELOG.md

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,16 +2,23 @@
22

33
All notable changes to this project will be documented in this file.
44

5+
## [1.0.2]
6+
- Added support for DASH.js video player monitoring
7+
- Enhanced analytics collection for DASH streams
8+
- Improved error tracking for DASH.js players
9+
510
## [1.0.1]
611
- Resolved proper cleanup of HLS streams upon the viewComplete event.
7-
- Enhanced stream handling logic: when a new player instance is initialized while another is in progress, the SDK now correctly destroys the previous players data monitoring and seamlessly switches to capture analytics for the incoming player.
12+
- Enhanced stream handling logic: when a new player instance is initialized while another is in progress, the SDK now correctly destroys the previous player's data monitoring and seamlessly switches to capture analytics for the incoming player.
813

914
## [1.0.0]
1015

1116
### Added
12-
- **Integration with HLS**:
13-
- Enabled video performance tracking using FastPix Data SDK, supporting HLS streams with user engagement metrics, playback quality monitoring, and real-time streaming diagnostics.
14-
- Provides robust error management and reporting capabilities for HLS video performance tracking.
15-
- Allows customizable behavior, including options to disable cookies, respect `Do Not Track` settings, and configure advanced error tracking and automatic error handling.
16-
- Includes support for custom metadata, enabling users to pass optional fields such as `video_id`, `video_title`, `video_duration`, and more.
17-
- Introduced event tracking for `videoChange` to handle metadata updates during playback transitions.
17+
- Initial release of FastPix Video Data Core SDK
18+
- Support for HLS.js video player monitoring
19+
- Real-time analytics collection and reporting
20+
- Custom event tracking capabilities
21+
- Error tracking and diagnostics
22+
- Performance metrics collection
23+
- Stream-level analytics
24+
- User interaction tracking

README.md

Lines changed: 67 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,30 @@
11
# Introduction:
22

3-
This SDK simplifies integration steps with [HLS.js](https://github.com/video-dev/hls.js), enabling the collection of player analytics. It enables automatic tracking of video performance metrics, making the data readily available on the [FastPix dashboard](https://dashboard.fastpix.io) for monitoring and analysis. While the SDK is developed in TypeScript, the published npm package currently includes only the JavaScript output. TypeScript support, including type definitions, will be released in a future version.
3+
FastPix Video Data Core SDK monitors and analyzes **HLS.js** and **DASH.js** video players. Get instant insights into video performance with our monitoring features:
44

5-
# Key Features:
5+
- Real-time stream analytics (manifest loading, segments, quality switches)
6+
- Player performance data (startup time, buffering, quality)
7+
- Network metrics (bandwidth, request timing)
8+
- Error logs and diagnostics
9+
- User interaction events
610

7-
- **Track Viewer Engagement:** Gain insights into how users interact with your videos.
8-
- **Monitor Playback Quality:** Ensure video streaming by monitoring real-time metrics, including bitrate, buffering, startup performance, render quality, and playback failure errors.
9-
- **Error Management:** Identify and resolve playback failures quickly with detailed error reports.
10-
- **Customizable Tracking:** Flexible configuration to match your specific monitoring needs.
11-
- **Centralized Dashboard:** Visualize and compare metrics on the [FastPix dashboard](https://dashboard.fastpix.io) to make data-driven decisions.
11+
The SDK instantly collects and sends all metrics to the [FastPix dashboard](https://dashboard.fastpix.io) for easy viewing. Currently available as a JavaScript bundle, with TypeScript support coming soon.
1212

1313
# Prerequisites:
1414

15-
## Getting started with FastPix:
15+
## Getting Started
1616

17-
To track and analyze video performance, initialize the FastPix Data SDK with your Workspace key (learn more about [Workspaces here](https://docs.fastpix.io/docs/workspaces)):
17+
To begin tracking your video analytics, you'll need your FastPix workspace key. Here's how to get it:
1818

19-
1. **[Access the FastPix Dashboard](https://dashboard.fastpix.io)**: Log in and navigate to the Workspaces section.
20-
2. **Locate Your Workspace Key**: Copy the Workspace Key for client-side monitoring.
19+
1. Sign up or login to [FastPix Dashboard](https://dashboard.fastpix.io).
20+
2. Navigate to the workspace page.
21+
3. Copy your preferred workspace key.
22+
23+
That's it! You're ready to integrate the SDK into your video player.
2124

2225
# Step 1: Installation and Setup:
2326

24-
To get started with the SDK, install using npm or your favourite node package manager 😉:
27+
Install the SDK using npm or another package manager of your choice:
2528

2629
```bash
2730
npm i @fastpix/video-data-core
@@ -35,9 +38,12 @@ import fastpixMetrix from "@fastpix/video-data-core";
3538

3639
# Step 3: Basic Integration
3740

38-
The `workspace_id` is a mandatory field that must be provided. In addition, install the hls.js package, import the Hls instance, and attach it to the HTML5 video element. Pass both the Hls instance and the Hls constructor function, along with custom metadata, to the `fastpixMetrix.tracker` function.
41+
Before using the FastPix Video Data Core SDK, ensure you have installed either HLS.js or DASH.js player libraries:
42+
43+
The `workspace_id` is a mandatory field that must be provided. Below are the
44+
integration steps for both HLS.js and DASH.js players.
3945

40-
Once the player has loaded the URL and playback has started, the SDK will then begin tracking the analytics.
46+
## HLS.js Integration
4147

4248
```javascript
4349
// Import HLS.js library for video streaming
@@ -50,10 +56,10 @@ const initializationTime = fastpixMetrix.utilityMethods.now();
5056

5157
// Create a new HLS instance
5258
const hlsPlayerInstance = new Hls();
53-
hlsPlayerInstance.loadSource(""); // Load the video stream
59+
hlsPlayerInstance.loadSource("YOUR_HLS_URL"); // Load the video stream
5460
hlsPlayerInstance.attachMedia(videoPlayerElement);
5561

56-
// Custom metadata for tracking
62+
// Custom dimensions for tracking
5763
const trackingData = {
5864
workspace_id: "WORKSPACE_KEY", // Unique key to identify your workspace (replace with your actual workspace key)
5965
player_name: "Main Video Player", // A custom name or identifier for this video player instance
@@ -62,41 +68,67 @@ const trackingData = {
6268
video_id: "VIDEO_ID", // Unique identifier for the video
6369
viewer_id: "VIEWER_ID", // Unique identifier for the viewer
6470

65-
// Add any additional metadata
71+
// Add any additional dimensions
6672
};
6773

6874
// Pass both `hlsPlayerInstance` and `Hls` to the FastPix tracker for correct tracking
6975
fastpixMetrix.tracker(videoPlayerElement, {
7076
debug: false, // Set to true to enable debug logs in the console
7177
hlsjs: hlsPlayerInstance, // Pass the `hlsPlayerInstance` created above
72-
Hls, // Pass the `Hls` constructor (imported)
78+
Hls: Hls, // Pass the `Hls` constructor (imported)
7379
data: trackingData, // Attach custom metadata for analytics and tracking
7480
});
81+
```
7582

76-
// To stop monitoring call when destroying the HLS player
77-
// videoPlayerElement.fp.destroy();
83+
## DASH.js Integration
84+
85+
```javascript
86+
// Import DASH.js library for video streaming
87+
import dashjs from "dashjs";
88+
import fastpixMetrix from "@fastpix/video-data-core";
89+
90+
// Reference to the video element
91+
const videoPlayerElement = document.getElementById("video-player");
92+
const initializationTime = fastpixMetrix.utilityMethods.now();
93+
94+
// Create a new DASH.js instance
95+
const dashPlayerInstance = dashjs.MediaPlayer().create();
96+
dashPlayerInstance.initialize(videoPlayerElement, "YOUR_DASH_URL", false);
97+
98+
// Custom metadata for tracking
99+
const trackingData = {
100+
workspace_id: "WORKSPACE_KEY", // Unique key to identify your workspace (replace with your actual workspace key)
101+
player_name: "Main Video Player", // A custom name or identifier for this video player instance
102+
player_init_time: initializationTime, // Timestamp of when the player was initialized (useful for tracking performance metrics)
103+
video_title: "VIDEO_TITLE", // Title of the video being played for analytics
104+
video_id: "VIDEO_ID", // Unique identifier for the video
105+
viewer_id: "VIEWER_ID", // Unique identifier for the viewer
106+
107+
// Add any additional metadata
108+
};
109+
110+
// Pass both `dashPlayerInstance` and `dashjs` to the FastPix tracker for correct tracking
111+
fastpixMetrix.tracker(videoPlayerElement, {
112+
debug: false, // Set to true to enable debug logs in the console
113+
dashPlayer: dashPlayerInstance, // Pass the `dashPlayerInstance` created above
114+
dashjs: dashjs, // Pass the `dashjs` constructor (imported)
115+
data: trackingData, // Attach custom metadata for analytics and tracking
116+
});
78117
```
79118

80-
After successfully completing Step 3, you can track viewer metrics in the FastPix dashboard once playback ends. Steps 4, 5, and 6 are optional and can be utilized as needed to enhance your integration.
119+
Once the player has loaded the URL and playback has started, the SDK will begin tracking the analytics. After playback ends, you can view the complete analytics report on your [FastPix dashboard](https://dashboard.fastpix.io).
81120

82121
# Step 4: Enhance Tracking with User Passable Metadata
83122

84-
Check out the [user-passable metadata](https://docs.fastpix.io/docs/user-passable-metadata) documentation to see the metadata supported by FastPix. You can use custom metadata fields like `custom_1` to `custom_10` for your business logic, giving you the flexibility to pass any required values. Named attributes, such as `video_title` and `video_id`, can be passed directly as they are.
123+
Check out the [user-passable metadata](https://docs.fastpix.io/docs/user-passable-metadata-1) documentation to see the metadata supported by FastPix. You can use custom metadata fields like `custom_1` to `custom_10` for your business logic, giving you the flexibility to pass any required values. Named attributes, such as `video_title` and `video_id`, can be passed directly as they are.
85124

86125
```javascript
87-
// Import HLS.js library for video streaming
88-
import Hls from "hls.js";
89126
import fastpixMetrix from "@fastpix/video-data-core";
90127

91128
// Reference to the video element
92129
const videoPlayerElement = document.getElementById("video-player");
93130
const initializationTime = fastpixMetrix.utilityMethods.now();
94131

95-
// Create a new HLS instance
96-
const hlsPlayerInstance = new Hls();
97-
hlsPlayerInstance.loadSource(""); // Load the video stream
98-
hlsPlayerInstance.attachMedia(videoPlayerElement);
99-
100132
// Custom metadata for tracking
101133
const trackingData = {
102134
workspace_id: "WORKSPACE_KEY", // Unique key to identify your workspace (replace with your actual workspace key)
@@ -118,18 +150,16 @@ const trackingData = {
118150
// Pass both `hlsPlayerInstance` and `Hls` to the FastPix tracker for correct tracking
119151
fastpixMetrix.tracker(videoPlayerElement, {
120152
debug: false, // Set to true to enable debug logs in the console
121-
hlsjs: hlsPlayerInstance, // Pass the `hlsPlayerInstance` created above
122-
Hls, // Pass the `Hls` constructor (imported)
123153
data: trackingData, // Attach custom metadata for analytics and tracking
124154
});
125155

126-
// To stop monitoring call when destroying the HLS player
156+
// To stop monitoring
127157
// videoPlayerElement.fp.destroy();
128158
```
129159

130160
### Note:
131161

132-
Keep metadata consistent across different video loads to make comparison easier in your analytics dashboard.
162+
Keep metadata consistent across different video loads to make comparison easier in the dashboard.
133163

134164
# Step 5: Advanced Customization with FastPix Data SDK
135165

@@ -147,8 +177,6 @@ const videoPlayerElement = document.getElementById("video-player");
147177
// Configuration for FastPix tracker
148178
const trackingData = {
149179
debug: true, // Set to true to enable debug logs in the console
150-
hlsjs: hls, // Pass the HLS.js instance
151-
Hls: Hls, // Pass the Hls constructor (imported)
152180
disableCookies: true, // Set to true to disable cookies for tracking sessions and unique viewers
153181
respectDoNotTrack: true, // Set to true to honor users' 'Do Not Track' preferences
154182
automaticErrorTracking: false, // Set to false to disable automatic tracking of fatal errors
@@ -182,7 +210,7 @@ videoPlayerElement.fp.dispatch("error", {
182210

183211
### Changing video streams in player
184212

185-
When your application plays multiple videos back-to-back in the same player, its 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.
213+
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.
186214

187215
```javascript
188216
// videoPlayerElement is the HTML5 <video> element representing your video player.
@@ -199,4 +227,6 @@ videoPlayerElement.fp.dispatch("videoChange", {
199227

200228
# Detailed Usage:
201229

202-
For more detailed steps and advanced usage, please refer to the official [FastPix Documentation](https://docs.fastpix.io/docs/monitor-hlsjs).
230+
For more detailed steps and advanced usage, please refer to our official documentation:
231+
- [HLS.js Monitoring Documentation](https://docs.fastpix.io/docs/monitor-hlsjs)
232+
- [DASH.js Monitoring Documentation](https://docs.fastpix.io/docs/monitor-dashjs)

src/IdGenerationMethod/index.ts

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,15 @@
11
import { v4 as uuidv4 } from "uuid";
22

3+
const idCharacter = "000000";
4+
35
// Returns 6 characters id
46
const generateIdToken: () => string = function () {
57
const idPart: string = Math.random()
68
.toString(36)
79
.replace("0.", "")
810
.slice(0, 6);
911

10-
return "000000".slice(idPart.length) + idPart;
12+
return idCharacter.slice(idPart.length) + idPart;
1113
};
1214

1315
// Returns unique UUID
@@ -16,8 +18,9 @@ const buildUUID: () => string = function () {
1618
};
1719

1820
const generateRandomIdentifier: () => string = function () {
21+
1922
return (
20-
"000000" + ((Math.random() * Math.pow(36, 6)) << 0).toString(36)
23+
idCharacter + ((Math.random() * Math.pow(36, 6)) << 0).toString(36)
2124
).slice(-6);
2225
};
2326

src/MonitorMetrics/PlayerEventHandler.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,6 @@ export class PlaybackEventHandler {
9494

9595
sendData(event: string, obj: EventMetaData): void {
9696
if (!event || !obj?.view_id) return;
97-
9897
if (this.shouldRespectDoNotTrack(event)) return;
9998
if (!this.validateEventData(obj)) return;
10099
if (
@@ -109,6 +108,7 @@ export class PlaybackEventHandler {
109108
return;
110109
}
111110
const data = this.prepareEventData(event, obj);
111+
112112
this.eventQueue.scheduleEvent(data);
113113

114114
if (event === "viewCompleted") {

src/MonitorMetrics/RequestMetricsMonitor.ts

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -51,12 +51,11 @@ export class RequestMetricsMonitor {
5151
const responseStart: number = reqData?.request_response_start ?? 0;
5252
const responseEnd: number = reqData?.request_response_end ?? 0;
5353
const loadedBytes: number = reqData?.request_bytes_loaded ?? 0;
54-
55-
this.requestCount++;
56-
5754
const latency = responseStart - requestStart;
5855
const duration = responseEnd - (responseStart ?? requestStart);
5956

57+
this.requestCount++;
58+
6059
if (duration > 0 && loadedBytes > 0) {
6160
this.processedChunks++;
6261
this.totalBytes += loadedBytes;

src/MonitorMetrics/VideoBufferMonitor.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,7 @@ class BufferProcessor {
9393
this.params.data.view_watch_time &&
9494
this.params.data.view_watch_time >= 0
9595
) {
96+
9697
if (
9798
this.params.data.view_rebuffer_count &&
9899
this.params.data.view_rebuffer_count > 0

src/MonitorMetrics/index.ts

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,6 @@ function nucleusState(
5353
const defaultConfig = {
5454
debug: actionableData?.debug ?? false,
5555
beaconDomain: actionableData.configDomain ?? "metrix.ws",
56-
sampleRate: 1,
5756
disableCookies: actionableData.disableCookies ?? false,
5857
respectDoNotTrack: actionableData.respectDoNotTrack ?? false,
5958
allowRebufferTracking: false,
@@ -85,7 +84,6 @@ function nucleusState(
8584
);
8685
fileInstance.data = {
8786
player_instance_id: buildUUID(),
88-
fastpix_sample_rate: actionableData.sampleRate,
8987
beacon_domain:
9088
actionableData.beaconCollectionDomain ?? actionableData.beaconDomain,
9189
};

src/StreamMonitoring/DashMonitoring.ts

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -247,7 +247,7 @@ export const setupDashMonitoring = (
247247
const { mediaType, newRepresentation, newQuality } = event;
248248

249249
if (mediaType === "video" && typeof newRepresentation === "object") {
250-
(videoContainer as any)?.fp?.dispatch("variantChanged", {
250+
videoContainer?.fp?.dispatch("variantChanged", {
251251
video_source_bitrate: newRepresentation.bandwidth,
252252
video_source_height: newRepresentation.height,
253253
video_source_width: newRepresentation.width,
@@ -276,7 +276,7 @@ export const setupDashMonitoring = (
276276

277277
const bitrateData = parseMediaData();
278278
if (bitrateData) {
279-
(videoContainer as any)?.fp?.dispatch("variantChanged", bitrateData);
279+
videoContainer?.fp?.dispatch("variantChanged", bitrateData);
280280
}
281281
}
282282
};
@@ -288,7 +288,7 @@ export const setupDashMonitoring = (
288288
const requesturl = mediaRequest?.url;
289289
const requestHostName = requesturl ? getHostName(requesturl) : "";
290290

291-
(videoContainer as any)?.fp?.dispatch("requestCanceled", {
291+
videoContainer?.fp?.dispatch("requestCanceled", {
292292
request_event_type: eventType,
293293
request_url: requesturl,
294294
request_type: mediaType,
@@ -307,7 +307,7 @@ export const setupDashMonitoring = (
307307
const key = data?.response ?? {};
308308

309309
if (error.code === 27) {
310-
(videoContainer as any)?.fp.dispatch("requestFailed", {
310+
videoContainer?.fp.dispatch("requestFailed", {
311311
request_error: `${options.type}_${options.action}`,
312312
request_url: options.url,
313313
request_hostname: options.url ? getHostName(options.url) : "",
@@ -328,23 +328,23 @@ export const setupDashMonitoring = (
328328
}
329329

330330
if (errorTracking?.automaticErrorTracking) {
331-
(videoContainer as any)?.fp.dispatch("error", {
331+
videoContainer?.fp.dispatch("error", {
332332
player_error_code: error.code,
333333
player_error_message: error.message,
334334
player_error_context: errorContext,
335335
});
336336
}
337337
};
338338

339-
if ((videoContainer as any)?.fp) {
340-
(videoContainer as any).fp.destroyDashMonitoring = () => {
339+
if (videoContainer?.fp) {
340+
videoContainer.fp.destroyDashMonitoring = () => {
341341
dashTag.off("error", handleErrorEvent);
342342
dashTag.off("fragmentLoadingAbandoned", handleCanceledRequest);
343343
dashTag.off("qualityChangeRendered", handleQualityChange);
344344
dashTag.off("manifestLoaded", handleManifestLoaded);
345345
dashTag.off("initFragmentLoaded", handleInitFragmentV4);
346346
dashTag.off("mediaFragmentLoaded", handleMediaFragmentV4);
347-
delete (videoContainer as any).fp?.destroyDashMonitoring;
347+
delete videoContainer.fp?.destroyDashMonitoring;
348348
};
349349
}
350350

0 commit comments

Comments
 (0)