Skip to content

Commit

Permalink
feat: video player sample with Inline AD for CHT
Browse files Browse the repository at this point in the history
  • Loading branch information
pickerweng committed Dec 19, 2024
1 parent dfac731 commit 22394c2
Show file tree
Hide file tree
Showing 11 changed files with 265 additions and 1 deletion.
4 changes: 4 additions & 0 deletions gradle/libs.versions.toml
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ playServicesAdsIdentifier = "18.1.0"
gson = "2.11.0"
retrofit = "2.11.0"
converterGson = "2.11.0"
media3Exoplayer = "1.5.0"
media3Ui = "1.5.0"

[libraries]
junit = { group = "junit", name = "junit", version.ref = "junit" }
Expand All @@ -30,6 +32,8 @@ play-services-ads-identifier = { group = "com.google.android.gms", name = "play-
gson = { group = "com.google.code.gson", name = "gson", version.ref = "gson" }
retrofit = { group = "com.squareup.retrofit2", name = "retrofit", version.ref = "retrofit" }
converter-gson = { group = "com.squareup.retrofit2", name = "converter-gson", version.ref = "converterGson" }
media3-exoplayer = { group = "androidx.media3", name = "media3-exoplayer", version.ref = "media3Exoplayer" }
media3-ui = { group = "androidx.media3", name = "media3-ui", version.ref = "media3Ui" }

[plugins]
android-application = { id = "com.android.application", version.ref = "agp" }
Expand Down
5 changes: 4 additions & 1 deletion sdkdemo/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ plugins {

android {
namespace = "io.tenmax.sdkdemo"
compileSdk = 34
compileSdk = 35

defaultConfig {
applicationId = "com.tenmax.sdkdemo"
Expand Down Expand Up @@ -52,6 +52,7 @@ android {
resValue("string", "topBannerId", "aa7947ea8e104da3")
resValue("string", "bottomBannerId", "2b07703707354bd6")
resValue("string", "floatingId", "5417d8bf58b34bac")
resValue("string", "videoInlineId", "cdc8203a5167467d")
resValue("string", "app_name", "TenMaxMobileSDKDemo (CHT)")
}
create("internal") {
Expand Down Expand Up @@ -94,6 +95,8 @@ dependencies {
implementation(libs.retrofit)
implementation(libs.converter.gson)
implementation(libs.play.services.ads.identifier)
implementation(libs.media3.exoplayer)
implementation(libs.media3.ui)
testImplementation(libs.junit)
androidTestImplementation(libs.ext.junit)
androidTestImplementation(libs.espresso.core)
Expand Down
4 changes: 4 additions & 0 deletions sdkdemo/src/main/java/io/tenmax/sdkdemo/SupportedSpaces.java
Original file line number Diff line number Diff line change
Expand Up @@ -23,4 +23,8 @@ static String inlineId(Context context) {
static String floatingId(Context context) {
return context.getResources().getString(R.string.floatingId);
}

static String videoInlineId(Context context) {
return context.getResources().getString(R.string.videoInlineId);
}
}
12 changes: 12 additions & 0 deletions sdkdemo/src/main/java/io/tenmax/sdkdemo/ui/home/HomeFragment.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import static io.tenmax.sdkdemo.SupportedSpaces.inlineId;
import static io.tenmax.sdkdemo.SupportedSpaces.interstitialId;
import static io.tenmax.sdkdemo.SupportedSpaces.topBannerId;
import static io.tenmax.sdkdemo.SupportedSpaces.videoInlineId;

import android.os.Bundle;
import android.view.LayoutInflater;
Expand All @@ -20,6 +21,7 @@
import io.tenmax.sdkdemo.R;
import io.tenmax.sdkdemo.databinding.FragmentHomeBinding;
import io.tenmax.sdkdemo.ui.dashboard.DashboardFragment;
import io.tenmax.sdkdemo.ui.video.VideoFragment;

public class HomeFragment extends Fragment {

Expand All @@ -36,6 +38,7 @@ public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container,
this.binding.showTopBannerAd.setOnClickListener((view) -> showAd("topBanner", topBannerId(getContext())));
this.binding.showBottomBannerAd.setOnClickListener((view) -> showAd("bottomBanner", bottomBannerId(getContext())));
this.binding.showFloatingAd.setOnClickListener((view) -> showAd("floating", floatingId(getContext())));
this.binding.videoPausePictureAd.setOnClickListener((view) -> showVideoFragment(videoInlineId(getContext())));

return root;
}
Expand All @@ -60,6 +63,15 @@ private void showAd(String type, String spaceId) {
this.pushFragment(dashboard);
}

private void showVideoFragment(String spaceId) {
Fragment videoFragment = new VideoFragment();
Bundle bundle = new Bundle();
bundle.putString("spaceType", "inline");
bundle.putString("spaceId", spaceId);
videoFragment.setArguments(bundle);
this.pushFragment(videoFragment);
}

private void pushFragment(Fragment fragment) {
FragmentManager manager = getParentFragmentManager();
manager.beginTransaction()
Expand Down
146 changes: 146 additions & 0 deletions sdkdemo/src/main/java/io/tenmax/sdkdemo/ui/video/VideoFragment.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,146 @@
package io.tenmax.sdkdemo.ui.video;

import static io.tenmax.mobilesdk.TenMaxBannerPosition.bottom;
import static io.tenmax.mobilesdk.TenMaxBannerPosition.top;
import static io.tenmax.mobilesdk.TenMaxMobileSDK.bannerAd;
import static io.tenmax.mobilesdk.TenMaxMobileSDK.cleanAd;
import static io.tenmax.mobilesdk.TenMaxMobileSDK.floatingAd;
import static io.tenmax.mobilesdk.TenMaxMobileSDK.inlineAd;
import static io.tenmax.mobilesdk.TenMaxMobileSDK.interstitialAd;

import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

import androidx.annotation.NonNull;
import androidx.fragment.app.Fragment;
import androidx.media3.common.MediaItem;
import androidx.media3.common.Player;
import androidx.media3.exoplayer.ExoPlayer;
import androidx.media3.exoplayer.SimpleExoPlayer;

import java.util.Map;

import io.tenmax.mobilesdk.TenMaxAd;
import io.tenmax.mobilesdk.TenMaxAdSessionListener;
import io.tenmax.mobilesdk.TenMaxAdSpace;
import io.tenmax.mobilesdk.TenMaxInitiationCallback;
import io.tenmax.sdkdemo.databinding.FragmentVideoBinding;
import io.tenmax.sdkdemo.ui.SimpleAdSessionListener;
import io.tenmax.sdkdemo.ui.SimpleInitiationCallback;

public class VideoFragment extends Fragment {

interface AdInitializer {
TenMaxAd init(String spaceId, Fragment fragment, FragmentVideoBinding binding, TenMaxAdSessionListener listener, TenMaxInitiationCallback<TenMaxAdSpace> callback);
}

private TenMaxAd presentingAd;
private FragmentVideoBinding binding;
private Player player;
private final Map<String, AdInitializer> adInitializers = Map.of(
"inline", (spaceId, fragment, binding, listener, callback) -> inlineAd(spaceId, fragment.getActivity(), binding.inlineAd, options -> {
options.listenSession(listener).monitorInitiation(callback);
})
);

@Override
public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
binding = FragmentVideoBinding.inflate(inflater, container, false);
View root = binding.getRoot();
binding.adContainer.setVisibility(View.GONE);
binding.closeAd.setVisibility(View.GONE);
binding.adContainer.setOnTouchListener((v, event) -> true);
player = new ExoPlayer.Builder(requireContext()).build();
binding.playerView.setPlayer(player);

MediaItem mediaItem = MediaItem.fromUri("https://media.w3.org/2010/05/sintel/trailer.mp4");
player.setMediaItem(mediaItem);
player.prepare();

SimpleAdSessionListener listener = new SimpleAdSessionListener(this.getContext());
SimpleInitiationCallback callback = new SimpleInitiationCallback(this.getContext());
if (getArguments() != null) {
String spaceId = getArguments().getString("spaceId");
String type = getArguments().getString("spaceType");
AdInitializer initializer = adInitializers.get(type);
if (initializer != null) {
this.presentingAd = initializer.init(spaceId, this, this.binding, listener, callback);
}
}

player.addListener(new Player.Listener() {
@Override
public void onPlaybackStateChanged(int playbackState) {
if (playbackState == Player.STATE_ENDED) {
showAd();
}
}

@Override
public void onIsPlayingChanged(boolean isPlaying) {
if (!isPlaying) {
showAd();
} else {
hideAd();
}
}
});

binding.playerView.setOnClickListener(view -> {
if (player.isPlaying()) {
player.pause();
} else {
player.play();
}
});

binding.closeAd.setOnClickListener(view -> {
hideAd();
player.play();
});

return root;
}

private void showAd() {
binding.adContainer.setVisibility(View.VISIBLE);
binding.closeAd.setVisibility(View.VISIBLE);
if (presentingAd != null) {
presentingAd.show();
}
}

private void hideAd() {
binding.adContainer.setVisibility(View.GONE);
binding.closeAd.setVisibility(View.GONE);
}

@Override
public void onResume() {
super.onResume();
if (player != null) {
player.play();
}
}

@Override
public void onPause() {
super.onPause();
if (player != null) {
player.pause();
}
}

@Override
public void onDestroyView() {
super.onDestroyView();
if (player != null) {
player.release();
player = null;
}
binding = null;
cleanAd(this.presentingAd);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package io.tenmax.sdkdemo.ui.video;

import androidx.lifecycle.LiveData;
import androidx.lifecycle.MutableLiveData;
import androidx.lifecycle.ViewModel;

public class VideoViewModel extends ViewModel {

private final MutableLiveData<String> mText;

public VideoViewModel() {
mText = new MutableLiveData<>();
mText.setValue("This is video fragment");
}

public LiveData<String> getText() {
return mText;
}
}



5 changes: 5 additions & 0 deletions sdkdemo/src/main/res/drawable/ic_close.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android" android:height="24dp" android:tint="#000000" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp">

<path android:fillColor="@android:color/white" android:pathData="M18.3,5.71c-0.39,-0.39 -1.02,-0.39 -1.41,0L12,10.59 7.11,5.7c-0.39,-0.39 -1.02,-0.39 -1.41,0 -0.39,0.39 -0.39,1.02 0,1.41L10.59,12 5.7,16.89c-0.39,0.39 -0.39,1.02 0,1.41 0.39,0.39 1.02,0.39 1.41,0L12,13.41l4.89,4.89c0.39,0.39 1.02,0.39 1.41,0 0.39,-0.39 0.39,-1.02 0,-1.41L13.41,12l4.89,-4.89c0.38,-0.38 0.38,-1.02 0,-1.4z"/>

</vector>
5 changes: 5 additions & 0 deletions sdkdemo/src/main/res/drawable/ic_pause.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android" android:height="24dp" android:tint="#000000" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp">

<path android:fillColor="@android:color/white" android:pathData="M12,2C6.48,2 2,6.48 2,12s4.48,10 10,10s10,-4.48 10,-10S17.52,2 12,2zM10,16L10,16c-0.55,0 -1,-0.45 -1,-1V9c0,-0.55 0.45,-1 1,-1l0,0c0.55,0 1,0.45 1,1v6C11,15.55 10.55,16 10,16zM14,16L14,16c-0.55,0 -1,-0.45 -1,-1V9c0,-0.55 0.45,-1 1,-1l0,0c0.55,0 1,0.45 1,1v6C15,15.55 14.55,16 14,16z"/>

</vector>
5 changes: 5 additions & 0 deletions sdkdemo/src/main/res/drawable/ic_play.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android" android:height="24dp" android:tint="#000000" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp">

<path android:fillColor="@android:color/white" android:pathData="M12,2C6.48,2 2,6.48 2,12s4.48,10 10,10s10,-4.48 10,-10S17.52,2 12,2zM9.5,14.67V9.33c0,-0.79 0.88,-1.27 1.54,-0.84l4.15,2.67c0.61,0.39 0.61,1.29 0,1.68l-4.15,2.67C10.38,15.94 9.5,15.46 9.5,14.67z"/>

</vector>
12 changes: 12 additions & 0 deletions sdkdemo/src/main/res/layout/fragment_home.xml
Original file line number Diff line number Diff line change
Expand Up @@ -56,4 +56,16 @@
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/showBottomBannerAd"/>

<Button
android:id="@+id/videoPausePictureAd"
android:layout_width="300dp"
android:layout_height="wrap_content"
android:layout_marginTop="20dp"
android:text="Video Pause Picture AD"
app:flow_horizontalAlign="center"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/showFloatingAd" />

</androidx.constraintlayout.widget.ConstraintLayout>
46 changes: 46 additions & 0 deletions sdkdemo/src/main/res/layout/fragment_video.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/black"
tools:context=".ui.video.VideoFragment">

<androidx.media3.ui.PlayerView
android:id="@+id/playerView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />

<FrameLayout
android:id="@+id/adContainer"
android:layout_width="0dp"
android:layout_height="0dp"
android:background="#80000000"
android:visibility="visible"
app:layout_constraintBottom_toBottomOf="@+id/playerView"
app:layout_constraintEnd_toEndOf="@+id/playerView"
app:layout_constraintStart_toStartOf="@+id/playerView"
app:layout_constraintTop_toTopOf="@+id/playerView">

<FrameLayout
android:id="@+id/inlineAd"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:background="@android:color/transparent"
android:paddingBottom="10dp" />

<ImageButton
android:id="@+id/closeAd"
android:layout_width="20dp"
android:layout_height="20dp"
android:padding="10dp"
android:layout_gravity="top|end"
android:src="@drawable/ic_close"
android:background="@android:color/darker_gray" />
</FrameLayout>
</androidx.constraintlayout.widget.ConstraintLayout>

0 comments on commit 22394c2

Please sign in to comment.