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
0
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.1.0 to 5.2.0

.github/scripts/defineVersion.js

77

CHANGELOG.md

@@ -10,4 +10,10 @@ # Changelog

## 5.1.0 - 2024-06-13
## [5.2.0] - 2024-07-08
### Added
- Server side ad tracking
- It is exposed via `ConvivaAnalytics.ssai`
- An example can be found in `examples/index.html`
## [5.1.0] - 2024-06-13
### Added
- Basic client ad tracking using `Conviva.AdAnalytics`

@@ -18,3 +24,3 @@

## 5.0.0 - 2024-05-21
## [5.0.0] - 2024-05-21
### Added

@@ -31,3 +37,3 @@ - Send player info metadata (framework and framework version)

## 4.2.0 - 2023-08-24
## [4.2.0] - 2023-08-24
### Added

@@ -42,15 +48,13 @@ - Support for Conviva-SDK version 4.7.0

## v4.1.0 - 2022-10-24
## [4.1.0] - 2022-10-24
### Added
- Support for Conviva-SDK version 4.5.7
### Fixed
- Consecutive playback of multiple sources not tracked correctly
### Removed
- Support for Conviva-SDK version 4.0.15
## 4.0.3 - 2021-04-30
### Fixed
- Consecutive playback of multiple sources not tracked correctly
## [4.0.3] - 2021-04-30
### Added

@@ -64,14 +68,11 @@ - `bitmovin-player@^8.31.0` as peer dependency.

## 4.0.2 - 2021-02-24
## [4.0.2] - 2021-02-24
### Fixed
- Metadata was cleared after playback finished.
## 4.0.1 - 2021-02-01
## [4.0.1] - 2021-02-01
### Fixed
- Uncaught TypeError (`Cannot read property 'release' of null`) when attempting to release the Conviva instance.
## 4.0.0 - 2021-01-15
## [4.0.0] - 2021-01-15
### Added

@@ -83,34 +84,27 @@ - Support for Conviva-SDK 4.0.15.

## 3.0.6 - 2020-04-16
## [3.0.6] - 2020-04-16
### Fixed
- Prefer `window.setInterval()` in `Html5Timer.ts` instead of the NodeJS definition.
## 3.0.5 - 2020-03-30
## [3.0.5] - 2020-03-30
### Fixed
- Updated `webpack-dev-server` to the latest version, to resolve console errors when running locally via `npm run start`.
## 3.0.4 - 2020-03-05
## [3.0.4] - 2020-03-05
### Fixed
- Send playing event after an ad break has finished.
## 3.0.3 - 2020-02-05
## [3.0.3] - 2020-02-05
### Added
- Added a configuration option to set the Conviva Device Category.
- Added a configuration option to set the Conviva Device Category.
## 3.0.2 - 2019-10-23
## [3.0.2] - 2019-10-23
### Added
- `endSession` will now prevent a new session from being initialized via internal event handling.
## 3.0.1 - 2019-05-16
## [3.0.1] - 2019-05-16
### Added
- Support for Conviva-SDK 2.151.0.36981.
## 3.0.0 - 2019-03-15
## [3.0.0] - 2019-03-15
### Added

@@ -130,4 +124,3 @@ - `initializeSession` to external start session.

## 2.1.0 - 2019-01-17
## [2.1.0] - 2019-01-17
### Added

@@ -138,3 +131,2 @@ - `integrationVersion` as custom `contentMetadata` attribute

## 2.0.0 - 2018-12-13
### Added

@@ -150,1 +142,20 @@ - Tracking of `autoplay` and `preload` config attributes.

- Seek event tracking
[Unreleased]: https://github.com/bitmovin/bitmovin-player-analytics-conviva/compare/v5.2.0...HEAD
[5.2.0]: https://github.com/bitmovin/bitmovin-player-analytics-conviva/compare/v5.1.0...v5.2.0
[5.1.0]: https://github.com/bitmovin/bitmovin-player-analytics-conviva/compare/v5.0.0...v5.1.0
[5.0.0]: https://github.com/bitmovin/bitmovin-player-analytics-conviva/compare/v4.2.0...v5.0.0
[4.2.0]: https://github.com/bitmovin/bitmovin-player-analytics-conviva/compare/v4.1.0...v4.2.0
[4.1.0]: https://github.com/bitmovin/bitmovin-player-analytics-conviva/compare/v4.0.3...v4.1.0
[4.0.3]: https://github.com/bitmovin/bitmovin-player-analytics-conviva/compare/v4.0.2...v4.0.3
[4.0.2]: https://github.com/bitmovin/bitmovin-player-analytics-conviva/compare/v4.0.1...v4.0.2
[4.0.1]: https://github.com/bitmovin/bitmovin-player-analytics-conviva/compare/v4.0.0...v4.0.1
[4.0.0]: https://github.com/bitmovin/bitmovin-player-analytics-conviva/compare/v3.0.6...v4.0.0
[3.0.6]: https://github.com/bitmovin/bitmovin-player-analytics-conviva/compare/v3.0.5...v3.0.6
[3.0.5]: https://github.com/bitmovin/bitmovin-player-analytics-conviva/compare/v3.0.4...v3.0.5
[3.0.4]: https://github.com/bitmovin/bitmovin-player-analytics-conviva/compare/v3.0.3...v3.0.4
[3.0.3]: https://github.com/bitmovin/bitmovin-player-analytics-conviva/compare/v3.0.2...v3.0.3
[3.0.2]: https://github.com/bitmovin/bitmovin-player-analytics-conviva/compare/v3.0.1...v3.0.2
[3.0.1]: https://github.com/bitmovin/bitmovin-player-analytics-conviva/compare/v3.0.0...v3.0.1
[3.0.0]: https://github.com/bitmovin/bitmovin-player-analytics-conviva/compare/v2.1.0...v3.0.0
[2.1.0]: https://github.com/bitmovin/bitmovin-player-analytics-conviva/compare/v2.0.0...v2.1.0

