UNPKG

@aws-amplify/analytics

Version:

Analytics category of aws-amplify

182 lines (179 loc) • 6.4 kB
import { isBrowser } from '@aws-amplify/core/internals/utils'; import { ConsoleLogger } from '@aws-amplify/core'; // Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. // SPDX-License-Identifier: Apache-2.0 var HTML5_MEDIA_EVENT; (function (HTML5_MEDIA_EVENT) { HTML5_MEDIA_EVENT["PLAY"] = "play"; HTML5_MEDIA_EVENT["PAUSE"] = "pause"; HTML5_MEDIA_EVENT["ENDED"] = "Ended"; })(HTML5_MEDIA_EVENT || (HTML5_MEDIA_EVENT = {})); var MEDIA_TYPE; (function (MEDIA_TYPE) { MEDIA_TYPE["IFRAME"] = "IFRAME"; MEDIA_TYPE["VIDEO"] = "VIDEO"; MEDIA_TYPE["AUDIO"] = "AUDIO"; })(MEDIA_TYPE || (MEDIA_TYPE = {})); var EVENT_TYPE; (function (EVENT_TYPE) { EVENT_TYPE["PLAY"] = "Play"; EVENT_TYPE["ENDED"] = "Ended"; EVENT_TYPE["PAUSE"] = "Pause"; EVENT_TYPE["TIME_WATCHED"] = "TimeWatched"; })(EVENT_TYPE || (EVENT_TYPE = {})); const logger = new ConsoleLogger('MediaAutoTrack'); const startIframeAutoTracking = (element, recordEvent) => { let isPlaying = false; let player; const mediaProperties = () => { const duration = Number(parseFloat(player.getDuration()).toFixed(4)); const currentTime = Number(parseFloat(player.getCurrentTime()).toFixed(4)); return { duration, eventValue: Number((currentTime / duration).toFixed(4)), }; }; const scriptElement = document.createElement('script'); scriptElement.type = 'text/javascript'; scriptElement.src = 'https://www.youtube.com/iframe_api'; document.body.append(scriptElement); const timer = setInterval(() => { if (isPlaying && player) { recordEvent(EVENT_TYPE.TIME_WATCHED, mediaProperties()); } }, 3000); element.addEventListener('unload', () => { clearInterval(timer); }); window.onYouTubeIframeAPIReady = () => { delete window.onYouTubeIframeAPIReady; player = new window.YT.Player(element.id, { events: { onStateChange: (event) => { const iframeEventMapping = { 0: EVENT_TYPE.ENDED, 1: EVENT_TYPE.PLAY, 2: EVENT_TYPE.PAUSE, }; const eventType = iframeEventMapping[event.data]; switch (eventType) { case EVENT_TYPE.ENDED: case EVENT_TYPE.PAUSE: isPlaying = false; break; case EVENT_TYPE.PLAY: isPlaying = true; break; } if (eventType) { recordEvent(eventType, mediaProperties()); } }, }, }); }; }; const startHTMLMediaAutoTracking = (element, recordEvent) => { let isPlaying = false; const mediaProperties = () => ({ duration: element.duration, eventValue: Number((element.currentTime / element.duration).toFixed(4)), }); const timer = setInterval(() => { if (isPlaying) { recordEvent(EVENT_TYPE.TIME_WATCHED, mediaProperties()); } }, 3000); element.addEventListener('unload', () => { clearInterval(timer); }); element.addEventListener(HTML5_MEDIA_EVENT.PLAY, () => { isPlaying = true; recordEvent(EVENT_TYPE.PLAY, mediaProperties()); }); element.addEventListener(HTML5_MEDIA_EVENT.PAUSE, () => { isPlaying = false; recordEvent(EVENT_TYPE.PAUSE, mediaProperties()); }); element.addEventListener(HTML5_MEDIA_EVENT.ENDED, () => { isPlaying = false; recordEvent(EVENT_TYPE.ENDED, mediaProperties()); }); }; const checkElementLoaded = (interval, maxTries) => { let retryCount = 0; const wait = () => new Promise(resolve => setTimeout(resolve, interval)); const check = async (elementId) => { if (retryCount >= maxTries) { return false; } const domElement = document.getElementById(elementId); if (domElement && domElement.clientHeight) { return true; } else { retryCount += 1; await wait(); return check(elementId); } }; return check; }; const recordEvent = (config, eventBuffer) => (eventType, properties) => { // override eventType and merge properties eventBuffer.append({ ...config, event: { ...config.event, eventType, properties: { ...config.event.properties, ...properties, }, }, timestamp: Date.now(), }); }; const autoTrackMedia = async (config, eventBuffer) => { const { eventType, properties } = config.event; const { domElementId, ...otherProperties } = properties; if (!isBrowser()) { logger.debug(`${eventType} only for browser`); return; } if (typeof domElementId === 'string' && !domElementId) { logger.debug("Missing domElementId field in 'properties' for MediaAutoTrack event type."); return; } const elementId = domElementId; const isElementLoaded = await checkElementLoaded(500, 5)(elementId); if (isElementLoaded) { const autoTrackConfigWithoutDomElementId = { ...config, event: { ...config.event, properties: otherProperties, }, }; const element = document.getElementById(elementId); switch (element?.tagName) { case MEDIA_TYPE.IFRAME: startIframeAutoTracking(element, recordEvent(autoTrackConfigWithoutDomElementId, eventBuffer)); break; case MEDIA_TYPE.VIDEO: case MEDIA_TYPE.AUDIO: if (element instanceof HTMLMediaElement) { startHTMLMediaAutoTracking(element, recordEvent(autoTrackConfigWithoutDomElementId, eventBuffer)); } break; default: logger.debug(`Unsupported DOM element tag: ${element?.tagName}`); break; } } else { logger.debug('Cannot find the media element.'); } }; export { autoTrackMedia }; //# sourceMappingURL=autoTrackMedia.mjs.map