media icon indicating copy to clipboard operation
media copied to clipboard

Two tracks are getting downloaded by Exoplayer and IMA SDK

Open nikky12 opened this issue 1 year ago • 3 comments

Version

ExoPlayer 2.16.1

More version details

No response

Devices that reproduce the issue

All Android devices

Devices that do not reproduce the issue

No response

Reproducible in the demo app?

Yes

Reproduction steps

We are using IMA SDK for playing video ads. We have tried with Single player and using Concatenating media source to have Ads and content media concatenated. But due to this issue https://github.com/google/ExoPlayer/issues/3693, we have to switch to two players One player used for content playback and another is for Ads playback.

Content Player

val renderersFactory = DefaultRenderersFactory(context.applicationContext).setEnableDecoderFallback(true)

        val builder = ExoPlayer.Builder(context, renderersFactory, decoderBehaviour)
                .setLoadControl(loadControl)
                .setOverrideDecoderBehavior(decoderBehaviour)
                .setSeekParameters(SeekParameters.CLOSEST_SYNC)
        trackSelector?.let { builder.setTrackSelector(it) }
        player = builder.build()
player?.apply {
                currentMediaSource?.let {
                    setMediaSources(
                        listOf(it),  /* startWindowIndex= */
                        if (resetPosition) 0 else C.INDEX_UNSET,  /* startPositionMs= */
                        C.TIME_UNSET
                    )
                }
                prepare()
            }

Ads Player

val dataSourceFactory: DataSource.Factory = DefaultDataSourceFactory(context)
        val mediaSourceFactory: MediaSourceFactory = DefaultMediaSourceFactory(dataSourceFactory)
            .setAdsLoaderProvider { adsLoader }
            .setAdViewProvider(imaVideoAdsView?.getAdUiContainer())

        val renderersFactory = DefaultRenderersFactory(context.applicationContext).setEnableDecoderFallback(true)
imaAdsPlayer = ExoPlayer.Builder(context, renderersFactory, overrideDecoderBehavior)
            .setMediaSourceFactory(mediaSourceFactory)
            .setOverrideDecoderBehavior(overrideDecoderBehavior)
            .setSeekParameters(SeekParameters.CLOSEST_SYNC)
            .build()
        imaVideoAdsView?.getAdUiContainer()?.player = imaAdsPlayer
        adsLoader?.setPlayer(imaAdsPlayer)
val contentUri = Uri.parse(playbackItem.contentUrl)
        val adTagUri = Uri.parse(playbackItem.adsMeta?.meta?.url)
        val adsConfig = MediaItem.AdsConfiguration.Builder(adTagUri).build()
        val mediaItem: MediaItem = MediaItem.Builder()
            .setUri(contentUri)
            .setAdsConfiguration(adsConfig)
            .build()

        // Prepare the content and ad to be played with the SimpleExoPlayer.
        imaAdsPlayer?.setMediaItem(mediaItem)
        imaAdsPlayer?.prepare()

Ima Ads player needs two media items - content and ad tag url Since there are two players, two tracks are getting downloaded for content playback. One track in the quality user has selected to play and another that is with Adsplayer.

Do we have a fix for the issue which i mentioned https://github.com/google/ExoPlayer/issues/3693 So that we can move to single player.

Expected result

Below Exception should not come when i use ConcatenatingMediaSource with Ads and content url .

01-11 14:46:43.654 2793-2793/com.intigral.splive W/System.err: java.lang.IllegalArgumentException
01-11 14:46:43.654 2793-2793/com.intigral.splive W/System.err: at com.google.android.exoplayer2.util.Assertions.checkArgument(Assertions.java:37)
01-11 14:46:43.654 2793-2793/com.intigral.splive W/System.err: at com.google.android.exoplayer2.ext.ima.ImaAdsLoader.onTimelineChanged(ImaAdsLoader.java:671)
01-11 14:46:43.654 2793-2793/com.intigral.splive W/System.err: at com.google.android.exoplayer2.ExoPlayerImpl.updatePlaybackInfo(ExoPlayerImpl.java:588)
01-11 14:46:43.654 2793-2793/com.intigral.splive W/System.err: at com.google.android.exoplayer2.ExoPlayerImpl.handlePlaybackInfo(ExoPlayerImpl.java:541)
01-11 14:46:43.654 2793-2793/com.intigral.splive W/System.err: at com.google.android.exoplayer2.ExoPlayerImpl.handleEvent(ExoPlayerImpl.java:483)
01-11 14:46:43.654 2793-2793/com.intigral.splive W/System.err: at com.google.android.exoplayer2.ExoPlayerImpl$1.handleMessage(ExoPlayerImpl.java:100)
01-11 14:46:43.654 2793-2793/com.intigral.splive W/System.err: at android.os.Handler.dispatchMessage(Handler.java:102)
01-11 14:46:43.654 2793-2793/com.intigral.splive W/System.err: at android.os.Looper.loop(Looper.java:154)
01-11 14:46:43.655 2793-2793/com.intigral.splive W/System.err: at android.app.ActivityThread.main(ActivityThread.java:6077)
01-11 14:46:43.655 2793-2793/com.intigral.splive W/System.err: at java.lang.reflect.Method.invoke(Native Method)
01-11 14:46:43.655 2793-2793/com.intigral.splive W/System.err: at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:865)
01-11 14:46:43.655 2793-2793/com.intigral.splive W/System.err: at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:755)

Actual result

Above exception is coming

Media

Not applicable

Bug Report

  • [ ] You will email the zip file produced by adb bugreport to [email protected] after filing this issue.

nikky12 avatar Feb 09 '24 04:02 nikky12

I think this is essentially a duplicate of https://github.com/google/ExoPlayer/issues/3693.

For your workaround case: Do you need to play the same content with your 'ads' player? What about playing some 'fake' local content, since I believe you will only actually be using this player when it's playing ads - that should avoid you downloading the content twice.

icbaker avatar Feb 09 '24 17:02 icbaker

@icbaker @tonihei Yes, i need to play the ads on same content. So video url, we are giving to ads player should be of same duration, how would it be possible to play a fake media source? Every video can of different duration, where would i get the fake video Also there is no API to set fake media item with val adsConfig = MediaItem.AdsConfiguration.Builder(adTagUri).build() val mediaItem: MediaItem = MediaItem.Builder() .setUri(contentUri) .setAdsConfiguration(adsConfig) .build()

    // Prepare the content and ad to be played with the SimpleExoPlayer.
    imaAdsPlayer?.setMediaItem(mediaItem)
    imaAdsPlayer?.prepare()

nikky12 avatar Feb 10 '24 12:02 nikky12

where would i get the fake video

You can use a SilenceMediaSource and then configure the player with an AdsMediaSource directly instead of using MediaItem. It should look roughly like this:

player.addMediaSource(
    new AdsMediaSource(
        new SilenceMediaSource(/* durationUs= */ [value >= last ad group time]),
        new DataSpec(adTagUri),
        /* adsId= */ "ads",
        new DefaultMediaSourceFactory(context),
        adsLoader,
        adViewProvider));

tonihei avatar Feb 20 '24 15:02 tonihei

I assume the question was answered and will close the issue.

tonihei avatar Mar 11 '24 09:03 tonihei