UNPKG

@aws-amplify/analytics

Version:

Analytics category of aws-amplify

184 lines (182 loc) • 6.54 kB
'use strict'; // Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. // SPDX-License-Identifier: Apache-2.0 Object.defineProperty(exports, "__esModule", { value: true }); exports.autoTrackMedia = void 0; const utils_1 = require("@aws-amplify/core/internals/utils"); const core_1 = require("@aws-amplify/core"); 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 core_1.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 (!(0, utils_1.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.'); } }; exports.autoTrackMedia = autoTrackMedia; //# sourceMappingURL=autoTrackMedia.js.map