Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

@bitmovin/player-integration-conviva

Package Overview
Dependencies
Maintainers
1
Versions
19
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@bitmovin/player-integration-conviva - npm Package Compare versions

Comparing version 5.0.0 to 5.1.0

dist/lib/helper/AdHelper.d.ts

7

CHANGELOG.md

@@ -10,2 +10,9 @@ # Changelog

## 5.1.0 - 2024-06-13
### Added
- Basic client ad tracking using `Conviva.AdAnalytics`
### Changed
- Update `bitmovin-player` dependency to `^8.165.0`
## 5.0.0 - 2024-05-21

@@ -12,0 +19,0 @@ ### Added

2

dist/bitmovin-player-analytics-conviva.js

@@ -1,2 +0,2 @@

!function(t,e){"object"==typeof exports&&"object"==typeof module?module.exports=e(require("@convivainc/conviva-js-coresdk")):"function"==typeof define&&define.amd?define("bitmovin-player-analytics-conviva",["@convivainc/conviva-js-coresdk"],e):"object"==typeof exports?exports["bitmovin-player-analytics-conviva"]=e(require("@convivainc/conviva-js-coresdk")):(t.bitmovin=t.bitmovin||{},t.bitmovin.player=t.bitmovin.player||{},t.bitmovin.player.analytics=e(t.Conviva))}(window,function(t){return function(t){var e={};function a(n){if(e[n])return e[n].exports;var i=e[n]={i:n,l:!1,exports:{}};return t[n].call(i.exports,i,i.exports,a),i.l=!0,i.exports}return a.m=t,a.c=e,a.d=function(t,e,n){a.o(t,e)||Object.defineProperty(t,e,{enumerable:!0,get:n})},a.r=function(t){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(t,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(t,"__esModule",{value:!0})},a.t=function(t,e){if(1&e&&(t=a(t)),8&e)return t;if(4&e&&"object"==typeof t&&t&&t.__esModule)return t;var n=Object.create(null);if(a.r(n),Object.defineProperty(n,"default",{enumerable:!0,value:t}),2&e&&"string"!=typeof t)for(var i in t)a.d(n,i,function(e){return t[e]}.bind(null,i));return n},a.n=function(t){var e=t&&t.__esModule?function(){return t.default}:function(){return t};return a.d(e,"a",e),e},a.o=function(t,e){return Object.prototype.hasOwnProperty.call(t,e)},a.p="",a(a.s=1)}([function(e,a){e.exports=t},function(t,e,a){"use strict";Object.defineProperty(e,"__esModule",{value:!0}),e.ConvivaAnalytics=void 0,a(2);var n=a(3);Object.defineProperty(e,"ConvivaAnalytics",{enumerable:!0,get:function(){return n.ConvivaAnalytics}})},function(t,e,a){"use strict";Object.defineProperty(e,"__esModule",{value:!0})},function(t,e,a){"use strict";Object.defineProperty(e,"__esModule",{value:!0}),e.ConvivaAnalytics=void 0;var n=a(0),i=a(4),o=a(5),s=a(6),r=a(7),d=a(8),l=a(9),c=a(10),u=a(11),v=a(12),y=a(13),p=a(14),h=function(){function t(e,a,v){var y;void 0===v&&(v={});var h=this;if(this.stallTrackingTimout=new l.Timeout(t.STALL_TRACKING_DELAY_MS,function(){h.convivaVideoAnalytics.reportPlaybackMetric(n.Constants.Playback.PLAYER_STATE,n.Constants.PlayerState.BUFFERING)}),this.sessionEndedExternally=!1,this.internalEndSession=function(t){h.isSessionActive()&&(h.debugLog("[ ConvivaAnalytics ] end session",n.Constants.NO_SESSION_KEY,t),h.convivaVideoAnalytics.release(),h.convivaVideoAnalytics=null,h.lastSeenBitrate=null)},this.onPlaybackStateChanged=function(t){if(!h.isAd&&h.isSessionActive()){var e;switch(t.type){case h.events.Play:case h.events.Seek:case h.events.TimeShift:h.stallTrackingTimout.start();break;case h.events.StallStarted:h.stallTrackingTimout.clear(),e=n.Constants.PlayerState.BUFFERING;break;case h.events.Playing:h.stallTrackingTimout.clear(),h.adBreakStartedToFire&&(h.trackAdBreakStarted(h.adBreakStartedToFire),h.adBreakStartedToFire=null),e=n.Constants.PlayerState.PLAYING;break;case h.events.Paused:h.stallTrackingTimout.clear(),e=n.Constants.PlayerState.PAUSED;break;case h.events.Seeked:case h.events.TimeShifted:case h.events.StallEnded:h.stallTrackingTimout.clear(),e=h.player.isPlaying()?n.Constants.PlayerState.PLAYING:n.Constants.PlayerState.PAUSED;break;case h.events.PlaybackFinished:h.stallTrackingTimout.clear(),h.convivaVideoAnalytics.reportPlaybackEnded()}e&&(h.debugLog("[ ConvivaAnalytics ] report playback state",e),h.convivaVideoAnalytics.reportPlaybackMetric(n.Constants.Playback.PLAYER_STATE,e))}},this.onSourceLoaded=function(t){h.isSessionActive()&&(h.buildSourceRelatedMetadata(h.player.getSource()),h.updateSession())},this.onPlay=function(t){h.debugLog("[ Player Event ] play",t),h.isAd||(h.isSessionActive()||h.sessionEndedExternally||h.internalInitializeSession(),h.onPlaybackStateChanged(t))},this.onPlaying=function(t){h.contentMetadataBuilder.setPlaybackStarted(!0),h.debugLog("[ Player Event ] playing",t),h.updateSession(),h.onPlaybackStateChanged(t)},this.onPlaybackFinished=function(t){h.debugLog("[ Player Event ] playback finished",t),h.isSessionActive()&&(h.onPlaybackStateChanged(t),h.convivaVideoAnalytics.release(),h.convivaVideoAnalytics=null)},this.onVideoQualityChanged=function(t){var e=Math.round(t.targetQuality.bitrate/1e3);h.isSessionActive()?(h.lastSeenBitrate=null,h.convivaVideoAnalytics.reportPlaybackMetric(n.Constants.Playback.BITRATE,e)):h.lastSeenBitrate=e},this.onCustomEvent=function(t){if(h.isSessionActive()){var e=u.ObjectUtils.flatten(t);h.sendCustomPlaybackEvent(t.type,e)}else h.debugLog("skip custom event, no session existing",t)},this.trackAdBreakStarted=function(t){h.debugLog("[ ConvivaAnalytics ] adbreak started",t),h.isAd=!0;p.AdBreakHelper.mapAdPosition(t.adBreak,h.player);h.isSessionActive()&&h.convivaVideoAnalytics.reportAdBreakStarted(n.Constants.AdType.CLIENT_SIDE,n.Constants.AdPlayer.SEPARATE)},this.onAdBreakFinished=function(t){h.debugLog("[ ConvivaAnalytics ] adbreak finished",t),h.isAd=!1,h.isSessionActive()&&(h.convivaVideoAnalytics.reportAdBreakEnded(),h.convivaVideoAnalytics.reportPlaybackMetric(n.Constants.Playback.PLAYER_STATE,n.Constants.PlayerState.PLAYING))},this.onAdSkipped=function(t){h.onCustomEvent(t)},this.onAdError=function(t){h.onCustomEvent(t)},this.onSeek=function(t){h.isSessionActive()&&(h.trackSeekStart(t.seekTarget),h.onPlaybackStateChanged(t))},this.onSeeked=function(t){h.isSessionActive()&&(h.trackSeekEnd(),h.onPlaybackStateChanged(t))},this.onTimeShift=function(t){h.isSessionActive()&&(h.trackSeekStart(-1),h.onPlaybackStateChanged(t))},this.onTimeShifted=function(t){h.isSessionActive()&&(h.trackSeekEnd(),h.onPlaybackStateChanged(t))},this.onAudioChanged=function(t){h.isSessionActive()&&h.updateAudioTrack(t.targetAudio)},this.onSubtitleEnabled=function(t){h.isSessionActive()&&h.updateSubtitleTrack(t.subtitle)},this.onSubtitleDisabled=function(t){h.isSessionActive()&&h.turnOffSubtitles()},this.onError=function(t){h.isSessionActive()||h.sessionEndedExternally||h.internalInitializeSession(),h.reportPlaybackDeficiency(String(t.code)+" "+t.name,n.Constants.ErrorSeverity.FATAL)},this.onSourceUnloaded=function(t){h.isAd||(h.internalEndSession(t),h.resetContentMetadata())},this.onDestroy=function(t){h.destroy(t)},this.onAdBreakStarted=function(t){if(t.adBreak.scheduleTime===1/0)return h.debugLog("[ ConvivaAnalytics ] detected post-roll ad ... Ending session"),void h.onPlaybackFinished({timestamp:Date.now(),type:h.events.PlaybackFinished});h.isSessionActive()?h.trackAdBreakStarted(t):h.adBreakStartedToFire=t},void 0!==n)if(e.getSource())console.error("Bitmovin Conviva integration must be instantiated before calling player.load()");else{this.player=e,this.events=e.exports.PlayerEvent,this.handlers=new g(e),this.config=v,this.config.debugLoggingEnabled=this.config.debugLoggingEnabled||!1,this.logger=new o.Html5Logging,this.sessionKey=n.Constants.NO_SESSION_KEY,this.isAd=!1;var f=this.config.deviceMetadata||{},S=((y={})[n.Constants.DeviceMetadata.CATEGORY]=f.category||this.config.deviceCategory||n.Constants.DeviceCategory.WEB,y[n.Constants.DeviceMetadata.BRAND]=f.brand,y[n.Constants.DeviceMetadata.MANUFACTURER]=f.manufacturer,y[n.Constants.DeviceMetadata.MODEL]=f.model,y[n.Constants.DeviceMetadata.TYPE]=f.type,y[n.Constants.DeviceMetadata.VERSION]=f.version,y[n.Constants.DeviceMetadata.OS_NAME]=f.osName,y[n.Constants.DeviceMetadata.OS_VERSION]=f.osVersion,y);n.Analytics.setDeviceMetadata(S);var m={};m[n.Constants.CallbackFunctions.CONSOLE_LOG]=this.logger.consoleLog,m[n.Constants.CallbackFunctions.MAKE_REQUEST]=(new i.Html5Http).makeRequest;var b=new s.Html5Storage;m[n.Constants.CallbackFunctions.SAVE_DATA]=b.saveData,m[n.Constants.CallbackFunctions.LOAD_DATA]=b.loadData,m[n.Constants.CallbackFunctions.CREATE_TIMER]=(new d.Html5Timer).createTimer,m[n.Constants.CallbackFunctions.GET_EPOCH_TIME_IN_MS]=(new r.Html5Time).getEpochTimeMs;var A={};A[n.Constants.GATEWAY_URL]=v.gatewayUrl,A[n.Constants.LOG_LEVEL]=this.config.debugLoggingEnabled?n.Constants.LogLevel.DEBUG:n.Constants.LogLevel.NONE,n.Analytics.init(a,m,A),this.contentMetadataBuilder=new c.ContentMetadataBuilder(this.logger),this.registerPlayerEvents()}else console.error("Conviva script missing, cannot init ConvivaAnalytics. Please load the Conviva script (conviva-core-sdk.min.js) before Bitmovin's ConvivaAnalytics integration.")}return t.prototype.initializeSession=function(){if(this.isSessionActive())this.logger.consoleLog("There is already a session running.",n.SystemSettings.LogLevel.WARNING);else{if(!this.player.getSource()&&!this.contentMetadataBuilder.assetName)throw"AssetName is missing. Load player source first or set assetName via updateContentMetadata";this.internalInitializeSession(),this.sessionEndedExternally=!1}},t.prototype.endSession=function(){this.isSessionActive()&&(this.convivaVideoAnalytics.reportPlaybackEnded(),this.internalEndSession(),this.resetContentMetadata(),this.sessionEndedExternally=!0)},t.prototype.sendCustomApplicationEvent=function(t,e){void 0===e&&(e={}),this.isSessionActive()?this.convivaVideoAnalytics.reportAppEvent(t,e):this.logger.consoleLog("cannot send application event, no active monitoring session",n.SystemSettings.LogLevel.WARNING)},t.prototype.sendCustomPlaybackEvent=function(t,e){void 0===e&&(e={}),this.isSessionActive()?this.convivaVideoAnalytics.reportPlaybackEvent(t,e):this.logger.consoleLog("cannot send playback event, no active monitoring session",n.SystemSettings.LogLevel.WARNING)},t.prototype.updateContentMetadata=function(t){this.internalUpdateContentMetadata(t)},t.prototype.reportPlaybackDeficiency=function(t,e,a){void 0===a&&(a=!0),this.isSessionActive()&&(this.convivaVideoAnalytics.reportPlaybackFailed(t),a&&(this.internalEndSession(),this.resetContentMetadata()))},t.prototype.pauseTracking=function(){this.convivaVideoAnalytics.reportAdBreakStarted(n.Constants.AdType.CLIENT_SIDE,n.Constants.AdPlayer.SEPARATE),this.debugLog("Tracking paused.")},t.prototype.resumeTracking=function(){this.convivaVideoAnalytics.reportAdBreakEnded(),this.debugLog("Tracking resumed.")},t.prototype.release=function(){this.destroy()},t.prototype.destroy=function(t){this.unregisterPlayerEvents(),this.internalEndSession(t),n.Analytics.release()},t.prototype.debugLog=function(t){for(var e=[],a=1;a<arguments.length;a++)e[a-1]=arguments[a];this.config.debugLoggingEnabled&&console.log.apply(console,arguments)},t.prototype.getUrlFromSource=function(t){switch(this.player.getStreamType()){case"dash":return t.dash;case"hls":return t.hls;case"progressive":return Array.isArray(t.progressive)?t.progressive[0].url:t.progressive}},t.prototype.internalUpdateContentMetadata=function(t){this.contentMetadataBuilder.setOverrides(t),this.isSessionActive()?(this.buildContentMetadata(),this.updateSession()):this.logger.consoleLog("[ ConvivaAnalytics ] no active session. Content metadata will be propagated to Conviva on session initialization.",n.SystemSettings.LogLevel.DEBUG)},t.prototype.internalInitializeSession=function(){var t,e=this;this.buildContentMetadata(),this.convivaVideoAnalytics=n.Analytics.buildVideoAnalytics(),this.convivaVideoAnalytics.setPlayerInfo(((t={})[n.Constants.FRAMEWORK_NAME]="Bitmovin Player",t[n.Constants.FRAMEWORK_VERSION]=this.player.version,t)),this.convivaVideoAnalytics.reportPlaybackRequested(this.contentMetadataBuilder.build()),this.sessionKey=this.convivaVideoAnalytics.getSessionId(),this.convivaVideoAnalytics.setCallback(function(){var t=1e3*e.player.getCurrentTime("relativetime");e.convivaVideoAnalytics.reportPlaybackMetric(n.Constants.Playback.PLAY_HEAD_TIME,t)}),this.debugLog("[ ConvivaAnalytics ] start session",this.sessionKey),this.isSessionActive()||this.logger.consoleLog("Something went wrong, could not obtain session key",n.SystemSettings.LogLevel.ERROR),this.convivaVideoAnalytics.reportPlaybackMetric(n.Constants.Playback.PLAYER_STATE,n.Constants.PlayerState.STOPPED),this.lastSeenBitrate&&this.convivaVideoAnalytics.reportPlaybackMetric(n.Constants.Playback.BITRATE,this.lastSeenBitrate),this.updateAudioTrack(this.player.getAudio()),this.checkSubtitleWhenInternalInitialize()},t.prototype.buildContentMetadata=function(){this.contentMetadataBuilder.duration=this.player.getDuration(),this.contentMetadataBuilder.streamType=this.player.isLive()?n.ContentMetadata.StreamType.LIVE:n.ContentMetadata.StreamType.VOD,this.contentMetadataBuilder.addToCustom({autoplay:f.getAutoplayConfig(this.player)+"",preload:f.getPreloadConfig(this.player)+"",integrationVersion:t.VERSION});var e=this.player.getSource();e&&this.buildSourceRelatedMetadata(e)},t.prototype.buildSourceRelatedMetadata=function(t){this.contentMetadataBuilder.assetName=this.getAssetNameFromSource(t),this.contentMetadataBuilder.viewerId=this.contentMetadataBuilder.viewerId,this.contentMetadataBuilder.addToCustom({playerType:this.player.getPlayerType(),streamType:this.player.getStreamType(),vrContentType:t.vr&&t.vr.contentType}),this.contentMetadataBuilder.streamUrl=this.getUrlFromSource(t)},t.prototype.updateSession=function(){this.isSessionActive()&&this.convivaVideoAnalytics.setContentInfo(this.contentMetadataBuilder.build())},t.prototype.getAssetNameFromSource=function(t){var e=t.title;return e||"Untitled (no source.title set)"},t.prototype.resetContentMetadata=function(){this.contentMetadataBuilder.reset()},t.prototype.isSessionActive=function(){return!!this.convivaVideoAnalytics},t.prototype.trackSeekStart=function(t){this.convivaVideoAnalytics.reportPlaybackMetric(n.Constants.Playback.SEEK_STARTED)},t.prototype.trackSeekEnd=function(){this.convivaVideoAnalytics.reportPlaybackMetric(n.Constants.Playback.SEEK_ENDED)},t.prototype.updateAudioTrack=function(t){var e="unknown"!==t.lang?"["+t.lang+"]:"+t.label:t.label;this.convivaVideoAnalytics.reportPlaybackMetric(n.Constants.Playback.AUDIO_LANGUAGE,e)},t.prototype.updateSubtitleTrack=function(t){var e="unknown"!==t.lang?"["+t.lang+"]:"+t.label:t.label;"subtitles"===t.kind?(this.convivaVideoAnalytics.reportPlaybackMetric(n.Constants.Playback.SUBTITLES_LANGUAGE,e),this.convivaVideoAnalytics.reportPlaybackMetric(n.Constants.Playback.CLOSED_CAPTIONS_LANGUAGE,"off")):"captions"===t.kind?(this.convivaVideoAnalytics.reportPlaybackMetric(n.Constants.Playback.CLOSED_CAPTIONS_LANGUAGE,e),this.convivaVideoAnalytics.reportPlaybackMetric(n.Constants.Playback.SUBTITLES_LANGUAGE,"off")):this.turnOffSubtitles()},t.prototype.checkSubtitleWhenInternalInitialize=function(){if(void 0!==this.player.subtitles){var t=this.player.subtitles.list().filter(function(t){return t.enabled});if(1===t.length)return void this.updateSubtitleTrack(t[0])}this.turnOffSubtitles()},t.prototype.turnOffSubtitles=function(){this.convivaVideoAnalytics.reportPlaybackMetric(n.Constants.Playback.SUBTITLES_LANGUAGE,"off"),this.convivaVideoAnalytics.reportPlaybackMetric(n.Constants.Playback.CLOSED_CAPTIONS_LANGUAGE,"off")},t.prototype.registerPlayerEvents=function(){var t=this.handlers;t.add(this.events.SourceLoaded,this.onSourceLoaded),t.add(this.events.Play,this.onPlay),t.add(this.events.Playing,this.onPlaying),t.add(this.events.Paused,this.onPlaybackStateChanged),t.add(this.events.StallStarted,this.onPlaybackStateChanged),t.add(this.events.StallEnded,this.onPlaybackStateChanged),t.add(this.events.PlaybackFinished,this.onPlaybackFinished),t.add(this.events.VideoPlaybackQualityChanged,this.onVideoQualityChanged),t.add(this.events.AudioPlaybackQualityChanged,this.onCustomEvent),t.add(this.events.Muted,this.onCustomEvent),t.add(this.events.Unmuted,this.onCustomEvent),t.add(this.events.ViewModeChanged,this.onCustomEvent),t.add(this.events.AdBreakStarted,this.onAdBreakStarted),t.add(this.events.AdBreakFinished,this.onAdBreakFinished),t.add(this.events.AdSkipped,this.onAdSkipped),t.add(this.events.AdError,this.onAdError),t.add(this.events.SourceUnloaded,this.onSourceUnloaded),t.add(this.events.Error,this.onError),t.add(this.events.Destroy,this.onDestroy),t.add(this.events.Seek,this.onSeek),t.add(this.events.Seeked,this.onSeeked),t.add(this.events.TimeShift,this.onTimeShift),t.add(this.events.TimeShifted,this.onTimeShifted),t.add(this.events.AudioChanged,this.onAudioChanged),t.add(this.events.SubtitleEnabled,this.onSubtitleEnabled),t.add(this.events.SubtitleDisabled,this.onSubtitleDisabled),t.add(this.events.CastStarted,this.onCustomEvent),t.add(this.events.CastStopped,this.onCustomEvent)},t.prototype.unregisterPlayerEvents=function(){this.handlers.clear()},Object.defineProperty(t,"version",{get:function(){return t.VERSION},enumerable:!1,configurable:!0}),t.VERSION="5.0.0",t.STALL_TRACKING_DELAY_MS=100,t}();e.ConvivaAnalytics=h;var f=function(){function t(){}return t.getAutoplayConfig=function(e){var a=e.getConfig();return a.playback&&void 0!==a.playback.autoplay?a.playback.autoplay:t.AUTOPLAY_DEFAULT_CONFIG},t.getPreloadConfig=function(t){var e=t.getConfig();if(v.BrowserUtils.isMobile()){if(e.adaptation&&e.adaptation.mobile&&void 0!==e.adaptation.mobile.preload)return e.adaptation.mobile.preload}else if(e.adaptation&&e.adaptation.desktop&&void 0!==e.adaptation.desktop.preload)return e.adaptation.desktop.preload;return e.adaptation&&void 0!==e.adaptation.preload?e.adaptation.preload:!t.isLive()},t.AUTOPLAY_DEFAULT_CONFIG=!1,t}(),g=function(){function t(t){this.player=t,this.eventHandlers={}}return t.prototype.add=function(t,e){this.player.on(t,e),this.eventHandlers[t]||(this.eventHandlers[t]=[]),this.eventHandlers[t].push(e)},t.prototype.remove=function(t,e){this.player.off(t,e),this.eventHandlers[t]&&y.ArrayUtils.remove(this.eventHandlers[t],e)},t.prototype.clear=function(){for(var t in this.eventHandlers)for(var e=0,a=this.eventHandlers[t];e<a.length;e++){var n=a[e];this.remove(t,n)}},t}()},function(t,e,a){"use strict";Object.defineProperty(e,"__esModule",{value:!0}),e.Html5Http=void 0;var n=function(){function t(){}return t.prototype.makeRequest=function(t,e,a,n,i,o){return this.makeRequestStandard.apply(this,arguments)},t.prototype.release=function(){},t.prototype.makeRequestStandard=function(t,e,a,n,i,o){var s=new XMLHttpRequest;return s.open(t,e,!0),n&&s.overrideMimeType&&s.overrideMimeType(n),n&&s.setRequestHeader&&s.setRequestHeader("Content-Type",n),i>0&&(s.timeout=i,s.ontimeout=function(){s.ontimeout=s.onreadystatechange=null,o&&o(!1,"timeout after "+i+" ms")}),s.onreadystatechange=function(){4===s.readyState&&(s.ontimeout=s.onreadystatechange=null,200===s.status?o&&o(!0,s.responseText):o&&o(!1,"http status "+s.status))},s.send(a),null},t}();e.Html5Http=n},function(t,e,a){"use strict";Object.defineProperty(e,"__esModule",{value:!0}),e.Html5Logging=void 0;var n=a(0),i=function(){function t(){}return t.prototype.consoleLog=function(t,e){"undefined"!=typeof console&&(console.log&&e===n.SystemSettings.LogLevel.DEBUG||e===n.SystemSettings.LogLevel.INFO?console.log(t):console.warn&&e===n.SystemSettings.LogLevel.WARNING?console.warn(t):console.error&&e===n.SystemSettings.LogLevel.ERROR&&console.error(t))},t.prototype.release=function(){},t}();e.Html5Logging=i},function(t,e,a){"use strict";Object.defineProperty(e,"__esModule",{value:!0}),e.Html5Storage=void 0;var n=function(){function t(){}return t.prototype.saveData=function(t,e,a,n){var i=t+"."+e;try{localStorage.setItem(i,a),n(!0,null)}catch(t){n(!1,t.toString())}},t.prototype.loadData=function(t,e,a){var n=t+"."+e;try{a(!0,localStorage.getItem(n))}catch(t){a(!1,t.toString())}},t.prototype.release=function(){},t}();e.Html5Storage=n},function(t,e,a){"use strict";Object.defineProperty(e,"__esModule",{value:!0}),e.Html5Time=void 0;var n=function(){function t(){}return t.prototype.getEpochTimeMs=function(){return(new Date).getTime()},t.prototype.release=function(){},t}();e.Html5Time=n},function(t,e,a){"use strict";Object.defineProperty(e,"__esModule",{value:!0}),e.Html5Timer=void 0;var n=function(){function t(){}return t.prototype.createTimer=function(t,e,a){var n=window.setInterval(t,e);return function(){-1!==n&&(clearInterval(n),n=-1)}},t.prototype.release=function(){},t}();e.Html5Timer=n},function(t,e,a){"use strict";Object.defineProperty(e,"__esModule",{value:!0});var n=function(){function t(t,e,a){void 0===a&&(a=!1),this.delay=t,this.callback=e,this.repeat=a,this.timeoutOrIntervalId=0}return t.prototype.start=function(){return this.reset(),this},t.prototype.clear=function(){this.clearInternal()},t.prototype.reset=function(){this.clearInternal(),this.repeat?this.timeoutOrIntervalId=setInterval(this.callback,this.delay):this.timeoutOrIntervalId=setTimeout(this.callback,this.delay)},t.prototype.clearInternal=function(){this.repeat?clearInterval(this.timeoutOrIntervalId):clearTimeout(this.timeoutOrIntervalId)},t}();e.Timeout=n},function(t,e,a){"use strict";var n=this&&this.__assign||function(){return(n=Object.assign||function(t){for(var e,a=1,n=arguments.length;a<n;a++)for(var i in e=arguments[a])Object.prototype.hasOwnProperty.call(e,i)&&(t[i]=e[i]);return t}).apply(this,arguments)};Object.defineProperty(e,"__esModule",{value:!0}),e.ContentMetadataBuilder=void 0;var i=a(0),o=function(){function t(t){this.metadataOverrides={},this.metadata={},this.latestBuiltMetadata={},this.playbackStarted=!1,this.logger=t}return t.prototype.setOverrides=function(t){this.playbackStarted&&this.logger.consoleLog("[ Conviva Analytics ] Playback has started. Only some metadata attributes will be updated",i.SystemSettings.LogLevel.WARNING),this.metadataOverrides=n(n({},this.metadataOverrides),t)},t.prototype.getOverrides=function(){return this.metadataOverrides},t.prototype.setPlaybackStarted=function(t){this.playbackStarted=t},t.prototype.getStaticMetadata=function(){var t={};return this.playbackStarted?(t.assetName=this.latestBuiltMetadata.assetName,t.viewerId=this.latestBuiltMetadata.viewerId,t.streamType=this.latestBuiltMetadata.streamType,t.applicationName=this.latestBuiltMetadata.applicationName,t.duration=this.latestBuiltMetadata.duration,t.custom=this.latestBuiltMetadata.custom):(t.assetName=this.latestBuiltMetadata.assetName||this.assetName,t.viewerId=this.viewerId,t.streamType=this.metadataOverrides.streamType||this.metadata.streamType,t.applicationName=this.metadataOverrides.applicationName||this.metadata.applicationName,t.duration=this.metadataOverrides.duration||this.metadata.duration,t.custom=n(n(n({},this.metadataOverrides.custom),this.metadataOverrides.additionalStandardTags),this.metadata.custom)),t},t.prototype.getDynamicMetadata=function(){return{encodedFrameRate:this.metadataOverrides.encodedFrameRate||this.metadata.encodedFrameRate,defaultResource:this.metadataOverrides.defaultResource||this.metadata.defaultResource,streamUrl:this.metadataOverrides.streamUrl||this.metadata.streamUrl}},t.prototype.build=function(){var t,e=n(n({},this.getStaticMetadata()),this.getDynamicMetadata());this.latestBuiltMetadata=e;var a=((t={})[i.Constants.ASSET_NAME]=e.assetName,t[i.Constants.ENCODED_FRAMERATE]=e.encodedFrameRate,t[i.Constants.DURATION]=e.duration,t[i.Constants.DEFAULT_RESOURCE]=e.defaultResource,t[i.Constants.STREAM_URL]=e.streamUrl,t[i.Constants.IS_LIVE]=e.streamType,t[i.Constants.VIEWER_ID]=e.viewerId||"GET_VIEWER_ID_FROM_PLAYER",t[i.Constants.PLAYER_NAME]=e.applicationName||"GET_PLAYER_NAME_OR_TYPE",t);return n(n({},a),e.custom)},Object.defineProperty(t.prototype,"assetName",{get:function(){return this.metadataOverrides.assetName||this.metadata.assetName},set:function(t){this.metadata.assetName=t},enumerable:!1,configurable:!0}),Object.defineProperty(t.prototype,"viewerId",{get:function(){return this.metadataOverrides.viewerId||this.metadata.viewerId},set:function(t){this.metadata.viewerId=t},enumerable:!1,configurable:!0}),Object.defineProperty(t.prototype,"streamType",{set:function(t){this.metadata.streamType=t},enumerable:!1,configurable:!0}),Object.defineProperty(t.prototype,"applicationName",{set:function(t){this.metadata.applicationName=t},enumerable:!1,configurable:!0}),t.prototype.addToCustom=function(t){this.metadata.custom=n(n({},this.metadata.custom),t)},Object.defineProperty(t.prototype,"duration",{set:function(t){this.metadata.duration=t},enumerable:!1,configurable:!0}),Object.defineProperty(t.prototype,"encodedFrameRate",{set:function(t){this.metadata.encodedFrameRate=t},enumerable:!1,configurable:!0}),Object.defineProperty(t.prototype,"defaultResource",{set:function(t){this.metadata.defaultResource=t},enumerable:!1,configurable:!0}),Object.defineProperty(t.prototype,"streamUrl",{set:function(t){this.metadata.streamUrl=t},enumerable:!1,configurable:!0}),t.prototype.reset=function(){this.metadataOverrides={},this.metadata={},this.playbackStarted=!1,this.latestBuiltMetadata={}},t}();e.ContentMetadataBuilder=o},function(t,e,a){"use strict";Object.defineProperty(e,"__esModule",{value:!0}),e.ObjectUtils=void 0,function(t){t.flatten=function(t,e){void 0===e&&(e="");var a={},n=function(t,e){for(var i in t)if(t.hasOwnProperty(i)){var o=t[i];"object"==typeof o?n(o,e+i+"."):a[e+i]=String(o)}};return n(t,e),a}}(e.ObjectUtils||(e.ObjectUtils={}))},function(t,e,a){"use strict";Object.defineProperty(e,"__esModule",{value:!0}),e.BrowserUtils=void 0;var n=function(){function t(){}return t.isMobile=function(){var t=/Android/i.test(navigator.userAgent),e=/IEMobile/i.test(navigator.userAgent),a=/Windows Phone 10.0/i.test(navigator.userAgent),n=/Safari/i.test(navigator.userAgent)&&/Mobile/i.test(navigator.userAgent);return t||e||a||n},t}();e.BrowserUtils=n},function(t,e,a){"use strict";Object.defineProperty(e,"__esModule",{value:!0}),function(t){t.remove=function(t,e){var a=t.indexOf(e);return a>-1?t.splice(a,1)[0]:null}}(e.ArrayUtils||(e.ArrayUtils={}))},function(t,e,a){"use strict";Object.defineProperty(e,"__esModule",{value:!0}),e.AdBreakHelper=void 0;var n=a(0),i=function(){function t(){}return t.mapAdPosition=function(t,e){return t.scheduleTime<=0?n.Constants.AdPosition.PREROLL:t.scheduleTime>=e.getDuration()?n.Constants.AdPosition.POSTROLL:n.Constants.AdPosition.MIDROLL},t}();e.AdBreakHelper=i}])});
!function(t,e){"object"==typeof exports&&"object"==typeof module?module.exports=e(require("@convivainc/conviva-js-coresdk")):"function"==typeof define&&define.amd?define("bitmovin-player-analytics-conviva",["@convivainc/conviva-js-coresdk"],e):"object"==typeof exports?exports["bitmovin-player-analytics-conviva"]=e(require("@convivainc/conviva-js-coresdk")):(t.bitmovin=t.bitmovin||{},t.bitmovin.player=t.bitmovin.player||{},t.bitmovin.player.analytics=e(t.Conviva))}(window,function(t){return function(t){var e={};function a(n){if(e[n])return e[n].exports;var i=e[n]={i:n,l:!1,exports:{}};return t[n].call(i.exports,i,i.exports,a),i.l=!0,i.exports}return a.m=t,a.c=e,a.d=function(t,e,n){a.o(t,e)||Object.defineProperty(t,e,{enumerable:!0,get:n})},a.r=function(t){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(t,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(t,"__esModule",{value:!0})},a.t=function(t,e){if(1&e&&(t=a(t)),8&e)return t;if(4&e&&"object"==typeof t&&t&&t.__esModule)return t;var n=Object.create(null);if(a.r(n),Object.defineProperty(n,"default",{enumerable:!0,value:t}),2&e&&"string"!=typeof t)for(var i in t)a.d(n,i,function(e){return t[e]}.bind(null,i));return n},a.n=function(t){var e=t&&t.__esModule?function(){return t.default}:function(){return t};return a.d(e,"a",e),e},a.o=function(t,e){return Object.prototype.hasOwnProperty.call(t,e)},a.p="",a(a.s=1)}([function(e,a){e.exports=t},function(t,e,a){"use strict";Object.defineProperty(e,"__esModule",{value:!0}),e.ConvivaAnalytics=void 0,a(2);var n=a(3);Object.defineProperty(e,"ConvivaAnalytics",{enumerable:!0,get:function(){return n.ConvivaAnalytics}})},function(t,e,a){"use strict";Object.defineProperty(e,"__esModule",{value:!0})},function(t,e,a){"use strict";Object.defineProperty(e,"__esModule",{value:!0}),e.ConvivaAnalytics=void 0;var n=a(0),i=a(4),o=a(5),s=a(6),r=a(7),d=a(8),l=a(9),c=a(10),u=a(11),v=a(12),y=a(13),p=a(14),h=function(){function t(e,a,v){var y;void 0===v&&(v={});var h=this;if(this.stallTrackingTimeout=new l.Timeout(t.STALL_TRACKING_DELAY_MS,function(){h.isAdBreak?(h.debugLog("[ ConvivaAnalytics ] report buffering ad playback state"),h.convivaAdAnalytics.reportAdMetric(n.Constants.Playback.PLAYER_STATE,n.Constants.PlayerState.BUFFERING)):(h.debugLog("[ ConvivaAnalytics ] report buffering playback state"),h.convivaVideoAnalytics.reportPlaybackMetric(n.Constants.Playback.PLAYER_STATE,n.Constants.PlayerState.BUFFERING))}),this.sessionEndedExternally=!1,this.internalEndSession=function(t){h.isSessionActive()&&(h.debugLog("[ ConvivaAnalytics ] end session",n.Constants.NO_SESSION_KEY,t),h.convivaVideoAnalytics.release(),h.convivaVideoAnalytics=null,h.convivaAdAnalytics.release(),h.convivaAdAnalytics=null,h.lastAdBreakEvent=null,h.isAdBreak=!1)},this.onPlaybackStateChanged=function(t){if(h.debugLog("[ Player Event ] playback state change related event",t),h.isSessionActive()){var e;switch(t.type){case h.events.StallStarted:e=n.Constants.PlayerState.BUFFERING;break;case h.events.Playing:e=n.Constants.PlayerState.PLAYING;break;case h.events.Paused:e=n.Constants.PlayerState.PAUSED;break;case h.events.Seeked:case h.events.TimeShifted:case h.events.StallEnded:e=h.player.isPlaying()?n.Constants.PlayerState.PLAYING:n.Constants.PlayerState.PAUSED}var a=[h.events.Play,h.events.Seek,h.events.TimeShift],i=[h.events.StallStarted,h.events.Playing,h.events.Paused,h.events.Seeked,h.events.TimeShifted,h.events.StallEnded,h.events.PlaybackFinished];-1!==a.indexOf(t.type)?h.stallTrackingTimeout.start():-1!==i.indexOf(t.type)&&h.stallTrackingTimeout.clear(),e&&(h.isAdBreak?(h.debugLog("[ ConvivaAdAnalytics ] report ad playback state",e),h.convivaAdAnalytics.reportAdMetric(n.Constants.Playback.PLAYER_STATE,e)):(h.debugLog("[ ConvivaAnalytics ] report playback state",e),h.convivaVideoAnalytics.reportPlaybackMetric(n.Constants.Playback.PLAYER_STATE,e))),t.type===h.events.PlaybackFinished&&(h.debugLog("[ ConvivaAnalytics ] report playback ended"),h.convivaVideoAnalytics.reportPlaybackEnded())}},this.onSourceLoaded=function(t){h.debugLog("[ Player Event ] source loaded",t),h.isSessionActive()&&(h.buildSourceRelatedMetadata(h.player.getSource()),h.updateSession())},this.onPlay=function(t){h.debugLog("[ Player Event ] play",t),h.isAdBreak||(h.isSessionActive()||h.sessionEndedExternally||h.internalInitializeSession(),h.onPlaybackStateChanged(t))},this.onPlaying=function(t){h.contentMetadataBuilder.setPlaybackStarted(!0),h.debugLog("[ Player Event ] playing",t),h.updateSession(),h.onPlaybackStateChanged(t)},this.onPlaybackFinished=function(t){h.debugLog("[ Player Event ] playback finished",t),h.isSessionActive()&&(h.onPlaybackStateChanged(t),h.convivaVideoAnalytics.release(),h.convivaVideoAnalytics=null,h.convivaAdAnalytics.release(),h.convivaAdAnalytics=null)},this.onVideoQualityChanged=function(t){h.debugLog("[ Player Event ] video quality changed",t);var e=Math.round(t.targetQuality.bitrate/1e3);h.debugLog("[ ConvivaAnalytics ] report bitrate",{event:t,bitrateKbps:e}),h.convivaVideoAnalytics.reportPlaybackMetric(n.Constants.Playback.BITRATE,e)},this.onCustomEvent=function(t){if(h.debugLog("[ Player Event ] custom playback related event",t),h.isSessionActive()){var e=u.ObjectUtils.flatten(t);h.sendCustomPlaybackEvent(t.type,e)}else h.debugLog("[ ConvivaAnalytics ] skip custom event, no session existing",t)},this.onAdBreakStarted=function(t){h.debugLog("[ Player Event ] adbreak started",t),h.isAdBreak=!0,h.lastAdBreakEvent=t,h.debugLog("[ ConvivaAnalytics ] report ad break started",t),h.convivaVideoAnalytics.reportAdBreakStarted(n.Constants.AdType.CLIENT_SIDE,n.Constants.AdPlayer.SEPARATE)},this.onAdStarted=function(t){var e;h.debugLog("[ Player Event ] ad started",t);var a=p.AdHelper.extractConvivaAdInfo(h.player,h.lastAdBreakEvent,t),i=null===(e=t.ad.data)||void 0===e?void 0:e.bitrate;h.debugLog("[ ConvivaAdAnalytics ] report ad started",{event:t,adInfo:a}),h.convivaAdAnalytics.reportAdStarted(a),h.debugLog("[ ConvivaAdAnalytics ] report playing ad playback state"),h.convivaAdAnalytics.reportAdMetric(n.Constants.Playback.PLAYER_STATE,n.Constants.PlayerState.PLAYING),i&&(h.debugLog("[ ConvivaAdAnalytics ] report ad bitrate",i),h.convivaAdAnalytics.reportAdMetric(n.Constants.Playback.BITRATE,i))},this.onAdFinished=function(t){h.debugLog("[ Player Event ] ad finished",t),h.debugLog("[ ConvivaAdAnalytics ] report ad ended",{event:t}),h.convivaAdAnalytics.reportAdEnded()},this.onAdSkipped=function(t){h.debugLog("[ Player Event ] ad skipped",t),h.debugLog("[ ConvivaAdAnalytics ] report ad skipped",t),h.convivaAdAnalytics.reportAdSkipped(),h.onCustomEvent(t)},this.onAdBreakFinished=function(t){h.debugLog("[ Player Event ] adbreak finished",t),h.isAdBreak=!1,h.debugLog("[ ConvivaAnalytics ] report ad break ended",t),h.convivaVideoAnalytics.reportAdBreakEnded(),h.debugLog("[ ConvivaAnalytics ] report playing playback state"),h.convivaVideoAnalytics.reportPlaybackMetric(n.Constants.Playback.PLAYER_STATE,n.Constants.PlayerState.PLAYING)},this.onAdError=function(t){h.debugLog("[ Player Event ] ad error",t);var e=p.AdHelper.formatAdErrorEvent(t);h.debugLog("[ ConvivaAdAnalytics ] report ad error",{event:t,formattedError:e}),h.convivaAdAnalytics.reportAdError(e,n.Constants.ErrorSeverity.WARNING),h.onCustomEvent(t)},this.onSeek=function(t){h.debugLog("[ Player Event ] seek",t),h.isSessionActive()&&(h.trackSeekStart(t.seekTarget),h.onPlaybackStateChanged(t))},this.onSeeked=function(t){h.debugLog("[ Player Event ] seeked",t),h.isSessionActive()&&(h.trackSeekEnd(),h.onPlaybackStateChanged(t))},this.onTimeShift=function(t){h.debugLog("[ Player Event ] time shift",t),h.isSessionActive()&&(h.trackSeekStart(-1),h.onPlaybackStateChanged(t))},this.onTimeShifted=function(t){h.debugLog("[ Player Event ] time shifted",t),h.isSessionActive()&&(h.trackSeekEnd(),h.onPlaybackStateChanged(t))},this.onAudioChanged=function(t){h.debugLog("[ Player Event ] audio changed",t),h.isSessionActive()&&h.updateAudioTrack(t.targetAudio)},this.onSubtitleEnabled=function(t){h.debugLog("[ Player Event ] subtitled enabled",t),h.isSessionActive()&&h.updateSubtitleTrack(t.subtitle)},this.onSubtitleDisabled=function(t){h.debugLog("[ Player Event ] subtitles disabled",t),h.isSessionActive()&&h.turnOffSubtitles()},this.onError=function(t){h.debugLog("[ Player Event ] error",t),h.isSessionActive()||h.sessionEndedExternally||h.internalInitializeSession(),h.reportPlaybackDeficiency(String(t.code)+" "+t.name,n.Constants.ErrorSeverity.FATAL)},this.onSourceUnloaded=function(t){h.debugLog("[ Player Event ] source unloaded",t),h.isAdBreak||(h.internalEndSession(t),h.resetContentMetadata())},this.onDestroy=function(t){h.debugLog("[ Player Event ] destroy",t),h.destroy(t)},void 0!==n)if(e.getSource())console.error("Bitmovin Conviva integration must be instantiated before calling player.load()");else{this.player=e,this.events=e.exports.PlayerEvent,this.handlers=new A(e),this.config=v,this.config.debugLoggingEnabled=this.config.debugLoggingEnabled||!1,this.logger=new o.Html5Logging,this.sessionKey=n.Constants.NO_SESSION_KEY,this.isAdBreak=!1;var g=this.config.deviceMetadata||{},f=((y={})[n.Constants.DeviceMetadata.CATEGORY]=g.category||this.config.deviceCategory||n.Constants.DeviceCategory.WEB,y[n.Constants.DeviceMetadata.BRAND]=g.brand,y[n.Constants.DeviceMetadata.MANUFACTURER]=g.manufacturer,y[n.Constants.DeviceMetadata.MODEL]=g.model,y[n.Constants.DeviceMetadata.TYPE]=g.type,y[n.Constants.DeviceMetadata.VERSION]=g.version,y[n.Constants.DeviceMetadata.OS_NAME]=g.osName,y[n.Constants.DeviceMetadata.OS_VERSION]=g.osVersion,y);n.Analytics.setDeviceMetadata(f);var b={};b[n.Constants.CallbackFunctions.CONSOLE_LOG]=this.logger.consoleLog,b[n.Constants.CallbackFunctions.MAKE_REQUEST]=(new i.Html5Http).makeRequest;var m=new s.Html5Storage;b[n.Constants.CallbackFunctions.SAVE_DATA]=m.saveData,b[n.Constants.CallbackFunctions.LOAD_DATA]=m.loadData,b[n.Constants.CallbackFunctions.CREATE_TIMER]=(new d.Html5Timer).createTimer,b[n.Constants.CallbackFunctions.GET_EPOCH_TIME_IN_MS]=(new r.Html5Time).getEpochTimeMs;var S={};S[n.Constants.GATEWAY_URL]=v.gatewayUrl,S[n.Constants.LOG_LEVEL]=this.config.debugLoggingEnabled?n.Constants.LogLevel.DEBUG:n.Constants.LogLevel.NONE,n.Analytics.init(a,b,S),this.contentMetadataBuilder=new c.ContentMetadataBuilder(this.logger),this.registerPlayerEvents()}else console.error("Conviva script missing, cannot init ConvivaAnalytics. Please load the Conviva script (conviva-core-sdk.min.js) before Bitmovin's ConvivaAnalytics integration.")}return t.prototype.initializeSession=function(){if(this.isSessionActive())this.logger.consoleLog("[ ConvivaAnalytics ] There is already a session running.",n.SystemSettings.LogLevel.WARNING);else{if(!this.player.getSource()&&!this.contentMetadataBuilder.assetName)throw"AssetName is missing. Load player source first or set assetName via updateContentMetadata";this.internalInitializeSession(),this.sessionEndedExternally=!1}},t.prototype.endSession=function(){this.isSessionActive()&&(this.debugLog("[ ConvivaAnalytics ] report playback ended state"),this.isAdBreak&&(this.debugLog("[ ConvivaAdAnalytics ] report ad skipped"),this.convivaAdAnalytics.reportAdSkipped()),this.convivaVideoAnalytics.reportPlaybackEnded(),this.internalEndSession(),this.resetContentMetadata(),this.sessionEndedExternally=!0)},t.prototype.sendCustomApplicationEvent=function(t,e){void 0===e&&(e={}),this.isSessionActive()?(this.debugLog("[ ConvivaAnalytics ] report custom app event",{eventName:t,eventAttributes:e}),this.convivaVideoAnalytics.reportAppEvent(t,e)):this.logger.consoleLog("[ ConvivaAnalytics ] cannot send application event, no active monitoring session",n.SystemSettings.LogLevel.WARNING)},t.prototype.sendCustomPlaybackEvent=function(t,e){void 0===e&&(e={}),this.isSessionActive()?(this.debugLog("[ ConvivaAnalytics ] report custom playback event",{eventName:t,eventAttributes:e}),this.convivaVideoAnalytics.reportPlaybackEvent(t,e)):this.logger.consoleLog("[ ConvivaAnalytics ] cannot send playback event, no active monitoring session",n.SystemSettings.LogLevel.WARNING)},t.prototype.updateContentMetadata=function(t){this.internalUpdateContentMetadata(t)},t.prototype.reportPlaybackDeficiency=function(t,e,a){void 0===a&&(a=!0),this.isSessionActive()&&(this.debugLog("[ ConvivaAnalytics ] report playback failed",{message:t}),this.convivaVideoAnalytics.reportPlaybackFailed(t),a&&(this.internalEndSession(),this.resetContentMetadata()))},t.prototype.pauseTracking=function(){this.debugLog("[ ConvivaAnalytics ] pause tracking via ad break started reporting"),this.convivaVideoAnalytics.reportAdBreakStarted(n.Constants.AdType.CLIENT_SIDE,n.Constants.AdPlayer.SEPARATE)},t.prototype.resumeTracking=function(){this.debugLog("[ ConvivaAnalytics ] resume tracking via ad break ended reporting"),this.convivaVideoAnalytics.reportAdBreakEnded()},t.prototype.release=function(){this.destroy()},t.prototype.destroy=function(t){this.unregisterPlayerEvents(),this.internalEndSession(t),n.Analytics.release()},t.prototype.debugLog=function(t){for(var e=[],a=1;a<arguments.length;a++)e[a-1]=arguments[a];this.config.debugLoggingEnabled&&console.log.apply(console,arguments)},t.prototype.getUrlFromSource=function(t){switch(this.player.getStreamType()){case"dash":return t.dash;case"hls":return t.hls;case"progressive":return Array.isArray(t.progressive)?t.progressive[0].url:t.progressive}},t.prototype.internalUpdateContentMetadata=function(t){this.contentMetadataBuilder.setOverrides(t),this.isSessionActive()?(this.buildContentMetadata(),this.updateSession()):this.logger.consoleLog("[ ConvivaAnalytics ] no active session. Content metadata will be propagated to Conviva on session initialization.",n.SystemSettings.LogLevel.DEBUG)},t.prototype.internalInitializeSession=function(){var t,e=this;this.buildContentMetadata(),this.convivaVideoAnalytics=n.Analytics.buildVideoAnalytics(),this.convivaAdAnalytics=n.Analytics.buildAdAnalytics(this.convivaVideoAnalytics);var a=((t={})[n.Constants.FRAMEWORK_NAME]="Bitmovin Player",t[n.Constants.FRAMEWORK_VERSION]=this.player.version,t);this.convivaVideoAnalytics.setPlayerInfo(a),this.convivaAdAnalytics.setAdPlayerInfo(a),this.debugLog("[ ConvivaAnalytics ] report playback requested"),this.convivaVideoAnalytics.reportPlaybackRequested(this.contentMetadataBuilder.build()),this.sessionKey=this.convivaVideoAnalytics.getSessionId(),this.convivaVideoAnalytics.setCallback(function(){var t=1e3*e.player.getCurrentTime("relativetime");e.isAdBreak?(e.debugLog("[ ConvivaAdAnalytics ] report ad player head time",t),e.convivaAdAnalytics.reportAdMetric(n.Constants.Playback.PLAY_HEAD_TIME,t)):(e.debugLog("[ ConvivaAnalytics ] report player head time",t),e.convivaVideoAnalytics.reportPlaybackMetric(n.Constants.Playback.PLAY_HEAD_TIME,t))}),this.debugLog("[ ConvivaAnalytics ] start session",this.sessionKey),this.isSessionActive()||this.logger.consoleLog("[ ConvivaAnalytics ] Something went wrong, could not obtain session key",n.SystemSettings.LogLevel.ERROR),this.updateAudioTrack(this.player.getAudio()),this.checkSubtitleWhenInternalInitialize()},t.prototype.buildContentMetadata=function(){this.contentMetadataBuilder.duration=this.player.getDuration(),this.contentMetadataBuilder.streamType=this.player.isLive()?n.ContentMetadata.StreamType.LIVE:n.ContentMetadata.StreamType.VOD,this.contentMetadataBuilder.addToCustom({autoplay:g.getAutoplayConfig(this.player)+"",preload:g.getPreloadConfig(this.player)+"",integrationVersion:t.VERSION});var e=this.player.getSource();e&&this.buildSourceRelatedMetadata(e)},t.prototype.buildSourceRelatedMetadata=function(t){this.contentMetadataBuilder.assetName=this.getAssetNameFromSource(t),this.contentMetadataBuilder.viewerId=this.contentMetadataBuilder.viewerId,this.contentMetadataBuilder.addToCustom({playerType:this.player.getPlayerType(),streamType:this.player.getStreamType(),vrContentType:t.vr&&t.vr.contentType}),this.contentMetadataBuilder.streamUrl=this.getUrlFromSource(t)},t.prototype.updateSession=function(){this.isSessionActive()&&this.convivaVideoAnalytics.setContentInfo(this.contentMetadataBuilder.build())},t.prototype.getAssetNameFromSource=function(t){var e=t.title;return e||"Untitled (no source.title set)"},t.prototype.resetContentMetadata=function(){this.contentMetadataBuilder.reset()},t.prototype.isSessionActive=function(){return!!this.convivaVideoAnalytics},t.prototype.trackSeekStart=function(t){this.debugLog("[ ConvivaAnalytics ] report seek started"),this.convivaVideoAnalytics.reportPlaybackMetric(n.Constants.Playback.SEEK_STARTED)},t.prototype.trackSeekEnd=function(){this.debugLog("[ ConvivaAnalytics ] report seek ended"),this.convivaVideoAnalytics.reportPlaybackMetric(n.Constants.Playback.SEEK_ENDED)},t.prototype.updateAudioTrack=function(t){var e="unknown"!==t.lang?"["+t.lang+"]:"+t.label:t.label;this.debugLog("[ ConvivaAnalytics ] report audio language",{formattedAudio:e}),this.convivaVideoAnalytics.reportPlaybackMetric(n.Constants.Playback.AUDIO_LANGUAGE,e)},t.prototype.updateSubtitleTrack=function(t){var e="unknown"!==t.lang?"["+t.lang+"]:"+t.label:t.label;"subtitles"===t.kind?(this.debugLog("[ ConvivaAnalytics ] report subtitles language",{formattedSubtitle:e}),this.convivaVideoAnalytics.reportPlaybackMetric(n.Constants.Playback.SUBTITLES_LANGUAGE,e),this.debugLog("[ ConvivaAnalytics ] report off closed captions language"),this.convivaVideoAnalytics.reportPlaybackMetric(n.Constants.Playback.CLOSED_CAPTIONS_LANGUAGE,"off")):"captions"===t.kind?(this.debugLog("[ ConvivaAnalytics ] report closed captions language",{formattedSubtitle:e}),this.convivaVideoAnalytics.reportPlaybackMetric(n.Constants.Playback.CLOSED_CAPTIONS_LANGUAGE,e),this.debugLog("[ ConvivaAnalytics ] report off subtitles language"),this.convivaVideoAnalytics.reportPlaybackMetric(n.Constants.Playback.SUBTITLES_LANGUAGE,"off")):this.turnOffSubtitles()},t.prototype.checkSubtitleWhenInternalInitialize=function(){if(void 0!==this.player.subtitles){var t=this.player.subtitles.list().filter(function(t){return t.enabled});if(1===t.length)return void this.updateSubtitleTrack(t[0])}this.turnOffSubtitles()},t.prototype.turnOffSubtitles=function(){this.debugLog("[ ConvivaAnalytics ] report off subtitles language"),this.convivaVideoAnalytics.reportPlaybackMetric(n.Constants.Playback.SUBTITLES_LANGUAGE,"off"),this.debugLog("[ ConvivaAnalytics ] report off closed captions language"),this.convivaVideoAnalytics.reportPlaybackMetric(n.Constants.Playback.CLOSED_CAPTIONS_LANGUAGE,"off")},t.prototype.registerPlayerEvents=function(){var t=this.handlers;t.add(this.events.SourceLoaded,this.onSourceLoaded),t.add(this.events.Play,this.onPlay),t.add(this.events.Playing,this.onPlaying),t.add(this.events.Paused,this.onPlaybackStateChanged),t.add(this.events.StallStarted,this.onPlaybackStateChanged),t.add(this.events.StallEnded,this.onPlaybackStateChanged),t.add(this.events.PlaybackFinished,this.onPlaybackFinished),t.add(this.events.VideoPlaybackQualityChanged,this.onVideoQualityChanged),t.add(this.events.AudioPlaybackQualityChanged,this.onCustomEvent),t.add(this.events.Muted,this.onCustomEvent),t.add(this.events.Unmuted,this.onCustomEvent),t.add(this.events.ViewModeChanged,this.onCustomEvent),t.add(this.events.AdStarted,this.onAdStarted),t.add(this.events.AdFinished,this.onAdFinished),t.add(this.events.AdBreakStarted,this.onAdBreakStarted),t.add(this.events.AdBreakFinished,this.onAdBreakFinished),t.add(this.events.AdSkipped,this.onAdSkipped),t.add(this.events.AdError,this.onAdError),t.add(this.events.SourceUnloaded,this.onSourceUnloaded),t.add(this.events.Error,this.onError),t.add(this.events.Destroy,this.onDestroy),t.add(this.events.Seek,this.onSeek),t.add(this.events.Seeked,this.onSeeked),t.add(this.events.TimeShift,this.onTimeShift),t.add(this.events.TimeShifted,this.onTimeShifted),t.add(this.events.AudioChanged,this.onAudioChanged),t.add(this.events.SubtitleEnabled,this.onSubtitleEnabled),t.add(this.events.SubtitleDisabled,this.onSubtitleDisabled),t.add(this.events.CastStarted,this.onCustomEvent),t.add(this.events.CastStopped,this.onCustomEvent)},t.prototype.unregisterPlayerEvents=function(){this.handlers.clear()},Object.defineProperty(t,"version",{get:function(){return t.VERSION},enumerable:!1,configurable:!0}),t.VERSION="5.1.0",t.STALL_TRACKING_DELAY_MS=100,t}();e.ConvivaAnalytics=h;var g=function(){function t(){}return t.getAutoplayConfig=function(e){var a=e.getConfig();return a.playback&&void 0!==a.playback.autoplay?a.playback.autoplay:t.AUTOPLAY_DEFAULT_CONFIG},t.getPreloadConfig=function(t){var e=t.getConfig();if(v.BrowserUtils.isMobile()){if(e.adaptation&&e.adaptation.mobile&&void 0!==e.adaptation.mobile.preload)return e.adaptation.mobile.preload}else if(e.adaptation&&e.adaptation.desktop&&void 0!==e.adaptation.desktop.preload)return e.adaptation.desktop.preload;return e.adaptation&&void 0!==e.adaptation.preload?e.adaptation.preload:!t.isLive()},t.AUTOPLAY_DEFAULT_CONFIG=!1,t}(),A=function(){function t(t){this.player=t,this.eventHandlers={}}return t.prototype.add=function(t,e){this.player.on(t,e),this.eventHandlers[t]||(this.eventHandlers[t]=[]),this.eventHandlers[t].push(e)},t.prototype.remove=function(t,e){this.player.off(t,e),this.eventHandlers[t]&&y.ArrayUtils.remove(this.eventHandlers[t],e)},t.prototype.clear=function(){for(var t in this.eventHandlers)for(var e=0,a=this.eventHandlers[t];e<a.length;e++){var n=a[e];this.remove(t,n)}},t}()},function(t,e,a){"use strict";Object.defineProperty(e,"__esModule",{value:!0}),e.Html5Http=void 0;var n=function(){function t(){}return t.prototype.makeRequest=function(t,e,a,n,i,o){return this.makeRequestStandard.apply(this,arguments)},t.prototype.release=function(){},t.prototype.makeRequestStandard=function(t,e,a,n,i,o){var s=new XMLHttpRequest;return s.open(t,e,!0),n&&s.overrideMimeType&&s.overrideMimeType(n),n&&s.setRequestHeader&&s.setRequestHeader("Content-Type",n),i>0&&(s.timeout=i,s.ontimeout=function(){s.ontimeout=s.onreadystatechange=null,o&&o(!1,"timeout after "+i+" ms")}),s.onreadystatechange=function(){4===s.readyState&&(s.ontimeout=s.onreadystatechange=null,200===s.status?o&&o(!0,s.responseText):o&&o(!1,"http status "+s.status))},s.send(a),null},t}();e.Html5Http=n},function(t,e,a){"use strict";Object.defineProperty(e,"__esModule",{value:!0}),e.Html5Logging=void 0;var n=a(0),i=function(){function t(){}return t.prototype.consoleLog=function(t,e){"undefined"!=typeof console&&(console.log&&e===n.SystemSettings.LogLevel.DEBUG||e===n.SystemSettings.LogLevel.INFO?console.log(t):console.warn&&e===n.SystemSettings.LogLevel.WARNING?console.warn(t):console.error&&e===n.SystemSettings.LogLevel.ERROR&&console.error(t))},t.prototype.release=function(){},t}();e.Html5Logging=i},function(t,e,a){"use strict";Object.defineProperty(e,"__esModule",{value:!0}),e.Html5Storage=void 0;var n=function(){function t(){}return t.prototype.saveData=function(t,e,a,n){var i=t+"."+e;try{localStorage.setItem(i,a),n(!0,null)}catch(t){n(!1,t.toString())}},t.prototype.loadData=function(t,e,a){var n=t+"."+e;try{a(!0,localStorage.getItem(n))}catch(t){a(!1,t.toString())}},t.prototype.release=function(){},t}();e.Html5Storage=n},function(t,e,a){"use strict";Object.defineProperty(e,"__esModule",{value:!0}),e.Html5Time=void 0;var n=function(){function t(){}return t.prototype.getEpochTimeMs=function(){return(new Date).getTime()},t.prototype.release=function(){},t}();e.Html5Time=n},function(t,e,a){"use strict";Object.defineProperty(e,"__esModule",{value:!0}),e.Html5Timer=void 0;var n=function(){function t(){}return t.prototype.createTimer=function(t,e,a){var n=window.setInterval(t,e);return function(){-1!==n&&(clearInterval(n),n=-1)}},t.prototype.release=function(){},t}();e.Html5Timer=n},function(t,e,a){"use strict";Object.defineProperty(e,"__esModule",{value:!0});var n=function(){function t(t,e,a){void 0===a&&(a=!1),this.delay=t,this.callback=e,this.repeat=a,this.timeoutOrIntervalId=0}return t.prototype.start=function(){return this.reset(),this},t.prototype.clear=function(){this.clearInternal()},t.prototype.reset=function(){this.clearInternal(),this.repeat?this.timeoutOrIntervalId=setInterval(this.callback,this.delay):this.timeoutOrIntervalId=setTimeout(this.callback,this.delay)},t.prototype.clearInternal=function(){this.repeat?clearInterval(this.timeoutOrIntervalId):clearTimeout(this.timeoutOrIntervalId)},t}();e.Timeout=n},function(t,e,a){"use strict";var n=this&&this.__assign||function(){return(n=Object.assign||function(t){for(var e,a=1,n=arguments.length;a<n;a++)for(var i in e=arguments[a])Object.prototype.hasOwnProperty.call(e,i)&&(t[i]=e[i]);return t}).apply(this,arguments)};Object.defineProperty(e,"__esModule",{value:!0}),e.ContentMetadataBuilder=void 0;var i=a(0),o=function(){function t(t){this.metadataOverrides={},this.metadata={},this.latestBuiltMetadata={},this.playbackStarted=!1,this.logger=t}return t.prototype.setOverrides=function(t){this.playbackStarted&&this.logger.consoleLog("[ Conviva Analytics ] Playback has started. Only some metadata attributes will be updated",i.SystemSettings.LogLevel.WARNING),this.metadataOverrides=n(n({},this.metadataOverrides),t)},t.prototype.getOverrides=function(){return this.metadataOverrides},t.prototype.setPlaybackStarted=function(t){this.playbackStarted=t},t.prototype.getStaticMetadata=function(){var t={};return this.playbackStarted?(t.assetName=this.latestBuiltMetadata.assetName,t.viewerId=this.latestBuiltMetadata.viewerId,t.streamType=this.latestBuiltMetadata.streamType,t.applicationName=this.latestBuiltMetadata.applicationName,t.duration=this.latestBuiltMetadata.duration,t.custom=this.latestBuiltMetadata.custom):(t.assetName=this.latestBuiltMetadata.assetName||this.assetName,t.viewerId=this.viewerId,t.streamType=this.metadataOverrides.streamType||this.metadata.streamType,t.applicationName=this.metadataOverrides.applicationName||this.metadata.applicationName,t.duration=this.metadataOverrides.duration||this.metadata.duration,t.custom=n(n(n({},this.metadataOverrides.custom),this.metadataOverrides.additionalStandardTags),this.metadata.custom)),t},t.prototype.getDynamicMetadata=function(){return{encodedFrameRate:this.metadataOverrides.encodedFrameRate||this.metadata.encodedFrameRate,defaultResource:this.metadataOverrides.defaultResource||this.metadata.defaultResource,streamUrl:this.metadataOverrides.streamUrl||this.metadata.streamUrl}},t.prototype.build=function(){var t,e=n(n({},this.getStaticMetadata()),this.getDynamicMetadata());this.latestBuiltMetadata=e;var a=((t={})[i.Constants.ASSET_NAME]=e.assetName,t[i.Constants.ENCODED_FRAMERATE]=e.encodedFrameRate,t[i.Constants.DURATION]=e.duration,t[i.Constants.DEFAULT_RESOURCE]=e.defaultResource,t[i.Constants.STREAM_URL]=e.streamUrl,t[i.Constants.IS_LIVE]=e.streamType,t[i.Constants.VIEWER_ID]=e.viewerId||"GET_VIEWER_ID_FROM_PLAYER",t[i.Constants.PLAYER_NAME]=e.applicationName||"GET_PLAYER_NAME_OR_TYPE",t);return n(n({},a),e.custom)},Object.defineProperty(t.prototype,"assetName",{get:function(){return this.metadataOverrides.assetName||this.metadata.assetName},set:function(t){this.metadata.assetName=t},enumerable:!1,configurable:!0}),Object.defineProperty(t.prototype,"viewerId",{get:function(){return this.metadataOverrides.viewerId||this.metadata.viewerId},set:function(t){this.metadata.viewerId=t},enumerable:!1,configurable:!0}),Object.defineProperty(t.prototype,"streamType",{set:function(t){this.metadata.streamType=t},enumerable:!1,configurable:!0}),Object.defineProperty(t.prototype,"applicationName",{set:function(t){this.metadata.applicationName=t},enumerable:!1,configurable:!0}),t.prototype.addToCustom=function(t){this.metadata.custom=n(n({},this.metadata.custom),t)},Object.defineProperty(t.prototype,"duration",{set:function(t){this.metadata.duration=t},enumerable:!1,configurable:!0}),Object.defineProperty(t.prototype,"encodedFrameRate",{set:function(t){this.metadata.encodedFrameRate=t},enumerable:!1,configurable:!0}),Object.defineProperty(t.prototype,"defaultResource",{set:function(t){this.metadata.defaultResource=t},enumerable:!1,configurable:!0}),Object.defineProperty(t.prototype,"streamUrl",{set:function(t){this.metadata.streamUrl=t},enumerable:!1,configurable:!0}),t.prototype.reset=function(){this.metadataOverrides={},this.metadata={},this.playbackStarted=!1,this.latestBuiltMetadata={}},t}();e.ContentMetadataBuilder=o},function(t,e,a){"use strict";Object.defineProperty(e,"__esModule",{value:!0}),e.ObjectUtils=void 0,function(t){t.flatten=function(t,e){void 0===e&&(e="");var a={},n=function(t,e){for(var i in t)if(t.hasOwnProperty(i)){var o=t[i];"object"==typeof o?n(o,e+i+"."):a[e+i]=String(o)}};return n(t,e),a}}(e.ObjectUtils||(e.ObjectUtils={}))},function(t,e,a){"use strict";Object.defineProperty(e,"__esModule",{value:!0}),e.BrowserUtils=void 0;var n=function(){function t(){}return t.isMobile=function(){var t=/Android/i.test(navigator.userAgent),e=/IEMobile/i.test(navigator.userAgent),a=/Windows Phone 10.0/i.test(navigator.userAgent),n=/Safari/i.test(navigator.userAgent)&&/Mobile/i.test(navigator.userAgent);return t||e||a||n},t}();e.BrowserUtils=n},function(t,e,a){"use strict";Object.defineProperty(e,"__esModule",{value:!0}),function(t){t.remove=function(t,e){var a=t.indexOf(e);return a>-1?t.splice(a,1)[0]:null}}(e.ArrayUtils||(e.ArrayUtils={}))},function(t,e,a){"use strict";Object.defineProperty(e,"__esModule",{value:!0}),e.AdHelper=void 0;var n=a(0),i=function(){function t(){}return t.mapAdPosition=function(t,e){return t.scheduleTime<=0?n.Constants.AdPosition.PREROLL:t.scheduleTime>=e.getDuration()?n.Constants.AdPosition.POSTROLL:n.Constants.AdPosition.MIDROLL},t.formatAdErrorEvent=function(t){var e,a,n=(null==t?void 0:t.message)||"Unknown message",i=(null==t?void 0:t.name)||"Unknown name";return["Ad error:","".concat(i,";"),(null===(e=t.data)||void 0===e?void 0:e.code)?"Ad error code: ".concat(null===(a=t.data)||void 0===a?void 0:a.code,";"):void 0,"Message:","".concat(n,";"),"Error code: ".concat(t.code,";"),t.troubleShootLink?"Troubleshoot link: ".concat(t.troubleShootLink):void 0].filter(Boolean).join(" ")},t.extractConvivaAdInfo=function(e,a,i){var o,s,r,d=t.mapAdPosition(a.adBreak,e),l=i.ad,c=l.data,u="NA",v="NA",y=l.id;c&&("adSystem"in c&&(null===(o=c.adSystem)||void 0===o?void 0:o.name)&&(u=c.adSystem.name),"creative"in c&&(null===(s=null==c?void 0:c.creative)||void 0===s?void 0:s.id)&&(v=c.creative.id),"adTitle"in c&&c.adTitle&&(r=c.adTitle),"wrapperAdIds"in c&&c.wrapperAdIds&&c.wrapperAdIds.length&&(y=c.wrapperAdIds[c.wrapperAdIds.length-1]));var p={"c3.ad.id":l.id,"c3.ad.technology":n.Constants.AdType.CLIENT_SIDE,"c3.ad.position":d,"c3.ad.system":u,"c3.ad.creativeId":v,"c3.ad.firstAdId":y,"c3.ad.mediaFileApiFramework":"NA","c3.ad.firstAdSystem":"NA","c3.ad.firstCreativeId":"NA"};return r&&(p[n.Constants.ASSET_NAME]=r),l.mediaFileUrl&&(p[n.Constants.STREAM_URL]=l.mediaFileUrl),"duration"in l&&l.duration&&(p[n.Constants.DURATION]=l.duration),p},t}();e.AdHelper=i}])});
//# sourceMappingURL=bitmovin-player-analytics-conviva.js.map

@@ -83,19 +83,15 @@ import * as Conviva from '@convivainc/conviva-js-coresdk';

private convivaVideoAnalytics;
private convivaAdAnalytics;
/**
* Tracks the ad playback status and is true between ON_AD_STARTED and ON_AD_FINISHED/SKIPPED/ERROR.
* Tracks the ad break status and is true between ON_AD_STARTED and ON_AD_FINISHED/SKIPPED/ERROR.
* This flag is required because player.isAd() is unreliable and not always true between the events.
*/
private isAd;
private isAdBreak;
/**
* Attributes needed to workaround wrong event order in case of a pre-roll ad.
* See {@link onAdBreakStarted} for more info
* Tracks the last ad break event to get the ad position and other ad break related information
* in the ad started event to report it to Conviva.
*/
private adBreakStartedToFire;
private lastAdBreakEvent;
private stallTrackingTimeout;
/**
* Needed to workaround wrong event order in case of a video-playback-quality-change event.
* See {@link onVideoQualityChanged} for more info
*/
private lastSeenBitrate;
private stallTrackingTimout;
/**
* Boolean to track whether a session was ended by an upstream caller instead of within internal session management.

@@ -118,3 +114,3 @@ * If this is true, we should avoid initializing a new session internally if a session is not active

/**
* Ends the current conviva tracking session.
* Ends the current conviva tracking session. If there an ad break is active it will also report the ad as skipped.
* Results in a no-opt if there is no active session.

@@ -214,5 +210,7 @@ *

private onCustomEvent;
private trackAdBreakStarted;
private onAdBreakStarted;
private onAdStarted;
private onAdFinished;
private onAdSkipped;
private onAdBreakFinished;
private onAdSkipped;
private onAdError;

@@ -236,3 +234,2 @@ private onSeek;

private registerPlayerEvents;
private onAdBreakStarted;
private unregisterPlayerEvents;

@@ -239,0 +236,0 @@ static get version(): string;

@@ -15,3 +15,3 @@ "use strict";

var arrayutils_1 = require("bitmovin-player-ui/dist/js/framework/arrayutils");
var AdBreakHelper_1 = require("./helper/AdBreakHelper");
var AdHelper_1 = require("./helper/AdHelper");
var ConvivaAnalytics = /** @class */ (function () {

@@ -24,4 +24,11 @@ function ConvivaAnalytics(player, customerKey, config) {

// to track stalling state between those events. To prevent tracking eg. when seeking in buffer we delay it.
this.stallTrackingTimout = new timeout_1.Timeout(ConvivaAnalytics.STALL_TRACKING_DELAY_MS, function () {
_this.convivaVideoAnalytics.reportPlaybackMetric(Conviva.Constants.Playback.PLAYER_STATE, Conviva.Constants.PlayerState.BUFFERING);
this.stallTrackingTimeout = new timeout_1.Timeout(ConvivaAnalytics.STALL_TRACKING_DELAY_MS, function () {
if (_this.isAdBreak) {
_this.debugLog('[ ConvivaAnalytics ] report buffering ad playback state');
_this.convivaAdAnalytics.reportAdMetric(Conviva.Constants.Playback.PLAYER_STATE, Conviva.Constants.PlayerState.BUFFERING);
}
else {
_this.debugLog('[ ConvivaAnalytics ] report buffering playback state');
_this.convivaVideoAnalytics.reportPlaybackMetric(Conviva.Constants.Playback.PLAYER_STATE, Conviva.Constants.PlayerState.BUFFERING);
}
});

@@ -40,8 +47,10 @@ /**

_this.convivaVideoAnalytics = null;
_this.lastSeenBitrate = null;
_this.convivaAdAnalytics.release();
_this.convivaAdAnalytics = null;
_this.lastAdBreakEvent = null;
_this.isAdBreak = false;
};
this.onPlaybackStateChanged = function (event) {
// Do not track playback state changes during ads, (e.g. triggered from IMA)
// or if there is no active session.
if (_this.isAd || !_this.isSessionActive()) {
_this.debugLog('[ Player Event ] playback state change related event', event);
if (!_this.isSessionActive()) {
return;

@@ -51,23 +60,9 @@ }

switch (event.type) {
case _this.events.Play:
case _this.events.Seek:
case _this.events.TimeShift:
_this.stallTrackingTimout.start();
break;
case _this.events.StallStarted:
_this.stallTrackingTimout.clear();
playerState = Conviva.Constants.PlayerState.BUFFERING;
break;
case _this.events.Playing:
_this.stallTrackingTimout.clear();
// In case of a pre-roll ad we need to fire the trackAdBreakStarted right after we got a onPlay
// See onAdBreakStarted for more details.
if (_this.adBreakStartedToFire) {
_this.trackAdBreakStarted(_this.adBreakStartedToFire);
_this.adBreakStartedToFire = null;
}
playerState = Conviva.Constants.PlayerState.PLAYING;
break;
case _this.events.Paused:
_this.stallTrackingTimout.clear();
playerState = Conviva.Constants.PlayerState.PAUSED;

@@ -78,3 +73,2 @@ break;

case _this.events.StallEnded:
_this.stallTrackingTimout.clear();
if (_this.player.isPlaying()) {

@@ -87,13 +81,40 @@ playerState = Conviva.Constants.PlayerState.PLAYING;

break;
case _this.events.PlaybackFinished:
_this.stallTrackingTimout.clear();
_this.convivaVideoAnalytics.reportPlaybackEnded();
break;
}
var stallTrackingStartEvents = [
_this.events.Play,
_this.events.Seek,
_this.events.TimeShift,
];
var stallTrackingClearEvents = [
_this.events.StallStarted,
_this.events.Playing,
_this.events.Paused,
_this.events.Seeked,
_this.events.TimeShifted,
_this.events.StallEnded,
_this.events.PlaybackFinished,
];
if (stallTrackingStartEvents.indexOf(event.type) !== -1) {
_this.stallTrackingTimeout.start();
}
else if (stallTrackingClearEvents.indexOf(event.type) !== -1) {
_this.stallTrackingTimeout.clear();
}
if (playerState) {
_this.debugLog('[ ConvivaAnalytics ] report playback state', playerState);
_this.convivaVideoAnalytics.reportPlaybackMetric(Conviva.Constants.Playback.PLAYER_STATE, playerState);
if (_this.isAdBreak) {
_this.debugLog('[ ConvivaAdAnalytics ] report ad playback state', playerState);
_this.convivaAdAnalytics.reportAdMetric(Conviva.Constants.Playback.PLAYER_STATE, playerState);
}
else {
_this.debugLog('[ ConvivaAnalytics ] report playback state', playerState);
_this.convivaVideoAnalytics.reportPlaybackMetric(Conviva.Constants.Playback.PLAYER_STATE, playerState);
}
}
if (event.type === _this.events.PlaybackFinished) {
_this.debugLog('[ ConvivaAnalytics ] report playback ended');
_this.convivaVideoAnalytics.reportPlaybackEnded();
}
};
this.onSourceLoaded = function (event) {
_this.debugLog('[ Player Event ] source loaded', event);
// In case the session was created external before loading the source

@@ -108,3 +129,3 @@ if (!_this.isSessionActive()) {

_this.debugLog('[ Player Event ] play', event);
if (_this.isAd) {
if (_this.isAdBreak) {
// Do not track play event during ad (e.g. triggered from IMA)

@@ -133,20 +154,20 @@ return;

_this.convivaVideoAnalytics = null;
_this.convivaAdAnalytics.release();
_this.convivaAdAnalytics = null;
};
this.onVideoQualityChanged = function (event) {
_this.debugLog('[ Player Event ] video quality changed', event);
// We calculate the bitrate with a divisor of 1000 so the values look nicer
// Example: 250000 / 1000 => 250 kbps (250000 / 1024 => 244kbps)
var bitrateKbps = Math.round(event.targetQuality.bitrate / 1000);
if (!_this.isSessionActive()) {
// Since the first videoPlaybackQualityChanged event comes before playback ever started we need to store the
// value and use it for tracking when initializing the session.
// TODO: remove this workaround when the player event order is fixed
_this.lastSeenBitrate = bitrateKbps;
return;
}
_this.lastSeenBitrate = null;
_this.debugLog('[ ConvivaAnalytics ] report bitrate', {
event: event,
bitrateKbps: bitrateKbps,
});
_this.convivaVideoAnalytics.reportPlaybackMetric(Conviva.Constants.Playback.BITRATE, bitrateKbps);
};
this.onCustomEvent = function (event) {
_this.debugLog('[ Player Event ] custom playback related event', event);
if (!_this.isSessionActive()) {
_this.debugLog('skip custom event, no session existing', event);
_this.debugLog('[ ConvivaAnalytics ] skip custom event, no session existing', event);
return;

@@ -157,29 +178,59 @@ }

};
this.trackAdBreakStarted = function (event) {
_this.debugLog('[ ConvivaAnalytics ] adbreak started', event);
_this.isAd = true;
var adPosition = AdBreakHelper_1.AdBreakHelper.mapAdPosition(event.adBreak, _this.player);
if (!_this.isSessionActive()) {
// Don't report without a valid session (e.g., in case of a pre-roll, or post-roll ad)
return;
}
this.onAdBreakStarted = function (event) {
_this.debugLog('[ Player Event ] adbreak started', event);
_this.isAdBreak = true;
_this.lastAdBreakEvent = event;
_this.debugLog('[ ConvivaAnalytics ] report ad break started', event);
_this.convivaVideoAnalytics.reportAdBreakStarted(Conviva.Constants.AdType.CLIENT_SIDE, Conviva.Constants.AdPlayer.SEPARATE);
};
this.onAdBreakFinished = function (event) {
_this.debugLog('[ ConvivaAnalytics ] adbreak finished', event);
_this.isAd = false;
if (!_this.isSessionActive()) {
// Don't report without a valid session (e.g., in case of a pre-roll, or post-roll ad)
return;
this.onAdStarted = function (event) {
var _a;
_this.debugLog('[ Player Event ] ad started', event);
var adInfo = AdHelper_1.AdHelper.extractConvivaAdInfo(_this.player, _this.lastAdBreakEvent, event);
var bitrateKbps = (_a = event.ad.data) === null || _a === void 0 ? void 0 : _a.bitrate;
_this.debugLog('[ ConvivaAdAnalytics ] report ad started', {
event: event,
adInfo: adInfo,
});
_this.convivaAdAnalytics.reportAdStarted(adInfo);
_this.debugLog('[ ConvivaAdAnalytics ] report playing ad playback state');
_this.convivaAdAnalytics.reportAdMetric(Conviva.Constants.Playback.PLAYER_STATE, Conviva.Constants.PlayerState.PLAYING);
if (bitrateKbps) {
_this.debugLog('[ ConvivaAdAnalytics ] report ad bitrate', bitrateKbps);
_this.convivaAdAnalytics.reportAdMetric(Conviva.Constants.Playback.BITRATE, bitrateKbps);
}
_this.convivaVideoAnalytics.reportAdBreakEnded();
_this.convivaVideoAnalytics.reportPlaybackMetric(Conviva.Constants.Playback.PLAYER_STATE, Conviva.Constants.PlayerState.PLAYING);
};
this.onAdFinished = function (event) {
_this.debugLog('[ Player Event ] ad finished', event);
_this.debugLog('[ ConvivaAdAnalytics ] report ad ended', {
event: event,
});
_this.convivaAdAnalytics.reportAdEnded();
};
this.onAdSkipped = function (event) {
_this.debugLog('[ Player Event ] ad skipped', event);
_this.debugLog('[ ConvivaAdAnalytics ] report ad skipped', event);
_this.convivaAdAnalytics.reportAdSkipped();
_this.onCustomEvent(event);
};
this.onAdBreakFinished = function (event) {
_this.debugLog('[ Player Event ] adbreak finished', event);
_this.isAdBreak = false;
_this.debugLog('[ ConvivaAnalytics ] report ad break ended', event);
_this.convivaVideoAnalytics.reportAdBreakEnded();
_this.debugLog('[ ConvivaAnalytics ] report playing playback state');
_this.convivaVideoAnalytics.reportPlaybackMetric(Conviva.Constants.Playback.PLAYER_STATE, Conviva.Constants.PlayerState.PLAYING);
};
this.onAdError = function (event) {
_this.debugLog('[ Player Event ] ad error', event);
var formattedError = AdHelper_1.AdHelper.formatAdErrorEvent(event);
_this.debugLog('[ ConvivaAdAnalytics ] report ad error', {
event: event,
formattedError: formattedError,
});
_this.convivaAdAnalytics.reportAdError(formattedError, Conviva.Constants.ErrorSeverity.WARNING);
_this.onCustomEvent(event);
};
this.onSeek = function (event) {
_this.debugLog('[ Player Event ] seek', event);
if (!_this.isSessionActive()) {

@@ -194,2 +245,3 @@ // Handle the case that the User seeks on the UI before play was triggered.

this.onSeeked = function (event) {
_this.debugLog('[ Player Event ] seeked', event);
if (!_this.isSessionActive()) {

@@ -203,2 +255,3 @@ // See comment in onSeek

this.onTimeShift = function (event) {
_this.debugLog('[ Player Event ] time shift', event);
if (!_this.isSessionActive()) {

@@ -213,2 +266,3 @@ // See comment in onSeek

this.onTimeShifted = function (event) {
_this.debugLog('[ Player Event ] time shifted', event);
if (!_this.isSessionActive()) {

@@ -222,2 +276,3 @@ // See comment in onSeek

this.onAudioChanged = function (event) {
_this.debugLog('[ Player Event ] audio changed', event);
if (!_this.isSessionActive()) {

@@ -230,2 +285,3 @@ // Handle the case that the User change audio on the UI before play was triggered.

this.onSubtitleEnabled = function (event) {
_this.debugLog('[ Player Event ] subtitled enabled', event);
if (!_this.isSessionActive()) {

@@ -238,2 +294,3 @@ // Handle the case that the User change subtitle on the UI before play was triggered.

this.onSubtitleDisabled = function (event) {
_this.debugLog('[ Player Event ] subtitles disabled', event);
if (!_this.isSessionActive()) {

@@ -246,2 +303,3 @@ // Handle the case that the User turn off subtitle on the UI before play was triggered.

this.onError = function (event) {
_this.debugLog('[ Player Event ] error', event);
if (!_this.isSessionActive() && !_this.sessionEndedExternally) {

@@ -254,3 +312,4 @@ // initialize Session if not yet initialized to capture Video Start Failures

this.onSourceUnloaded = function (event) {
if (_this.isAd) {
_this.debugLog('[ Player Event ] source unloaded', event);
if (_this.isAdBreak) {
// Ignore sourceUnloaded events during ads

@@ -265,31 +324,5 @@ return;

this.onDestroy = function (event) {
_this.debugLog('[ Player Event ] destroy', event);
_this.destroy(event);
};
this.onAdBreakStarted = function (event) {
// Specific post-roll handling
var isPostRollAdBreak = function (adBreak) {
return adBreak.scheduleTime === Infinity;
};
if (isPostRollAdBreak(event.adBreak)) {
// Fire playbackFinished in case of a post-roll ad to stop session and do not track post roll ad
_this.debugLog('[ ConvivaAnalytics ] detected post-roll ad ... Ending session');
_this.onPlaybackFinished({
timestamp: Date.now(),
type: _this.events.PlaybackFinished,
});
return;
}
// Specific pre-roll handling
// TODO: remove this workaround when event order is correct
// Since the event order on initial playback in case of a pre-roll ad is false we need to workaround
// a to early triggered adBreakStarted event. The initial onPlay event is called after the AdBreakStarted
// of the pre-roll ad so we won't initialize a session. Therefore we save the adBreakStarted event and
// trigger it in the initial onPlay event (after initializing the session). (See #onPlaybackStateChanged)
if (!_this.isSessionActive()) {
_this.adBreakStartedToFire = event;
}
else {
_this.trackAdBreakStarted(event);
}
};
if (typeof Conviva === 'undefined') {

@@ -312,3 +345,3 @@ console.error("Conviva script missing, cannot init ConvivaAnalytics. Please load the Conviva script (conviva-core-sdk.min.js) before Bitmovin's ConvivaAnalytics integration.");

this.sessionKey = Conviva.Constants.NO_SESSION_KEY;
this.isAd = false;
this.isAdBreak = false;
var deviceMetadataFromConfig = this.config.deviceMetadata || {};

@@ -355,3 +388,3 @@ var deviceMetadata = (_a = {},

if (this.isSessionActive()) {
this.logger.consoleLog('There is already a session running.', Conviva.SystemSettings.LogLevel.WARNING);
this.logger.consoleLog('[ ConvivaAnalytics ] There is already a session running.', Conviva.SystemSettings.LogLevel.WARNING);
return;

@@ -368,3 +401,3 @@ }

/**
* Ends the current conviva tracking session.
* Ends the current conviva tracking session. If there an ad break is active it will also report the ad as skipped.
* Results in a no-opt if there is no active session.

@@ -381,2 +414,7 @@ *

}
this.debugLog('[ ConvivaAnalytics ] report playback ended state');
if (this.isAdBreak) {
this.debugLog('[ ConvivaAdAnalytics ] report ad skipped');
this.convivaAdAnalytics.reportAdSkipped();
}
this.convivaVideoAnalytics.reportPlaybackEnded();

@@ -395,7 +433,10 @@ this.internalEndSession();

if (eventAttributes === void 0) { eventAttributes = {}; }
// Check for active session
if (!this.isSessionActive()) {
this.logger.consoleLog('cannot send application event, no active monitoring session', Conviva.SystemSettings.LogLevel.WARNING);
this.logger.consoleLog('[ ConvivaAnalytics ] cannot send application event, no active monitoring session', Conviva.SystemSettings.LogLevel.WARNING);
return;
}
this.debugLog('[ ConvivaAnalytics ] report custom app event', {
eventName: eventName,
eventAttributes: eventAttributes,
});
// NOTE Conviva has event attribute capped and 256 bytes for custom events and will show up as a warning

@@ -413,7 +454,10 @@ // in monitoring session if greater than 256 bytes

if (eventAttributes === void 0) { eventAttributes = {}; }
// Check for active session
if (!this.isSessionActive()) {
this.logger.consoleLog('cannot send playback event, no active monitoring session', Conviva.SystemSettings.LogLevel.WARNING);
this.logger.consoleLog('[ ConvivaAnalytics ] cannot send playback event, no active monitoring session', Conviva.SystemSettings.LogLevel.WARNING);
return;
}
this.debugLog('[ ConvivaAnalytics ] report custom playback event', {
eventName: eventName,
eventAttributes: eventAttributes,
});
// NOTE Conviva has event attribute capped and 256 bytes for custom events and will show up as a warning

@@ -449,2 +493,5 @@ // in monitoring session if greater than 256 bytes

}
this.debugLog('[ ConvivaAnalytics ] report playback failed', {
message: message,
});
this.convivaVideoAnalytics.reportPlaybackFailed(message);

@@ -460,5 +507,5 @@ if (endSession) {

ConvivaAnalytics.prototype.pauseTracking = function () {
this.debugLog('[ ConvivaAnalytics ] pause tracking via ad break started reporting');
// AdStart is the right way to pause monitoring according to conviva.
this.convivaVideoAnalytics.reportAdBreakStarted(Conviva.Constants.AdType.CLIENT_SIDE, Conviva.Constants.AdPlayer.SEPARATE);
this.debugLog('Tracking paused.');
};

@@ -469,5 +516,5 @@ /**

ConvivaAnalytics.prototype.resumeTracking = function () {
this.debugLog('[ ConvivaAnalytics ] resume tracking via ad break ended reporting');
// AdEnd is the right way to resume monitoring according to conviva.
this.convivaVideoAnalytics.reportAdBreakEnded();
this.debugLog('Tracking resumed.');
};

@@ -544,6 +591,10 @@ ConvivaAnalytics.prototype.release = function () {

this.convivaVideoAnalytics = Conviva.Analytics.buildVideoAnalytics();
this.convivaVideoAnalytics.setPlayerInfo((_a = {},
this.convivaAdAnalytics = Conviva.Analytics.buildAdAnalytics(this.convivaVideoAnalytics);
var playerInfo = (_a = {},
_a[Conviva.Constants.FRAMEWORK_NAME] = 'Bitmovin Player',
_a[Conviva.Constants.FRAMEWORK_VERSION] = this.player.version,
_a));
_a);
this.convivaVideoAnalytics.setPlayerInfo(playerInfo);
this.convivaAdAnalytics.setAdPlayerInfo(playerInfo);
this.debugLog('[ ConvivaAnalytics ] report playback requested');
this.convivaVideoAnalytics.reportPlaybackRequested(this.contentMetadataBuilder.build());

@@ -553,3 +604,10 @@ this.sessionKey = this.convivaVideoAnalytics.getSessionId();

var playheadTimeMs = _this.player.getCurrentTime('relativetime') * 1000;
_this.convivaVideoAnalytics.reportPlaybackMetric(Conviva.Constants.Playback.PLAY_HEAD_TIME, playheadTimeMs);
if (_this.isAdBreak) {
_this.debugLog('[ ConvivaAdAnalytics ] report ad player head time', playheadTimeMs);
_this.convivaAdAnalytics.reportAdMetric(Conviva.Constants.Playback.PLAY_HEAD_TIME, playheadTimeMs);
}
else {
_this.debugLog('[ ConvivaAnalytics ] report player head time', playheadTimeMs);
_this.convivaVideoAnalytics.reportPlaybackMetric(Conviva.Constants.Playback.PLAY_HEAD_TIME, playheadTimeMs);
}
});

@@ -559,8 +617,4 @@ this.debugLog('[ ConvivaAnalytics ] start session', this.sessionKey);

// Something went wrong. With stable system interfaces, this should never happen.
this.logger.consoleLog('Something went wrong, could not obtain session key', Conviva.SystemSettings.LogLevel.ERROR);
this.logger.consoleLog('[ ConvivaAnalytics ] Something went wrong, could not obtain session key', Conviva.SystemSettings.LogLevel.ERROR);
}
this.convivaVideoAnalytics.reportPlaybackMetric(Conviva.Constants.Playback.PLAYER_STATE, Conviva.Constants.PlayerState.STOPPED);
if (this.lastSeenBitrate) {
this.convivaVideoAnalytics.reportPlaybackMetric(Conviva.Constants.Playback.BITRATE, this.lastSeenBitrate);
}
// Send the session init audio language values.

@@ -625,5 +679,7 @@ this.updateAudioTrack(this.player.getAudio());

ConvivaAnalytics.prototype.trackSeekStart = function (target) {
this.debugLog('[ ConvivaAnalytics ] report seek started');
this.convivaVideoAnalytics.reportPlaybackMetric(Conviva.Constants.Playback.SEEK_STARTED);
};
ConvivaAnalytics.prototype.trackSeekEnd = function () {
this.debugLog('[ ConvivaAnalytics ] report seek ended');
this.convivaVideoAnalytics.reportPlaybackMetric(Conviva.Constants.Playback.SEEK_ENDED);

@@ -633,2 +689,5 @@ };

var formattedAudio = audioTrack.lang !== 'unknown' ? '[' + audioTrack.lang + ']:' + audioTrack.label : audioTrack.label;
this.debugLog('[ ConvivaAnalytics ] report audio language', {
formattedAudio: formattedAudio,
});
this.convivaVideoAnalytics.reportPlaybackMetric(Conviva.Constants.Playback.AUDIO_LANGUAGE, formattedAudio);

@@ -639,7 +698,15 @@ };

if (subtitleTrack.kind === 'subtitles') {
this.debugLog('[ ConvivaAnalytics ] report subtitles language', {
formattedSubtitle: formattedSubtitle,
});
this.convivaVideoAnalytics.reportPlaybackMetric(Conviva.Constants.Playback.SUBTITLES_LANGUAGE, formattedSubtitle);
this.debugLog('[ ConvivaAnalytics ] report off closed captions language');
this.convivaVideoAnalytics.reportPlaybackMetric(Conviva.Constants.Playback.CLOSED_CAPTIONS_LANGUAGE, 'off');
}
else if (subtitleTrack.kind === 'captions') {
this.debugLog('[ ConvivaAnalytics ] report closed captions language', {
formattedSubtitle: formattedSubtitle,
});
this.convivaVideoAnalytics.reportPlaybackMetric(Conviva.Constants.Playback.CLOSED_CAPTIONS_LANGUAGE, formattedSubtitle);
this.debugLog('[ ConvivaAnalytics ] report off subtitles language');
this.convivaVideoAnalytics.reportPlaybackMetric(Conviva.Constants.Playback.SUBTITLES_LANGUAGE, 'off');

@@ -663,3 +730,5 @@ }

ConvivaAnalytics.prototype.turnOffSubtitles = function () {
this.debugLog('[ ConvivaAnalytics ] report off subtitles language');
this.convivaVideoAnalytics.reportPlaybackMetric(Conviva.Constants.Playback.SUBTITLES_LANGUAGE, 'off');
this.debugLog('[ ConvivaAnalytics ] report off closed captions language');
this.convivaVideoAnalytics.reportPlaybackMetric(Conviva.Constants.Playback.CLOSED_CAPTIONS_LANGUAGE, 'off');

@@ -681,2 +750,4 @@ };

playerEvents.add(this.events.ViewModeChanged, this.onCustomEvent);
playerEvents.add(this.events.AdStarted, this.onAdStarted);
playerEvents.add(this.events.AdFinished, this.onAdFinished);
playerEvents.add(this.events.AdBreakStarted, this.onAdBreakStarted);

@@ -683,0 +754,0 @@ playerEvents.add(this.events.AdBreakFinished, this.onAdBreakFinished);

{
"name": "@bitmovin/player-integration-conviva",
"version": "5.0.0",
"version": "5.1.0",
"description": "Conviva analytics integration for the Bitmovin Player",

@@ -33,3 +33,3 @@ "repository": {

"@types/jest": "^24.0.1",
"bitmovin-player": "^8.31.0",
"bitmovin-player": "^8.165.0",
"bitmovin-player-ui": "^3.3.1",

@@ -54,4 +54,4 @@ "create-file-webpack": "^1.0.2",

"@convivainc/conviva-js-coresdk": "^4.7.6",
"bitmovin-player": "^8.31.0"
"bitmovin-player": "^8.165.0"
}
}
import * as Conviva from '@convivainc/conviva-js-coresdk';
import type {
AdBreak,
AdBreakEvent,

@@ -20,2 +19,6 @@ AdEvent,

TimeMode,
AdData,
VastAdData,
Ad,
LinearAd,
} from 'bitmovin-player';

@@ -32,3 +35,3 @@ import { Html5Http } from './Html5Http';

import { ArrayUtils } from 'bitmovin-player-ui/dist/js/framework/arrayutils';
import { AdBreakHelper } from './helper/AdBreakHelper';
import { AdHelper } from './helper/AdHelper';

@@ -128,28 +131,33 @@ type Player = PlayerAPI;

private convivaVideoAnalytics: Conviva.VideoAnalytics;
private convivaAdAnalytics: Conviva.AdAnalytics;
/**
* Tracks the ad playback status and is true between ON_AD_STARTED and ON_AD_FINISHED/SKIPPED/ERROR.
* Tracks the ad break status and is true between ON_AD_STARTED and ON_AD_FINISHED/SKIPPED/ERROR.
* This flag is required because player.isAd() is unreliable and not always true between the events.
*/
private isAd: boolean;
private isAdBreak: boolean;
/**
* Attributes needed to workaround wrong event order in case of a pre-roll ad.
* See {@link onAdBreakStarted} for more info
* Tracks the last ad break event to get the ad position and other ad break related information
* in the ad started event to report it to Conviva.
*/
private adBreakStartedToFire: AdBreakEvent;
private lastAdBreakEvent: AdBreakEvent;
/**
* Needed to workaround wrong event order in case of a video-playback-quality-change event.
* See {@link onVideoQualityChanged} for more info
*/
private lastSeenBitrate: number;
// Since there are no stall events during play / playing; seek / seeked; timeShift / timeShifted we need
// to track stalling state between those events. To prevent tracking eg. when seeking in buffer we delay it.
private stallTrackingTimout: Timeout = new Timeout(ConvivaAnalytics.STALL_TRACKING_DELAY_MS, () => {
this.convivaVideoAnalytics.reportPlaybackMetric(
Conviva.Constants.Playback.PLAYER_STATE,
Conviva.Constants.PlayerState.BUFFERING,
);
private stallTrackingTimeout: Timeout = new Timeout(ConvivaAnalytics.STALL_TRACKING_DELAY_MS, () => {
if (this.isAdBreak) {
this.debugLog('[ ConvivaAnalytics ] report buffering ad playback state');
this.convivaAdAnalytics.reportAdMetric(
Conviva.Constants.Playback.PLAYER_STATE,
Conviva.Constants.PlayerState.BUFFERING,
);
} else {
this.debugLog('[ ConvivaAnalytics ] report buffering playback state');
this.convivaVideoAnalytics.reportPlaybackMetric(
Conviva.Constants.Playback.PLAYER_STATE,
Conviva.Constants.PlayerState.BUFFERING,
);
}
});

@@ -189,3 +197,3 @@

this.sessionKey = Conviva.Constants.NO_SESSION_KEY;
this.isAd = false;
this.isAdBreak = false;

@@ -240,3 +248,3 @@ const deviceMetadataFromConfig = this.config.deviceMetadata || {};

if (this.isSessionActive()) {
this.logger.consoleLog('There is already a session running.', Conviva.SystemSettings.LogLevel.WARNING);
this.logger.consoleLog('[ ConvivaAnalytics ] There is already a session running.', Conviva.SystemSettings.LogLevel.WARNING);
return;

@@ -256,3 +264,3 @@ }

/**
* Ends the current conviva tracking session.
* Ends the current conviva tracking session. If there an ad break is active it will also report the ad as skipped.
* Results in a no-opt if there is no active session.

@@ -270,3 +278,11 @@ *

this.debugLog('[ ConvivaAnalytics ] report playback ended state');
if (this.isAdBreak) {
this.debugLog('[ ConvivaAdAnalytics ] report ad skipped');
this.convivaAdAnalytics.reportAdSkipped();
}
this.convivaVideoAnalytics.reportPlaybackEnded();
this.internalEndSession();

@@ -284,6 +300,5 @@ this.resetContentMetadata();

public sendCustomApplicationEvent(eventName: string, eventAttributes: EventAttributes = {}): void {
// Check for active session
if (!this.isSessionActive()) {
this.logger.consoleLog(
'cannot send application event, no active monitoring session',
'[ ConvivaAnalytics ] cannot send application event, no active monitoring session',
Conviva.SystemSettings.LogLevel.WARNING,

@@ -294,2 +309,6 @@ );

this.debugLog('[ ConvivaAnalytics ] report custom app event', {
eventName,
eventAttributes,
});
// NOTE Conviva has event attribute capped and 256 bytes for custom events and will show up as a warning

@@ -307,6 +326,5 @@ // in monitoring session if greater than 256 bytes

public sendCustomPlaybackEvent(eventName: string, eventAttributes: EventAttributes = {}): void {
// Check for active session
if (!this.isSessionActive()) {
this.logger.consoleLog(
'cannot send playback event, no active monitoring session',
'[ ConvivaAnalytics ] cannot send playback event, no active monitoring session',
Conviva.SystemSettings.LogLevel.WARNING,

@@ -317,2 +335,6 @@ );

this.debugLog('[ ConvivaAnalytics ] report custom playback event', {
eventName,
eventAttributes,
});
// NOTE Conviva has event attribute capped and 256 bytes for custom events and will show up as a warning

@@ -354,2 +376,5 @@ // in monitoring session if greater than 256 bytes

this.debugLog('[ ConvivaAnalytics ] report playback failed', {
message,
});
this.convivaVideoAnalytics.reportPlaybackFailed(message);

@@ -366,2 +391,3 @@ if (endSession) {

public pauseTracking(): void {
this.debugLog('[ ConvivaAnalytics ] pause tracking via ad break started reporting');
// AdStart is the right way to pause monitoring according to conviva.

@@ -372,3 +398,2 @@ this.convivaVideoAnalytics.reportAdBreakStarted(

);
this.debugLog('Tracking paused.');
}

@@ -380,5 +405,5 @@

public resumeTracking(): void {
this.debugLog('[ ConvivaAnalytics ] resume tracking via ad break ended reporting');
// AdEnd is the right way to resume monitoring according to conviva.
this.convivaVideoAnalytics.reportAdBreakEnded();
this.debugLog('Tracking resumed.');
}

@@ -461,13 +486,27 @@

this.convivaVideoAnalytics = Conviva.Analytics.buildVideoAnalytics();
this.convivaAdAnalytics = Conviva.Analytics.buildAdAnalytics(this.convivaVideoAnalytics);
this.convivaVideoAnalytics.setPlayerInfo({
const playerInfo = {
[Conviva.Constants.FRAMEWORK_NAME]: 'Bitmovin Player',
[Conviva.Constants.FRAMEWORK_VERSION]: this.player.version,
});
};
this.convivaVideoAnalytics.setPlayerInfo(playerInfo);
this.convivaAdAnalytics.setAdPlayerInfo(playerInfo);
this.debugLog('[ ConvivaAnalytics ] report playback requested');
this.convivaVideoAnalytics.reportPlaybackRequested(this.contentMetadataBuilder.build());
this.sessionKey = this.convivaVideoAnalytics.getSessionId();
this.convivaVideoAnalytics.setCallback(() => {
const playheadTimeMs = this.player.getCurrentTime('relativetime' as TimeMode) * 1000;
this.convivaVideoAnalytics.reportPlaybackMetric(Conviva.Constants.Playback.PLAY_HEAD_TIME, playheadTimeMs);
if (this.isAdBreak) {
this.debugLog('[ ConvivaAdAnalytics ] report ad player head time', playheadTimeMs);
this.convivaAdAnalytics.reportAdMetric(Conviva.Constants.Playback.PLAY_HEAD_TIME, playheadTimeMs);
} else {
this.debugLog('[ ConvivaAnalytics ] report player head time', playheadTimeMs);
this.convivaVideoAnalytics.reportPlaybackMetric(Conviva.Constants.Playback.PLAY_HEAD_TIME, playheadTimeMs);
}
});

@@ -480,3 +519,3 @@

this.logger.consoleLog(
'Something went wrong, could not obtain session key',
'[ ConvivaAnalytics ] Something went wrong, could not obtain session key',
Conviva.SystemSettings.LogLevel.ERROR,

@@ -486,11 +525,2 @@ );

this.convivaVideoAnalytics.reportPlaybackMetric(
Conviva.Constants.Playback.PLAYER_STATE,
Conviva.Constants.PlayerState.STOPPED,
);
if (this.lastSeenBitrate) {
this.convivaVideoAnalytics.reportPlaybackMetric(Conviva.Constants.Playback.BITRATE, this.lastSeenBitrate);
}
// Send the session init audio language values.

@@ -566,6 +596,12 @@ this.updateAudioTrack(this.player.getAudio());

this.debugLog('[ ConvivaAnalytics ] end session', Conviva.Constants.NO_SESSION_KEY, event);
this.convivaVideoAnalytics.release();
this.convivaVideoAnalytics = null;
this.convivaVideoAnalytics = null;
this.lastSeenBitrate = null;
this.convivaAdAnalytics.release();
this.convivaAdAnalytics = null;
this.lastAdBreakEvent = null;
this.isAdBreak = false;
};

@@ -582,5 +618,5 @@

private onPlaybackStateChanged = (event: PlayerEventBase) => {
// Do not track playback state changes during ads, (e.g. triggered from IMA)
// or if there is no active session.
if (this.isAd || !this.isSessionActive()) {
this.debugLog('[ Player Event ] playback state change related event', event);
if (!this.isSessionActive()) {
return;

@@ -592,25 +628,9 @@ }

switch (event.type) {
case this.events.Play:
case this.events.Seek:
case this.events.TimeShift:
this.stallTrackingTimout.start();
break;
case this.events.StallStarted:
this.stallTrackingTimout.clear();
playerState = Conviva.Constants.PlayerState.BUFFERING;
break;
case this.events.Playing:
this.stallTrackingTimout.clear();
// In case of a pre-roll ad we need to fire the trackAdBreakStarted right after we got a onPlay
// See onAdBreakStarted for more details.
if (this.adBreakStartedToFire) {
this.trackAdBreakStarted(this.adBreakStartedToFire);
this.adBreakStartedToFire = null;
}
playerState = Conviva.Constants.PlayerState.PLAYING;
break;
case this.events.Paused:
this.stallTrackingTimout.clear();
playerState = Conviva.Constants.PlayerState.PAUSED;

@@ -621,3 +641,2 @@ break;

case this.events.StallEnded:
this.stallTrackingTimout.clear();
if (this.player.isPlaying()) {

@@ -629,15 +648,45 @@ playerState = Conviva.Constants.PlayerState.PLAYING;

break;
case this.events.PlaybackFinished:
this.stallTrackingTimout.clear();
this.convivaVideoAnalytics.reportPlaybackEnded();
break;
}
const stallTrackingStartEvents = [
this.events.Play,
this.events.Seek,
this.events.TimeShift,
];
const stallTrackingClearEvents = [
this.events.StallStarted,
this.events.Playing,
this.events.Paused,
this.events.Seeked,
this.events.TimeShifted,
this.events.StallEnded,
this.events.PlaybackFinished,
];
if (stallTrackingStartEvents.indexOf(event.type) !== -1) {
this.stallTrackingTimeout.start();
} else if (stallTrackingClearEvents.indexOf(event.type) !== -1) {
this.stallTrackingTimeout.clear();
}
if (playerState) {
this.debugLog('[ ConvivaAnalytics ] report playback state', playerState);
this.convivaVideoAnalytics.reportPlaybackMetric(Conviva.Constants.Playback.PLAYER_STATE, playerState);
if (this.isAdBreak) {
this.debugLog('[ ConvivaAdAnalytics ] report ad playback state', playerState);
this.convivaAdAnalytics.reportAdMetric(Conviva.Constants.Playback.PLAYER_STATE, playerState);
} else {
this.debugLog('[ ConvivaAnalytics ] report playback state', playerState);
this.convivaVideoAnalytics.reportPlaybackMetric(Conviva.Constants.Playback.PLAYER_STATE, playerState);
}
}
if (event.type === this.events.PlaybackFinished) {
this.debugLog('[ ConvivaAnalytics ] report playback ended');
this.convivaVideoAnalytics.reportPlaybackEnded();
}
};
private onSourceLoaded = (event: PlayerEventBase) => {
this.debugLog('[ Player Event ] source loaded', event);
// In case the session was created external before loading the source

@@ -655,3 +704,3 @@ if (!this.isSessionActive()) {

if (this.isAd) {
if (this.isAdBreak) {
// Do not track play event during ad (e.g. triggered from IMA)

@@ -684,7 +733,13 @@ return;

this.onPlaybackStateChanged(event);
this.convivaVideoAnalytics.release();
this.convivaVideoAnalytics = null;
this.convivaAdAnalytics.release();
this.convivaAdAnalytics = null;
};
private onVideoQualityChanged = (event: VideoQualityChangedEvent) => {
this.debugLog('[ Player Event ] video quality changed', event);
// We calculate the bitrate with a divisor of 1000 so the values look nicer

@@ -694,11 +749,6 @@ // Example: 250000 / 1000 => 250 kbps (250000 / 1024 => 244kbps)

if (!this.isSessionActive()) {
// Since the first videoPlaybackQualityChanged event comes before playback ever started we need to store the
// value and use it for tracking when initializing the session.
// TODO: remove this workaround when the player event order is fixed
this.lastSeenBitrate = bitrateKbps;
return;
}
this.lastSeenBitrate = null;
this.debugLog('[ ConvivaAnalytics ] report bitrate', {
event,
bitrateKbps,
});
this.convivaVideoAnalytics.reportPlaybackMetric(Conviva.Constants.Playback.BITRATE, bitrateKbps);

@@ -708,4 +758,6 @@ };

private onCustomEvent = (event: PlayerEventBase) => {
this.debugLog('[ Player Event ] custom playback related event', event);
if (!this.isSessionActive()) {
this.debugLog('skip custom event, no session existing', event);
this.debugLog('[ ConvivaAnalytics ] skip custom event, no session existing', event);
return;

@@ -718,13 +770,9 @@ }

private trackAdBreakStarted = (event: AdBreakEvent) => {
this.debugLog('[ ConvivaAnalytics ] adbreak started', event);
this.isAd = true;
private onAdBreakStarted = (event: AdBreakEvent) => {
this.debugLog('[ Player Event ] adbreak started', event);
const adPosition = AdBreakHelper.mapAdPosition(event.adBreak, this.player);
this.isAdBreak = true;
this.lastAdBreakEvent = event;
if (!this.isSessionActive()) {
// Don't report without a valid session (e.g., in case of a pre-roll, or post-roll ad)
return;
}
this.debugLog('[ ConvivaAnalytics ] report ad break started', event);
this.convivaVideoAnalytics.reportAdBreakStarted(

@@ -736,12 +784,49 @@ Conviva.Constants.AdType.CLIENT_SIDE,

private onAdBreakFinished = (event: AdBreakEvent | ErrorEvent) => {
this.debugLog('[ ConvivaAnalytics ] adbreak finished', event);
this.isAd = false;
private onAdStarted = (event: AdEvent) => {
this.debugLog('[ Player Event ] ad started', event);
if (!this.isSessionActive()) {
// Don't report without a valid session (e.g., in case of a pre-roll, or post-roll ad)
return;
const adInfo = AdHelper.extractConvivaAdInfo(this.player, this.lastAdBreakEvent, event);
const bitrateKbps = event.ad.data?.bitrate;
this.debugLog('[ ConvivaAdAnalytics ] report ad started', {
event,
adInfo,
});
this.convivaAdAnalytics.reportAdStarted(adInfo);
this.debugLog('[ ConvivaAdAnalytics ] report playing ad playback state');
this.convivaAdAnalytics.reportAdMetric(Conviva.Constants.Playback.PLAYER_STATE, Conviva.Constants.PlayerState.PLAYING);
if (bitrateKbps) {
this.debugLog('[ ConvivaAdAnalytics ] report ad bitrate', bitrateKbps);
this.convivaAdAnalytics.reportAdMetric(Conviva.Constants.Playback.BITRATE, bitrateKbps);
}
}
private onAdFinished = (event: AdEvent) => {
this.debugLog('[ Player Event ] ad finished', event);
this.debugLog('[ ConvivaAdAnalytics ] report ad ended', {
event,
});
this.convivaAdAnalytics.reportAdEnded();
}
private onAdSkipped = (event: AdEvent) => {
this.debugLog('[ Player Event ] ad skipped', event);
this.debugLog('[ ConvivaAdAnalytics ] report ad skipped', event);
this.convivaAdAnalytics.reportAdSkipped();
this.onCustomEvent(event);
};
private onAdBreakFinished = (event: AdBreakEvent | ErrorEvent) => {
this.debugLog('[ Player Event ] adbreak finished', event);
this.isAdBreak = false;
this.debugLog('[ ConvivaAnalytics ] report ad break ended', event);
this.convivaVideoAnalytics.reportAdBreakEnded();
this.debugLog('[ ConvivaAnalytics ] report playing playback state');
this.convivaVideoAnalytics.reportPlaybackMetric(

@@ -753,7 +838,13 @@ Conviva.Constants.Playback.PLAYER_STATE,

private onAdSkipped = (event: AdEvent) => {
this.onCustomEvent(event);
};
private onAdError = (event: ErrorEvent) => {
this.debugLog('[ Player Event ] ad error', event);
private onAdError = (event: AdEvent) => {
const formattedError = AdHelper.formatAdErrorEvent(event);
this.debugLog('[ ConvivaAdAnalytics ] report ad error', {
event,
formattedError,
});
this.convivaAdAnalytics.reportAdError(formattedError, Conviva.Constants.ErrorSeverity.WARNING);
this.onCustomEvent(event);

@@ -763,2 +854,4 @@ };

private onSeek = (event: SeekEvent) => {
this.debugLog('[ Player Event ] seek', event);
if (!this.isSessionActive()) {

@@ -775,2 +868,4 @@ // Handle the case that the User seeks on the UI before play was triggered.

private onSeeked = (event: SeekEvent) => {
this.debugLog('[ Player Event ] seeked', event);
if (!this.isSessionActive()) {

@@ -786,2 +881,4 @@ // See comment in onSeek

private onTimeShift = (event: TimeShiftEvent) => {
this.debugLog('[ Player Event ] time shift', event);
if (!this.isSessionActive()) {

@@ -798,2 +895,4 @@ // See comment in onSeek

private onTimeShifted = (event: TimeShiftEvent) => {
this.debugLog('[ Player Event ] time shifted', event);
if (!this.isSessionActive()) {

@@ -809,2 +908,3 @@ // See comment in onSeek

private trackSeekStart(target: number) {
this.debugLog('[ ConvivaAnalytics ] report seek started');
this.convivaVideoAnalytics.reportPlaybackMetric(Conviva.Constants.Playback.SEEK_STARTED);

@@ -814,5 +914,8 @@ }

private trackSeekEnd() {
this.debugLog('[ ConvivaAnalytics ] report seek ended');
this.convivaVideoAnalytics.reportPlaybackMetric(Conviva.Constants.Playback.SEEK_ENDED);
}
private onAudioChanged = (event: AudioChangedEvent) => {
this.debugLog('[ Player Event ] audio changed', event);
if (!this.isSessionActive()) {

@@ -829,2 +932,6 @@ // Handle the case that the User change audio on the UI before play was triggered.

audioTrack.lang !== 'unknown' ? '[' + audioTrack.lang + ']:' + audioTrack.label : audioTrack.label;
this.debugLog('[ ConvivaAnalytics ] report audio language', {
formattedAudio,
});
this.convivaVideoAnalytics.reportPlaybackMetric(Conviva.Constants.Playback.AUDIO_LANGUAGE, formattedAudio);

@@ -834,2 +941,4 @@ }

private onSubtitleEnabled = (event: SubtitleEvent) => {
this.debugLog('[ Player Event ] subtitled enabled', event);
if (!this.isSessionActive()) {

@@ -847,6 +956,13 @@ // Handle the case that the User change subtitle on the UI before play was triggered.

if (subtitleTrack.kind === 'subtitles') {
this.debugLog('[ ConvivaAnalytics ] report subtitles language', {
formattedSubtitle,
});
this.convivaVideoAnalytics.reportPlaybackMetric(Conviva.Constants.Playback.SUBTITLES_LANGUAGE, formattedSubtitle);
this.debugLog('[ ConvivaAnalytics ] report off closed captions language');
this.convivaVideoAnalytics.reportPlaybackMetric(Conviva.Constants.Playback.CLOSED_CAPTIONS_LANGUAGE, 'off');
} else if (subtitleTrack.kind === 'captions') {
this.debugLog('[ ConvivaAnalytics ] report closed captions language', {
formattedSubtitle,
});
this.convivaVideoAnalytics.reportPlaybackMetric(

@@ -857,2 +973,3 @@ Conviva.Constants.Playback.CLOSED_CAPTIONS_LANGUAGE,

this.debugLog('[ ConvivaAnalytics ] report off subtitles language');
this.convivaVideoAnalytics.reportPlaybackMetric(Conviva.Constants.Playback.SUBTITLES_LANGUAGE, 'off');

@@ -865,2 +982,4 @@ } else {

private onSubtitleDisabled = (event: SubtitleEvent) => {
this.debugLog('[ Player Event ] subtitles disabled', event);
if (!this.isSessionActive()) {

@@ -889,4 +1008,6 @@ // Handle the case that the User turn off subtitle on the UI before play was triggered.

private turnOffSubtitles() {
this.debugLog('[ ConvivaAnalytics ] report off subtitles language');
this.convivaVideoAnalytics.reportPlaybackMetric(Conviva.Constants.Playback.SUBTITLES_LANGUAGE, 'off');
this.debugLog('[ ConvivaAnalytics ] report off closed captions language');
this.convivaVideoAnalytics.reportPlaybackMetric(Conviva.Constants.Playback.CLOSED_CAPTIONS_LANGUAGE, 'off');

@@ -896,2 +1017,4 @@ }

private onError = (event: ErrorEvent) => {
this.debugLog('[ Player Event ] error', event);
if (!this.isSessionActive() && !this.sessionEndedExternally) {

@@ -906,3 +1029,5 @@ // initialize Session if not yet initialized to capture Video Start Failures

private onSourceUnloaded = (event: PlayerEventBase) => {
if (this.isAd) {
this.debugLog('[ Player Event ] source unloaded', event);
if (this.isAdBreak) {
// Ignore sourceUnloaded events during ads

@@ -917,2 +1042,4 @@ return;

private onDestroy = (event: any) => {
this.debugLog('[ Player Event ] destroy', event);
this.destroy(event);

@@ -936,2 +1063,4 @@ };

playerEvents.add(this.events.ViewModeChanged, this.onCustomEvent);
playerEvents.add(this.events.AdStarted, this.onAdStarted);
playerEvents.add(this.events.AdFinished, this.onAdFinished);
playerEvents.add(this.events.AdBreakStarted, this.onAdBreakStarted);

@@ -956,31 +1085,2 @@ playerEvents.add(this.events.AdBreakFinished, this.onAdBreakFinished);

private onAdBreakStarted = (event: AdBreakEvent) => {
// Specific post-roll handling
const isPostRollAdBreak = (adBreak: AdBreak) => {
return adBreak.scheduleTime === Infinity;
};
if (isPostRollAdBreak(event.adBreak)) {
// Fire playbackFinished in case of a post-roll ad to stop session and do not track post roll ad
this.debugLog('[ ConvivaAnalytics ] detected post-roll ad ... Ending session');
this.onPlaybackFinished({
timestamp: Date.now(),
type: this.events.PlaybackFinished,
});
return;
}
// Specific pre-roll handling
// TODO: remove this workaround when event order is correct
// Since the event order on initial playback in case of a pre-roll ad is false we need to workaround
// a to early triggered adBreakStarted event. The initial onPlay event is called after the AdBreakStarted
// of the pre-roll ad so we won't initialize a session. Therefore we save the adBreakStarted event and
// trigger it in the initial onPlay event (after initializing the session). (See #onPlaybackStateChanged)
if (!this.isSessionActive()) {
this.adBreakStartedToFire = event;
} else {
this.trackAdBreakStarted(event);
}
};
private unregisterPlayerEvents(): void {

@@ -987,0 +1087,0 @@ this.handlers.clear();

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc