UNPKG

@speechkit/speechkit-audio-player

Version:

A web player component that can play audio from https://speechkit.io

246 lines (212 loc) 6.8 kB
import MobileDetect from 'mobile-detect' import { defaults } from 'lodash' import uuidv4 from 'uuid/v4' import EventTracker from '../SKSDK/EventTracker' import { getCookieValue, setCookieValue } from '../utils/Cookie' import MEDIA_TYPES from '../constants/mediaTypes' class Analytics { constructor({ options, podcast, media, mediaType, mediaAds, ads, player }) { this.options = options this.media = media this.podcast = podcast this.player = player this.mediaType = mediaType this.mediaAds = mediaAds this.ads = ads this.userId = this.getUserId() this.deviceType = this.getDeviceType() // So we can track one play and group it for progress stuff this.listenSessionId = uuidv4() this.percentPlayed = 0 if (!this.options.isDemo) { this.eventTracker = new EventTracker({ skBackend: options.skBackend, projectId: options.projectId, publisherId: options.publisherId, projectCampaignId: options.projectCampaignId, mediaType: this.mediaType, podcastId: this.podcast.id }) } } getUserId() { let userId = getCookieValue('userId') if (!userId) { userId = uuidv4() setCookieValue('userId', userId) } return userId } getDeviceType() { const md = new MobileDetect(window.navigator.userAgent) if (md.phone()) { return 'phone' } else if (md.tablet()) { return 'tablet' } else { return 'desktop' } } getDefaultTrackOptions() { return { listen_session_id: this.listenSessionId, media_id: this.mediaType === MEDIA_TYPES.PODCAST ? this.media.id : this.mediaAds.id, referrer: document.referrer, location: document.location.href, user_id: this.userId, device_type: this.deviceType } } setMediaType(mediaType) { if (!this.options.isDemo) { this.mediaType = mediaType this.eventTracker.setMediaType(this.mediaType) } } startProgressTimer() { // Track progress every 10 sec this.intervalTimer = setInterval(this.trackProgress.bind(this), 10 * 1000) } // Ad Timer Code - so ad can be displayed for right time startPercentTimer() { const nSegment = this.player.getDuration() / 100 * 1000; // may need remainingTime to double check progress. // this.remainingTime = this.player.getDuration() - this.player.getCurrentTime(); if (this.percentPlayed <= 100){ this.percentPlayed += 1; this.onProgress(this.percentPlayed); this.progressTimer = setTimeout(this.startPercentTimer.bind(this), nSegment) } } // track url using image beacon addImageBeacon(sPath){ return new Promise((resolve, reject) => { const img = new Image() img.onload = () => resolve('ok') img.onerror = () => resolve('error') img.src = sPath }) } // send tracking to google tag if present in page sendGaEvent(eventName){ const sPreText = this.mediaType === MEDIA_TYPES.PREROLL ? 'Ad ' : ''; if(typeof gtag === 'function') { const gaEventName = eventName === 'Load' ? eventName : (sPreText + eventName); // console.log('event: ',gaEventName) gtag('event', gaEventName, { event_category: 'SpeechKit Player', event_label: this.podcast.url }); } } // take array for urls and fire each one trackUrls(sEventName){ // exit here if we do not have any ads present if(!this.mediaAds || !this.mediaAds.trackingUrls) return; // now get the array of tracking URLs and fire them off const oTracking = this.mediaAds.trackingUrls; const aUrls = oTracking[sEventName]; if(aUrls) { for(let i = aUrls.length -1; i >= 0; i--){ const sTrackingUrl = aUrls[i].trim() aUrls.splice(i, 1); this.addImageBeacon(sTrackingUrl) } } } // using the percent timer, track each of the events at the // correct time whilst content plays, including quartiles onProgress(nPercent){ switch (nPercent) { case 1: this.trackUrls('impression'); this.trackUrls('start'); break; case 25: this.trackUrls('firstQuartile'); this.sendGaEvent('25% Listened'); break; case 50: this.trackUrls('midpoint'); this.sendGaEvent('50% Listened'); break; case 75: this.trackUrls('thirdQuartile'); this.sendGaEvent('75% Listened'); break; default: break; } } stopTimer() { clearInterval(this.intervalTimer) clearInterval(this.progressTimer) } trackEvent(event, params) { if (!this.options.isDemo) { params = defaults(params, { event_type: event }, this.getDefaultTrackOptions()) if (this.mediaAds) { params = { ...params, duration: this.mediaAds.duration, campaign_id: this.ads.campaign_id } } this.eventTracker.trackEvent(params) } } trackDidLoad(params = {}) { this.trackEvent('load', params) // Google Analytics - record audio load event (but only first call) if(params.media_type) { this.sendGaEvent('Load') } } trackDidPlay() { this.startProgressTimer() this.trackEvent('play') // start percent timer to trigger quartile events for ads and Google Analytics this.startPercentTimer() // Google Analytics - send click event if currentTime=0 (first-play) const currentTime = this.player.getCurrentTime() if(currentTime < 0.1) { this.sendGaEvent('Play') } } trackProgress() { this.trackEvent('progress', { listen_length_seconds: this.player.getCurrentTime(), listen_length_percent: this.player.getCurrentPercentage() }) } trackDidResume() { this.trackEvent('resume') } trackDidPause(listenLengthSeconds, listenLengthPercent) { this.stopTimer() this.trackEvent('pause', { ui_location: 'button', listen_length_seconds: listenLengthSeconds, listen_length_percent: listenLengthPercent }) } trackDidListenToEnd() { this.stopTimer() this.trackEvent('listenToEnd') this.sendGaEvent('Complete') this.trackUrls('complete'); this.percentPlayed = 0; } trackDidChangeSpeed(speed) { this.trackEvent('speed', { speed }) } trackAdLogoClick() { this.trackEvent('ad_logo_click') this.sendGaEvent('Ad Logo Click') } trackAdLinkClick() { this.trackEvent('ad_link_click') this.sendGaEvent('Ad Link Click') } } export default Analytics