diff --git a/embedded-player/embedded-player.js b/embedded-player/embedded-player.js index a7298190..5073ed3c 100644 --- a/embedded-player/embedded-player.js +++ b/embedded-player/embedded-player.js @@ -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)); } @@ -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; @@ -206,5 +323,5 @@ webPlayer.addPlayerListener((status) => { protocol: webPlayer.currentPlayType, }); } - console.debug("player event: ", status); + //console.debug("player event: ", status); }); \ No newline at end of file diff --git a/embedded-player/package.json b/embedded-player/package.json index 460cf011..d4bcb5ab 100644 --- a/embedded-player/package.json +++ b/embedded-player/package.json @@ -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": { diff --git a/src/main/webapp/play.html b/src/main/webapp/play.html index e8cc9471..23f7c204 100644 --- a/src/main/webapp/play.html +++ b/src/main/webapp/play.html @@ -34,17 +34,27 @@