@@ -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.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}])});
!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(i){if(e[i])return e[i].exports;var n=e[i]={i:i,l:!1,exports:{}};return t[i].call(n.exports,n,n.exports,a),n.l=!0,n.exports}return a.m=t,a.c=e,a.d=function(t,e,i){a.o(t,e)||Object.defineProperty(t,e,{enumerable:!0,get:i})},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 i=Object.create(null);if(a.r(i),Object.defineProperty(i,"default",{enumerable:!0,value:t}),2&e&&"string"!=typeof t)for(var n in t)a.d(i,n,function(e){return t[e]}.bind(null,n));return i},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=4)}([function(e,a){e.exports=t},function(t,e,a){"use strict";var i=this&&this.__assign||function(){return(i=Object.assign||function(t){for(var e,a=1,i=arguments.length;a<i;a++)for(var n in e=arguments[a])Object.prototype.hasOwnProperty.call(e,n)&&(t[n]=e[n]);return t}).apply(this,arguments)};Object.defineProperty(e,"__esModule",{value:!0}),e.AdHelper=void 0;var n=a(0),s=a(2),o=function(){function t(){}return t.mapCsaiAdPosition=function(t,e){return t.scheduleTime<=0?n.Constants.AdPosition.PREROLL:t.scheduleTime>=e.getDuration()?n.Constants.AdPosition.POSTROLL:n.Constants.AdPosition.MIDROLL},t.formatCsaiAdError=function(t){var e,a,i=(null==t?void 0:t.message)||"Unknown message",n=(null==t?void 0:t.name)||"Unknown name";return["Ad error:","".concat(n,";"),(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(i,";"),"Error code: ".concat(t.code,";"),t.troubleShootLink?"Troubleshoot link: ".concat(t.troubleShootLink):void 0].filter(Boolean).join(" ")},t.extractCsaiConvivaAdInfo=function(e,a,i){var s,o,r,c=i.ad,d=c.data,l="NA",v="NA",u="NA",y=c.id;d&&("adSystem"in d&&(null===(o=d.adSystem)||void 0===o?void 0:o.name)&&(l=d.adSystem.name),"creative"in d&&(null===(r=null==d?void 0:d.creative)||void 0===r?void 0:r.id)&&(v=d.creative.id),"adTitle"in d&&d.adTitle&&(u=d.adTitle),"wrapperAdIds"in d&&d.wrapperAdIds&&d.wrapperAdIds.length&&(y=d.wrapperAdIds[d.wrapperAdIds.length-1]));var A=((s={"c3.ad.id":c.id,"c3.ad.technology":n.Constants.AdType.CLIENT_SIDE,"c3.ad.position":t.mapCsaiAdPosition(a.adBreak,e),"c3.ad.system":l,"c3.ad.creativeId":v,"c3.ad.firstAdId":y})[n.Constants.ASSET_NAME]=u,s[n.Constants.STREAM_URL]=c.mediaFileUrl||"NA",s["c3.ad.mediaFileApiFramework"]="NA",s["c3.ad.firstAdSystem"]="NA",s["c3.ad.firstCreativeId"]="NA",s);return"duration"in c&&c.duration&&(A[n.Constants.DURATION]=c.duration),A},t.convertSsaiAdInfoToConvivaAdInfo=function(t,e){var a,o=[s.INTEGRATION_VERSION_CONTENT_METADATA_CUSTOM_TAG,s.STREAM_TYPE_CONTENT_METADATA_CUSTOM_TAG,n.Constants.ASSET_NAME,n.Constants.IS_LIVE,n.Constants.DEFAULT_RESOURCE,n.Constants.ENCODED_FRAMERATE,n.Constants.VIEWER_ID,n.Constants.PLAYER_NAME],r={};o.forEach(function(t){r[t]=e[t]});var c=i(i(i({},r),t.additionalMetadata),((a={"c3.ad.id":t.id,"c3.ad.technology":n.Constants.AdType.SERVER_SIDE,"c3.ad.position":t.position||"NA","c3.ad.system":t.adSystem||"NA"})[n.Constants.ASSET_NAME]=t.title||r[n.Constants.ASSET_NAME]||"NA",a["c3.ad.adStitcher"]=t.adStitcher||"NA",a["c3.ad.isSlate"]=void 0===t.isSlate?"NA":t.isSlate.toString(),a));return t.duration&&(c[n.Constants.DURATION]=t.duration),c},t}();e.AdHelper=o},function(t,e,a){"use strict";Object.defineProperty(e,"__esModule",{value:!0}),e.ConvivaAnalyticsTracker=e.VR_CONTENT_TYPE_CONTENT_METADATA_CUSTOM_TAG=e.STREAM_TYPE_CONTENT_METADATA_CUSTOM_TAG=e.PLAYER_TYPE_CONTENT_METADATA_CUSTOM_TAG=e.INTEGRATION_VERSION_CONTENT_METADATA_CUSTOM_TAG=e.PRELOAD_CONTENT_METADATA_CUSTOM_TAG=e.AUTOPLAY_CONTENT_METADATA_CUSTOM_TAG=void 0;var i=a(0),n=a(8),s=a(9),o=a(10),r=a(11),c=a(12),d=a(13),l=a(14),v=a(1),u=a(3),y=a(16),A=a(18);e.AUTOPLAY_CONTENT_METADATA_CUSTOM_TAG="autoplay",e.PRELOAD_CONTENT_METADATA_CUSTOM_TAG="preload",e.INTEGRATION_VERSION_CONTENT_METADATA_CUSTOM_TAG="integrationVersion",e.PLAYER_TYPE_CONTENT_METADATA_CUSTOM_TAG="playerType",e.STREAM_TYPE_CONTENT_METADATA_CUSTOM_TAG="streamType",e.VR_CONTENT_TYPE_CONTENT_METADATA_CUSTOM_TAG="vrContentType";var p=function(){function t(e,a,y){var p;void 0===y&&(y={});var h=this;if(this.stallTrackingTimeout=new d.Timeout(t.STALL_TRACKING_DELAY_MS,function(){h._isAdBreakActive?(h.debugLog("[ ConvivaAnalyticsTracker ] report buffering ad playback state"),h.convivaAdAnalytics.reportAdMetric(i.Constants.Playback.PLAYER_STATE,i.Constants.PlayerState.BUFFERING)):(h.debugLog("[ ConvivaAnalyticsTracker ] report buffering playback state"),h.convivaVideoAnalytics.reportPlaybackMetric(i.Constants.Playback.PLAYER_STATE,i.Constants.PlayerState.BUFFERING))}),this.sessionEndedExternally=!1,this.internalEndSession=function(t){h.isSessionActive()&&(h.debugLog("[ ConvivaAnalyticsTracker ] end session",i.Constants.NO_SESSION_KEY,t),h.convivaVideoAnalytics.release(),h.convivaVideoAnalytics=null,h.convivaAdAnalytics.release(),h.convivaAdAnalytics=null,h._isAdBreakActive=!1)},this.onSourceLoaded=function(t){h.debugLog("[ ConvivaAnalyticsTracker ] [ Player Event ] source loaded",t),h.isSessionActive()&&(h.buildSourceRelatedMetadata(h.player.getSource()),h.updateSession())},this.onPlay=function(t){h.debugLog("[ ConvivaAnalyticsTracker ] [ Player Event ] play"),h.canTrackPlayEvent&&(h.isSessionActive()||h.sessionEndedExternally||h.internalInitializeSession())},this.onPlaying=function(t){h.debugLog("[ ConvivaAnalyticsTracker ] [ Player Event ] playing",t),h.isSessionActive()&&(h.contentMetadataBuilder.setPlaybackStarted(!0),h.updateSession())},this.onPlaybackFinished=function(t){h.debugLog("[ ConvivaAnalyticsTracker ] [ Player Event ] playback finished",t),h.isSessionActive()&&(h.convivaVideoAnalytics.release(),h.convivaVideoAnalytics=null,h.convivaAdAnalytics.release(),h.convivaAdAnalytics=null)},this.trackVideoQualityChanged=function(t){if(h.isSessionActive()){var e=Math.round(t.targetQuality.bitrate/1e3);h.debugLog("[ ConvivaAnalyticsTracker ] report bitrate",{event:t,bitrateKbps:e}),h.convivaVideoAnalytics.reportPlaybackMetric(i.Constants.Playback.BITRATE,e)}},this.trackAdBreakStarted=function(t){h.isSessionActive()&&(h._isAdBreakActive=!0,h.debugLog("[ ConvivaAnalyticsTracker ] report ad break started",{type:t}),h.convivaVideoAnalytics.reportAdBreakStarted(t,t===i.Constants.AdType.CLIENT_SIDE?i.Constants.AdPlayer.SEPARATE:i.Constants.AdPlayer.CONTENT))},this.trackAdStarted=function(t,e,a){if(h.isSessionActive()){if(h.debugLog("[ ConvivaAnalyticsTracker ] report ad started",{adInfo:t,type:e,bitrateKbps:a}),h.convivaAdAnalytics.reportAdStarted(t),h.debugLog("[ ConvivaAnalyticsTracker ] report ".concat(A.PlayerStateHelper.getPlayerState(h.player)," ad playback state")),h.convivaAdAnalytics.reportAdMetric(i.Constants.Playback.PLAYER_STATE,A.PlayerStateHelper.getPlayerState(h.player)),e===i.Constants.AdType.SERVER_SIDE){var n=h.player.getPlaybackVideoData(),s="".concat(n.width,"x").concat(n.height);h.debugLog("[ ConvivaAnalyticsTracker ] report ad resolution",s),h.convivaAdAnalytics.reportAdMetric(i.Constants.Playback.RESOLUTION,s),n.frameRate&&(h.debugLog("[ ConvivaAnalyticsTracker ] report framerate",n.frameRate),h.convivaAdAnalytics.reportAdMetric(i.Constants.Playback.RENDERED_FRAMERATE,n.frameRate))}a&&(h.debugLog("[ ConvivaAnalyticsTracker ] report ad bitrate",a),h.convivaAdAnalytics.reportAdMetric(i.Constants.Playback.BITRATE,a))}},this.trackAdFinished=function(){h.isSessionActive()&&(h.debugLog("[ ConvivaAnalyticsTracker ] report ad ended"),h.convivaAdAnalytics.reportAdEnded())},this.trackAdSkipped=function(){h.isSessionActive()&&(h.debugLog("[ ConvivaAnalyticsTracker ] report ad skipped"),h.convivaAdAnalytics.reportAdSkipped())},this.trackAdBreakFinished=function(){h.isSessionActive()&&(h._isAdBreakActive=!1,h.debugLog("[ ConvivaAnalyticsTracker ] report ad break ended"),h.convivaVideoAnalytics.reportAdBreakEnded(),h.debugLog("[ ConvivaAnalyticsTracker ] report ".concat(A.PlayerStateHelper.getPlayerState(h.player)," playback state")),h.convivaVideoAnalytics.reportPlaybackMetric(i.Constants.Playback.PLAYER_STATE,A.PlayerStateHelper.getPlayerState(h.player)))},this.trackAdError=function(t){if(h.isSessionActive()){var e=v.AdHelper.formatCsaiAdError(t);h.debugLog("[ ConvivaAnalyticsTracker ] report ad error",{event:t,formattedError:e}),h.convivaAdAnalytics.reportAdError(e,i.Constants.ErrorSeverity.WARNING)}},this.trackError=function(t){h.isSessionActive()||h.sessionEndedExternally||h.internalInitializeSession(),h.debugLog("[ ConvivaAnalyticsTracker ] report playback deficiency",t),h.reportPlaybackDeficiency(String(t.code)+" "+t.name,i.Constants.ErrorSeverity.FATAL)},this.onSourceUnloaded=function(t){h.debugLog("[ ConvivaAnalyticsTracker ] [ Player Event ] source unloaded",t),h._isAdBreakActive||(h.internalEndSession(t),h.resetContentMetadata())},this.onDestroy=function(t){h.debugLog("[ ConvivaAnalyticsTracker ] [ Player Event ] destroy",t),h.release(t)},void 0!==i)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 u.PlayerEventWrapper(e),this.config=y,this.config.debugLoggingEnabled=this.config.debugLoggingEnabled||!1,this.logger=new s.Html5Logging,this.sessionKey=i.Constants.NO_SESSION_KEY,this._isAdBreakActive=!1;var g=this.config.deviceMetadata||{},f=((p={})[i.Constants.DeviceMetadata.CATEGORY]=g.category||this.config.deviceCategory||i.Constants.DeviceCategory.WEB,p[i.Constants.DeviceMetadata.BRAND]=g.brand,p[i.Constants.DeviceMetadata.MANUFACTURER]=g.manufacturer,p[i.Constants.DeviceMetadata.MODEL]=g.model,p[i.Constants.DeviceMetadata.TYPE]=g.type,p[i.Constants.DeviceMetadata.VERSION]=g.version,p[i.Constants.DeviceMetadata.OS_NAME]=g.osName,p[i.Constants.DeviceMetadata.OS_VERSION]=g.osVersion,p);i.Analytics.setDeviceMetadata(f);var T={};T[i.Constants.CallbackFunctions.CONSOLE_LOG]=this.logger.consoleLog,T[i.Constants.CallbackFunctions.MAKE_REQUEST]=(new n.Html5Http).makeRequest;var S=new o.Html5Storage;T[i.Constants.CallbackFunctions.SAVE_DATA]=S.saveData,T[i.Constants.CallbackFunctions.LOAD_DATA]=S.loadData,T[i.Constants.CallbackFunctions.CREATE_TIMER]=(new c.Html5Timer).createTimer,T[i.Constants.CallbackFunctions.GET_EPOCH_TIME_IN_MS]=(new r.Html5Time).getEpochTimeMs;var k={};k[i.Constants.GATEWAY_URL]=y.gatewayUrl,k[i.Constants.LOG_LEVEL]=this.config.debugLoggingEnabled?i.Constants.LogLevel.DEBUG:i.Constants.LogLevel.NONE,i.Analytics.init(a,T,k),this.contentMetadataBuilder=new l.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 Object.defineProperty(t.prototype,"isAdBreakActive",{get:function(){return this._isAdBreakActive},enumerable:!1,configurable:!0}),Object.defineProperty(t.prototype,"canTrackPlayEvent",{get:function(){return!this._isAdBreakActive},enumerable:!1,configurable:!0}),t.prototype.getContentMetadata=function(){return this.contentMetadataBuilder.build()},t.prototype.initializeSession=function(){if(this.isSessionActive())this.logger.consoleLog("[ ConvivaAnalyticsTracker ] There is already a session running.",i.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._isAdBreakActive&&(this.debugLog("[ ConvivaAnalyticsTracker ] report ad skipped"),this.convivaAdAnalytics.reportAdSkipped()),this.debugLog("[ ConvivaAnalyticsTracker ] report playback ended state"),this.convivaVideoAnalytics.reportPlaybackEnded(),this.internalEndSession(),this.resetContentMetadata(),this.sessionEndedExternally=!0)},t.prototype.sendCustomApplicationEvent=function(t,e){void 0===e&&(e={}),this.isSessionActive()?(this.debugLog("[ ConvivaAnalyticsTracker ] report custom app event",{eventName:t,eventAttributes:e}),this.convivaVideoAnalytics.reportAppEvent(t,e)):this.logger.consoleLog("[ ConvivaAnalyticsTracker ] cannot send application event, no active monitoring session",i.SystemSettings.LogLevel.WARNING)},t.prototype.sendCustomPlaybackEvent=function(t,e){void 0===e&&(e={}),this.isSessionActive()?(this.debugLog("[ ConvivaAnalyticsTracker ] report custom playback event",{eventName:t,eventAttributes:e}),this.convivaVideoAnalytics.reportPlaybackEvent(t,e)):this.logger.consoleLog("[ ConvivaAnalyticsTracker ] cannot send playback event, no active monitoring session",i.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("[ ConvivaAnalyticsTracker ] report playback failed",{message:t}),this.convivaVideoAnalytics.reportPlaybackFailed(t),a&&(this.internalEndSession(),this.resetContentMetadata()))},t.prototype.pauseTracking=function(){this.debugLog("[ ConvivaAnalyticsTracker ] pause tracking via ad break started reporting"),this.convivaVideoAnalytics.reportAdBreakStarted(i.Constants.AdType.CLIENT_SIDE,i.Constants.AdPlayer.SEPARATE)},t.prototype.resumeTracking=function(){this.debugLog("[ ConvivaAnalyticsTracker ] resume tracking via ad break ended reporting"),this.convivaVideoAnalytics.reportAdBreakEnded()},t.prototype.release=function(t){this.debugLog("[ ConvivaAnalyticsTracker ] releasing",t),this.unregisterPlayerEvents(),this.internalEndSession(t),i.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("[ ConvivaAnalyticsTracker ] no active session. Content metadata will be propagated to Conviva on session initialization.",i.SystemSettings.LogLevel.DEBUG)},t.prototype.internalInitializeSession=function(){var t,e=this;this.debugLog("[ ConvivaAnalyticsTracker ] initializing session"),this.buildContentMetadata(),this.convivaVideoAnalytics=i.Analytics.buildVideoAnalytics(),this.convivaAdAnalytics=i.Analytics.buildAdAnalytics(this.convivaVideoAnalytics);var a=((t={})[i.Constants.FRAMEWORK_NAME]="Bitmovin Player",t[i.Constants.FRAMEWORK_VERSION]=this.player.version,t);this.convivaVideoAnalytics.setPlayerInfo(a),this.convivaAdAnalytics.setAdPlayerInfo(a),this.debugLog("[ ConvivaAnalyticsTracker ] report playback requested"),this.convivaVideoAnalytics.reportPlaybackRequested(this.contentMetadataBuilder.build()),this.sessionKey=this.convivaVideoAnalytics.getSessionId(),this.debugLog("[ ConvivaAnalyticsTracker ] new session key",this.sessionKey),this.convivaVideoAnalytics.setCallback(function(){var t=1e3*e.player.getCurrentTime("relativetime");e._isAdBreakActive?(e.debugLog("[ ConvivaAnalyticsTracker ] report ad player head time",t),e.convivaAdAnalytics.reportAdMetric(i.Constants.Playback.PLAY_HEAD_TIME,t)):(e.debugLog("[ ConvivaAnalyticsTracker ] report player head time",t),e.convivaVideoAnalytics.reportPlaybackMetric(i.Constants.Playback.PLAY_HEAD_TIME,t))}),this.isSessionActive()||this.logger.consoleLog("[ ConvivaAnalyticsTracker ] Something went wrong, could not obtain session key",i.SystemSettings.LogLevel.ERROR),this.trackUpdateAudioTrack(this.player.getAudio()),this.trackSubtitleWhenInternalInitialize()},t.prototype.buildContentMetadata=function(){var a;this.contentMetadataBuilder.duration=this.player.getDuration(),this.contentMetadataBuilder.streamType=this.player.isLive()?i.ContentMetadata.StreamType.LIVE:i.ContentMetadata.StreamType.VOD,this.contentMetadataBuilder.addToCustom(((a={})[e.AUTOPLAY_CONTENT_METADATA_CUSTOM_TAG]=y.PlayerConfigHelper.getAutoplayConfig(this.player)+"",a[e.PRELOAD_CONTENT_METADATA_CUSTOM_TAG]=y.PlayerConfigHelper.getPreloadConfig(this.player)+"",a[e.INTEGRATION_VERSION_CONTENT_METADATA_CUSTOM_TAG]=t.VERSION,a));var n=this.player.getSource();n&&this.buildSourceRelatedMetadata(n)},t.prototype.buildSourceRelatedMetadata=function(t){var a;this.contentMetadataBuilder.assetName=this.getAssetNameFromSource(t),this.contentMetadataBuilder.viewerId=this.contentMetadataBuilder.viewerId,this.contentMetadataBuilder.addToCustom(((a={})[e.PLAYER_TYPE_CONTENT_METADATA_CUSTOM_TAG]=this.player.getPlayerType(),a[e.STREAM_TYPE_CONTENT_METADATA_CUSTOM_TAG]=this.player.getStreamType(),a[e.VR_CONTENT_TYPE_CONTENT_METADATA_CUSTOM_TAG]=t.vr&&t.vr.contentType,a)),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.trackPlaybackStateChanged=function(t){if(this.isSessionActive()){var e=A.PlayerStateHelper.getPlayerStateFromEvent(t,this.events,this.player),a=[this.events.Play,this.events.Seek,this.events.TimeShift],n=[this.events.StallStarted,this.events.Playing,this.events.Paused,this.events.Seeked,this.events.TimeShifted,this.events.StallEnded,this.events.PlaybackFinished];-1!==a.indexOf(t.type)?this.stallTrackingTimeout.start():-1!==n.indexOf(t.type)&&this.stallTrackingTimeout.clear(),e&&(this._isAdBreakActive?(this.debugLog("[ ConvivaAnalyticsTracker ] report ad playback state",e),this.convivaAdAnalytics.reportAdMetric(i.Constants.Playback.PLAYER_STATE,e)):(this.debugLog("[ ConvivaAnalyticsTracker ] report playback state",e),this.convivaVideoAnalytics.reportPlaybackMetric(i.Constants.Playback.PLAYER_STATE,e))),t.type===this.events.PlaybackFinished&&(this.debugLog("[ ConvivaAnalyticsTracker ] report playback ended"),this.convivaVideoAnalytics.reportPlaybackEnded())}},t.prototype.trackSeekStart=function(t){this.isSessionActive()&&(this.debugLog("[ ConvivaAnalyticsTracker ] report seek started"),this.convivaVideoAnalytics.reportPlaybackMetric(i.Constants.Playback.SEEK_STARTED,t))},t.prototype.trackSeekEnd=function(){this.isSessionActive()&&(this.debugLog("[ ConvivaAnalyticsTracker ] report seek ended"),this.convivaVideoAnalytics.reportPlaybackMetric(i.Constants.Playback.SEEK_ENDED))},t.prototype.trackUpdateAudioTrack=function(t){if(this.isSessionActive()){var e="unknown"!==t.lang?"["+t.lang+"]:"+t.label:t.label;this.debugLog("[ ConvivaAnalyticsTracker ] report audio language",{formattedAudio:e}),this.convivaVideoAnalytics.reportPlaybackMetric(i.Constants.Playback.AUDIO_LANGUAGE,e)}},t.prototype.trackUpdateSubtitleTrack=function(t){if(this.isSessionActive()){var e="unknown"!==t.lang?"["+t.lang+"]:"+t.label:t.label;"subtitles"===t.kind?(this.debugLog("[ ConvivaAnalyticsTracker ] report subtitles language",{formattedSubtitle:e}),this.convivaVideoAnalytics.reportPlaybackMetric(i.Constants.Playback.SUBTITLES_LANGUAGE,e),this.debugLog("[ ConvivaAnalyticsTracker ] report off closed captions language"),this.convivaVideoAnalytics.reportPlaybackMetric(i.Constants.Playback.CLOSED_CAPTIONS_LANGUAGE,"off")):"captions"===t.kind?(this.debugLog("[ ConvivaAnalyticsTracker ] report closed captions language",{formattedSubtitle:e}),this.convivaVideoAnalytics.reportPlaybackMetric(i.Constants.Playback.CLOSED_CAPTIONS_LANGUAGE,e),this.debugLog("[ ConvivaAnalyticsTracker ] report off subtitles language"),this.convivaVideoAnalytics.reportPlaybackMetric(i.Constants.Playback.SUBTITLES_LANGUAGE,"off")):this.trackTurnOffSubtitles()}},t.prototype.trackSubtitleWhenInternalInitialize=function(){if(this.isSessionActive()){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.trackUpdateSubtitleTrack(t[0])}this.trackTurnOffSubtitles()}},t.prototype.trackTurnOffSubtitles=function(){this.isSessionActive()&&(this.debugLog("[ ConvivaAnalyticsTracker ] report off subtitles language"),this.convivaVideoAnalytics.reportPlaybackMetric(i.Constants.Playback.SUBTITLES_LANGUAGE,"off"),this.debugLog("[ ConvivaAnalyticsTracker ] report off closed captions language"),this.convivaVideoAnalytics.reportPlaybackMetric(i.Constants.Playback.CLOSED_CAPTIONS_LANGUAGE,"off"))},t.prototype.registerPlayerEvents=function(){this.handlers.add(this.events.SourceLoaded,this.onSourceLoaded),this.handlers.add(this.events.Play,this.onPlay),this.handlers.add(this.events.Playing,this.onPlaying),this.handlers.add(this.events.PlaybackFinished,this.onPlaybackFinished),this.handlers.add(this.events.SourceUnloaded,this.onSourceUnloaded),this.handlers.add(this.events.Destroy,this.onDestroy)},t.prototype.unregisterPlayerEvents=function(){this.handlers.clear()},Object.defineProperty(t,"version",{get:function(){return t.VERSION},enumerable:!1,configurable:!0}),t.VERSION="5.2.0",t.STALL_TRACKING_DELAY_MS=100,t}();e.ConvivaAnalyticsTracker=p},function(t,e,a){"use strict";Object.defineProperty(e,"__esModule",{value:!0}),e.PlayerEventWrapper=void 0;var i=a(15),n=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]&&i.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 i=a[e];this.remove(t,i)}},t}();e.PlayerEventWrapper=n},function(t,e,a){"use strict";Object.defineProperty(e,"__esModule",{value:!0}),e.ConvivaAnalytics=void 0,a(5);var i=a(6);Object.defineProperty(e,"ConvivaAnalytics",{enumerable:!0,get:function(){return i.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 i=a(0),n=a(7),s=a(2),o=a(19),r=a(3),c=a(1),d=function(){function t(t,e,a){void 0===a&&(a={});var d=this;this.onPlaybackStateChanged=function(t){d.debugLog("[ ConvivaAnalytics ] [ Player Event ] playback state change related event",t),d.convivaAnalyticsTracker.trackPlaybackStateChanged(t)},this.onPlay=function(t){d.debugLog("[ ConvivaAnalytics ] [ Player Event ] play",t),d.convivaAnalyticsTracker.canTrackPlayEvent&&d.onPlaybackStateChanged(t)},this.onPlaying=function(t){d.debugLog("[ ConvivaAnalytics ] [ Player Event ] playing",t),d.onPlaybackStateChanged(t)},this.onPlaybackFinished=function(t){d.debugLog("[ ConvivaAnalytics ] [ Player Event ] playback finished",t),d.onPlaybackStateChanged(t)},this.onVideoQualityChanged=function(t){d.debugLog("[ ConvivaAnalytics ] [ Player Event ] video quality changed",t),d.convivaAnalyticsTracker.trackVideoQualityChanged(t)},this.onCustomEvent=function(t){d.debugLog("[ ConvivaAnalytics ] [ Player Event ] custom playback related event",t);var e=n.ObjectUtils.flatten(t);d.sendCustomPlaybackEvent(t.type,e)},this.onAdBreakStarted=function(t){d.debugLog("[ ConvivaAnalytics ] [ Player Event ] adbreak started",t),d.lastAdBreakEvent=t,d.convivaAnalyticsTracker.trackAdBreakStarted(i.Constants.AdType.CLIENT_SIDE)},this.onAdStarted=function(t){var e;d.debugLog("[ ConvivaAnalytics ] [ Player Event ] ad started",t);var a=c.AdHelper.extractCsaiConvivaAdInfo(d.player,d.lastAdBreakEvent,t),n=null===(e=t.ad.data)||void 0===e?void 0:e.bitrate;d.convivaAnalyticsTracker.trackAdStarted(a,i.Constants.AdType.CLIENT_SIDE,n)},this.onAdFinished=function(t){d.debugLog("[ ConvivaAnalytics ] [ Player Event ] ad finished",t),d.convivaAnalyticsTracker.trackAdFinished()},this.onAdSkipped=function(t){d.debugLog("[ ConvivaAnalytics ] [ Player Event ] ad skipped",t),d.convivaAnalyticsTracker.trackAdSkipped(),d.onCustomEvent(t)},this.onAdBreakFinished=function(t){d.debugLog("[ ConvivaAnalytics ] [ Player Event ] adbreak finished",t),d.convivaAnalyticsTracker.trackAdBreakFinished()},this.onAdError=function(t){d.debugLog("[ ConvivaAnalytics ] [ Player Event ] ad error",t),d.convivaAnalyticsTracker.trackAdError(t),d.onCustomEvent(t)},this.onSeek=function(t){d.debugLog("[ ConvivaAnalytics ] [ Player Event ] seek",t),d.convivaAnalyticsTracker.trackSeekStart(t.seekTarget),d.onPlaybackStateChanged(t)},this.onSeeked=function(t){d.debugLog("[ ConvivaAnalytics ] [ Player Event ] seeked",t),d.convivaAnalyticsTracker.trackSeekEnd(),d.onPlaybackStateChanged(t)},this.onTimeShift=function(t){d.debugLog("[ ConvivaAnalytics ] [ Player Event ] time shift",t),d.convivaAnalyticsTracker.trackSeekStart(-1),d.onPlaybackStateChanged(t)},this.onTimeShifted=function(t){d.debugLog("[ ConvivaAnalytics ] [ Player Event ] time shifted",t),d.convivaAnalyticsTracker.trackSeekEnd(),d.onPlaybackStateChanged(t)},this.onAudioChanged=function(t){d.debugLog("[ ConvivaAnalytics ] [ Player Event ] audio changed",t),d.convivaAnalyticsTracker.trackUpdateAudioTrack(t.targetAudio)},this.onSubtitleEnabled=function(t){d.debugLog("[ ConvivaAnalytics ] [ Player Event ] subtitled enabled",t),d.convivaAnalyticsTracker.trackUpdateSubtitleTrack(t.subtitle)},this.onSubtitleDisabled=function(t){d.debugLog("[ ConvivaAnalytics ] [ Player Event ] subtitles disabled",t),d.convivaAnalyticsTracker.trackTurnOffSubtitles()},this.onError=function(t){d.debugLog("[ ConvivaAnalytics ] [ Player Event ] error",t),d.convivaAnalyticsTracker.trackError(t)},this.onDestroy=function(t){d.debugLog("[ ConvivaAnalytics ] [ Player Event ] destroy",t),d.destroy(t)},this.convivaAnalyticsTracker=new s.ConvivaAnalyticsTracker(t,e,a),this.debugLoggingEnabled=a.debugLoggingEnabled||!1,this.player=t,this.events=t.exports.PlayerEvent,this.handlers=new r.PlayerEventWrapper(t),this.registerPlayerEvents(),this.convivaSsaiAnalytics=new o.ConvivaAnalyticsSsai(this.convivaAnalyticsTracker),this.ssai={get isAdBreakActive(){return this.convivaSsaiAnalytics.isAdBreakActive},reportAdBreakStarted:this.convivaSsaiAnalytics.reportAdBreakStarted.bind(this.convivaSsaiAnalytics),reportAdStarted:this.convivaSsaiAnalytics.reportAdStarted.bind(this.convivaSsaiAnalytics),reportAdFinished:this.convivaSsaiAnalytics.reportAdFinished.bind(this.convivaSsaiAnalytics),reportAdSkipped:this.convivaSsaiAnalytics.reportAdSkipped.bind(this.convivaSsaiAnalytics),reportAdBreakFinished:this.convivaSsaiAnalytics.reportAdBreakFinished.bind(this.convivaSsaiAnalytics)}}return t.prototype.initializeSession=function(){this.convivaAnalyticsTracker.initializeSession()},t.prototype.endSession=function(){this.reset(),this.convivaAnalyticsTracker.endSession()},t.prototype.reset=function(){this.lastAdBreakEvent=null,this.convivaSsaiAnalytics.reset()},t.prototype.sendCustomApplicationEvent=function(t,e){void 0===e&&(e={}),this.convivaAnalyticsTracker.sendCustomApplicationEvent(t,e)},t.prototype.sendCustomPlaybackEvent=function(t,e){void 0===e&&(e={}),this.convivaAnalyticsTracker.sendCustomPlaybackEvent(t,e)},t.prototype.updateContentMetadata=function(t){this.convivaAnalyticsTracker.updateContentMetadata(t)},t.prototype.reportPlaybackDeficiency=function(t,e,a){void 0===a&&(a=!0),this.convivaAnalyticsTracker.reportPlaybackDeficiency(t,e,a)},t.prototype.pauseTracking=function(){this.convivaAnalyticsTracker.pauseTracking()},t.prototype.resumeTracking=function(){this.convivaAnalyticsTracker.resumeTracking()},t.prototype.release=function(){this.destroy(),this.convivaAnalyticsTracker.release()},t.prototype.destroy=function(t){this.reset(),this.unregisterPlayerEvents(),this.convivaAnalyticsTracker.release(t)},t.prototype.debugLog=function(t){for(var e=[],a=1;a<arguments.length;a++)e[a-1]=arguments[a];this.debugLoggingEnabled&&console.log.apply(console,arguments)},t.prototype.registerPlayerEvents=function(){this.handlers.add(this.events.Play,this.onPlay),this.handlers.add(this.events.Playing,this.onPlaying),this.handlers.add(this.events.Paused,this.onPlaybackStateChanged),this.handlers.add(this.events.StallStarted,this.onPlaybackStateChanged),this.handlers.add(this.events.StallEnded,this.onPlaybackStateChanged),this.handlers.add(this.events.PlaybackFinished,this.onPlaybackFinished),this.handlers.add(this.events.VideoPlaybackQualityChanged,this.onVideoQualityChanged),this.handlers.add(this.events.AudioPlaybackQualityChanged,this.onCustomEvent),this.handlers.add(this.events.Muted,this.onCustomEvent),this.handlers.add(this.events.Unmuted,this.onCustomEvent),this.handlers.add(this.events.ViewModeChanged,this.onCustomEvent),this.handlers.add(this.events.AdStarted,this.onAdStarted),this.handlers.add(this.events.AdFinished,this.onAdFinished),this.handlers.add(this.events.AdBreakStarted,this.onAdBreakStarted),this.handlers.add(this.events.AdBreakFinished,this.onAdBreakFinished),this.handlers.add(this.events.AdSkipped,this.onAdSkipped),this.handlers.add(this.events.AdError,this.onAdError),this.handlers.add(this.events.Error,this.onError),this.handlers.add(this.events.Destroy,this.onDestroy),this.handlers.add(this.events.Seek,this.onSeek),this.handlers.add(this.events.Seeked,this.onSeeked),this.handlers.add(this.events.TimeShift,this.onTimeShift),this.handlers.add(this.events.TimeShifted,this.onTimeShifted),this.handlers.add(this.events.AudioChanged,this.onAudioChanged),this.handlers.add(this.events.SubtitleEnabled,this.onSubtitleEnabled),this.handlers.add(this.events.SubtitleDisabled,this.onSubtitleDisabled),this.handlers.add(this.events.CastStarted,this.onCustomEvent),this.handlers.add(this.events.CastStopped,this.onCustomEvent)},t.prototype.unregisterPlayerEvents=function(){this.handlers.clear()},t}();e.ConvivaAnalytics=d},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={},i=function(t,e){for(var n in t)if(t.hasOwnProperty(n)){var s=t[n];"object"==typeof s?i(s,e+n+"."):a[e+n]=String(s)}};return i(t,e),a}}(e.ObjectUtils||(e.ObjectUtils={}))},function(t,e,a){"use strict";Object.defineProperty(e,"__esModule",{value:!0}),e.Html5Http=void 0;var i=function(){function t(){}return t.prototype.makeRequest=function(t,e,a,i,n,s){return this.makeRequestStandard.apply(this,arguments)},t.prototype.release=function(){},t.prototype.makeRequestStandard=function(t,e,a,i,n,s){var o=new XMLHttpRequest;return o.open(t,e,!0),i&&o.overrideMimeType&&o.overrideMimeType(i),i&&o.setRequestHeader&&o.setRequestHeader("Content-Type",i),n>0&&(o.timeout=n,o.ontimeout=function(){o.ontimeout=o.onreadystatechange=null,s&&s(!1,"timeout after "+n+" ms")}),o.onreadystatechange=function(){4===o.readyState&&(o.ontimeout=o.onreadystatechange=null,200===o.status?s&&s(!0,o.responseText):s&&s(!1,"http status "+o.status))},o.send(a),null},t}();e.Html5Http=i},function(t,e,a){"use strict";Object.defineProperty(e,"__esModule",{value:!0}),e.Html5Logging=void 0;var i=a(0),n=function(){function t(){}return t.prototype.consoleLog=function(t,e){"undefined"!=typeof console&&(console.log&&e===i.SystemSettings.LogLevel.DEBUG||e===i.SystemSettings.LogLevel.INFO?console.log(t):console.warn&&e===i.SystemSettings.LogLevel.WARNING?console.warn(t):console.error&&e===i.SystemSettings.LogLevel.ERROR&&console.error(t))},t.prototype.release=function(){},t}();e.Html5Logging=n},function(t,e,a){"use strict";Object.defineProperty(e,"__esModule",{value:!0}),e.Html5Storage=void 0;var i=function(){function t(){}return t.prototype.saveData=function(t,e,a,i){var n=t+"."+e;try{localStorage.setItem(n,a),i(!0,null)}catch(t){i(!1,t.toString())}},t.prototype.loadData=function(t,e,a){var i=t+"."+e;try{a(!0,localStorage.getItem(i))}catch(t){a(!1,t.toString())}},t.prototype.release=function(){},t}();e.Html5Storage=i},function(t,e,a){"use strict";Object.defineProperty(e,"__esModule",{value:!0}),e.Html5Time=void 0;var i=function(){function t(){}return t.prototype.getEpochTimeMs=function(){return(new Date).getTime()},t.prototype.release=function(){},t}();e.Html5Time=i},function(t,e,a){"use strict";Object.defineProperty(e,"__esModule",{value:!0}),e.Html5Timer=void 0;var i=function(){function t(){}return t.prototype.createTimer=function(t,e,a){var i=window.setInterval(t,e);return function(){-1!==i&&(clearInterval(i),i=-1)}},t.prototype.release=function(){},t}();e.Html5Timer=i},function(t,e,a){"use strict";Object.defineProperty(e,"__esModule",{value:!0});var i=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=i},function(t,e,a){"use strict";var i=this&&this.__assign||function(){return(i=Object.assign||function(t){for(var e,a=1,i=arguments.length;a<i;a++)for(var n in e=arguments[a])Object.prototype.hasOwnProperty.call(e,n)&&(t[n]=e[n]);return t}).apply(this,arguments)};Object.defineProperty(e,"__esModule",{value:!0}),e.ContentMetadataBuilder=void 0;var n=a(0),s=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",n.SystemSettings.LogLevel.WARNING),this.metadataOverrides=i(i({},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=i(i(i({},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=i(i({},this.getStaticMetadata()),this.getDynamicMetadata());this.latestBuiltMetadata=e;var a=((t={})[n.Constants.ASSET_NAME]=e.assetName,t[n.Constants.ENCODED_FRAMERATE]=e.encodedFrameRate,t[n.Constants.DURATION]=e.duration,t[n.Constants.DEFAULT_RESOURCE]=e.defaultResource,t[n.Constants.STREAM_URL]=e.streamUrl,t[n.Constants.IS_LIVE]=e.streamType,t[n.Constants.VIEWER_ID]=e.viewerId||"GET_VIEWER_ID_FROM_PLAYER",t[n.Constants.PLAYER_NAME]=e.applicationName||"GET_PLAYER_NAME_OR_TYPE",t);return i(i({},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=i(i({},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=s},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.PlayerConfigHelper=void 0;var i=a(17),n=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(i.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}();e.PlayerConfigHelper=n},function(t,e,a){"use strict";Object.defineProperty(e,"__esModule",{value:!0}),e.BrowserUtils=void 0;var i=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),i=/Safari/i.test(navigator.userAgent)&&/Mobile/i.test(navigator.userAgent);return t||e||a||i},t}();e.BrowserUtils=i},function(t,e,a){"use strict";Object.defineProperty(e,"__esModule",{value:!0}),e.PlayerStateHelper=void 0;var i=a(0),n=function(){function t(){}return t.getPlayerStateFromEvent=function(t,e,a){var n;switch(t.type){case e.StallStarted:n=i.Constants.PlayerState.BUFFERING;break;case e.Playing:n=i.Constants.PlayerState.PLAYING;break;case e.Paused:n=i.Constants.PlayerState.PAUSED;break;case e.Seeked:case e.TimeShifted:case e.StallEnded:n=a.isPlaying()?i.Constants.PlayerState.PLAYING:i.Constants.PlayerState.PAUSED}return n},t.getPlayerState=function(t){return t.isStalled()?i.Constants.PlayerState.BUFFERING:t.isPlaying()?i.Constants.PlayerState.PLAYING:i.Constants.PlayerState.PAUSED},t}();e.PlayerStateHelper=n},function(t,e,a){"use strict";Object.defineProperty(e,"__esModule",{value:!0}),e.ConvivaAnalyticsSsai=void 0;var i=a(0),n=a(1),s=function(){function t(t){this._isAdBreakActive=!1,this.convivaAnalyticsTracker=t}return Object.defineProperty(t.prototype,"isAdBreakActive",{get:function(){return this._isAdBreakActive},enumerable:!1,configurable:!0}),t.prototype.reset=function(){this._isAdBreakActive=!1},t.prototype.reportAdBreakStarted=function(){this.convivaAnalyticsTracker.isAdBreakActive||this._isAdBreakActive||(this._isAdBreakActive=!0,this.convivaAnalyticsTracker.trackAdBreakStarted(i.Constants.AdType.SERVER_SIDE))},t.prototype.reportAdStarted=function(t){this._isAdBreakActive&&this.convivaAnalyticsTracker.trackAdStarted(n.AdHelper.convertSsaiAdInfoToConvivaAdInfo(t,this.convivaAnalyticsTracker.getContentMetadata()),i.Constants.AdType.SERVER_SIDE)},t.prototype.reportAdFinished=function(){this.isAdBreakActive&&this.convivaAnalyticsTracker.trackAdFinished()},t.prototype.reportAdSkipped=function(){this._isAdBreakActive&&this.convivaAnalyticsTracker.trackAdSkipped()},t.prototype.reportAdBreakFinished=function(){this._isAdBreakActive&&(this._isAdBreakActive=!1,this.convivaAnalyticsTracker.trackAdBreakFinished())},t}();e.ConvivaAnalyticsSsai=s}])});
//# sourceMappingURL=bitmovin-player-analytics-conviva.js.map
import * as Conviva from '@convivainc/conviva-js-coresdk';
import type { PlayerAPI } from 'bitmovin-player';
import { Metadata } from './ContentMetadataBuilder';
type Player = PlayerAPI;
export interface ConvivaAnalyticsConfiguration {
/**
* Enables debug logging when set to true (default: false).
*/
debugLoggingEnabled?: boolean;
/**
* The TOUCHSTONE_SERVICE_URL for testing with Touchstone. Only to be used for development, must not be set in
* production or automated testing.
*/
gatewayUrl?: string;
/**
* Option to set the Conviva Device Category, which is used to assist with
* user agent string parsing by the Conviva SDK. (default: WEB)
* @deprecated Use `deviceMetadata.category` field
*/
deviceCategory?: Conviva.valueof<Conviva.ConvivaConstants['DeviceCategory']>;
/**
* Option to override the Conviva Device Metadata.
* (Default: Auto extract all options from User Agent string)
*/
deviceMetadata?: {
/**
* Option to set the Conviva Device Category, which is used to assist with
* user agent string parsing by the Conviva SDK.
* (default: The same specified in config.deviceCategory)
*/
category?: Conviva.valueof<Conviva.ConvivaConstants['DeviceCategory']>;
/**
* Option to override the Conviva Device Brand.
* (Default: Auto extract from User Agent string)
*/
brand?: string;
/**
* Option to override the Conviva Device Manufacturer.
* (Default: Auto extract from User Agent string)
*/
manufacturer?: string;
/**
* Option to override the Conviva Device Model.
* (Default: Auto extract from User Agent string)
*/
model?: string;
/**
* Option to override the Conviva Device Type
* (Default: Auto extract from User Agent string)
*/
type?: Conviva.valueof<Conviva.ConvivaConstants['DeviceType']>;
/**
* Option to override the Conviva Device Version.
* (Default: Auto extract from User Agent string)
*/
version?: string;
/**
* Option to override the Conviva Operating System Name
* (Default: Auto extract from User Agent string)
*/
osName?: string;
/**
* Option to override the Conviva Operating System Version
* (Default: Auto extract from User Agent string)
*/
osVersion?: string;
};
}
export interface EventAttributes {
[key: string]: string;
}
import { ConvivaAnalyticsConfiguration, EventAttributes } from './ConvivaAnalyticsTracker';
import { ConvivaAnalyticsSsai } from './ConvivaAnalyticsSsai';
export declare class ConvivaAnalytics {
private static readonly VERSION;
private static STALL_TRACKING_DELAY_MS;
private readonly events;
private readonly handlers;
private readonly convivaAnalyticsTracker;
private readonly player;
private events;
private readonly handlers;
private config;
private readonly contentMetadataBuilder;
private readonly logger;
private sessionKey;
private convivaVideoAnalytics;
private convivaAdAnalytics;
private readonly debugLoggingEnabled;
/**
* 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 isAdBreak;
/**
* Tracks the last ad break event to get the ad position and other ad break related information

@@ -94,10 +17,6 @@ * in the ad started event to report it to Conviva.

private lastAdBreakEvent;
private stallTrackingTimeout;
private convivaSsaiAnalytics;
readonly ssai: Omit<ConvivaAnalyticsSsai, 'reset'>;
constructor(player: PlayerAPI, customerKey: string, config?: ConvivaAnalyticsConfiguration);
/**
* Boolean to track whether a session was ended by an upstream caller instead of within internal session management.
* If this is true, we should avoid initializing a new session internally if a session is not active
*/
private sessionEndedExternally;
constructor(player: Player, customerKey: string, config?: ConvivaAnalyticsConfiguration);
/**
* Initializes a new conviva tracking session.

@@ -123,2 +42,3 @@ *

endSession(): void;
private reset;
/**

@@ -169,38 +89,3 @@ * Sends a custom application-level event to Conviva's Player Insight. An application-level event can always

private debugLog;
private getUrlFromSource;
private internalUpdateContentMetadata;
/**
* A Conviva Session should only be initialized when there is a source provided in the player because
* Conviva only allows to update different `contentMetadata` only at different times.
*
* The session should be created as soon as there was a play intention from the user.
*
* Set only once:
* - assetName
*
* Update before first video frame:
* - viewerId
* - streamType
* - playerName
* - duration
* - custom
*
* Multiple updates during session:
* - streamUrl
* - defaultResource (unused)
* - encodedFrameRate (unused)
*/
private internalInitializeSession;
/**
* Update contentMetadata which must be present before first video frame
*/
private buildContentMetadata;
private buildSourceRelatedMetadata;
private updateSession;
private getAssetNameFromSource;
private internalEndSession;
private resetContentMetadata;
private isSessionActive;
private onPlaybackStateChanged;
private onSourceLoaded;
private onPlay;

@@ -221,18 +106,9 @@ private onPlaying;

private onTimeShifted;
private trackSeekStart;
private trackSeekEnd;
private onAudioChanged;
private updateAudioTrack;
private onSubtitleEnabled;
private updateSubtitleTrack;
private onSubtitleDisabled;
private checkSubtitleWhenInternalInitialize;
private turnOffSubtitles;
private onError;
private onSourceUnloaded;
private onDestroy;
private registerPlayerEvents;
private unregisterPlayerEvents;
static get version(): string;
}
export {};

@@ -5,164 +5,36 @@ "use strict";

var Conviva = require("@convivainc/conviva-js-coresdk");
var Html5Http_1 = require("./Html5Http");
var Html5Logging_1 = require("./Html5Logging");
var Html5Storage_1 = require("./Html5Storage");
var Html5Time_1 = require("./Html5Time");
var Html5Timer_1 = require("./Html5Timer");
var timeout_1 = require("bitmovin-player-ui/dist/js/framework/timeout");
var ContentMetadataBuilder_1 = require("./ContentMetadataBuilder");
var ObjectUtils_1 = require("./helper/ObjectUtils");
var BrowserUtils_1 = require("./helper/BrowserUtils");
var arrayutils_1 = require("bitmovin-player-ui/dist/js/framework/arrayutils");
var ConvivaAnalyticsTracker_1 = require("./ConvivaAnalyticsTracker");
var ConvivaAnalyticsSsai_1 = require("./ConvivaAnalyticsSsai");
var PlayerEventWrapper_1 = require("./helper/PlayerEventWrapper");
var AdHelper_1 = require("./helper/AdHelper");
var ConvivaAnalytics = /** @class */ (function () {
function ConvivaAnalytics(player, customerKey, config) {
var _a;
if (config === void 0) { config = {}; }
var _this = this;
// 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.
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);
}
});
/**
* Boolean to track whether a session was ended by an upstream caller instead of within internal session management.
* If this is true, we should avoid initializing a new session internally if a session is not active
*/
this.sessionEndedExternally = false;
this.internalEndSession = function (event) {
if (!_this.isSessionActive()) {
return;
}
_this.debugLog('[ ConvivaAnalytics ] end session', Conviva.Constants.NO_SESSION_KEY, event);
_this.convivaVideoAnalytics.release();
_this.convivaVideoAnalytics = null;
_this.convivaAdAnalytics.release();
_this.convivaAdAnalytics = null;
_this.lastAdBreakEvent = null;
_this.isAdBreak = false;
};
this.onPlaybackStateChanged = function (event) {
_this.debugLog('[ Player Event ] playback state change related event', event);
if (!_this.isSessionActive()) {
return;
}
var playerState;
switch (event.type) {
case _this.events.StallStarted:
playerState = Conviva.Constants.PlayerState.BUFFERING;
break;
case _this.events.Playing:
playerState = Conviva.Constants.PlayerState.PLAYING;
break;
case _this.events.Paused:
playerState = Conviva.Constants.PlayerState.PAUSED;
break;
case _this.events.Seeked:
case _this.events.TimeShifted:
case _this.events.StallEnded:
if (_this.player.isPlaying()) {
playerState = Conviva.Constants.PlayerState.PLAYING;
}
else {
playerState = Conviva.Constants.PlayerState.PAUSED;
}
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) {
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.debugLog('[ ConvivaAnalytics ] [ Player Event ] playback state change related event', event);
_this.convivaAnalyticsTracker.trackPlaybackStateChanged(event);
};
this.onSourceLoaded = function (event) {
_this.debugLog('[ Player Event ] source loaded', event);
// In case the session was created external before loading the source
if (!_this.isSessionActive()) {
return;
}
_this.buildSourceRelatedMetadata(_this.player.getSource());
_this.updateSession();
};
this.onPlay = function (event) {
_this.debugLog('[ Player Event ] play', event);
if (_this.isAdBreak) {
// Do not track play event during ad (e.g. triggered from IMA)
_this.debugLog('[ ConvivaAnalytics ] [ Player Event ] play', event);
if (!_this.convivaAnalyticsTracker.canTrackPlayEvent) {
return;
}
// in case the playback has finished and the user replays the stream create a new session
if (!_this.isSessionActive() && !_this.sessionEndedExternally) {
_this.internalInitializeSession();
}
_this.onPlaybackStateChanged(event);
};
this.onPlaying = function (event) {
_this.contentMetadataBuilder.setPlaybackStarted(true);
_this.debugLog('[ Player Event ] playing', event);
_this.updateSession();
_this.debugLog('[ ConvivaAnalytics ] [ Player Event ] playing', event);
_this.onPlaybackStateChanged(event);
};
this.onPlaybackFinished = function (event) {
_this.debugLog('[ Player Event ] playback finished', event);
if (!_this.isSessionActive()) {
return;
}
_this.debugLog('[ ConvivaAnalytics ] [ Player Event ] playback finished', event);
_this.onPlaybackStateChanged(event);
_this.convivaVideoAnalytics.release();
_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);
_this.debugLog('[ ConvivaAnalytics ] report bitrate', {
event: event,
bitrateKbps: bitrateKbps,
});
_this.convivaVideoAnalytics.reportPlaybackMetric(Conviva.Constants.Playback.BITRATE, bitrateKbps);
_this.debugLog('[ ConvivaAnalytics ] [ Player Event ] video quality changed', event);
_this.convivaAnalyticsTracker.trackVideoQualityChanged(event);
};
this.onCustomEvent = function (event) {
_this.debugLog('[ Player Event ] custom playback related event', event);
if (!_this.isSessionActive()) {
_this.debugLog('[ ConvivaAnalytics ] skip custom event, no session existing', event);
return;
}
_this.debugLog('[ ConvivaAnalytics ] [ Player Event ] custom playback related event', event);
var eventAttributes = ObjectUtils_1.ObjectUtils.flatten(event);

@@ -172,187 +44,91 @@ _this.sendCustomPlaybackEvent(event.type, eventAttributes);

this.onAdBreakStarted = function (event) {
_this.debugLog('[ Player Event ] adbreak started', event);
_this.isAdBreak = true;
_this.debugLog('[ ConvivaAnalytics ] [ Player Event ] adbreak started', event);
_this.lastAdBreakEvent = event;
_this.debugLog('[ ConvivaAnalytics ] report ad break started', event);
_this.convivaVideoAnalytics.reportAdBreakStarted(Conviva.Constants.AdType.CLIENT_SIDE, Conviva.Constants.AdPlayer.SEPARATE);
_this.convivaAnalyticsTracker.trackAdBreakStarted(Conviva.Constants.AdType.CLIENT_SIDE);
};
this.onAdStarted = function (event) {
var _a;
_this.debugLog('[ Player Event ] ad started', event);
var adInfo = AdHelper_1.AdHelper.extractConvivaAdInfo(_this.player, _this.lastAdBreakEvent, event);
_this.debugLog('[ ConvivaAnalytics ] [ Player Event ] ad started', event);
var adInfo = AdHelper_1.AdHelper.extractCsaiConvivaAdInfo(_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.convivaAnalyticsTracker.trackAdStarted(adInfo, Conviva.Constants.AdType.CLIENT_SIDE, bitrateKbps);
};
this.onAdFinished = function (event) {
_this.debugLog('[ Player Event ] ad finished', event);
_this.debugLog('[ ConvivaAdAnalytics ] report ad ended', {
event: event,
});
_this.convivaAdAnalytics.reportAdEnded();
_this.debugLog('[ ConvivaAnalytics ] [ Player Event ] ad finished', event);
_this.convivaAnalyticsTracker.trackAdFinished();
};
this.onAdSkipped = function (event) {
_this.debugLog('[ Player Event ] ad skipped', event);
_this.debugLog('[ ConvivaAdAnalytics ] report ad skipped', event);
_this.convivaAdAnalytics.reportAdSkipped();
_this.debugLog('[ ConvivaAnalytics ] [ Player Event ] ad skipped', event);
_this.convivaAnalyticsTracker.trackAdSkipped();
_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.debugLog('[ ConvivaAnalytics ] [ Player Event ] adbreak finished', event);
_this.convivaAnalyticsTracker.trackAdBreakFinished();
};
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.debugLog('[ ConvivaAnalytics ] [ Player Event ] ad error', event);
_this.convivaAnalyticsTracker.trackAdError(event);
_this.onCustomEvent(event);
};
this.onSeek = function (event) {
_this.debugLog('[ Player Event ] seek', event);
if (!_this.isSessionActive()) {
// Handle the case that the User seeks on the UI before play was triggered.
// This also handles startTime feature. The same applies for onTimeShift.
return;
}
_this.trackSeekStart(event.seekTarget);
_this.debugLog('[ ConvivaAnalytics ] [ Player Event ] seek', event);
_this.convivaAnalyticsTracker.trackSeekStart(event.seekTarget);
_this.onPlaybackStateChanged(event);
};
this.onSeeked = function (event) {
_this.debugLog('[ Player Event ] seeked', event);
if (!_this.isSessionActive()) {
// See comment in onSeek
return;
}
_this.trackSeekEnd();
_this.debugLog('[ ConvivaAnalytics ] [ Player Event ] seeked', event);
_this.convivaAnalyticsTracker.trackSeekEnd();
_this.onPlaybackStateChanged(event);
};
this.onTimeShift = function (event) {
_this.debugLog('[ Player Event ] time shift', event);
if (!_this.isSessionActive()) {
// See comment in onSeek
return;
}
_this.debugLog('[ ConvivaAnalytics ] [ Player Event ] time shift', event);
// According to conviva it is valid to pass -1 for seeking in live streams
_this.trackSeekStart(-1);
_this.convivaAnalyticsTracker.trackSeekStart(-1);
_this.onPlaybackStateChanged(event);
};
this.onTimeShifted = function (event) {
_this.debugLog('[ Player Event ] time shifted', event);
if (!_this.isSessionActive()) {
// See comment in onSeek
return;
}
_this.trackSeekEnd();
_this.debugLog('[ ConvivaAnalytics ] [ Player Event ] time shifted', event);
_this.convivaAnalyticsTracker.trackSeekEnd();
_this.onPlaybackStateChanged(event);
};
this.onAudioChanged = function (event) {
_this.debugLog('[ Player Event ] audio changed', event);
if (!_this.isSessionActive()) {
// Handle the case that the User change audio on the UI before play was triggered.
return;
}
_this.updateAudioTrack(event.targetAudio);
_this.debugLog('[ ConvivaAnalytics ] [ Player Event ] audio changed', event);
_this.convivaAnalyticsTracker.trackUpdateAudioTrack(event.targetAudio);
};
this.onSubtitleEnabled = function (event) {
_this.debugLog('[ Player Event ] subtitled enabled', event);
if (!_this.isSessionActive()) {
// Handle the case that the User change subtitle on the UI before play was triggered.
return;
}
_this.updateSubtitleTrack(event.subtitle);
_this.debugLog('[ ConvivaAnalytics ] [ Player Event ] subtitled enabled', event);
_this.convivaAnalyticsTracker.trackUpdateSubtitleTrack(event.subtitle);
};
this.onSubtitleDisabled = function (event) {
_this.debugLog('[ Player Event ] subtitles disabled', event);
if (!_this.isSessionActive()) {
// Handle the case that the User turn off subtitle on the UI before play was triggered.
return;
}
_this.turnOffSubtitles();
_this.debugLog('[ ConvivaAnalytics ] [ Player Event ] subtitles disabled', event);
_this.convivaAnalyticsTracker.trackTurnOffSubtitles();
};
this.onError = function (event) {
_this.debugLog('[ Player Event ] error', event);
if (!_this.isSessionActive() && !_this.sessionEndedExternally) {
// initialize Session if not yet initialized to capture Video Start Failures
_this.internalInitializeSession();
}
_this.reportPlaybackDeficiency(String(event.code) + ' ' + event.name, Conviva.Constants.ErrorSeverity.FATAL);
_this.debugLog('[ ConvivaAnalytics ] [ Player Event ] error', event);
_this.convivaAnalyticsTracker.trackError(event);
};
this.onSourceUnloaded = function (event) {
_this.debugLog('[ Player Event ] source unloaded', event);
if (_this.isAdBreak) {
// Ignore sourceUnloaded events during ads
return;
}
else {
_this.internalEndSession(event);
_this.resetContentMetadata();
}
};
this.onDestroy = function (event) {
_this.debugLog('[ Player Event ] destroy', event);
_this.debugLog('[ ConvivaAnalytics ] [ Player Event ] destroy', event);
_this.destroy(event);
};
if (typeof Conviva === 'undefined') {
console.error("Conviva script missing, cannot init ConvivaAnalytics. Please load the Conviva script (conviva-core-sdk.min.js) before Bitmovin's ConvivaAnalytics integration.");
return; // Cancel initialization
}
if (player.getSource()) {
console.error('Bitmovin Conviva integration must be instantiated before calling player.load()');
return; // Cancel initialization
}
this.convivaAnalyticsTracker = new ConvivaAnalyticsTracker_1.ConvivaAnalyticsTracker(player, customerKey, config);
this.debugLoggingEnabled = config.debugLoggingEnabled || false;
this.player = player;
// TODO: Use alternative to deprecated player.exports
this.events = player.exports.PlayerEvent;
this.handlers = new PlayerEventWrapper(player);
this.config = config;
// Set default config values
this.config.debugLoggingEnabled = this.config.debugLoggingEnabled || false;
this.logger = new Html5Logging_1.Html5Logging();
this.sessionKey = Conviva.Constants.NO_SESSION_KEY;
this.isAdBreak = false;
var deviceMetadataFromConfig = this.config.deviceMetadata || {};
var deviceMetadata = (_a = {},
_a[Conviva.Constants.DeviceMetadata.CATEGORY] = deviceMetadataFromConfig.category || this.config.deviceCategory || Conviva.Constants.DeviceCategory.WEB,
_a[Conviva.Constants.DeviceMetadata.BRAND] = deviceMetadataFromConfig.brand,
_a[Conviva.Constants.DeviceMetadata.MANUFACTURER] = deviceMetadataFromConfig.manufacturer,
_a[Conviva.Constants.DeviceMetadata.MODEL] = deviceMetadataFromConfig.model,
_a[Conviva.Constants.DeviceMetadata.TYPE] = deviceMetadataFromConfig.type,
_a[Conviva.Constants.DeviceMetadata.VERSION] = deviceMetadataFromConfig.version,
_a[Conviva.Constants.DeviceMetadata.OS_NAME] = deviceMetadataFromConfig.osName,
_a[Conviva.Constants.DeviceMetadata.OS_VERSION] = deviceMetadataFromConfig.osVersion,
_a);
Conviva.Analytics.setDeviceMetadata(deviceMetadata);
var callbackFunctions = {};
callbackFunctions[Conviva.Constants.CallbackFunctions.CONSOLE_LOG] = this.logger.consoleLog;
callbackFunctions[Conviva.Constants.CallbackFunctions.MAKE_REQUEST] = new Html5Http_1.Html5Http().makeRequest;
var html5Storage = new Html5Storage_1.Html5Storage();
callbackFunctions[Conviva.Constants.CallbackFunctions.SAVE_DATA] = html5Storage.saveData;
callbackFunctions[Conviva.Constants.CallbackFunctions.LOAD_DATA] = html5Storage.loadData;
callbackFunctions[Conviva.Constants.CallbackFunctions.CREATE_TIMER] = new Html5Timer_1.Html5Timer().createTimer;
callbackFunctions[Conviva.Constants.CallbackFunctions.GET_EPOCH_TIME_IN_MS] = new Html5Time_1.Html5Time().getEpochTimeMs;
var settings = {};
settings[Conviva.Constants.GATEWAY_URL] = config.gatewayUrl;
settings[Conviva.Constants.LOG_LEVEL] = this.config.debugLoggingEnabled
? Conviva.Constants.LogLevel.DEBUG
: Conviva.Constants.LogLevel.NONE;
Conviva.Analytics.init(customerKey, callbackFunctions, settings);
this.contentMetadataBuilder = new ContentMetadataBuilder_1.ContentMetadataBuilder(this.logger);
this.handlers = new PlayerEventWrapper_1.PlayerEventWrapper(player);
this.registerPlayerEvents();
this.convivaSsaiAnalytics = new ConvivaAnalyticsSsai_1.ConvivaAnalyticsSsai(this.convivaAnalyticsTracker);
// Do not expose `reset` method to the public API.
this.ssai = {
get isAdBreakActive() {
return this.convivaSsaiAnalytics.isAdBreakActive;
},
reportAdBreakStarted: this.convivaSsaiAnalytics.reportAdBreakStarted.bind(this.convivaSsaiAnalytics),
reportAdStarted: this.convivaSsaiAnalytics.reportAdStarted.bind(this.convivaSsaiAnalytics),
reportAdFinished: this.convivaSsaiAnalytics.reportAdFinished.bind(this.convivaSsaiAnalytics),
reportAdSkipped: this.convivaSsaiAnalytics.reportAdSkipped.bind(this.convivaSsaiAnalytics),
reportAdBreakFinished: this.convivaSsaiAnalytics.reportAdBreakFinished.bind(this.convivaSsaiAnalytics),
};
}

@@ -370,13 +146,3 @@ /**

ConvivaAnalytics.prototype.initializeSession = function () {
if (this.isSessionActive()) {
this.logger.consoleLog('[ ConvivaAnalytics ] There is already a session running.', Conviva.SystemSettings.LogLevel.WARNING);
return;
}
// This could be called before source loaded.
// Without setting the asset name on the content metadata the SDK will throw errors when we initialize the session.
if (!this.player.getSource() && !this.contentMetadataBuilder.assetName) {
throw 'AssetName is missing. Load player source first or set assetName via updateContentMetadata';
}
this.internalInitializeSession();
this.sessionEndedExternally = false;
this.convivaAnalyticsTracker.initializeSession();
};

@@ -393,15 +159,9 @@ /**

ConvivaAnalytics.prototype.endSession = function () {
if (!this.isSessionActive()) {
return;
}
this.debugLog('[ ConvivaAnalytics ] report playback ended state');
if (this.isAdBreak) {
this.debugLog('[ ConvivaAdAnalytics ] report ad skipped');
this.convivaAdAnalytics.reportAdSkipped();
}
this.convivaVideoAnalytics.reportPlaybackEnded();
this.internalEndSession();
this.resetContentMetadata();
this.sessionEndedExternally = true;
this.reset();
this.convivaAnalyticsTracker.endSession();
};
ConvivaAnalytics.prototype.reset = function () {
this.lastAdBreakEvent = null;
this.convivaSsaiAnalytics.reset();
};
/**

@@ -415,13 +175,3 @@ * Sends a custom application-level event to Conviva's Player Insight. An application-level event can always

if (eventAttributes === void 0) { eventAttributes = {}; }
if (!this.isSessionActive()) {
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
// in monitoring session if greater than 256 bytes
this.convivaVideoAnalytics.reportAppEvent(eventName, eventAttributes);
this.convivaAnalyticsTracker.sendCustomApplicationEvent(eventName, eventAttributes);
};

@@ -436,13 +186,3 @@ /**

if (eventAttributes === void 0) { eventAttributes = {}; }
if (!this.isSessionActive()) {
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
// in monitoring session if greater than 256 bytes
this.convivaVideoAnalytics.reportPlaybackEvent(eventName, eventAttributes);
this.convivaAnalyticsTracker.sendCustomPlaybackEvent(eventName, eventAttributes);
};

@@ -460,3 +200,3 @@ /**

ConvivaAnalytics.prototype.updateContentMetadata = function (metadataOverrides) {
this.internalUpdateContentMetadata(metadataOverrides);
this.convivaAnalyticsTracker.updateContentMetadata(metadataOverrides);
};

@@ -473,13 +213,3 @@ /**

if (endSession === void 0) { endSession = true; }
if (!this.isSessionActive()) {
return;
}
this.debugLog('[ ConvivaAnalytics ] report playback failed', {
message: message,
});
this.convivaVideoAnalytics.reportPlaybackFailed(message);
if (endSession) {
this.internalEndSession();
this.resetContentMetadata();
}
this.convivaAnalyticsTracker.reportPlaybackDeficiency(message, severity, endSession);
};

@@ -490,5 +220,3 @@ /**

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.convivaAnalyticsTracker.pauseTracking();
};

@@ -499,13 +227,12 @@ /**

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.convivaAnalyticsTracker.resumeTracking();
};
ConvivaAnalytics.prototype.release = function () {
this.destroy();
this.convivaAnalyticsTracker.release();
};
ConvivaAnalytics.prototype.destroy = function (event) {
this.reset();
this.unregisterPlayerEvents();
this.internalEndSession(event);
Conviva.Analytics.release();
this.convivaAnalyticsTracker.release(event);
};

@@ -517,229 +244,35 @@ ConvivaAnalytics.prototype.debugLog = function (message) {

}
if (this.config.debugLoggingEnabled) {
if (this.debugLoggingEnabled) {
console.log.apply(console, arguments);
}
};
ConvivaAnalytics.prototype.getUrlFromSource = function (source) {
switch (this.player.getStreamType()) {
case 'dash':
return source.dash;
case 'hls':
return source.hls;
case 'progressive':
if (Array.isArray(source.progressive)) {
// TODO check if the first stream can be another index (e.g. ordered by bitrate), and select the current
// startup url
return source.progressive[0].url;
}
else {
return source.progressive;
}
}
};
ConvivaAnalytics.prototype.internalUpdateContentMetadata = function (metadataOverrides) {
this.contentMetadataBuilder.setOverrides(metadataOverrides);
if (!this.isSessionActive()) {
this.logger.consoleLog('[ ConvivaAnalytics ] no active session. Content metadata will be propagated to Conviva on session initialization.', Conviva.SystemSettings.LogLevel.DEBUG);
return;
}
this.buildContentMetadata();
this.updateSession();
};
/**
* A Conviva Session should only be initialized when there is a source provided in the player because
* Conviva only allows to update different `contentMetadata` only at different times.
*
* The session should be created as soon as there was a play intention from the user.
*
* Set only once:
* - assetName
*
* Update before first video frame:
* - viewerId
* - streamType
* - playerName
* - duration
* - custom
*
* Multiple updates during session:
* - streamUrl
* - defaultResource (unused)
* - encodedFrameRate (unused)
*/
ConvivaAnalytics.prototype.internalInitializeSession = function () {
var _a;
var _this = this;
this.buildContentMetadata();
// Create a Conviva monitoring session.
this.convivaVideoAnalytics = Conviva.Analytics.buildVideoAnalytics();
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);
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(function () {
var playheadTimeMs = _this.player.getCurrentTime('relativetime') * 1000;
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);
}
});
this.debugLog('[ ConvivaAnalytics ] start session', this.sessionKey);
if (!this.isSessionActive()) {
// Something went wrong. With stable system interfaces, this should never happen.
this.logger.consoleLog('[ ConvivaAnalytics ] Something went wrong, could not obtain session key', Conviva.SystemSettings.LogLevel.ERROR);
}
// Send the session init audio language values.
this.updateAudioTrack(this.player.getAudio());
// Check if at session init has a subtitle enabled.
this.checkSubtitleWhenInternalInitialize();
};
/**
* Update contentMetadata which must be present before first video frame
*/
ConvivaAnalytics.prototype.buildContentMetadata = function () {
this.contentMetadataBuilder.duration = this.player.getDuration();
this.contentMetadataBuilder.streamType = this.player.isLive()
? Conviva.ContentMetadata.StreamType.LIVE
: Conviva.ContentMetadata.StreamType.VOD;
this.contentMetadataBuilder.addToCustom({
// Autoplay and preload are important options for the Video Startup Time so we track it as custom tags
autoplay: PlayerConfigHelper.getAutoplayConfig(this.player) + '',
preload: PlayerConfigHelper.getPreloadConfig(this.player) + '',
integrationVersion: ConvivaAnalytics.VERSION,
});
var source = this.player.getSource();
// This could be called before we got a source
if (source) {
this.buildSourceRelatedMetadata(source);
}
};
ConvivaAnalytics.prototype.buildSourceRelatedMetadata = function (source) {
this.contentMetadataBuilder.assetName = this.getAssetNameFromSource(source);
this.contentMetadataBuilder.viewerId = this.contentMetadataBuilder.viewerId;
this.contentMetadataBuilder.addToCustom({
playerType: this.player.getPlayerType(),
streamType: this.player.getStreamType(),
vrContentType: source.vr && source.vr.contentType,
});
this.contentMetadataBuilder.streamUrl = this.getUrlFromSource(source);
};
ConvivaAnalytics.prototype.updateSession = function () {
if (!this.isSessionActive()) {
return;
}
this.convivaVideoAnalytics.setContentInfo(this.contentMetadataBuilder.build());
};
ConvivaAnalytics.prototype.getAssetNameFromSource = function (source) {
var assetName;
var assetTitle = source.title;
if (assetTitle) {
assetName = assetTitle;
}
else {
assetName = 'Untitled (no source.title set)';
}
return assetName;
};
ConvivaAnalytics.prototype.resetContentMetadata = function () {
this.contentMetadataBuilder.reset();
};
ConvivaAnalytics.prototype.isSessionActive = function () {
return !!this.convivaVideoAnalytics;
};
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);
};
ConvivaAnalytics.prototype.updateAudioTrack = function (audioTrack) {
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);
};
ConvivaAnalytics.prototype.updateSubtitleTrack = function (subtitleTrack) {
var formattedSubtitle = subtitleTrack.lang !== 'unknown' ? '[' + subtitleTrack.lang + ']:' + subtitleTrack.label : subtitleTrack.label;
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');
}
else {
this.turnOffSubtitles();
}
};
ConvivaAnalytics.prototype.checkSubtitleWhenInternalInitialize = function () {
if (this.player.subtitles !== undefined) {
var enableSubtitle = this.player.subtitles.list().filter(function (i) { return i.enabled; });
// Send the session init subtitle language values.
if (enableSubtitle.length === 1) {
this.updateSubtitleTrack(enableSubtitle[0]);
return;
}
}
this.turnOffSubtitles();
};
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');
};
ConvivaAnalytics.prototype.registerPlayerEvents = function () {
var playerEvents = this.handlers;
playerEvents.add(this.events.SourceLoaded, this.onSourceLoaded);
playerEvents.add(this.events.Play, this.onPlay);
playerEvents.add(this.events.Playing, this.onPlaying);
playerEvents.add(this.events.Paused, this.onPlaybackStateChanged);
playerEvents.add(this.events.StallStarted, this.onPlaybackStateChanged);
playerEvents.add(this.events.StallEnded, this.onPlaybackStateChanged);
playerEvents.add(this.events.PlaybackFinished, this.onPlaybackFinished);
playerEvents.add(this.events.VideoPlaybackQualityChanged, this.onVideoQualityChanged);
playerEvents.add(this.events.AudioPlaybackQualityChanged, this.onCustomEvent);
playerEvents.add(this.events.Muted, this.onCustomEvent);
playerEvents.add(this.events.Unmuted, this.onCustomEvent);
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);
playerEvents.add(this.events.AdBreakFinished, this.onAdBreakFinished);
playerEvents.add(this.events.AdSkipped, this.onAdSkipped);
playerEvents.add(this.events.AdError, this.onAdError);
playerEvents.add(this.events.SourceUnloaded, this.onSourceUnloaded);
playerEvents.add(this.events.Error, this.onError);
playerEvents.add(this.events.Destroy, this.onDestroy);
playerEvents.add(this.events.Seek, this.onSeek);
playerEvents.add(this.events.Seeked, this.onSeeked);
playerEvents.add(this.events.TimeShift, this.onTimeShift);
playerEvents.add(this.events.TimeShifted, this.onTimeShifted);
playerEvents.add(this.events.AudioChanged, this.onAudioChanged);
playerEvents.add(this.events.SubtitleEnabled, this.onSubtitleEnabled);
playerEvents.add(this.events.SubtitleDisabled, this.onSubtitleDisabled);
playerEvents.add(this.events.CastStarted, this.onCustomEvent);
playerEvents.add(this.events.CastStopped, this.onCustomEvent);
this.handlers.add(this.events.Play, this.onPlay);
this.handlers.add(this.events.Playing, this.onPlaying);
this.handlers.add(this.events.Paused, this.onPlaybackStateChanged);
this.handlers.add(this.events.StallStarted, this.onPlaybackStateChanged);
this.handlers.add(this.events.StallEnded, this.onPlaybackStateChanged);
this.handlers.add(this.events.PlaybackFinished, this.onPlaybackFinished);
this.handlers.add(this.events.VideoPlaybackQualityChanged, this.onVideoQualityChanged);
this.handlers.add(this.events.AudioPlaybackQualityChanged, this.onCustomEvent);
this.handlers.add(this.events.Muted, this.onCustomEvent);
this.handlers.add(this.events.Unmuted, this.onCustomEvent);
this.handlers.add(this.events.ViewModeChanged, this.onCustomEvent);
this.handlers.add(this.events.AdStarted, this.onAdStarted);
this.handlers.add(this.events.AdFinished, this.onAdFinished);
this.handlers.add(this.events.AdBreakStarted, this.onAdBreakStarted);
this.handlers.add(this.events.AdBreakFinished, this.onAdBreakFinished);
this.handlers.add(this.events.AdSkipped, this.onAdSkipped);
this.handlers.add(this.events.AdError, this.onAdError);
this.handlers.add(this.events.Error, this.onError);
this.handlers.add(this.events.Destroy, this.onDestroy);
this.handlers.add(this.events.Seek, this.onSeek);
this.handlers.add(this.events.Seeked, this.onSeeked);
this.handlers.add(this.events.TimeShift, this.onTimeShift);
this.handlers.add(this.events.TimeShifted, this.onTimeShifted);
this.handlers.add(this.events.AudioChanged, this.onAudioChanged);
this.handlers.add(this.events.SubtitleEnabled, this.onSubtitleEnabled);
this.handlers.add(this.events.SubtitleDisabled, this.onSubtitleDisabled);
this.handlers.add(this.events.CastStarted, this.onCustomEvent);
this.handlers.add(this.events.CastStopped, this.onCustomEvent);
};

