Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
161 changes: 139 additions & 22 deletions embedded-player/embedded-player.js
Original file line number Diff line number Diff line change
Expand Up @@ -51,30 +51,75 @@ function getHttpBaseUrl() {
}

function sendEventToBackend(data) {
if (!sendAnalytic) {
return;
// Send to backend if analytics is enabled
if (sendAnalytic) {
let url = getHttpBaseUrl() + "analytic/events/";
if (data.event.startsWith("play")) {
url += "play"
}
else if (data.event.startsWith("watch")) {
url += "watch-time"
}
else {
console.warn("Not known event type");
}
fetch(url, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify(data),
})
.then(response => response.json())
.then(data => console.log('Event sent successfully:', data))
.catch((error) => console.error('Error sending event:', error));
}

let url = getHttpBaseUrl() + "analytic/events/";
if (data.event.startsWith("play")) {
url += "play"
}
else if (data.event.startsWith("watch")) {
url += "watch-time"
}
else {
console.warn("Not known event type");
// Send to Google Analytics if enabled
if (gaEnabled && window.gtag) {
// Map backend event names to Google Analytics event names
let gaEventName = null;
let gaEventParams = {
stream_id: data.streamId || '',
protocol: data.protocol || '',
subscriber_id: data.subscriberId || ''
};

// Map events to GA4 event names
switch(data.event) {
case "playStartedFirstTime":
gaEventName = "video_play_started_first_time";
break;
case "playStarted":
gaEventName = "video_play_started";
break;
case "playPaused":
gaEventName = "video_play_paused";
break;
case "playEnded":
gaEventName = "video_play_ended";
break;
case "watchTime":
gaEventName = "video_watch_time";
// Add watch time specific parameters
if (data.watchTimeMs) {
gaEventParams.watch_time_ms = data.watchTimeMs;
gaEventParams.watch_time_seconds = Math.round(data.watchTimeMs / 1000);
}
if (data.startTimeMs) {
gaEventParams.start_time_ms = data.startTimeMs;
}
break;
default:
// Use event name as-is for unknown events
gaEventName = data.event.toLowerCase().replace(/([A-Z])/g, '_$1');
break;
}

if (gaEventName) {
sendEventToGoogleAnalytics(gaEventName, gaEventParams);
}
}
fetch(url, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify(data),
})
.then(response => response.json())
.then(data => console.log('Event sent successfully:', data))
.catch((error) => console.error('Error sending event:', error));
}


Expand All @@ -99,6 +144,78 @@ if (getUrlParameter("sendAnalytic", window.location.search) == "true") {
sendAnalytic = true;
}

// Google Analytics configuration
let gaEnabled = false;
let gaMeasurementId = null;

// Check if Google Analytics is enabled via URL parameter
const gaEnabledParam = getUrlParameter("gaEnabled", window.location.search);
if (gaEnabledParam == "true" || gaEnabledParam === true) {
gaEnabled = true;
// Get GA Measurement ID from URL parameter (e.g., G-XXXXXXXXXX)
gaMeasurementId = getUrlParameter("gaId", window.location.search);

// If no gaId provided, try gaMeasurementId as alternative parameter name
if (!gaMeasurementId) {
gaMeasurementId = getUrlParameter("gaMeasurementId", window.location.search);
}

if (gaMeasurementId) {
loadGoogleAnalytics(gaMeasurementId);
} else {
console.warn("[Google Analytics] gaEnabled is true but no gaId or gaMeasurementId provided in URL");
}
}

/**
* Load Google Analytics script dynamically
* @param {string} measurementId - Google Analytics Measurement ID (e.g., G-XXXXXXXXXX)
*/
function loadGoogleAnalytics(measurementId) {
if (window.gtag) {
console.debug("[Google Analytics] Already loaded");
return;
}

console.debug(`[Google Analytics] Loading Google Analytics with Measurement ID: ${measurementId}`);

// Create and configure gtag script
const script1 = document.createElement('script');
script1.async = true;
script1.src = `https://www.googletagmanager.com/gtag/js?id=${measurementId}`;
document.head.appendChild(script1);

// Initialize gtag dataLayer and function
window.dataLayer = window.dataLayer || [];
function gtag(){dataLayer.push(arguments);}
window.gtag = gtag;

gtag('js', new Date());
gtag('config', measurementId, {
// Optional: Add any custom configuration here
});

console.debug("[Google Analytics] Google Analytics loaded successfully");
}

/**
* Send event to Google Analytics
* @param {string} eventName - GA4 event name
* @param {object} eventParams - Event parameters
*/
function sendEventToGoogleAnalytics(eventName, eventParams) {
if (!gaEnabled || !window.gtag) {
return;
}

try {
window.gtag('event', eventName, eventParams);
console.debug(`[Google Analytics] Event sent: ${eventName}`, eventParams);
} catch (error) {
console.error("[Google Analytics] Error sending event:", error);
}
}

httpBaseUrl = getHttpBaseUrl();

window.webPlayer = webPlayer;
Expand Down Expand Up @@ -206,5 +323,5 @@ webPlayer.addPlayerListener((status) => {
protocol: webPlayer.currentPlayType,
});
}
console.debug("player event: ", status);
//console.debug("player event: ", status);
});
2 changes: 1 addition & 1 deletion embedded-player/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
"author": "",
"license": "ISC",
"dependencies": {
"@antmedia/web_player": "3.0.0-SNAPSHOT-2025-Aug-15-08-27"
"@antmedia/web_player": "3.0.0-SNAPSHOT-2026-Mar-17-01-00"
},

"devDependencies": {
Expand Down
14 changes: 12 additions & 2 deletions src/main/webapp/play.html
Original file line number Diff line number Diff line change
Expand Up @@ -34,17 +34,27 @@
<script type="module" src="./js/embedded-player.js">
/**
* This page accepts following arguments through http query parameters
*
* 1. "id": the stream id to play.It is mandatory
*
* 2. "token": the token to play stream. It's mandatory if token security is enabled on server side.
*
* 3. "autoplay": To start playing automatically if streams is available. Optional. Default value is true
*
* 4. "mute": To start playing with mute if streams is available. Optional. Default value is true
*
* 5. "playOrder": the order which technologies is used in playing. Optional. Default value is "webrtc,hls".
* possible values are "hls,webrtc","webrtc","hls","vod","dash"
* possible values are "webrtc","hls","vod","dash", "ll-hls". You can give the playOrder comma-separated
*
* 6. "playType": the order which play type is used in playing. Optional. Default value is "mp4,webm".
* possible values are "webm,mp4"","mp4","webm","mov"
*
* 7. "targetLatency": To define target latency for the DASH player. Optional. Default value is 3.
*
* 8. "is360": To play the stream in 360. Default value is false.

*
* 9. "player": "videojs" or "hlsjs". Default value is videojs. It defines the player library to use for hls and vod playback.
*
* It support vod playback directly from name of the file. Just give the stream id having a prefix with streams folder
* streams/test.mp4
*/
Expand Down
Loading