basically im trying to implement ima ads in exoplayer and then take the native view to flutter via method channel but im facing a problem and that's i want to track the status of ad completion so as soon an ad is completed i want to print ad completed or trigger a method from flutter but print will work for now
import android.content.Context
import android.content.pm.ActivityInfo
import android.net.Uri
import android.view.LayoutInflater
import android.view.View
import com.google.ads.interactivemedia.v3.api.AdErrorEvent.AdErrorListener
import com.google.ads.interactivemedia.v3.api.AdEvent.AdEventListener
import com.google.ads.interactivemedia.v3.api.AdEvent.AdEventType
import com.google.ads.interactivemedia.v3.api.AdsManager
import com.google.ads.interactivemedia.v3.api.AdsManagerLoadedEvent
import com.google.ads.interactivemedia.v3.api.ImaSdkFactory
import com.google.ads.interactivemedia.v3.api.ImaSdkSettings
import com.google.android.exoplayer2.C
import com.google.android.exoplayer2.ExoPlayer
import com.google.android.exoplayer2.MediaItem
import com.google.android.exoplayer2.MediaItem.AdsConfiguration
import com.google.android.exoplayer2.ext.ima.ImaAdsLoader
import com.google.android.exoplayer2.source.DefaultMediaSourceFactory
import com.google.android.exoplayer2.source.MediaSource
import com.google.android.exoplayer2.source.ads.AdPlaybackState
//import com.google.android.exoplayer2.source.ads.AdsLoader
import com.google.ads.interactivemedia.v3.api.AdsLoader;
import com.google.ads.interactivemedia.v3.internal.ad
import com.google.android.exoplayer2.ui.StyledPlayerView
import com.google.android.exoplayer2.upstream.DataSource
import com.google.android.exoplayer2.upstream.DefaultDataSource
import com.google.android.exoplayer2.util.Util
import io.flutter.plugin.common.BinaryMessenger
import io.flutter.plugin.common.MethodCall
import io.flutter.plugin.common.MethodChannel
import io.flutter.plugin.platform.PlatformView
internal class NativeView(context: Context, id: Int, creationParams: Map<String?,
Any?>?, messenger: BinaryMessenger,
mainActivity: MainActivity
) : PlatformView,
MethodChannel.MethodCallHandler ,AdsLoader.AdsLoadedListener{
private val videoList =
listOf("https://storage.googleapis.com/gvabox/media/samples/stock.mp4",
"http://commondatastorage.googleapis.com/gtv-videos-
bucket/sample/WhatCarCanYouGetForAGrand.mp4")
private var playerView: StyledPlayerView
private var adsLoader: ImaAdsLoader? = null
// private var eventListener: AdsLoader.? = null
var player: ExoPlayer? = null
var contentUri: Uri? = null
var adTagUri: Uri? = null
private val methodChannel: MethodChannel
var imaSdkSettings: ImaSdkSettings?=null
var imsdkgg: ImaSdkFactory?=null
private var view: View =
LayoutInflater.from(context).inflate(R.layout.activity_video_ad, null)
private var adCompleted = false
override fun getView(): View {
return view
}
override fun dispose() {
adsLoader!!.setPlayer(null)
playerView.player = null
player!!.release()
player = null
ActivityInfo.SCREEN_ORIENTATION_PORTRAIT
}
// callbacks for next, previous, pause and resume
override fun onMethodCall(call: MethodCall, result: MethodChannel.Result) {
when (call.method) {
"loadUrl" -> {
contentUri = Uri.parse(call.arguments.toString())
}
"pauseVideo" -> {
player?.pause()
}
"loadpre" -> {
val fff = call.arguments.toString()
println("bvvvvvvvvvvv= $fff")
player?.seekToPreviousMediaItem()
}
"loadnew" -> {
val fff = call.arguments.toString()
println("bvvvvvvvvvvv= $fff")
player?.seekToNextMediaItem()
}
"resumeVideo" -> {
player?.play()
}
else -> result.notImplemented()
}
}
init {
methodChannel = MethodChannel(messenger, "bms_video_player")
methodChannel.setMethodCallHandler(this)
// playerView = StyledPlayerView(context)
playerView = view.findViewById(R.id.player_view)
// localization
imsdkgg = ImaSdkFactory.getInstance()
imaSdkSettings = imsdkgg!!.createImaSdkSettings()
imaSdkSettings!!.language = "he"
adsLoader = ImaAdsLoader.Builder(context).setImaSdkSettings(imaSdkSettings!!).build()
//adsManager.adProgressInfo.takeUnless { }
if (Util.SDK_INT > 23) {
initializePlayer(id, mainActivity, creationParams, methodChannel)
}
}
private fun initializePlayer(
id: Int,
mainActivity: MainActivity,
creationParams: Map<String?, Any?>?,
methodChannel: MethodChannel
) {
// Set up the factory for media sources, passing the ads loader and ad view providers.
val dataSourceFactory: DataSource.Factory = DefaultDataSource.Factory(view.context)
val mediaSourceFactory: MediaSource.Factory = DefaultMediaSourceFactory(dataSourceFactory)
.setLocalAdInsertionComponents(
{ unusedAdTagUri: AdsConfiguration? -> adsLoader },
playerView
)
player = ExoPlayer.Builder(view.context).setMediaSourceFactory(mediaSourceFactory).build()
playerView.player = player
adsLoader!!.setPlayer(player)
// adsLoader!!.adsLoader!!.addAdsLoadedListener(this)
playerView.isControllerFullyVisible
playerView.setShowNextButton(false)
playerView.setShowPreviousButton(false)
playerView.showController()
playerView.useController = true
playerView.controllerAutoShow = true
// playerView.resizeMode = AspectRatioFrameLayout.RESIZE_MODE_FIT
// playerView.controllerHideOnTouch = false
// Create the MediaItem to play, specifying the content URI and ad tag URI.
contentUri = Uri.parse(creationParams?.get("videoURL") as String?)
adTagUri =Uri.parse(creationParams?.get("adURL") as String?)
println("myddddddddd=${contentUri.toString()}")
// var adPlaybackState = AdPlaybackState(0, 500 * C.MICROS_PER_SECOND)
// adPlaybackState = adPlaybackState.withAdCount(0,4)
//
// eventListener?.onAdPlaybackState(adPlaybackState);
// println("stateeee=${adPlaybackState}")
// Build the playlist.
for (i in videoList.indices){
var songPath:String = videoList.get(i)
val item =Uri.parse(songPath)
val contentStartmmm = MediaItem.Builder().setUri(item)
.setAdsConfiguration(
AdsConfiguration.Builder(adTagUri!!).build()
) .setClipStartPositionMs(0).build()
println("paliiyn comtent")
player!!.addMediaItem(contentStartmmm)
}
// Prepare the content and ad to be played with the SimpleExoPlayer.
player!!.prepare()
// Set PlayWhenReady. If true, content and ads autoplay.
// player!!.playWhenReady = false
player!!.playWhenReady = true
}
private var adsManager: AdsManager? = null
private val playAdsAfterTime = -1.0
override fun onAdsManagerLoaded(adsManagerLoadedEvent: AdsManagerLoadedEvent?) {
adsManager = adsManagerLoadedEvent!!.getAdsManager()
// Attach event and error event listeners.
// Attach event and error event listeners.
adsManager!!.addAdErrorListener(
AdErrorListener { adErrorEvent ->
/** An event raised when there is an error loading or playing ads. */
/** An event raised when there is an error loading or playing ads. */
})
adsManager!!.addAdEventListener(
AdEventListener { adEvent ->
/** Responds to AdEvents. */
/** Responds to AdEvents. */
if (adEvent.type != AdEventType.AD_PROGRESS) {
println("Event: " + adEvent.type)
}
when (adEvent.type) {
AdEventType.LOADED -> {
println("Ad fetch loaded")
adsManager!!.start()}
AdEventType.CONTENT_PAUSE_REQUESTED -> {}
AdEventType.CONTENT_RESUME_REQUESTED -> {}
AdEventType.PAUSED -> {
println("Ad fetch paused")
// isAdPlaying = false
// videoPlayerWithAdPlayback.enableControls()
}
AdEventType.RESUMED -> {
println("Ad fetch resumed")
// isAdPlaying = true
// videoPlayerWithAdPlayback.disableControls()
}
AdEventType.ALL_ADS_COMPLETED -> {
adCompleted = true
println("Ad fetch complete")
if (adsManager != null) {
adsManager!!.destroy()
adsManager = null
}
adsLoader!!.release()
}
AdEventType.AD_BREAK_FETCH_ERROR -> println("Ad Fetch Error. Resuming content.")
else -> {}
}
})
val adsRenderingSettings = imsdkgg!!.createAdsRenderingSettings()
adsRenderingSettings.setPlayAdsAfterTime(playAdsAfterTime)
adsManager!!.init(adsRenderingSettings)
// seek(playAdsAfterTime)
// videoStarted = true
}
}