diff --git a/conviva/src/main/java/com/bitmovin/analytics/conviva/BitmovinPlayerHelper.java b/conviva/src/main/java/com/bitmovin/analytics/conviva/BitmovinPlayerHelper.java deleted file mode 100644 index c1c4b6e..0000000 --- a/conviva/src/main/java/com/bitmovin/analytics/conviva/BitmovinPlayerHelper.java +++ /dev/null @@ -1,31 +0,0 @@ -package com.bitmovin.analytics.conviva; - -import com.bitmovin.player.api.Player; - -class BitmovinPlayerHelper { - private final Player player; - - BitmovinPlayerHelper(Player player) { - this.player = player; - } - - String getSdkVersionString() { - return Player.getSdkVersion(); - } - - String getStreamType() { - if (player.getSource() == null) { - return null; - } else { - return player.getSource().getConfig().getType().name(); - } - } - - String getStreamUrl() { - if (player.getSource() == null) { - return null; - } else { - return player.getSource().getConfig().getUrl(); - } - } -} diff --git a/conviva/src/main/java/com/bitmovin/analytics/conviva/ConvivaAnalyticsIntegration.java b/conviva/src/main/java/com/bitmovin/analytics/conviva/ConvivaAnalyticsIntegration.java index 01ab80f..88cfb62 100644 --- a/conviva/src/main/java/com/bitmovin/analytics/conviva/ConvivaAnalyticsIntegration.java +++ b/conviva/src/main/java/com/bitmovin/analytics/conviva/ConvivaAnalyticsIntegration.java @@ -4,9 +4,9 @@ import android.os.Handler; import android.util.Log; -import com.bitmovin.analytics.conviva.ssai.DefaultPlaybackInfoProvider; +import androidx.annotation.NonNull; + import com.bitmovin.analytics.conviva.ssai.DefaultSsaiApi; -import com.bitmovin.analytics.conviva.ssai.PlaybackInfoProvider; import com.bitmovin.analytics.conviva.ssai.SsaiApi; import com.bitmovin.player.api.Player; import com.bitmovin.player.api.advertising.Ad; @@ -18,8 +18,6 @@ import com.bitmovin.player.api.event.EventListener; import com.bitmovin.player.api.event.PlayerEvent; import com.bitmovin.player.api.event.SourceEvent; -import com.bitmovin.player.api.source.Source; -import com.bitmovin.player.api.source.SourceConfig; import com.conviva.sdk.ConvivaAdAnalytics; import com.conviva.sdk.ConvivaAnalytics; import com.conviva.sdk.ConvivaExperienceAnalytics; @@ -36,18 +34,14 @@ public class ConvivaAnalyticsIntegration { private static final String TAG = "ConvivaAnalyticsInt"; - private final Player bitmovinPlayer; private final ContentMetadataBuilder contentMetadataBuilder = new ContentMetadataBuilder(); private final ConvivaVideoAnalytics convivaVideoAnalytics; private final ConvivaAdAnalytics convivaAdAnalytics; - private final PlaybackInfoProvider playbackInfoProvider; + @NonNull + private final PlayerDecorator player; private MetadataOverrides metadataOverrides; private final DefaultSsaiApi ssai; - - // Wrapper to extract bitmovinPlayer helper methods - private final BitmovinPlayerHelper playerHelper; - // Helper private Boolean isSessionActive = false; private Boolean isBumper = false; @@ -75,8 +69,7 @@ public ConvivaAnalyticsIntegration( ConvivaAdAnalytics adAnalytics, DefaultSsaiApi ssai ) { - this.bitmovinPlayer = player; - this.playerHelper = new BitmovinPlayerHelper(player); + this.player = new DefaultPlayerDecorator(player); Map settings = new HashMap<>(); if (config.getGatewayUrl() != null || config.isDebugLoggingEnabled()) { if (config.getGatewayUrl() != null) { @@ -98,10 +91,9 @@ public ConvivaAnalyticsIntegration( } else { convivaAdAnalytics = adAnalytics; } - playbackInfoProvider = new DefaultPlaybackInfoProvider(player); if (ssai == null) { - this.ssai = new DefaultSsaiApi(convivaVideoAnalytics, convivaAdAnalytics, playbackInfoProvider); + this.ssai = new DefaultSsaiApi(convivaVideoAnalytics, convivaAdAnalytics, this.player); } else { this.ssai = ssai; } @@ -115,7 +107,7 @@ private void setUpAdAnalyticsCallback() { @Override public void update() { if (isAdActive()) { - convivaAdAnalytics.reportAdMetric(ConvivaSdkConstants.PLAYBACK.PLAY_HEAD_TIME, ((long) (bitmovinPlayer.getCurrentTime() * 1000))); + convivaAdAnalytics.reportAdMetric(ConvivaSdkConstants.PLAYBACK.PLAY_HEAD_TIME, ((long) (player.getPlayHeadTimeMillis()))); } } @@ -126,7 +118,7 @@ public void update(String s) { } private boolean isAdActive() { - return bitmovinPlayer.isAd() || ssai.isAdBreakActive(); + return player.isAd() || ssai.isAdBreakActive(); } // region public methods @@ -163,7 +155,7 @@ public void sendCustomPlaybackEvent(String name, Map attributes) * If no source was loaded this method will throw an error. */ public void initializeSession() throws ConvivaAnalyticsException { - if ((bitmovinPlayer.getSource() == null || bitmovinPlayer.getSource().getConfig().getTitle() == null) + if ((player.getStreamTitle() == null) && this.contentMetadataBuilder.getAssetName() == null) { throw new ConvivaAnalyticsException( "AssetName is missing. Load player source (with Title) first or set assetName via updateContentMetadata" @@ -308,7 +300,7 @@ private void setupPlayerStateManager() { convivaVideoAnalytics.reportPlaybackMetric(ConvivaSdkConstants.PLAYBACK.PLAYER_STATE, ConvivaSdkConstants.PlayerState.STOPPED); Map playerInfo = new HashMap<>(); playerInfo.put(ConvivaSdkConstants.FRAMEWORK_NAME, "Bitmovin Player Android"); - playerInfo.put(ConvivaSdkConstants.FRAMEWORK_VERSION, playerHelper.getSdkVersionString()); + playerInfo.put(ConvivaSdkConstants.FRAMEWORK_VERSION, Player.getSdkVersion()); convivaVideoAnalytics.setPlayerInfo(playerInfo); convivaAdAnalytics.setAdPlayerInfo(playerInfo); } @@ -337,7 +329,7 @@ private void updateSession() { } private void updatePlaybackVideoData() { - HashMap playbackVideoData = playbackInfoProvider.getPlaybackVideoData(); + HashMap playbackVideoData = player.getPlaybackVideoData(); for (Map.Entry entry : playbackVideoData.entrySet()) { convivaVideoAnalytics.reportPlaybackMetric(entry.getKey(), entry.getValue()); if (ssai.isAdBreakActive()) { @@ -347,14 +339,18 @@ private void updatePlaybackVideoData() { } private void createContentMetadata() { - Source source = bitmovinPlayer.getSource(); - if (source != null) { - SourceConfig sourceConfig = source.getConfig(); - String overriddenAssetName = metadataOverrides != null ? metadataOverrides.getAssetName() : null; - - contentMetadataBuilder.setAssetName(overriddenAssetName != null ? overriddenAssetName : sourceConfig.getTitle()); + String overriddenAssetName = metadataOverrides != null ? metadataOverrides.getAssetName() : null; + if (overriddenAssetName != null) { + contentMetadataBuilder.setAssetName(overriddenAssetName); + } else { + if (player.getStreamTitle() != null) { + contentMetadataBuilder.setAssetName(player.getStreamTitle()); + } else { + Log.w(TAG, "No asset name provided for content metadata."); + } } - this.buildDynamicContentMetadata(); + + buildDynamicContentMetadata(); } private void buildDynamicContentMetadata() { @@ -362,18 +358,18 @@ private void buildDynamicContentMetadata() { // streamType could be missing at time of session initialization // as source information could be unavailable at that time Map customInternTags = new HashMap<>(); - customInternTags.put(STREAM_TYPE, playerHelper.getStreamType()); + customInternTags.put(STREAM_TYPE, player.getStreamType()); customInternTags.put(INTEGRATION_VERSION, BuildConfig.VERSION_NAME); contentMetadataBuilder.setCustom(customInternTags); - if (bitmovinPlayer.isLive()) { + if (player.isLive()) { contentMetadataBuilder.setStreamType(ConvivaSdkConstants.StreamType.LIVE); } else { contentMetadataBuilder.setStreamType(ConvivaSdkConstants.StreamType.VOD); - contentMetadataBuilder.setDuration((int) bitmovinPlayer.getDuration()); + contentMetadataBuilder.setDuration((int) player.getDuration()); } - contentMetadataBuilder.setStreamUrl(playerHelper.getStreamUrl()); + contentMetadataBuilder.setStreamUrl(player.getStreamUrl()); } private void internalEndSession() { @@ -389,80 +385,83 @@ private void internalEndSession() { // endregion private void attachBitmovinEventListeners() { - bitmovinPlayer.on(SourceEvent.Unloaded.class, onSourceUnloadedListener); - bitmovinPlayer.on(PlayerEvent.Error.class, onPlayerErrorListener); - bitmovinPlayer.on(SourceEvent.Error.class, onSourceErrorListener); - bitmovinPlayer.on(PlayerEvent.Warning.class, onPlayerWarningListener); - bitmovinPlayer.on(SourceEvent.Warning.class, onSourceWarningListener); - - bitmovinPlayer.on(PlayerEvent.Muted.class, onMutedListener); - bitmovinPlayer.on(PlayerEvent.Unmuted.class, onUnmutedListener); - - // Playback state events - bitmovinPlayer.on(PlayerEvent.Play.class, onPlayListener); - bitmovinPlayer.on(PlayerEvent.Playing.class, onPlayingListener); - bitmovinPlayer.on(PlayerEvent.Paused.class, onPausedListener); - bitmovinPlayer.on(PlayerEvent.StallEnded.class, onStallEndedListener); - bitmovinPlayer.on(PlayerEvent.StallStarted.class, onStallStartedListener); - bitmovinPlayer.on(PlayerEvent.PlaybackFinished.class, onPlaybackFinishedListener); - - // Seek events - bitmovinPlayer.on(PlayerEvent.Seeked.class, onSeekedListener); - bitmovinPlayer.on(PlayerEvent.Seek.class, onSeekListener); - - // Timeshift events - bitmovinPlayer.on(PlayerEvent.TimeShift.class, onTimeShiftListener); - bitmovinPlayer.on(PlayerEvent.TimeShifted.class, onTimeShiftedListener); - - // Ad events - bitmovinPlayer.on(PlayerEvent.AdBreakStarted.class, onAdBreakStarted); - bitmovinPlayer.on(PlayerEvent.AdBreakFinished.class, onAdBreakFinished); - bitmovinPlayer.on(PlayerEvent.AdStarted.class, onAdStartedListener); - bitmovinPlayer.on(PlayerEvent.AdFinished.class, onAdFinishedListener); - bitmovinPlayer.on(PlayerEvent.AdSkipped.class, onAdSkippedListener); - bitmovinPlayer.on(PlayerEvent.AdError.class, onAdErrorListener); - bitmovinPlayer.on(PlayerEvent.TimeChanged.class, onTimeChangedListener); - - bitmovinPlayer.on(PlayerEvent.VideoPlaybackQualityChanged.class, onVideoPlaybackQualityChangedListener); + player.withEventEmitter(eventEmitter -> { + eventEmitter.on(SourceEvent.Unloaded.class, onSourceUnloadedListener); + eventEmitter.on(PlayerEvent.Error.class, onPlayerErrorListener); + eventEmitter.on(SourceEvent.Error.class, onSourceErrorListener); + eventEmitter.on(PlayerEvent.Warning.class, onPlayerWarningListener); + eventEmitter.on(SourceEvent.Warning.class, onSourceWarningListener); + + eventEmitter.on(PlayerEvent.Muted.class, onMutedListener); + eventEmitter.on(PlayerEvent.Unmuted.class, onUnmutedListener); + + // Playback state events + eventEmitter.on(PlayerEvent.Play.class, onPlayListener); + eventEmitter.on(PlayerEvent.Playing.class, onPlayingListener); + eventEmitter.on(PlayerEvent.Paused.class, onPausedListener); + eventEmitter.on(PlayerEvent.StallEnded.class, onStallEndedListener); + eventEmitter.on(PlayerEvent.StallStarted.class, onStallStartedListener); + eventEmitter.on(PlayerEvent.PlaybackFinished.class, onPlaybackFinishedListener); + + // Seek events + eventEmitter.on(PlayerEvent.Seeked.class, onSeekedListener); + eventEmitter.on(PlayerEvent.Seek.class, onSeekListener); + + // Time shift events + eventEmitter.on(PlayerEvent.TimeShift.class, onTimeShiftListener); + eventEmitter.on(PlayerEvent.TimeShifted.class, onTimeShiftedListener); + + // Ad events + eventEmitter.on(PlayerEvent.AdBreakStarted.class, onAdBreakStarted); + eventEmitter.on(PlayerEvent.AdBreakFinished.class, onAdBreakFinished); + eventEmitter.on(PlayerEvent.AdStarted.class, onAdStartedListener); + eventEmitter.on(PlayerEvent.AdFinished.class, onAdFinishedListener); + eventEmitter.on(PlayerEvent.AdSkipped.class, onAdSkippedListener); + eventEmitter.on(PlayerEvent.AdError.class, onAdErrorListener); + eventEmitter.on(PlayerEvent.TimeChanged.class, onTimeChangedListener); + + eventEmitter.on(PlayerEvent.VideoPlaybackQualityChanged.class, onVideoPlaybackQualityChangedListener); + }); } private void detachBitmovinEventListeners() { - bitmovinPlayer.off(SourceEvent.Unloaded.class, onSourceUnloadedListener); - bitmovinPlayer.off(PlayerEvent.Error.class, onPlayerErrorListener); - bitmovinPlayer.off(SourceEvent.Error.class, onSourceErrorListener); - bitmovinPlayer.off(PlayerEvent.Warning.class, onPlayerWarningListener); - bitmovinPlayer.off(SourceEvent.Warning.class, onSourceWarningListener); - - bitmovinPlayer.off(PlayerEvent.Muted.class, onMutedListener); - bitmovinPlayer.off(PlayerEvent.Unmuted.class, onUnmutedListener); - - // Playback state events - bitmovinPlayer.off(PlayerEvent.Play.class, onPlayListener); - bitmovinPlayer.off(PlayerEvent.Playing.class, onPlayingListener); - bitmovinPlayer.off(PlayerEvent.Paused.class, onPausedListener); - bitmovinPlayer.off(PlayerEvent.StallEnded.class, onStallEndedListener); - bitmovinPlayer.off(PlayerEvent.StallStarted.class, onStallStartedListener); - bitmovinPlayer.off(PlayerEvent.PlaybackFinished.class, onPlaybackFinishedListener); - - // Seek events - bitmovinPlayer.off(PlayerEvent.Seeked.class, onSeekedListener); - bitmovinPlayer.off(PlayerEvent.Seek.class, onSeekListener); - - // Timeshift events - bitmovinPlayer.off(PlayerEvent.TimeShift.class, onTimeShiftListener); - bitmovinPlayer.off(PlayerEvent.TimeShifted.class, onTimeShiftedListener); - - // Ad events - bitmovinPlayer.off(PlayerEvent.AdBreakStarted.class, onAdBreakStarted); - bitmovinPlayer.off(PlayerEvent.AdBreakFinished.class, onAdBreakFinished); - bitmovinPlayer.off(PlayerEvent.AdStarted.class, onAdStartedListener); - bitmovinPlayer.off(PlayerEvent.AdFinished.class, onAdFinishedListener); - bitmovinPlayer.off(PlayerEvent.AdSkipped.class, onAdSkippedListener); - bitmovinPlayer.off(PlayerEvent.AdError.class, onAdErrorListener); - bitmovinPlayer.off(PlayerEvent.TimeChanged.class, onTimeChangedListener); - - bitmovinPlayer.off(PlayerEvent.VideoPlaybackQualityChanged.class, - onVideoPlaybackQualityChangedListener); + player.withEventEmitter(bitmovinPlayer -> { + bitmovinPlayer.off(SourceEvent.Unloaded.class, onSourceUnloadedListener); + bitmovinPlayer.off(PlayerEvent.Error.class, onPlayerErrorListener); + bitmovinPlayer.off(SourceEvent.Error.class, onSourceErrorListener); + bitmovinPlayer.off(PlayerEvent.Warning.class, onPlayerWarningListener); + bitmovinPlayer.off(SourceEvent.Warning.class, onSourceWarningListener); + + bitmovinPlayer.off(PlayerEvent.Muted.class, onMutedListener); + bitmovinPlayer.off(PlayerEvent.Unmuted.class, onUnmutedListener); + + // Playback state events + bitmovinPlayer.off(PlayerEvent.Play.class, onPlayListener); + bitmovinPlayer.off(PlayerEvent.Playing.class, onPlayingListener); + bitmovinPlayer.off(PlayerEvent.Paused.class, onPausedListener); + bitmovinPlayer.off(PlayerEvent.StallEnded.class, onStallEndedListener); + bitmovinPlayer.off(PlayerEvent.StallStarted.class, onStallStartedListener); + bitmovinPlayer.off(PlayerEvent.PlaybackFinished.class, onPlaybackFinishedListener); + + // Seek events + bitmovinPlayer.off(PlayerEvent.Seeked.class, onSeekedListener); + bitmovinPlayer.off(PlayerEvent.Seek.class, onSeekListener); + + // Timeshift events + bitmovinPlayer.off(PlayerEvent.TimeShift.class, onTimeShiftListener); + bitmovinPlayer.off(PlayerEvent.TimeShifted.class, onTimeShiftedListener); + + // Ad events + bitmovinPlayer.off(PlayerEvent.AdBreakStarted.class, onAdBreakStarted); + bitmovinPlayer.off(PlayerEvent.AdBreakFinished.class, onAdBreakFinished); + bitmovinPlayer.off(PlayerEvent.AdStarted.class, onAdStartedListener); + bitmovinPlayer.off(PlayerEvent.AdFinished.class, onAdFinishedListener); + bitmovinPlayer.off(PlayerEvent.AdSkipped.class, onAdSkippedListener); + bitmovinPlayer.off(PlayerEvent.AdError.class, onAdErrorListener); + bitmovinPlayer.off(PlayerEvent.TimeChanged.class, onTimeChangedListener); + + bitmovinPlayer.off(PlayerEvent.VideoPlaybackQualityChanged.class, onVideoPlaybackQualityChangedListener); + }); } private synchronized void transitionState(ConvivaSdkConstants.PlayerState state) { @@ -586,7 +585,7 @@ public void onEvent(PlayerEvent.StallEnded stallEndedEvent) { new Handler().postDelayed(() -> { Log.d(TAG, "[Player Event] StallEnded"); ConvivaSdkConstants.PlayerState state = ConvivaSdkConstants.PlayerState.PLAYING; - if (bitmovinPlayer.isPaused()) { + if (player.isPaused()) { state = ConvivaSdkConstants.PlayerState.PAUSED; } transitionState(state); @@ -632,7 +631,7 @@ public void setSeekEnd() { // Notify of seek buffering complete at this stage. Log.d(TAG, "[Player Event] Update state after buffering"); ConvivaSdkConstants.PlayerState state = ConvivaSdkConstants.PlayerState.PAUSED; - if (bitmovinPlayer.isPlaying()) { + if (player.isPlaying()) { state = ConvivaSdkConstants.PlayerState.PLAYING; } transitionState(state); @@ -703,7 +702,7 @@ private Map adStartedToAdInfo(PlayerEvent.AdStarted adStartedEve adInfo.put(ConvivaSdkConstants.FRAMEWORK_VERSION, imaSdkVersion); } else { adInfo.put(ConvivaSdkConstants.FRAMEWORK_NAME, "Bitmovin"); - adInfo.put(ConvivaSdkConstants.FRAMEWORK_VERSION, playerHelper.getSdkVersionString()); + adInfo.put(ConvivaSdkConstants.FRAMEWORK_VERSION, Player.getSdkVersion()); } adInfo.put("c3.ad.position", getAdPosition(adStartedEvent.getTimeOffset())); adInfo.put(ConvivaSdkConstants.DURATION, adStartedEvent.getDuration()); @@ -756,7 +755,7 @@ private ConvivaSdkConstants.AdPosition getAdPosition(double timeOffset) { ConvivaSdkConstants.AdPosition adPosition = ConvivaSdkConstants.AdPosition.MIDROLL; if (timeOffset == 0.0) { adPosition = ConvivaSdkConstants.AdPosition.PREROLL; - } else if (timeOffset == bitmovinPlayer.getDuration()) { + } else if (timeOffset == player.getDuration()) { adPosition = ConvivaSdkConstants.AdPosition.POSTROLL; } return adPosition; @@ -796,24 +795,10 @@ public void onEvent(PlayerEvent.AdError adError) { private final EventListener onTimeChangedListener = new EventListener() { @Override public void onEvent(PlayerEvent.TimeChanged timeChangedEvent) { - if (bitmovinPlayer.isLive()) { - double playerTimeshiftMax = bitmovinPlayer.getMaxTimeShift(); - double playerTimeshift = bitmovinPlayer.getTimeShift(); - long playerDurationMs = -(Math.round(playerTimeshiftMax * 1000)); - long playerPositionMs = playerDurationMs - -(Math.round(playerTimeshift * 1000)); - reportPlayHeadTime(playerPositionMs); - } else { - double currentTime = bitmovinPlayer.getCurrentTime(); - long playerDurationMs = (long) (currentTime * 1000); - reportPlayHeadTime(playerDurationMs); + if (isSessionActive) { + convivaVideoAnalytics.reportPlaybackMetric(ConvivaSdkConstants.PLAYBACK.PLAY_HEAD_TIME, player.getPlayHeadTimeMillis()); } } }; - - private void reportPlayHeadTime(long playerDurationMs) { - if (isSessionActive) { - convivaVideoAnalytics.reportPlaybackMetric(ConvivaSdkConstants.PLAYBACK.PLAY_HEAD_TIME, playerDurationMs); - } - } // endregion } diff --git a/conviva/src/main/java/com/bitmovin/analytics/conviva/ssai/DefaultPlaybackInfoProvider.java b/conviva/src/main/java/com/bitmovin/analytics/conviva/DefaultPlayerDecorator.java similarity index 50% rename from conviva/src/main/java/com/bitmovin/analytics/conviva/ssai/DefaultPlaybackInfoProvider.java rename to conviva/src/main/java/com/bitmovin/analytics/conviva/DefaultPlayerDecorator.java index e8cab57..d809e38 100644 --- a/conviva/src/main/java/com/bitmovin/analytics/conviva/ssai/DefaultPlaybackInfoProvider.java +++ b/conviva/src/main/java/com/bitmovin/analytics/conviva/DefaultPlayerDecorator.java @@ -1,15 +1,16 @@ -package com.bitmovin.analytics.conviva.ssai; +package com.bitmovin.analytics.conviva; +import com.bitmovin.analytics.conviva.helper.WithEventEmitter; import com.bitmovin.player.api.Player; import com.bitmovin.player.api.media.video.quality.VideoQuality; import com.conviva.sdk.ConvivaSdkConstants; import java.util.HashMap; -public class DefaultPlaybackInfoProvider implements PlaybackInfoProvider { +public class DefaultPlayerDecorator implements PlayerDecorator { private final Player player; - public DefaultPlaybackInfoProvider(Player player) { + public DefaultPlayerDecorator(Player player) { this.player = player; } @@ -44,4 +45,63 @@ public HashMap getPlaybackVideoData() { } return videoData; } + + @Override + public String getStreamTitle() { + return player.getSource() == null ? null : player.getSource().getConfig().getTitle(); + } + + @Override + public String getStreamType() { + return player.getSource() == null ? null : player.getSource().getConfig().getType().name(); + } + + @Override + public String getStreamUrl() { + return player.getSource() == null ? null : player.getSource().getConfig().getUrl(); + } + + + @Override + public boolean isAd() { + return player.isAd(); + } + + @Override + public boolean isLive() { + return player.isLive(); + } + + @Override + public boolean isPaused() { + return player.isPaused(); + } + + @Override + public boolean isPlaying() { + return player.isPlaying(); + } + + @Override + public double getDuration() { + return player.getDuration(); + } + + @Override + public long getPlayHeadTimeMillis() { + if (player.isLive()) { + double playerTimeShiftMax = player.getMaxTimeShift(); + double playerTimeShift = player.getTimeShift(); + long playerDurationMs = -(Math.round(playerTimeShiftMax * 1000)); + return playerDurationMs - -(Math.round(playerTimeShift * 1000)); + } else { + double currentTime = player.getCurrentTime(); + return (long) (currentTime * 1000); + } + } + + @Override + public void withEventEmitter(WithEventEmitter withEventEmitter) { + withEventEmitter.call(player); + } } diff --git a/conviva/src/main/java/com/bitmovin/analytics/conviva/PlayerDecorator.java b/conviva/src/main/java/com/bitmovin/analytics/conviva/PlayerDecorator.java new file mode 100644 index 0000000..629c8d5 --- /dev/null +++ b/conviva/src/main/java/com/bitmovin/analytics/conviva/PlayerDecorator.java @@ -0,0 +1,32 @@ +package com.bitmovin.analytics.conviva; + +import com.bitmovin.analytics.conviva.helper.WithEventEmitter; +import com.conviva.sdk.ConvivaSdkConstants; + +import java.util.HashMap; + +public interface PlayerDecorator { + ConvivaSdkConstants.PlayerState getPlayerState(); + + HashMap getPlaybackVideoData(); + + boolean isAd(); + + String getStreamTitle(); + + String getStreamType(); + + String getStreamUrl(); + + long getPlayHeadTimeMillis(); + + boolean isLive(); + + double getDuration(); + + void withEventEmitter(WithEventEmitter withEventEmitter); + + boolean isPaused(); + + boolean isPlaying(); +} diff --git a/conviva/src/main/java/com/bitmovin/analytics/conviva/helper/WithEventEmitter.java b/conviva/src/main/java/com/bitmovin/analytics/conviva/helper/WithEventEmitter.java new file mode 100644 index 0000000..6a342b3 --- /dev/null +++ b/conviva/src/main/java/com/bitmovin/analytics/conviva/helper/WithEventEmitter.java @@ -0,0 +1,8 @@ +package com.bitmovin.analytics.conviva.helper; + +import com.bitmovin.player.api.event.Event; +import com.bitmovin.player.api.event.JavaEventEmitter; + +public interface WithEventEmitter { + void call(JavaEventEmitter player); +} diff --git a/conviva/src/main/java/com/bitmovin/analytics/conviva/ssai/DefaultSsaiApi.java b/conviva/src/main/java/com/bitmovin/analytics/conviva/ssai/DefaultSsaiApi.java index b43b0bd..4f93fcc 100644 --- a/conviva/src/main/java/com/bitmovin/analytics/conviva/ssai/DefaultSsaiApi.java +++ b/conviva/src/main/java/com/bitmovin/analytics/conviva/ssai/DefaultSsaiApi.java @@ -3,6 +3,7 @@ import android.util.Log; import com.bitmovin.analytics.conviva.ConvivaAnalyticsIntegration; +import com.bitmovin.analytics.conviva.PlayerDecorator; import com.conviva.sdk.ConvivaAdAnalytics; import com.conviva.sdk.ConvivaSdkConstants; import com.conviva.sdk.ConvivaVideoAnalytics; @@ -15,9 +16,13 @@ public class DefaultSsaiApi implements SsaiApi { private static final String TAG = "DefaultSsaiApi"; private final ConvivaVideoAnalytics convivaVideoAnalytics; private final ConvivaAdAnalytics convivaAdAnalytics; - private final PlaybackInfoProvider player; + private final PlayerDecorator player; - public DefaultSsaiApi(ConvivaVideoAnalytics convivaVideoAnalytics, ConvivaAdAnalytics convivaAdAnalytics, PlaybackInfoProvider player) { + public DefaultSsaiApi( + ConvivaVideoAnalytics convivaVideoAnalytics, + ConvivaAdAnalytics convivaAdAnalytics, + PlayerDecorator player + ) { this.convivaVideoAnalytics = convivaVideoAnalytics; this.convivaAdAnalytics = convivaAdAnalytics; this.player = player; diff --git a/conviva/src/main/java/com/bitmovin/analytics/conviva/ssai/PlaybackInfoProvider.java b/conviva/src/main/java/com/bitmovin/analytics/conviva/ssai/PlaybackInfoProvider.java deleted file mode 100644 index 43ddd39..0000000 --- a/conviva/src/main/java/com/bitmovin/analytics/conviva/ssai/PlaybackInfoProvider.java +++ /dev/null @@ -1,11 +0,0 @@ -package com.bitmovin.analytics.conviva.ssai; - -import com.conviva.sdk.ConvivaSdkConstants; - -import java.util.HashMap; - -public interface PlaybackInfoProvider { - ConvivaSdkConstants.PlayerState getPlayerState(); - - HashMap getPlaybackVideoData(); -} diff --git a/conviva/src/test/kotlin/com/bitmovin/analytics/conviva/ssai/DefaultSsaiApiTest.kt b/conviva/src/test/kotlin/com/bitmovin/analytics/conviva/ssai/DefaultSsaiApiTest.kt index f3c7049..4f9b319 100644 --- a/conviva/src/test/kotlin/com/bitmovin/analytics/conviva/ssai/DefaultSsaiApiTest.kt +++ b/conviva/src/test/kotlin/com/bitmovin/analytics/conviva/ssai/DefaultSsaiApiTest.kt @@ -1,6 +1,7 @@ package com.bitmovin.analytics.conviva.ssai import android.util.Log +import com.bitmovin.analytics.conviva.PlayerDecorator import com.conviva.sdk.ConvivaAdAnalytics import com.conviva.sdk.ConvivaSdkConstants import com.conviva.sdk.ConvivaVideoAnalytics @@ -29,13 +30,13 @@ import strikt.assertions.isTrue class DefaultSsaiApiTest { private val videoAnalytics: ConvivaVideoAnalytics = mockk(relaxed = true) private val adAnalytics: ConvivaAdAnalytics = mockk() - private val playbackInfoProvider = mockk() + private val playerDecorator = mockk() private lateinit var ssaiApi: DefaultSsaiApi @Before fun beforeTest() { - every { playbackInfoProvider.playerState } returns ConvivaSdkConstants.PlayerState.PLAYING - every { playbackInfoProvider.playbackVideoData } returns hashMapOf>( + every { playerDecorator.playerState } returns ConvivaSdkConstants.PlayerState.PLAYING + every { playerDecorator.playbackVideoData } returns hashMapOf>( ConvivaSdkConstants.PLAYBACK.BITRATE to arrayOf(1), ConvivaSdkConstants.PLAYBACK.RESOLUTION to arrayOf(800, 1600), ConvivaSdkConstants.PLAYBACK.RENDERED_FRAMERATE to arrayOf(60), @@ -52,15 +53,15 @@ class DefaultSsaiApiTest { } ssaiApi = DefaultSsaiApi( - videoAnalytics, - adAnalytics, - playbackInfoProvider, + videoAnalytics, + adAnalytics, + playerDecorator, ) } @After fun afterTest() { - clearMocks(videoAnalytics, adAnalytics, playbackInfoProvider) + clearMocks(videoAnalytics, adAnalytics, playerDecorator) } @@ -131,7 +132,7 @@ class DefaultSsaiApiTest { @Test fun `reports ad playback state playing to conviva when ad starts while paused`() { - every { playbackInfoProvider.playerState } returns ConvivaSdkConstants.PlayerState.PAUSED + every { playerDecorator.playerState } returns ConvivaSdkConstants.PlayerState.PAUSED ssaiApi.reportAdBreakStarted() ssaiApi.reportAdStarted(SsaiApi.AdInfo()) @@ -146,7 +147,7 @@ class DefaultSsaiApiTest { @Test fun `reports ad playback state buffering to conviva when ad starts while stalling`() { - every { playbackInfoProvider.playerState } returns + every { playerDecorator.playerState } returns ConvivaSdkConstants.PlayerState.BUFFERING ssaiApi.reportAdBreakStarted()