@@ -749,96 +282,5 @@ ConvivaAnalytics.prototype.unregisterPlayerEvents = function () {

};
Object.defineProperty(ConvivaAnalytics, "version", {
get: function () {
return ConvivaAnalytics.VERSION;
},
enumerable: false,
configurable: true
});
ConvivaAnalytics.VERSION = '{{VERSION}}';
ConvivaAnalytics.STALL_TRACKING_DELAY_MS = 100;
return ConvivaAnalytics;
}());
exports.ConvivaAnalytics = ConvivaAnalytics;
var PlayerConfigHelper = /** @class */ (function () {
function PlayerConfigHelper() {
}
/**
* Extract autoplay config form player
*
* @param player: Player
*/
PlayerConfigHelper.getAutoplayConfig = function (player) {
var playerConfig = player.getConfig();
if (playerConfig.playback && playerConfig.playback.autoplay !== undefined) {
return playerConfig.playback.autoplay;
}
else {
return PlayerConfigHelper.AUTOPLAY_DEFAULT_CONFIG;
}
};
/**
* Extract preload config from player
*
* The preload config can be set individual for mobile or desktop as well as on root level for both platforms.
* Default value is true for VOD and false for live streams. If the value is not set for current platform or on root
* level the default value will be used over the value for the other platform.
*
* @param player: Player
*/
PlayerConfigHelper.getPreloadConfig = function (player) {
var playerConfig = player.getConfig();
if (BrowserUtils_1.BrowserUtils.isMobile()) {
if (playerConfig.adaptation &&
playerConfig.adaptation.mobile &&
playerConfig.adaptation.mobile.preload !== undefined) {
return playerConfig.adaptation.mobile.preload;
}
}
else {
if (playerConfig.adaptation &&
playerConfig.adaptation.desktop &&
playerConfig.adaptation.desktop.preload !== undefined) {
return playerConfig.adaptation.desktop.preload;
}
}
if (playerConfig.adaptation && playerConfig.adaptation.preload !== undefined) {
return playerConfig.adaptation.preload;
}
return !player.isLive();
};
/**
* The config for autoplay and preload have great impact to the VST (Video Startup Time) we track it.
* Since there is no way to get default config values from the player they are hardcoded.
*/
PlayerConfigHelper.AUTOPLAY_DEFAULT_CONFIG = false;
return PlayerConfigHelper;
}());
var PlayerEventWrapper = /** @class */ (function () {
function PlayerEventWrapper(player) {
this.player = player;
this.eventHandlers = {};
}
PlayerEventWrapper.prototype.add = function (eventType, callback) {
this.player.on(eventType, callback);
if (!this.eventHandlers[eventType]) {
this.eventHandlers[eventType] = [];
}
this.eventHandlers[eventType].push(callback);
};
PlayerEventWrapper.prototype.remove = function (eventType, callback) {
this.player.off(eventType, callback);
if (this.eventHandlers[eventType]) {
arrayutils_1.ArrayUtils.remove(this.eventHandlers[eventType], callback);
}
};
PlayerEventWrapper.prototype.clear = function () {
for (var eventType in this.eventHandlers) {
for (var _i = 0, _a = this.eventHandlers[eventType]; _i < _a.length; _i++) {
var callback = _a[_i];
this.remove(eventType, callback);
}
}
};
return PlayerEventWrapper;
}());
//# sourceMappingURL=ConvivaAnalytics.js.map
import { AdBreak, AdBreakEvent, AdEvent, ErrorEvent, PlayerAPI } from 'bitmovin-player';
import * as Conviva from '@convivainc/conviva-js-coresdk';
export interface SsaiAdInfo {
/**
* The ad ID extracted from the ad server that contains the ad creative.
*/
id: string;
/**
* The title of the ad.
*/
title?: string;
/**
* Duration of the ad, in seconds.
*/
duration?: number;
/**
* The name of the ad system (i.e., the ad server).
*/
adSystem?: string;
/**
* The position of the ad.
*/
position?: Conviva.valueof<Conviva.ConvivaConstants['AdPosition']>;
/**
* Indicates whether this ad is a slate or not. Set to <code>true</code> for slate and <code>false</code> for a regular ad.
*/
isSlate?: boolean;
/**
* The name of the ad stitcher.
*/
adStitcher?: string;
/**
* Additional ad metadata. This is a map of key-value pairs that can be used to pass additional metadata about the ad.
* A list of ad metadata can be found here: <a href="https://pulse.conviva.com/learning-center/content/sensor_developer_center/sensor_integration/javascript/javascript_stream_sensor.htm#IntegrateAdManagers">Conviva documentation</a>
* <p>
* Metadata provided here will supersede any data provided in the ad break info.
*/
additionalMetadata?: Record<string, string>;
}
export declare class AdHelper {
static mapAdPosition(adBreak: AdBreak, player: PlayerAPI): Conviva.valueof<Conviva.ConvivaConstants['AdPosition']>;
static formatAdErrorEvent(event: ErrorEvent & {
static mapCsaiAdPosition(adBreak: AdBreak, player: PlayerAPI): Conviva.valueof<Conviva.ConvivaConstants['AdPosition']>;
static formatCsaiAdError(event: ErrorEvent & {
data?: {

@@ -10,3 +47,4 @@ code?: number;

}): string;
static extractConvivaAdInfo(player: PlayerAPI, adBreakEvent: AdBreakEvent, adEvent: AdEvent): Conviva.ConvivaMetadata;
static extractCsaiConvivaAdInfo(player: PlayerAPI, adBreakEvent: AdBreakEvent, adEvent: AdEvent): Conviva.ConvivaMetadata;
static convertSsaiAdInfoToConvivaAdInfo(ssaiAdInfo: SsaiAdInfo, allCurrentContentMetadata: Conviva.ConvivaMetadata): Conviva.ConvivaMetadata;
}
"use strict";
var __assign = (this && this.__assign) || function () {
__assign = Object.assign || function(t) {
for (var s, i = 1, n = arguments.length; i < n; i++) {
s = arguments[i];
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
t[p] = s[p];
}
return t;
};
return __assign.apply(this, arguments);
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.AdHelper = void 0;
var Conviva = require("@convivainc/conviva-js-coresdk");
var ConvivaAnalyticsTracker_1 = require("../ConvivaAnalyticsTracker");
var AdHelper = /** @class */ (function () {
function AdHelper() {
}
AdHelper.mapAdPosition = function (adBreak, player) {
AdHelper.mapCsaiAdPosition = function (adBreak, player) {
if (adBreak.scheduleTime <= 0) {

@@ -17,3 +29,3 @@ return Conviva.Constants.AdPosition.PREROLL;

};
AdHelper.formatAdErrorEvent = function (event) {
AdHelper.formatCsaiAdError = function (event) {
var _a, _b;

@@ -33,5 +45,5 @@ var message = (event === null || event === void 0 ? void 0 : event.message) || 'Unknown message';

};
AdHelper.extractConvivaAdInfo = function (player, adBreakEvent, adEvent) {
var _a, _b;
var adPosition = AdHelper.mapAdPosition(adBreakEvent.adBreak, player);
AdHelper.extractCsaiConvivaAdInfo = function (player, adBreakEvent, adEvent) {
var _a;
var _b, _c;
var ad = adEvent.ad;

@@ -41,17 +53,9 @@ var adData = ad.data;

var creativeId = 'NA';
var adTitle;
var adTitle = 'NA';
var firstAdId = ad.id;
// TODO these two are not exposed currently. Add them whenever the player
// exposes them similar to https://github.com/bitmovin-engineering/player-android/pull/3147.
// Related discussion https://bitmovin.slack.com/archives/C0LJ16JBS/p1716801796326889.
var firstAdSystem = 'NA';
var firstCreativeId = 'NA';
// TODO This is not exposed currently. Add it whenever the player
// exposes it. Related discussion https://bitmovin.slack.com/archives/C0LJ16JBS/p1716801970037469.
var mediaFileApiFramework = 'NA';
if (adData) {
if ('adSystem' in adData && ((_a = adData.adSystem) === null || _a === void 0 ? void 0 : _a.name)) {
if ('adSystem' in adData && ((_b = adData.adSystem) === null || _b === void 0 ? void 0 : _b.name)) {
adSystemName = adData.adSystem.name;
}
if ('creative' in adData && ((_b = adData === null || adData === void 0 ? void 0 : adData.creative) === null || _b === void 0 ? void 0 : _b.id)) {
if ('creative' in adData && ((_c = adData === null || adData === void 0 ? void 0 : adData.creative) === null || _c === void 0 ? void 0 : _c.id)) {
creativeId = adData.creative.id;

@@ -66,22 +70,21 @@ }

}
var adInfo = {
'c3.ad.id': ad.id,
'c3.ad.technology': Conviva.Constants.AdType.CLIENT_SIDE,
'c3.ad.position': adPosition,
'c3.ad.system': adSystemName,
'c3.ad.creativeId': creativeId,
'c3.ad.firstAdId': firstAdId,
'c3.ad.mediaFileApiFramework': mediaFileApiFramework,
'c3.ad.firstAdSystem': firstAdSystem,
'c3.ad.firstCreativeId': firstCreativeId,
// These two are not relevant for the client side (keep in the code for documentation purposes)
// 'c3.ad.adStitcher': undefined,
// 'c3.ad.isSlate': undefined,
};
if (adTitle) {
adInfo[Conviva.Constants.ASSET_NAME] = adTitle;
}
if (ad.mediaFileUrl) {
adInfo[Conviva.Constants.STREAM_URL] = ad.mediaFileUrl;
}
var adInfo = (_a = {
'c3.ad.id': ad.id,
'c3.ad.technology': Conviva.Constants.AdType.CLIENT_SIDE,
'c3.ad.position': AdHelper.mapCsaiAdPosition(adBreakEvent.adBreak, player),
'c3.ad.system': adSystemName,
'c3.ad.creativeId': creativeId,
'c3.ad.firstAdId': firstAdId
},
_a[Conviva.Constants.ASSET_NAME] = adTitle,
_a[Conviva.Constants.STREAM_URL] = ad.mediaFileUrl || 'NA',
// TODO This is not exposed currently. Add it whenever the player
// exposes it. Related discussion https://bitmovin.slack.com/archives/C0LJ16JBS/p1716801970037469.
_a['c3.ad.mediaFileApiFramework'] = 'NA',
// TODO these two are not exposed currently. Add them whenever the player
// exposes them similar to https://github.com/bitmovin-engineering/player-android/pull/3147.
// Related discussion https://bitmovin.slack.com/archives/C0LJ16JBS/p1716801796326889.
_a['c3.ad.firstAdSystem'] = 'NA',
_a['c3.ad.firstCreativeId'] = 'NA',
_a);
if ('duration' in ad && ad.duration) {

@@ -92,2 +95,24 @@ adInfo[Conviva.Constants.DURATION] = ad.duration;

};
AdHelper.convertSsaiAdInfoToConvivaAdInfo = function (ssaiAdInfo, allCurrentContentMetadata) {
var _a;
var keysToPick = [
ConvivaAnalyticsTracker_1.INTEGRATION_VERSION_CONTENT_METADATA_CUSTOM_TAG,
ConvivaAnalyticsTracker_1.STREAM_TYPE_CONTENT_METADATA_CUSTOM_TAG,
Conviva.Constants.ASSET_NAME,
Conviva.Constants.IS_LIVE,
Conviva.Constants.DEFAULT_RESOURCE,
Conviva.Constants.ENCODED_FRAMERATE,
Conviva.Constants.VIEWER_ID,
Conviva.Constants.PLAYER_NAME,
];
var selectedCurrentContentMetadata = {};
keysToPick.forEach(function (key) {
selectedCurrentContentMetadata[key] = allCurrentContentMetadata[key];
});
var adInfo = __assign(__assign(__assign({}, selectedCurrentContentMetadata), ssaiAdInfo.additionalMetadata), (_a = { 'c3.ad.id': ssaiAdInfo.id, 'c3.ad.technology': Conviva.Constants.AdType.SERVER_SIDE, 'c3.ad.position': ssaiAdInfo.position || 'NA', 'c3.ad.system': ssaiAdInfo.adSystem || 'NA' }, _a[Conviva.Constants.ASSET_NAME] = ssaiAdInfo.title || selectedCurrentContentMetadata[Conviva.Constants.ASSET_NAME] || 'NA', _a['c3.ad.adStitcher'] = ssaiAdInfo.adStitcher || 'NA', _a['c3.ad.isSlate'] = ssaiAdInfo.isSlate === undefined ? 'NA' : ssaiAdInfo.isSlate.toString(), _a));
if (ssaiAdInfo.duration) {
adInfo[Conviva.Constants.DURATION] = ssaiAdInfo.duration;
}
return adInfo;
};
return AdHelper;

@@ -94,0 +119,0 @@ }());

@@ -1,4 +0,4 @@

import { EventAttributes } from '../ConvivaAnalytics';
import { EventAttributes } from '../ConvivaAnalyticsTracker';
export declare namespace ObjectUtils {
function flatten(object: any, prefix?: string): EventAttributes;
}
import './conviva/ConvivaExtension';
export { ConvivaAnalytics, ConvivaAnalyticsConfiguration, EventAttributes } from './ConvivaAnalytics';
export { ConvivaAnalyticsConfiguration, EventAttributes } from './ConvivaAnalyticsTracker';
export { ConvivaAnalytics } from './ConvivaAnalytics';
export { Metadata } from './ContentMetadataBuilder';
export { SsaiAdInfo } from './helper/AdHelper';
{
"name": "@bitmovin/player-integration-conviva",
"version": "5.1.0",
"version": "5.2.0",
"description": "Conviva analytics integration for the Bitmovin Player",

@@ -35,8 +35,11 @@ "repository": {

"bitmovin-player-ui": "^3.3.1",
"changelog-parser": "^3.0.1",
"create-file-webpack": "^1.0.2",
"husky": "^8.0.3",
"jest": "^24.1.0",
"jest-mock-extended": "^3.0.7",
"kacl": "^1.1.1",
"lint-staged": "^13.2.2",
"prettier": "^2.8.8",
"semver": "^7.6.2",
"string-replace-loader": "^2.1.1",

@@ -43,0 +46,0 @@ "ts-jest": "^23.10.5",

@@ -6,3 +6,2 @@ import * as Conviva from '@convivainc/conviva-js-coresdk';

AudioChangedEvent,
AudioTrack,
ErrorEvent,

@@ -14,127 +13,22 @@ PlaybackEvent,

SeekEvent,
SourceConfig,
TimeShiftEvent,
VideoQualityChangedEvent,
SubtitleEvent,
SubtitleTrack,
TimeMode,
AdData,
VastAdData,
Ad,
LinearAd,
} from 'bitmovin-player';
import { Html5Http } from './Html5Http';
import { Html5Logging } from './Html5Logging';
import { Html5Storage } from './Html5Storage';
import { Html5Time } from './Html5Time';
import { Html5Timer } from './Html5Timer';
import { Timeout } from 'bitmovin-player-ui/dist/js/framework/timeout';
import { ContentMetadataBuilder, Metadata } from './ContentMetadataBuilder';
import { Metadata } from './ContentMetadataBuilder';
import { ObjectUtils } from './helper/ObjectUtils';
import { BrowserUtils } from './helper/BrowserUtils';
import { ArrayUtils } from 'bitmovin-player-ui/dist/js/framework/arrayutils';
import { ConvivaAnalyticsConfiguration, ConvivaAnalyticsTracker, EventAttributes } from './ConvivaAnalyticsTracker';
import { ConvivaAnalyticsSsai } from './ConvivaAnalyticsSsai';
import { PlayerEventWrapper } from './helper/PlayerEventWrapper';
import { AdHelper } from './helper/AdHelper';
type Player = PlayerAPI;
export interface ConvivaAnalyticsConfiguration {
/**
* Enables debug logging when set to true (default: false).
*/
debugLoggingEnabled?: boolean;
/**
* The TOUCHSTONE_SERVICE_URL for testing with Touchstone. Only to be used for development, must not be set in
* production or automated testing.
*/
gatewayUrl?: string;
/**
* Option to set the Conviva Device Category, which is used to assist with
* user agent string parsing by the Conviva SDK. (default: WEB)
* @deprecated Use `deviceMetadata.category` field
*/
deviceCategory?: Conviva.valueof<Conviva.ConvivaConstants['DeviceCategory']>;
/**
* Option to override the Conviva Device Metadata.
* (Default: Auto extract all options from User Agent string)
*/
deviceMetadata?: {
/**
* Option to set the Conviva Device Category, which is used to assist with
* user agent string parsing by the Conviva SDK.
* (default: The same specified in config.deviceCategory)
*/
category?: Conviva.valueof<Conviva.ConvivaConstants['DeviceCategory']>;
/**
* Option to override the Conviva Device Brand.
* (Default: Auto extract from User Agent string)
*/
brand?: string;
/**
* Option to override the Conviva Device Manufacturer.
* (Default: Auto extract from User Agent string)
*/
manufacturer?: string;
/**
* Option to override the Conviva Device Model.
* (Default: Auto extract from User Agent string)
*/
model?: string;
/**
* Option to override the Conviva Device Type
* (Default: Auto extract from User Agent string)
*/
type?: Conviva.valueof<Conviva.ConvivaConstants['DeviceType']>;
/**
* Option to override the Conviva Device Version.
* (Default: Auto extract from User Agent string)
*/
version?: string;
/**
* Option to override the Conviva Operating System Name
* (Default: Auto extract from User Agent string)
*/
osName?: string;
/**
* Option to override the Conviva Operating System Version
* (Default: Auto extract from User Agent string)
*/
osVersion?: string;
};
}
export interface EventAttributes {
[key: string]: string;
}
export class ConvivaAnalytics {
private static readonly VERSION: string = '{{VERSION}}';
private static STALL_TRACKING_DELAY_MS = 100;
private readonly player: Player;
private events: typeof PlayerEvent;
private readonly events: typeof PlayerEvent;
private readonly handlers: PlayerEventWrapper;
private config: ConvivaAnalyticsConfiguration;
private readonly contentMetadataBuilder: ContentMetadataBuilder;
private readonly convivaAnalyticsTracker: ConvivaAnalyticsTracker;
private readonly player: PlayerAPI;
private readonly logger: Conviva.LoggingInterface;
private sessionKey: number;
private convivaVideoAnalytics: Conviva.VideoAnalytics;
private convivaAdAnalytics: Conviva.AdAnalytics;
private readonly debugLoggingEnabled: boolean;
/**
* 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 isAdBreak: boolean;
/**
* Tracks the last ad break event to get the ad position and other ad break related information

@@ -145,89 +39,29 @@ * in the ad started event to report it to Conviva.

// 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 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,
);
}
private convivaSsaiAnalytics: ConvivaAnalyticsSsai;
});
public readonly ssai: Omit<ConvivaAnalyticsSsai, 'reset'>;
/**
* Boolean to track whether a session was ended by an upstream caller instead of within internal session management.
* If this is true, we should avoid initializing a new session internally if a session is not active
*/
private sessionEndedExternally = false;
constructor(player: Player, customerKey: string, config: ConvivaAnalyticsConfiguration = {}) {
if (typeof Conviva === 'undefined') {
console.error(
`Conviva script missing, cannot init ConvivaAnalytics. Please load the Conviva script (conviva-core-sdk.min.js) before Bitmovin's ConvivaAnalytics integration.`,
);
return; // Cancel initialization
}
if (player.getSource()) {
console.error('Bitmovin Conviva integration must be instantiated before calling player.load()');
return; // Cancel initialization
}
constructor(player: PlayerAPI, customerKey: string, config: ConvivaAnalyticsConfiguration = {}) {
this.convivaAnalyticsTracker = new ConvivaAnalyticsTracker(player, customerKey, config);
this.debugLoggingEnabled = config.debugLoggingEnabled || false;
this.player = player;
// TODO: Use alternative to deprecated player.exports
this.events = player.exports.PlayerEvent;
this.handlers = new PlayerEventWrapper(player);
this.config = config;
// Set default config values
this.config.debugLoggingEnabled = this.config.debugLoggingEnabled || false;
this.registerPlayerEvents();
this.logger = new Html5Logging();
this.sessionKey = Conviva.Constants.NO_SESSION_KEY;
this.isAdBreak = false;
this.convivaSsaiAnalytics = new ConvivaAnalyticsSsai(this.convivaAnalyticsTracker);
const deviceMetadataFromConfig = this.config.deviceMetadata || {};
const deviceMetadata: Conviva.ConvivaDeviceMetadata = {
[Conviva.Constants.DeviceMetadata.CATEGORY]:
deviceMetadataFromConfig.category || this.config.deviceCategory || Conviva.Constants.DeviceCategory.WEB,
[Conviva.Constants.DeviceMetadata.BRAND]: deviceMetadataFromConfig.brand,
[Conviva.Constants.DeviceMetadata.MANUFACTURER]: deviceMetadataFromConfig.manufacturer,
[Conviva.Constants.DeviceMetadata.MODEL]: deviceMetadataFromConfig.model,
[Conviva.Constants.DeviceMetadata.TYPE]: deviceMetadataFromConfig.type,
[Conviva.Constants.DeviceMetadata.VERSION]: deviceMetadataFromConfig.version,
[Conviva.Constants.DeviceMetadata.OS_NAME]: deviceMetadataFromConfig.osName,
[Conviva.Constants.DeviceMetadata.OS_VERSION]: deviceMetadataFromConfig.osVersion,
// Do not expose `reset` method to the public API.
this.ssai = {
get isAdBreakActive() {
return this.convivaSsaiAnalytics.isAdBreakActive;
},
reportAdBreakStarted: this.convivaSsaiAnalytics.reportAdBreakStarted.bind(this.convivaSsaiAnalytics),
reportAdStarted: this.convivaSsaiAnalytics.reportAdStarted.bind(this.convivaSsaiAnalytics),
reportAdFinished: this.convivaSsaiAnalytics.reportAdFinished.bind(this.convivaSsaiAnalytics),
reportAdSkipped: this.convivaSsaiAnalytics.reportAdSkipped.bind(this.convivaSsaiAnalytics),
reportAdBreakFinished: this.convivaSsaiAnalytics.reportAdBreakFinished.bind(this.convivaSsaiAnalytics),
};
Conviva.Analytics.setDeviceMetadata(deviceMetadata);
let callbackFunctions: Record<string, Function> = {};
callbackFunctions[Conviva.Constants.CallbackFunctions.CONSOLE_LOG] = this.logger.consoleLog;
callbackFunctions[Conviva.Constants.CallbackFunctions.MAKE_REQUEST] = new Html5Http().makeRequest;
const html5Storage = new Html5Storage();
callbackFunctions[Conviva.Constants.CallbackFunctions.SAVE_DATA] = html5Storage.saveData;
callbackFunctions[Conviva.Constants.CallbackFunctions.LOAD_DATA] = html5Storage.loadData;
callbackFunctions[Conviva.Constants.CallbackFunctions.CREATE_TIMER] = new Html5Timer().createTimer;
callbackFunctions[Conviva.Constants.CallbackFunctions.GET_EPOCH_TIME_IN_MS] = new Html5Time().getEpochTimeMs;
const settings: Record<string, string | number> = {};
settings[Conviva.Constants.GATEWAY_URL] = config.gatewayUrl;
settings[Conviva.Constants.LOG_LEVEL] = this.config.debugLoggingEnabled
? Conviva.Constants.LogLevel.DEBUG
: Conviva.Constants.LogLevel.NONE;
Conviva.Analytics.init(customerKey, callbackFunctions, settings);
this.contentMetadataBuilder = new ContentMetadataBuilder(this.logger);
this.registerPlayerEvents();
}

@@ -246,15 +80,3 @@

public initializeSession(): void {
if (this.isSessionActive()) {
this.logger.consoleLog('[ ConvivaAnalytics ] There is already a session running.', Conviva.SystemSettings.LogLevel.WARNING);
return;
}
// This could be called before source loaded.
// Without setting the asset name on the content metadata the SDK will throw errors when we initialize the session.
if (!this.player.getSource() && !this.contentMetadataBuilder.assetName) {
throw 'AssetName is missing. Load player source first or set assetName via updateContentMetadata';
}
this.internalInitializeSession();
this.sessionEndedExternally = false;
this.convivaAnalyticsTracker.initializeSession();
}

@@ -272,18 +94,9 @@

public endSession(): void {
if (!this.isSessionActive()) {
return;
}
this.reset();
this.convivaAnalyticsTracker.endSession();
}
this.debugLog('[ ConvivaAnalytics ] report playback ended state');
if (this.isAdBreak) {
this.debugLog('[ ConvivaAdAnalytics ] report ad skipped');
this.convivaAdAnalytics.reportAdSkipped();
}
this.convivaVideoAnalytics.reportPlaybackEnded();
this.internalEndSession();
this.resetContentMetadata();
this.sessionEndedExternally = true;
private reset(): void {
this.lastAdBreakEvent = null;
this.convivaSsaiAnalytics.reset();
}

@@ -298,17 +111,3 @@

public sendCustomApplicationEvent(eventName: string, eventAttributes: EventAttributes = {}): void {
if (!this.isSessionActive()) {
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,
eventAttributes,
});
// NOTE Conviva has event attribute capped and 256 bytes for custom events and will show up as a warning
// in monitoring session if greater than 256 bytes
this.convivaVideoAnalytics.reportAppEvent(eventName, eventAttributes);
this.convivaAnalyticsTracker.sendCustomApplicationEvent(eventName, eventAttributes);
}

@@ -323,17 +122,3 @@

public sendCustomPlaybackEvent(eventName: string, eventAttributes: EventAttributes = {}): void {
if (!this.isSessionActive()) {
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,
eventAttributes,
});
// NOTE Conviva has event attribute capped and 256 bytes for custom events and will show up as a warning
// in monitoring session if greater than 256 bytes
this.convivaVideoAnalytics.reportPlaybackEvent(eventName, eventAttributes);
this.convivaAnalyticsTracker.sendCustomPlaybackEvent(eventName, eventAttributes);
}

@@ -352,3 +137,3 @@

public updateContentMetadata(metadataOverrides: Partial<Metadata>) {
this.internalUpdateContentMetadata(metadataOverrides);
this.convivaAnalyticsTracker.updateContentMetadata(metadataOverrides);
}

@@ -369,14 +154,3 @@

) {
if (!this.isSessionActive()) {
return;
}
this.debugLog('[ ConvivaAnalytics ] report playback failed', {
message,
});
this.convivaVideoAnalytics.reportPlaybackFailed(message);
if (endSession) {
this.internalEndSession();
this.resetContentMetadata();
}
this.convivaAnalyticsTracker.reportPlaybackDeficiency(message, severity, endSession);
}

@@ -388,8 +162,3 @@

public pauseTracking(): void {
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.convivaAnalyticsTracker.pauseTracking();
}

@@ -401,5 +170,3 @@

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.convivaAnalyticsTracker.resumeTracking();
}

@@ -409,13 +176,13 @@

this.destroy();
this.convivaAnalyticsTracker.release();
}
private destroy(event?: PlayerEventBase): void {
this.reset();
this.unregisterPlayerEvents();
this.internalEndSession(event);
Conviva.Analytics.release();
this.convivaAnalyticsTracker.release(event);
}
private debugLog(message?: any, ...optionalParams: any[]): void {
if (this.config.debugLoggingEnabled) {
if (this.debugLoggingEnabled) {
console.log.apply(console, arguments);

@@ -425,280 +192,14 @@ }

private getUrlFromSource(source: SourceConfig): string {
switch (this.player.getStreamType()) {
case 'dash':
return source.dash;
case 'hls':
return source.hls;
case 'progressive':
if (Array.isArray(source.progressive)) {
// TODO check if the first stream can be another index (e.g. ordered by bitrate), and select the current
// startup url
return source.progressive[0].url;
} else {
return source.progressive;
}
}
}
private internalUpdateContentMetadata(metadataOverrides: Partial<Metadata>) {
this.contentMetadataBuilder.setOverrides(metadataOverrides);
if (!this.isSessionActive()) {
this.logger.consoleLog(
'[ ConvivaAnalytics ] no active session. Content metadata will be propagated to Conviva on session initialization.',
Conviva.SystemSettings.LogLevel.DEBUG,
);
return;
}
this.buildContentMetadata();
this.updateSession();
}
/**
* A Conviva Session should only be initialized when there is a source provided in the player because
* Conviva only allows to update different `contentMetadata` only at different times.
*
* The session should be created as soon as there was a play intention from the user.
*
* Set only once:
* - assetName
*
* Update before first video frame:
* - viewerId
* - streamType
* - playerName
* - duration
* - custom
*
* Multiple updates during session:
* - streamUrl
* - defaultResource (unused)
* - encodedFrameRate (unused)
*/
private internalInitializeSession() {
this.buildContentMetadata();
// Create a Conviva monitoring session.
this.convivaVideoAnalytics = Conviva.Analytics.buildVideoAnalytics();
this.convivaAdAnalytics = Conviva.Analytics.buildAdAnalytics(this.convivaVideoAnalytics);
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;
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);
}
});
this.debugLog('[ ConvivaAnalytics ] start session', this.sessionKey);
if (!this.isSessionActive()) {
// Something went wrong. With stable system interfaces, this should never happen.
this.logger.consoleLog(
'[ ConvivaAnalytics ] Something went wrong, could not obtain session key',
Conviva.SystemSettings.LogLevel.ERROR,
);
}
// Send the session init audio language values.
this.updateAudioTrack(this.player.getAudio());
// Check if at session init has a subtitle enabled.
this.checkSubtitleWhenInternalInitialize();
}
/**
* Update contentMetadata which must be present before first video frame
*/
private buildContentMetadata() {
this.contentMetadataBuilder.duration = this.player.getDuration();
this.contentMetadataBuilder.streamType = this.player.isLive()
? Conviva.ContentMetadata.StreamType.LIVE
: Conviva.ContentMetadata.StreamType.VOD;
this.contentMetadataBuilder.addToCustom({
// Autoplay and preload are important options for the Video Startup Time so we track it as custom tags
autoplay: PlayerConfigHelper.getAutoplayConfig(this.player) + '',
preload: PlayerConfigHelper.getPreloadConfig(this.player) + '',
integrationVersion: ConvivaAnalytics.VERSION,
});
const source = this.player.getSource();
// This could be called before we got a source
if (source) {
this.buildSourceRelatedMetadata(source);
}
}
private buildSourceRelatedMetadata(source: SourceConfig) {
this.contentMetadataBuilder.assetName = this.getAssetNameFromSource(source);
this.contentMetadataBuilder.viewerId = this.contentMetadataBuilder.viewerId;
this.contentMetadataBuilder.addToCustom({
playerType: this.player.getPlayerType(),
streamType: this.player.getStreamType(),
vrContentType: source.vr && source.vr.contentType,
});
this.contentMetadataBuilder.streamUrl = this.getUrlFromSource(source);
}
private updateSession() {
if (!this.isSessionActive()) {
return;
}
this.convivaVideoAnalytics.setContentInfo(this.contentMetadataBuilder.build());
}
private getAssetNameFromSource(source: SourceConfig): string {
let assetName;
const assetTitle = source.title;
if (assetTitle) {
assetName = assetTitle;
} else {
assetName = 'Untitled (no source.title set)';
}
return assetName;
}
private internalEndSession = (event?: PlayerEventBase) => {
if (!this.isSessionActive()) {
return;
}
this.debugLog('[ ConvivaAnalytics ] end session', Conviva.Constants.NO_SESSION_KEY, event);
this.convivaVideoAnalytics.release();
this.convivaVideoAnalytics = null;
this.convivaAdAnalytics.release();
this.convivaAdAnalytics = null;
this.lastAdBreakEvent = null;
this.isAdBreak = false;
};
private resetContentMetadata(): void {
this.contentMetadataBuilder.reset();
}
private isSessionActive(): boolean {
return !!this.convivaVideoAnalytics;
}
private onPlaybackStateChanged = (event: PlayerEventBase) => {
this.debugLog('[ Player Event ] playback state change related event', event);
if (!this.isSessionActive()) {
return;
}
let playerState;
switch (event.type) {
case this.events.StallStarted:
playerState = Conviva.Constants.PlayerState.BUFFERING;
break;
case this.events.Playing:
playerState = Conviva.Constants.PlayerState.PLAYING;
break;
case this.events.Paused:
playerState = Conviva.Constants.PlayerState.PAUSED;
break;
case this.events.Seeked:
case this.events.TimeShifted:
case this.events.StallEnded:
if (this.player.isPlaying()) {
playerState = Conviva.Constants.PlayerState.PLAYING;
} else {
playerState = Conviva.Constants.PlayerState.PAUSED;
}
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) {
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.debugLog('[ ConvivaAnalytics ] [ Player Event ] playback state change related event', event);
this.convivaAnalyticsTracker.trackPlaybackStateChanged(event);
};
private onSourceLoaded = (event: PlayerEventBase) => {
this.debugLog('[ Player Event ] source loaded', event);
// In case the session was created external before loading the source
if (!this.isSessionActive()) {
return;
}
this.buildSourceRelatedMetadata(this.player.getSource());
this.updateSession();
};
private onPlay = (event: PlaybackEvent) => {
this.debugLog('[ Player Event ] play', event);
this.debugLog('[ ConvivaAnalytics ] [ Player Event ] play', event);
if (this.isAdBreak) {
// Do not track play event during ad (e.g. triggered from IMA)
if (!this.convivaAnalyticsTracker.canTrackPlayEvent) {
return;
}
// in case the playback has finished and the user replays the stream create a new session
if (!this.isSessionActive() && !this.sessionEndedExternally) {
this.internalInitializeSession();
}
this.onPlaybackStateChanged(event);

@@ -708,5 +209,3 @@ };

private onPlaying = (event: PlaybackEvent) => {
this.contentMetadataBuilder.setPlaybackStarted(true);
this.debugLog('[ Player Event ] playing', event);
this.updateSession();
this.debugLog('[ ConvivaAnalytics ] [ Player Event ] playing', event);
this.onPlaybackStateChanged(event);

@@ -716,39 +215,13 @@ };

private onPlaybackFinished = (event: PlayerEventBase) => {
this.debugLog('[ Player Event ] playback finished', event);
if (!this.isSessionActive()) {
return;
}
this.debugLog('[ ConvivaAnalytics ] [ Player Event ] playback finished', event);
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
// Example: 250000 / 1000 => 250 kbps (250000 / 1024 => 244kbps)
const bitrateKbps = Math.round(event.targetQuality.bitrate / 1000);
this.debugLog('[ ConvivaAnalytics ] report bitrate', {
event,
bitrateKbps,
});
this.convivaVideoAnalytics.reportPlaybackMetric(Conviva.Constants.Playback.BITRATE, bitrateKbps);
this.debugLog('[ ConvivaAnalytics ] [ Player Event ] video quality changed', event);
this.convivaAnalyticsTracker.trackVideoQualityChanged(event);
};
private onCustomEvent = (event: PlayerEventBase) => {
this.debugLog('[ Player Event ] custom playback related event', event);
if (!this.isSessionActive()) {
this.debugLog('[ ConvivaAnalytics ] skip custom event, no session existing', event);
return;
}
this.debugLog('[ ConvivaAnalytics ] [ Player Event ] custom playback related event', event);
const eventAttributes = ObjectUtils.flatten(event);

@@ -759,78 +232,35 @@ this.sendCustomPlaybackEvent(event.type, eventAttributes);

private onAdBreakStarted = (event: AdBreakEvent) => {
this.debugLog('[ Player Event ] adbreak started', event);
this.isAdBreak = true;
this.debugLog('[ ConvivaAnalytics ] [ Player Event ] adbreak started', event);
this.lastAdBreakEvent = event;
this.debugLog('[ ConvivaAnalytics ] report ad break started', event);
this.convivaVideoAnalytics.reportAdBreakStarted(
Conviva.Constants.AdType.CLIENT_SIDE,
Conviva.Constants.AdPlayer.SEPARATE,
);
this.convivaAnalyticsTracker.trackAdBreakStarted(Conviva.Constants.AdType.CLIENT_SIDE);
};
private onAdStarted = (event: AdEvent) => {
this.debugLog('[ Player Event ] ad started', event);
this.debugLog('[ ConvivaAnalytics ] [ Player Event ] ad started', event);
const adInfo = AdHelper.extractConvivaAdInfo(this.player, this.lastAdBreakEvent, event);
const adInfo = AdHelper.extractCsaiConvivaAdInfo(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);
}
this.convivaAnalyticsTracker.trackAdStarted(adInfo, Conviva.Constants.AdType.CLIENT_SIDE, bitrateKbps);
}
private onAdFinished = (event: AdEvent) => {
this.debugLog('[ Player Event ] ad finished', event);
this.debugLog('[ ConvivaAdAnalytics ] report ad ended', {
event,
});
this.convivaAdAnalytics.reportAdEnded();
this.debugLog('[ ConvivaAnalytics ] [ Player Event ] ad finished', event);
this.convivaAnalyticsTracker.trackAdFinished();
}
private onAdSkipped = (event: AdEvent) => {
this.debugLog('[ Player Event ] ad skipped', event);
this.debugLog('[ ConvivaAdAnalytics ] report ad skipped', event);
this.convivaAdAnalytics.reportAdSkipped();
this.debugLog('[ ConvivaAnalytics ] [ Player Event ] ad skipped', event);
this.convivaAnalyticsTracker.trackAdSkipped();
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(
Conviva.Constants.Playback.PLAYER_STATE,
Conviva.Constants.PlayerState.PLAYING,
);
private onAdBreakFinished = (event: AdBreakEvent) => {
this.debugLog('[ ConvivaAnalytics ] [ Player Event ] adbreak finished', event);
this.convivaAnalyticsTracker.trackAdBreakFinished();
};
private onAdError = (event: ErrorEvent) => {
this.debugLog('[ Player Event ] ad error', event);
const formattedError = AdHelper.formatAdErrorEvent(event);
this.debugLog('[ ConvivaAdAnalytics ] report ad error', {
event,
formattedError,
});
this.convivaAdAnalytics.reportAdError(formattedError, Conviva.Constants.ErrorSeverity.WARNING);
this.debugLog('[ ConvivaAnalytics ] [ Player Event ] ad error', event);
this.convivaAnalyticsTracker.trackAdError(event);
this.onCustomEvent(event);

@@ -840,11 +270,4 @@ };

private onSeek = (event: SeekEvent) => {
this.debugLog('[ Player Event ] seek', event);
if (!this.isSessionActive()) {
// Handle the case that the User seeks on the UI before play was triggered.
// This also handles startTime feature. The same applies for onTimeShift.
return;
}
this.trackSeekStart(event.seekTarget);
this.debugLog('[ ConvivaAnalytics ] [ Player Event ] seek', event);
this.convivaAnalyticsTracker.trackSeekStart(event.seekTarget);
this.onPlaybackStateChanged(event);

@@ -854,10 +277,4 @@ };

private onSeeked = (event: SeekEvent) => {
this.debugLog('[ Player Event ] seeked', event);
if (!this.isSessionActive()) {
// See comment in onSeek
return;
}
this.trackSeekEnd();
this.debugLog('[ ConvivaAnalytics ] [ Player Event ] seeked', event);
this.convivaAnalyticsTracker.trackSeekEnd();
this.onPlaybackStateChanged(event);

@@ -867,11 +284,5 @@ };

private onTimeShift = (event: TimeShiftEvent) => {
this.debugLog('[ Player Event ] time shift', event);
if (!this.isSessionActive()) {
// See comment in onSeek
return;
}
this.debugLog('[ ConvivaAnalytics ] [ Player Event ] time shift', event);
// According to conviva it is valid to pass -1 for seeking in live streams
this.trackSeekStart(-1);
this.convivaAnalyticsTracker.trackSeekStart(-1);
this.onPlaybackStateChanged(event);

@@ -881,140 +292,29 @@ };

private onTimeShifted = (event: TimeShiftEvent) => {
this.debugLog('[ Player Event ] time shifted', event);
if (!this.isSessionActive()) {
// See comment in onSeek
return;
}
this.trackSeekEnd();
this.debugLog('[ ConvivaAnalytics ] [ Player Event ] time shifted', event);
this.convivaAnalyticsTracker.trackSeekEnd();
this.onPlaybackStateChanged(event);
};
private trackSeekStart(target: number) {
this.debugLog('[ ConvivaAnalytics ] report seek started');
this.convivaVideoAnalytics.reportPlaybackMetric(Conviva.Constants.Playback.SEEK_STARTED);
}
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()) {
// Handle the case that the User change audio on the UI before play was triggered.
return;
}
this.updateAudioTrack(event.targetAudio);
this.debugLog('[ ConvivaAnalytics ] [ Player Event ] audio changed', event);
this.convivaAnalyticsTracker.trackUpdateAudioTrack(event.targetAudio);
};
private updateAudioTrack(audioTrack: AudioTrack) {
const formattedAudio =
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);
}
private onSubtitleEnabled = (event: SubtitleEvent) => {
this.debugLog('[ Player Event ] subtitled enabled', event);
if (!this.isSessionActive()) {
// Handle the case that the User change subtitle on the UI before play was triggered.
return;
}
this.updateSubtitleTrack(event.subtitle);
this.debugLog('[ ConvivaAnalytics ] [ Player Event ] subtitled enabled', event);
this.convivaAnalyticsTracker.trackUpdateSubtitleTrack(event.subtitle);
};
private updateSubtitleTrack(subtitleTrack: SubtitleTrack) {
const formattedSubtitle =
subtitleTrack.lang !== 'unknown' ? '[' + subtitleTrack.lang + ']:' + subtitleTrack.label : subtitleTrack.label;
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(
Conviva.Constants.Playback.CLOSED_CAPTIONS_LANGUAGE,
formattedSubtitle,
);
this.debugLog('[ ConvivaAnalytics ] report off subtitles language');
this.convivaVideoAnalytics.reportPlaybackMetric(Conviva.Constants.Playback.SUBTITLES_LANGUAGE, 'off');
} else {
this.turnOffSubtitles();
}
}
private onSubtitleDisabled = (event: SubtitleEvent) => {
this.debugLog('[ Player Event ] subtitles disabled', event);
if (!this.isSessionActive()) {
// Handle the case that the User turn off subtitle on the UI before play was triggered.
return;
}
this.turnOffSubtitles();
this.debugLog('[ ConvivaAnalytics ] [ Player Event ] subtitles disabled', event);
this.convivaAnalyticsTracker.trackTurnOffSubtitles();
};
private checkSubtitleWhenInternalInitialize() {
if (this.player.subtitles !== undefined) {
const enableSubtitle = this.player.subtitles.list().filter((i) => i.enabled);
// Send the session init subtitle language values.
if (enableSubtitle.length === 1) {
this.updateSubtitleTrack(enableSubtitle[0]);
return;
}
}
this.turnOffSubtitles();
}
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');
}
private onError = (event: ErrorEvent) => {
this.debugLog('[ Player Event ] error', event);
if (!this.isSessionActive() && !this.sessionEndedExternally) {
// initialize Session if not yet initialized to capture Video Start Failures
this.internalInitializeSession();
}
this.reportPlaybackDeficiency(String(event.code) + ' ' + event.name, Conviva.Constants.ErrorSeverity.FATAL);
this.debugLog('[ ConvivaAnalytics ] [ Player Event ] error', event);
this.convivaAnalyticsTracker.trackError(event);
};
private onSourceUnloaded = (event: PlayerEventBase) => {
this.debugLog('[ Player Event ] source unloaded', event);
if (this.isAdBreak) {
// Ignore sourceUnloaded events during ads
return;
} else {
this.internalEndSession(event);
this.resetContentMetadata();
}
};
private onDestroy = (event: any) => {
this.debugLog('[ Player Event ] destroy', event);
this.debugLog('[ ConvivaAnalytics ] [ Player Event ] destroy', event);
this.destroy(event);

@@ -1024,35 +324,31 @@ };

private registerPlayerEvents(): void {
const playerEvents = this.handlers;
this.handlers.add(this.events.Play, this.onPlay);
this.handlers.add(this.events.Playing, this.onPlaying);
this.handlers.add(this.events.Paused, this.onPlaybackStateChanged);
this.handlers.add(this.events.StallStarted, this.onPlaybackStateChanged);
this.handlers.add(this.events.StallEnded, this.onPlaybackStateChanged);
this.handlers.add(this.events.PlaybackFinished, this.onPlaybackFinished);
this.handlers.add(this.events.VideoPlaybackQualityChanged, this.onVideoQualityChanged);
this.handlers.add(this.events.AudioPlaybackQualityChanged, this.onCustomEvent);
this.handlers.add(this.events.Muted, this.onCustomEvent);
this.handlers.add(this.events.Unmuted, this.onCustomEvent);
this.handlers.add(this.events.ViewModeChanged, this.onCustomEvent);
this.handlers.add(this.events.AdStarted, this.onAdStarted);
this.handlers.add(this.events.AdFinished, this.onAdFinished);
this.handlers.add(this.events.AdBreakStarted, this.onAdBreakStarted);
this.handlers.add(this.events.AdBreakFinished, this.onAdBreakFinished);
this.handlers.add(this.events.AdSkipped, this.onAdSkipped);
this.handlers.add(this.events.AdError, this.onAdError);
this.handlers.add(this.events.Error, this.onError);
this.handlers.add(this.events.Destroy, this.onDestroy);
this.handlers.add(this.events.Seek, this.onSeek);
this.handlers.add(this.events.Seeked, this.onSeeked);
this.handlers.add(this.events.TimeShift, this.onTimeShift);
this.handlers.add(this.events.TimeShifted, this.onTimeShifted);
this.handlers.add(this.events.AudioChanged, this.onAudioChanged);
this.handlers.add(this.events.SubtitleEnabled, this.onSubtitleEnabled);
this.handlers.add(this.events.SubtitleDisabled, this.onSubtitleDisabled);
playerEvents.add(this.events.SourceLoaded, this.onSourceLoaded);
playerEvents.add(this.events.Play, this.onPlay);
playerEvents.add(this.events.Playing, this.onPlaying);
playerEvents.add(this.events.Paused, this.onPlaybackStateChanged);
playerEvents.add(this.events.StallStarted, this.onPlaybackStateChanged);
playerEvents.add(this.events.StallEnded, this.onPlaybackStateChanged);
playerEvents.add(this.events.PlaybackFinished, this.onPlaybackFinished);
playerEvents.add(this.events.VideoPlaybackQualityChanged, this.onVideoQualityChanged);
playerEvents.add(this.events.AudioPlaybackQualityChanged, this.onCustomEvent);
playerEvents.add(this.events.Muted, this.onCustomEvent);
playerEvents.add(this.events.Unmuted, this.onCustomEvent);
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);
playerEvents.add(this.events.AdBreakFinished, this.onAdBreakFinished);
playerEvents.add(this.events.AdSkipped, this.onAdSkipped);
playerEvents.add(this.events.AdError, this.onAdError);
playerEvents.add(this.events.SourceUnloaded, this.onSourceUnloaded);
playerEvents.add(this.events.Error, this.onError);
playerEvents.add(this.events.Destroy, this.onDestroy);
playerEvents.add(this.events.Seek, this.onSeek);
playerEvents.add(this.events.Seeked, this.onSeeked);
playerEvents.add(this.events.TimeShift, this.onTimeShift);
playerEvents.add(this.events.TimeShifted, this.onTimeShifted);
playerEvents.add(this.events.AudioChanged, this.onAudioChanged);
playerEvents.add(this.events.SubtitleEnabled, this.onSubtitleEnabled);
playerEvents.add(this.events.SubtitleDisabled, this.onSubtitleDisabled);
playerEvents.add(this.events.CastStarted, this.onCustomEvent);
playerEvents.add(this.events.CastStopped, this.onCustomEvent);
this.handlers.add(this.events.CastStarted, this.onCustomEvent);
this.handlers.add(this.events.CastStopped, this.onCustomEvent);
}

@@ -1063,102 +359,2 @@

}
static get version(): string {
return ConvivaAnalytics.VERSION;
}
}
class PlayerConfigHelper {
/**
* The config for autoplay and preload have great impact to the VST (Video Startup Time) we track it.
* Since there is no way to get default config values from the player they are hardcoded.
*/
public static AUTOPLAY_DEFAULT_CONFIG: boolean = false;
/**
* Extract autoplay config form player
*
* @param player: Player
*/
public static getAutoplayConfig(player: Player): boolean {
const playerConfig = player.getConfig();
if (playerConfig.playback && playerConfig.playback.autoplay !== undefined) {
return playerConfig.playback.autoplay;
} else {
return PlayerConfigHelper.AUTOPLAY_DEFAULT_CONFIG;
}
}
/**
* Extract preload config from player
*
* The preload config can be set individual for mobile or desktop as well as on root level for both platforms.
* Default value is true for VOD and false for live streams. If the value is not set for current platform or on root
* level the default value will be used over the value for the other platform.
*
* @param player: Player
*/
public static getPreloadConfig(player: Player): boolean {
const playerConfig = player.getConfig();
if (BrowserUtils.isMobile()) {
if (
playerConfig.adaptation &&
playerConfig.adaptation.mobile &&
playerConfig.adaptation.mobile.preload !== undefined
) {
return playerConfig.adaptation.mobile.preload;
}
} else {
if (
playerConfig.adaptation &&
playerConfig.adaptation.desktop &&
playerConfig.adaptation.desktop.preload !== undefined
) {
return playerConfig.adaptation.desktop.preload;
}
}
if (playerConfig.adaptation && playerConfig.adaptation.preload !== undefined) {
return playerConfig.adaptation.preload;
}
return !player.isLive();
}
}
class PlayerEventWrapper {
private player: Player;
private readonly eventHandlers: { [eventType: string]: Array<(event?: PlayerEventBase) => void> };
constructor(player: Player) {
this.player = player;
this.eventHandlers = {};
}
public add(eventType: PlayerEvent, callback: (event?: PlayerEventBase) => void): void {
this.player.on(eventType, callback);
if (!this.eventHandlers[eventType]) {
this.eventHandlers[eventType] = [];
}
this.eventHandlers[eventType].push(callback);
}
public remove(eventType: PlayerEvent, callback: (event?: PlayerEventBase) => void): void {
this.player.off(eventType, callback);
if (this.eventHandlers[eventType]) {
ArrayUtils.remove(this.eventHandlers[eventType], callback);
}
}
public clear(): void {
for (const eventType in this.eventHandlers) {
for (const callback of this.eventHandlers[eventType]) {
this.remove(eventType as PlayerEvent, callback);
}
}
}
}
import { Ad, AdBreak, AdBreakEvent, AdData, AdEvent, ErrorEvent, LinearAd, PlayerAPI, VastAdData } from 'bitmovin-player';
import * as Conviva from '@convivainc/conviva-js-coresdk';
import { INTEGRATION_VERSION_CONTENT_METADATA_CUSTOM_TAG, STREAM_TYPE_CONTENT_METADATA_CUSTOM_TAG } from '../ConvivaAnalyticsTracker';
export interface SsaiAdInfo {
/**
* The ad ID extracted from the ad server that contains the ad creative.
*/
id: string;
/**
* The title of the ad.
*/
title?: string;
/**
* Duration of the ad, in seconds.
*/
duration?: number;
/**
* The name of the ad system (i.e., the ad server).
*/
adSystem?: string;
/**
* The position of the ad.
*/
position?: Conviva.valueof<Conviva.ConvivaConstants['AdPosition']>;
/**
* Indicates whether this ad is a slate or not. Set to <code>true</code> for slate and <code>false</code> for a regular ad.
*/
isSlate?: boolean;
/**
* The name of the ad stitcher.
*/
adStitcher?: string;
/**
* Additional ad metadata. This is a map of key-value pairs that can be used to pass additional metadata about the ad.
* A list of ad metadata can be found here: <a href="https://pulse.conviva.com/learning-center/content/sensor_developer_center/sensor_integration/javascript/javascript_stream_sensor.htm#IntegrateAdManagers">Conviva documentation</a>
* <p>
* Metadata provided here will supersede any data provided in the ad break info.
*/
additionalMetadata?: Record<string, string>;
}
export class AdHelper {
public static mapAdPosition(
public static mapCsaiAdPosition(
adBreak: AdBreak,

@@ -20,3 +59,3 @@ player: PlayerAPI,

public static formatAdErrorEvent(event: ErrorEvent & {
public static formatCsaiAdError(event: ErrorEvent & {
data?: {

@@ -41,4 +80,3 @@ code?: number,

public static extractConvivaAdInfo(player: PlayerAPI, adBreakEvent: AdBreakEvent, adEvent: AdEvent): Conviva.ConvivaMetadata {
const adPosition = AdHelper.mapAdPosition(adBreakEvent.adBreak, player);
public static extractCsaiConvivaAdInfo(player: PlayerAPI, adBreakEvent: AdBreakEvent, adEvent: AdEvent): Conviva.ConvivaMetadata {
const ad = adEvent.ad as Ad | LinearAd;

@@ -49,15 +87,6 @@ const adData = ad.data as undefined | AdData | VastAdData;

let creativeId = 'NA';
let adTitle: string | undefined;
let adTitle = 'NA';
let firstAdId = ad.id;
// TODO these two are not exposed currently. Add them whenever the player
// exposes them similar to https://github.com/bitmovin-engineering/player-android/pull/3147.
// Related discussion https://bitmovin.slack.com/archives/C0LJ16JBS/p1716801796326889.
let firstAdSystem = 'NA';
let firstCreativeId = 'NA';
// TODO This is not exposed currently. Add it whenever the player
// exposes it. Related discussion https://bitmovin.slack.com/archives/C0LJ16JBS/p1716801970037469.
let mediaFileApiFramework = 'NA';
if (adData) {

@@ -84,11 +113,21 @@ if ('adSystem' in adData && adData.adSystem?.name) {

'c3.ad.technology': Conviva.Constants.AdType.CLIENT_SIDE,
'c3.ad.position': adPosition,
'c3.ad.position': AdHelper.mapCsaiAdPosition(adBreakEvent.adBreak, player),
'c3.ad.system': adSystemName,
'c3.ad.creativeId': creativeId,
'c3.ad.firstAdId': firstAdId,
'c3.ad.mediaFileApiFramework': mediaFileApiFramework,
'c3.ad.firstAdSystem': firstAdSystem,
'c3.ad.firstCreativeId': firstCreativeId,
[Conviva.Constants.ASSET_NAME]: adTitle,
[Conviva.Constants.STREAM_URL]: ad.mediaFileUrl || 'NA',
// These two are not relevant for the client side (keep in the code for documentation purposes)
// TODO This is not exposed currently. Add it whenever the player
// exposes it. Related discussion https://bitmovin.slack.com/archives/C0LJ16JBS/p1716801970037469.
'c3.ad.mediaFileApiFramework': 'NA',
// TODO these two are not exposed currently. Add them whenever the player
// exposes them similar to https://github.com/bitmovin-engineering/player-android/pull/3147.
// Related discussion https://bitmovin.slack.com/archives/C0LJ16JBS/p1716801796326889.
'c3.ad.firstAdSystem': 'NA',
'c3.ad.firstCreativeId': 'NA',
// These are not relevant for the client side (keep in the code for documentation purposes)
// 'c3.ad.adStitcher': undefined,

@@ -98,12 +137,49 @@ // 'c3.ad.isSlate': undefined,

if (adTitle) {
adInfo[Conviva.Constants.ASSET_NAME] = adTitle;
if ('duration' in ad && ad.duration) {
adInfo[Conviva.Constants.DURATION] = ad.duration;
}
if (ad.mediaFileUrl) {
adInfo[Conviva.Constants.STREAM_URL] = ad.mediaFileUrl;
}
return adInfo;
}
if ('duration' in ad && ad.duration) {
adInfo[Conviva.Constants.DURATION] = ad.duration;
public static convertSsaiAdInfoToConvivaAdInfo(ssaiAdInfo: SsaiAdInfo, allCurrentContentMetadata: Conviva.ConvivaMetadata): Conviva.ConvivaMetadata {
const keysToPick = [
INTEGRATION_VERSION_CONTENT_METADATA_CUSTOM_TAG,
STREAM_TYPE_CONTENT_METADATA_CUSTOM_TAG,
Conviva.Constants.ASSET_NAME,
Conviva.Constants.IS_LIVE,
Conviva.Constants.DEFAULT_RESOURCE,
Conviva.Constants.ENCODED_FRAMERATE,
Conviva.Constants.VIEWER_ID,
Conviva.Constants.PLAYER_NAME,
];
const selectedCurrentContentMetadata: Record<string, string> = {};
keysToPick.forEach(key => {
selectedCurrentContentMetadata[key] = allCurrentContentMetadata[key];
});
const adInfo: Conviva.ConvivaMetadata = {
...selectedCurrentContentMetadata,
...ssaiAdInfo.additionalMetadata,
'c3.ad.id': ssaiAdInfo.id,
'c3.ad.technology': Conviva.Constants.AdType.SERVER_SIDE,
'c3.ad.position': ssaiAdInfo.position || 'NA',
'c3.ad.system': ssaiAdInfo.adSystem || 'NA',
[Conviva.Constants.ASSET_NAME]: ssaiAdInfo.title || selectedCurrentContentMetadata[Conviva.Constants.ASSET_NAME] || 'NA',
'c3.ad.adStitcher': ssaiAdInfo.adStitcher || 'NA',
'c3.ad.isSlate': ssaiAdInfo.isSlate === undefined ? 'NA' : ssaiAdInfo.isSlate.toString(),
// These are not relevant for the server side (keep in the code for documentation purposes)
// 'c3.ad.creativeId': undefined,
// 'c3.ad.firstAdId': undefined,
// [Conviva.Constants.STREAM_URL]: undefined,
// 'c3.ad.firstAdSystem': undefined,
// 'c3.ad.firstCreativeId': undefined,
// 'c3.ad.mediaFileApiFramework': undefined
};
if (ssaiAdInfo.duration) {
adInfo[Conviva.Constants.DURATION] = ssaiAdInfo.duration;
}

@@ -110,0 +186,0 @@

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

import { EventAttributes } from '../ConvivaAnalytics';
import { EventAttributes } from '../ConvivaAnalyticsTracker';

@@ -3,0 +3,0 @@ export namespace ObjectUtils {

// Import to extend Conviva types.
import './conviva/ConvivaExtension';
export { ConvivaAnalytics, ConvivaAnalyticsConfiguration, EventAttributes } from './ConvivaAnalytics';
export { ConvivaAnalyticsConfiguration, EventAttributes } from './ConvivaAnalyticsTracker';
export { ConvivaAnalytics } from './ConvivaAnalytics';
export { Metadata } from './ContentMetadataBuilder';
export { SsaiAdInfo } from './helper/AdHelper';

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

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