Skip to content

Commit

Permalink
Load ad before content (kaltura#201)
Browse files Browse the repository at this point in the history
* integrate 0.2.17 into develop

* add PKAdProviderListener

* add AdResponseType

* add     private AdResponseType adResponseType;
to config

* add
    void setAdProviderListener(AdEnabledPlayerController adEnabledPlayerController);
    void removeAdProviderListener();

to AdsProvider

* fix LOG ERROR behaviour
Add prepare impl in decorator

* start from pos 0

* fix remove all views

* clean = null

* fix typo

* add new line

* protect npe

* add hide in java doc

* refactor AD_RESPONSE_TYPE to AD_TAG_TYPE

* remove unneeded handler

* fix codacy

* codify
  • Loading branch information
giladna authored Apr 3, 2017
1 parent 851c2f1 commit a7d2f04
Show file tree
Hide file tree
Showing 8 changed files with 251 additions and 72 deletions.
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
package com.kaltura.playkit.ads;

import android.support.annotation.NonNull;

import com.kaltura.playkit.PKLog;
import com.kaltura.playkit.PKMediaConfig;
import com.kaltura.playkit.PlayerDecorator;
import com.kaltura.playkit.plugins.ads.AdsProvider;
import com.kaltura.playkit.utils.Consts;
Expand All @@ -9,35 +12,60 @@
* @hide
*/

public class AdEnabledPlayerController extends PlayerDecorator implements AdController {
public class AdEnabledPlayerController extends PlayerDecorator implements AdController, PKAdProviderListener{

private static final PKLog log = PKLog.get("AdEnablController");

AdsProvider adsProvider;
private AdsProvider adsProvider;
private PKMediaConfig mediaConfig;

public AdEnabledPlayerController(AdsProvider adsProvider) {
log.d("Init AdEnabledPlayerController");
this.adsProvider = adsProvider;
}

/*
In order to avoid network resources race between IMA and Content CDN
we prevent the prepare until AD is STARTED, No Pre-Roll or AD ERROR is received
*/
@Override
public void prepare(@NonNull final PKMediaConfig mediaConfig) {
this.mediaConfig = mediaConfig;

if (adsProvider != null) {
if (adsProvider.isAdRequested()) {
super.prepare(mediaConfig);
} else {
adsProvider.setAdProviderListener(this);
}
}
}

@Override
public long getDuration() {
if (adsProvider.isAdDisplayed()) {
long adDuration = adsProvider.getDuration();
log.v("getDuration: " + adDuration);
log.d("getDuration: " + adDuration);
return Consts.MILLISECONDS_MULTIPLIER * adDuration;
} else {
return super.getDuration();
long contentDuration = super.getDuration();
log.d("content getDuration: " + contentDuration);
return contentDuration;
}
}

@Override
public long getCurrentPosition() {
if (adsProvider.isAdDisplayed()) {
boolean isAdDisplayed = adsProvider.isAdDisplayed();
log.d("getCurrentPosition isAdDisplayed = " + isAdDisplayed);
if (isAdDisplayed) {
long adPosition = adsProvider.getCurrentPosition();
log.v("getCurrentPosition = " + adPosition);
log.d("getCurrentPosition = " + adPosition);
return Consts.MILLISECONDS_MULTIPLIER * adPosition;
} else {
return super.getCurrentPosition();
long contentCurrentPosition = super.getCurrentPosition();
log.d("contnent getCurrentPosition: " + contentCurrentPosition);
return contentCurrentPosition;
}
}

Expand All @@ -56,7 +84,6 @@ public void play() {
log.d("PLAY isAdDisplayed = " + adsProvider.isAdDisplayed() + " isAdPaused = " + adsProvider.isAdPaused());
if (adsProvider != null) {
if (!adsProvider.isAdRequested()) {
super.getView().hideVideoSurface();
adsProvider.start();
return;
} else if (adsProvider.isAdDisplayed()) {
Expand Down Expand Up @@ -88,4 +115,13 @@ public void skipAd() {
public AdController getAdController() {
return this;
}

@Override
public void onAdLoadingFinished() {
log.d("onAdLoadingFinished pkPrepareReason");
prepare(mediaConfig);
if (adsProvider != null) {
adsProvider.removeAdProviderListener();
}
}
}
8 changes: 8 additions & 0 deletions playkit/src/main/java/com/kaltura/playkit/ads/AdTagType.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package com.kaltura.playkit.ads;

public enum AdTagType {
UNKNOWN,
VMAP,
VAST,
VPAID
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
package com.kaltura.playkit.ads;

public interface PKAdProviderListener {
void onAdLoadingFinished();
}

Original file line number Diff line number Diff line change
Expand Up @@ -34,14 +34,11 @@ public class PlayerController implements Player {
private static final int ALLOWED_ERROR_RETRIES = 3;



private PlayerEngine player = null;
private PlayerEngine player;
private Context context;
private PlayerView rootPlayerView;

private PKMediaConfig mediaConfig;
private PKMediaSourceConfig sourceConfig;

private PKEvent.Listener eventListener;
private PlayerView playerEngineView;

Expand All @@ -60,8 +57,6 @@ public Player.Settings setContentRequestDecorator(PKRequestInfo.Decorator conten
}
}



public void setEventListener(PKEvent.Listener eventListener) {
this.eventListener = eventListener;
}
Expand Down Expand Up @@ -183,6 +178,7 @@ public Player.Settings getSettings() {
return settings;
}


public void prepare(@NonNull PKMediaConfig mediaConfig) {

isNewEntry = isNewEntry(mediaConfig);
Expand All @@ -195,29 +191,31 @@ public void prepare(@NonNull PKMediaConfig mediaConfig) {
return;
}

boolean shouldSwitchBetweenPlayers = shouldSwitchBetweenPlayers(source);

if (shouldSwitchBetweenPlayers || player == null) { //if player is null consider it as switch player flow.
switchPlayers(source.getMediaFormat());
}


boolean shouldSwitchBetweenPlayers = shouldSwitchBetweenPlayers(source);
this.sourceConfig = new PKMediaSourceConfig(source, contentRequestDecorator);
if (player == null) {
switchPlayers(source.getMediaFormat(), false);
} else if (shouldSwitchBetweenPlayers) {
switchPlayers(source.getMediaFormat(), true);
}

player.load(sourceConfig);

}

private void switchPlayers(PKMediaFormat mediaFormat) {
removeAllViews();
private void switchPlayers(PKMediaFormat mediaFormat, boolean removePlayerView) {
if (removePlayerView) {
removePlayerView();
}

if (player != null) {
player.destroy();
}
initializePlayer(mediaFormat);

addPlayerView();
}

}

private void initializePlayer(PKMediaFormat mediaFormat) {
//Decide which player wrapper should be initialized.
Expand All @@ -241,8 +239,11 @@ private void addPlayerView() {

@Override
public void destroy() {
log.e("destroy");
log.d("destroy");
if (player != null) {
if (playerEngineView != null) {
rootPlayerView.removeView(playerEngineView);
}
player.destroy();
togglePlayerListeners(false);
}
Expand All @@ -253,7 +254,9 @@ public void destroy() {

@Override
public void stop() {
player.stop();
if (player != null) {
player.stop();
}
}

private void startPlaybackFrom(long startPosition) {
Expand Down Expand Up @@ -310,12 +313,12 @@ public AdController getAdController() {

public void play() {
log.d("play");

if (player == null) {
log.e("Attempt to invoke 'play()' on null instance of the player engine");
return;
}


addPlayerView();
player.play();
}

Expand Down Expand Up @@ -407,9 +410,10 @@ public void onApplicationResumed() {
log.d("onApplicationResumed");
if (player != null) {
player.restore();
prepare(mediaConfig);
togglePlayerListeners(true);
}
prepare(mediaConfig);
togglePlayerListeners(true);

}

@Override
Expand Down Expand Up @@ -449,9 +453,9 @@ private boolean shouldSwitchBetweenPlayers(PKMediaSource newSource) {
return false;
}

private void removeAllViews() {
private void removePlayerView() {
togglePlayerListeners(false);
rootPlayerView.removeAllViews();
rootPlayerView.removeView(playerEngineView);
playerEngineView = null;
}

Expand All @@ -469,7 +473,6 @@ private boolean maybeHandleExceptionLocally(PlayerEvent.ExceptionInfo exceptionI
ExoPlayerWrapper exoPlayerWrapper = (ExoPlayerWrapper) player;
long currentPosition = player.getCurrentPosition();
exoPlayerWrapper.savePlayerPosition();

exoPlayerWrapper.load(sourceConfig);
exoPlayerWrapper.startFrom(currentPosition);
return true;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,8 @@ public enum Type {
LOADED,
CONTENT_PAUSE_REQUESTED,
CONTENT_RESUME_REQUESTED,
ALL_ADS_COMPLETED
ALL_ADS_COMPLETED,
AD_LOAD_TIMEOUT_TIMER_STARTED
}


Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,9 @@
package com.kaltura.playkit.plugins.ads;

import com.kaltura.playkit.ads.AdEnabledPlayerController;
import com.kaltura.playkit.ads.PKAdInfo;
import com.kaltura.playkit.plugins.ads.ima.IMAConfig;

/**
* Created by gilad.nadav on 17/11/2016.
*/

public interface AdsProvider {
IMAConfig getAdsConfig();
Expand All @@ -20,6 +18,7 @@ public interface AdsProvider {
boolean isAdRequested();
long getDuration();
long getCurrentPosition();

void setAdProviderListener(AdEnabledPlayerController adEnabledPlayerController);
void removeAdProviderListener();
void skipAd();
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import com.google.gson.JsonObject;
import com.google.gson.JsonPrimitive;
import com.kaltura.playkit.PKMediaFormat;
import com.kaltura.playkit.ads.AdTagType;

import java.util.ArrayList;
import java.util.List;
Expand All @@ -19,10 +20,11 @@ public class IMAConfig {
public static final int DEFAULT_CUE_POINTS_CHANGED_DELAY = 2000;
public static final int DEFAULT_AD_LOAD_COUNT_DOWN_TICK = 250;

public static final String AD_TAG_LANGUAGE = "language";
public static final String AD_TAG_URL = "adTagURL";
public static final String ENABLE_BG_PLAYBACK = "enableBackgroundPlayback";
public static final String AD_VIDEO_BITRATE = "videoBitrate";
public static final String AD_TAG_LANGUAGE = "language";
public static final String AD_TAG_TYPE = "adTagType";
public static final String AD_TAG_URL = "adTagURL";
public static final String ENABLE_BG_PLAYBACK = "enableBackgroundPlayback";
public static final String AD_VIDEO_BITRATE = "videoBitrate";
public static final String AD_VIDEO_MIME_TYPES = "videoMimeTypes";
//public static final String AD_TAG_TIMES = "tagsTimes";
public static final String AD_ATTRIBUTION_UIELEMENT = "adAttribution";
Expand All @@ -32,6 +34,7 @@ public class IMAConfig {

private String language;
private String adTagURL;
private AdTagType adTagType;
private boolean enableBackgroundPlayback;
private int videoBitrate; // in KB
private boolean adAttribution;
Expand All @@ -44,6 +47,7 @@ public class IMAConfig {

public IMAConfig() {
this.language = "en";
this.adTagType = AdTagType.VAST;
this.enableBackgroundPlayback = false;
this.videoBitrate = -1;
this.adAttribution = true;
Expand All @@ -70,6 +74,11 @@ public IMAConfig setLanguage(String language) {
return this;
}

public IMAConfig setAdTagType(AdTagType adTagType) {
this.adTagType = adTagType;
return this;
}

public boolean getEnableBackgroundPlayback() {
return enableBackgroundPlayback;
}
Expand Down Expand Up @@ -119,6 +128,11 @@ public boolean getAdAttribution() {
return adAttribution;
}

public AdTagType getAdTagType() {
return adTagType;
}


//ad attribution true is required for a countdown timer to be displayed
// default is true
public IMAConfig setAdAttribution(boolean adAttribution) {
Expand Down Expand Up @@ -146,7 +160,7 @@ public IMAConfig setAdLoadTimeOut(int adLoadTimeOut) {
return this;
}

// public Map<Double, String> getTagsTimes() {
// public Map<Double, String> getTagsTimes() {
// return tagsTimes;
// }
//
Expand All @@ -166,6 +180,7 @@ public IMAConfig setAdLoadTimeOut(int adLoadTimeOut) {
public JsonObject toJSONObject() {
JsonObject jsonObject = new JsonObject();
jsonObject.addProperty(AD_TAG_LANGUAGE, language);
jsonObject.addProperty(AD_TAG_TYPE, adTagType.name());
jsonObject.addProperty(AD_TAG_URL, adTagURL);
jsonObject.addProperty(ENABLE_BG_PLAYBACK, enableBackgroundPlayback);
jsonObject.addProperty(AD_VIDEO_BITRATE, videoBitrate);
Expand Down
Loading

0 comments on commit a7d2f04

Please sign in to comment.