Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

IMA not playing all Ads from a midroll #7477

Closed
fpittersacc opened this issue Jun 8, 2020 · 5 comments
Closed

IMA not playing all Ads from a midroll #7477

fpittersacc opened this issue Jun 8, 2020 · 5 comments
Assignees
Labels

Comments

@fpittersacc
Copy link

[REQUIRED] Issue description

The following IMA Ad Uri is producing an undesired behavior, in which not all Ads in the Midrolls are being played. After 2-3 Ads (out of 7 or 8) content is getting resumed.

It seems that the state hold by AdPlaybackState AdGroup.count differs from what AdPodInfo.getTotalAds() is providing after the actual Ad sequence is loaded.

[REQUIRED] Reproduction steps

  1. On Exoplayer demo module, include the IMA Uri from below into a content longer than 10 min to allow midrolls to be reached.
  2. Play midrolls.

Expected: All 7/8 Ads are played.
Actual: Only first 2/3 Ads are played and it continues with Content. (Depending on the Exo version)

[REQUIRED] Link to test content

https://pubads.g.doubleclick.net/gampad/ads?env=vp&gdfp_req=1&unviewed_position_start=1&output=vast&iu=/5374/TV2video/avod/programmer/underholdning/love-island-uk/sesong-5&sz=640x480&description_url=https://www.tv2.no/v/1463716&hl=no&cmsid=2510181&vid=1463716

[REQUIRED] A full bug report captured from the device

Notice the behavior/result is slightly different from 2.11.3 and 2.11.5

2.11.3 is logging some warning after the 3rd Ad is played and content playback continues
ImaAdsLoader: Unexpected ad count in LOADED, 7, expected 3

2.11.5 is logging the following exception after the 2nd Ad is played and content playback continues.

2020-06-08 13:08:00.792 8357-8357/com.google.android.exoplayer2.demo E/ImaAdsLoader: Internal error in loadAd
      java.lang.IllegalArgumentException
        at com.google.android.exoplayer2.util.Assertions.checkArgument(Assertions.java:39)
        at com.google.android.exoplayer2.source.ads.AdPlaybackState$AdGroup.withAdUri(AdPlaybackState.java:151)
        at com.google.android.exoplayer2.source.ads.AdPlaybackState.withAdUri(AdPlaybackState.java:399)
        at com.google.android.exoplayer2.ext.ima.ImaAdsLoader.loadAd(ImaAdsLoader.java:872)
        at com.google.ads.interactivemedia.v3.internal.akf.a(IMASDK:23)
        at com.google.ads.interactivemedia.v3.internal.akb.a(IMASDK:177)
        at com.google.ads.interactivemedia.v3.internal.akb.a(IMASDK:43)
        at com.google.ads.interactivemedia.v3.internal.ake.b(IMASDK:28)
        at com.google.ads.interactivemedia.v3.internal.akc.shouldOverrideUrlLoading(IMASDK:6)
        at android.webkit.WebViewClient.shouldOverrideUrlLoading(WebViewClient.java:77)
        at org.chromium.android_webview.AwContentsClientBridge.shouldOverrideUrlLoading(chromium-Monochrome.aab-stable-410409673:16)
        at android.os.MessageQueue.nativePollOnce(Native Method)
        at android.os.MessageQueue.next(MessageQueue.java:326)
        at android.os.Looper.loop(Looper.java:165)
        at android.app.ActivityThread.main(ActivityThread.java:6810)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:547)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:873)
2020-06-08 13:08:00.796 8357-8357/com.google.android.exoplayer2.demo E/EventLogger: internalError [eventTime=29.60, mediaPos=0.21, window=0, loadError
      com.google.android.exoplayer2.source.ads.AdsMediaSource$AdLoadException: java.lang.RuntimeException: Internal error in loadAd
        at com.google.android.exoplayer2.ext.ima.ImaAdsLoader.maybeNotifyInternalError(ImaAdsLoader.java:1440)
        at com.google.android.exoplayer2.ext.ima.ImaAdsLoader.loadAd(ImaAdsLoader.java:875)
        at com.google.ads.interactivemedia.v3.internal.akf.a(IMASDK:23)
        at com.google.ads.interactivemedia.v3.internal.akb.a(IMASDK:177)
        at com.google.ads.interactivemedia.v3.internal.akb.a(IMASDK:43)
        at com.google.ads.interactivemedia.v3.internal.ake.b(IMASDK:28)
        at com.google.ads.interactivemedia.v3.internal.akc.shouldOverrideUrlLoading(IMASDK:6)
        at android.webkit.WebViewClient.shouldOverrideUrlLoading(WebViewClient.java:77)
        at org.chromium.android_webview.AwContentsClientBridge.shouldOverrideUrlLoading(chromium-Monochrome.aab-stable-410409673:16)
        at android.os.MessageQueue.nativePollOnce(Native Method)
        at android.os.MessageQueue.next(MessageQueue.java:326)
        at android.os.Looper.loop(Looper.java:165)
        at android.app.ActivityThread.main(ActivityThread.java:6810)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:547)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:873)
     Caused by: java.lang.RuntimeException: Internal error in loadAd
        at com.google.android.exoplayer2.ext.ima.ImaAdsLoader.maybeNotifyInternalError(ImaAdsLoader.java:1439)
        at com.google.android.exoplayer2.ext.ima.ImaAdsLoader.loadAd(ImaAdsLoader.java:875) 
        at com.google.ads.interactivemedia.v3.internal.akf.a(IMASDK:23) 
        at com.google.ads.interactivemedia.v3.internal.akb.a(IMASDK:177) 
        at com.google.ads.interactivemedia.v3.internal.akb.a(IMASDK:43) 
        at com.google.ads.interactivemedia.v3.internal.ake.b(IMASDK:28) 
        at com.google.ads.interactivemedia.v3.internal.akc.shouldOverrideUrlLoading(IMASDK:6) 
        at android.webkit.WebViewClient.shouldOverrideUrlLoading(WebViewClient.java:77) 
        at org.chromium.android_webview.AwContentsClientBridge.shouldOverrideUrlLoading(chromium-Monochrome.aab-stable-410409673:16) 
        at android.os.MessageQueue.nativePollOnce(Native Method) 
        at android.os.MessageQueue.next(MessageQueue.java:326) 
        at android.os.Looper.loop(Looper.java:165) 
        at android.app.ActivityThread.main(ActivityThread.java:6810) 
        at java.lang.reflect.Method.invoke(Native Method) 
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:547) 
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:873) 
     Caused by: java.lang.IllegalArgumentException
        at com.google.android.exoplayer2.util.Assertions.checkArgument(Assertions.java:39)
        at com.google.android.exoplayer2.source.ads.AdPlaybackState$AdGroup.withAdUri(AdPlaybackState.java:151)
        at com.google.android.exoplayer2.source.ads.AdPlaybackState.withAdUri(AdPlaybackState.java:399)
        at com.google.android.exoplayer2.ext.ima.ImaAdsLoader.loadAd(ImaAdsLoader.java:872)
        at com.google.ads.interactivemedia.v3.internal.akf.a(IMASDK:23) 
        at com.google.ads.interactivemedia.v3.internal.akb.a(IMASDK:177) 
        at com.google.ads.interactivemedia.v3.internal.akb.a(IMASDK:43) 
        at com.google.ads.interactivemedia.v3.internal.ake.b(IMASDK:28) 
        at com.google.ads.interactivemedia.v3.internal.akc.shouldOverrideUrlLoading(IMASDK:6) 
        at android.webkit.WebViewClient.shouldOverrideUrlLoading(WebViewClient.java:77) 
        at org.chromium.android_webview.AwContentsClientBridge.shouldOverrideUrlLoading(chromium-Monochrome.aab-stable-410409673:16) 
        at android.os.MessageQueue.nativePollOnce(Native Method) 
        at android.os.MessageQueue.next(MessageQueue.java:326) 
        at android.os.Looper.loop(Looper.java:165) 
        at android.app.ActivityThread.main(ActivityThread.java:6810) 
        at java.lang.reflect.Method.invoke(Native Method) 
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:547) 
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:873) 
    ]

[REQUIRED] Version of ExoPlayer being used

2.11.3 & 2.11.5 (latest)

[REQUIRED] Device(s) and version(s) of Android being used

It doesn't seem to be affected by device / android version. All.

Potential solution

We have seen that if we allow to change AdGroup.count when the received one from the updated AdPod is greater than the one in the AdGroup, it seems to work.

In r2.11.5, on ImaAdsLoader.loadAd method we have included the mentioned condition.

      int adCount = Math.max(adPodInfo.getTotalAds(), adGroup.states.length);
      if (adGroup.count == C.LENGTH_UNSET || adCount > adGroup.count)) {
        adPlaybackState = adPlaybackState.withAdCount(adInfo.adGroupIndex, adCount);
        adGroup = adPlaybackState.adGroups[adInfo.adGroupIndex];
      }

Above requires that AdGroupd.withAdCount copy method doesn't check for count == C.LENGTH_UNSET condition.

It seems to be working fine for us so far, but I'm not sure if this is the proper solution. There are other places on ImaAdsLoader where AdPlaybackState.withAdCount is used.

** Sorry this didn't come before 2.11.5 was released :)

@andrewlewis
Copy link
Collaborator

Thanks for the report. Filed [Internal: b/159042225] to ask the IMA SDK team to take a look and advise whether this is working as intended, and if so what the cause is.

@andrewlewis
Copy link
Collaborator

Regarding the potential solution, I'd expect it to work as long as the final/correct ad count is known before the player buffers to the end of the last ad in the ad pod, but without understanding what's going on in more detail I'm not sure that is guaranteed.

@andrewlewis
Copy link
Collaborator

At the point of loading the first ad future ads in the pod may still be loading, and in general to total ad count is an estimate until the last ad in the pod loads.

I think it's safe just to remove the requirement that the ad count doesn't change as it looks like we discard buffered media periods as required to support this in MediaPeriodQueue. I will make a fix to do that.

andrewlewis added a commit that referenced this issue Jun 17, 2020
Ads can appear due to asynchronous ad tag requests completing after
earlier ads in a pod have loaded, so remove the requirement that the
ad count can't change. The MediaPeriodQueue should handling discarding
buffered content if an ad appears before already buffered content, so
I think this case is actually handled correctly by the core player
already.

Also remove the requirement that an ad URI can't change. This is a
defensive measure for now, but it's likely that a later fix in the IMA
SDK for an issue where loadAd is not called after preloading then
seeking before a preloaded ad plays will result in loadAd being called
more than once, and I think it's possible that the second call to
loadAd may have a different URI. Because the ad URI should only change
after an intermediate seek to another MediaPeriod, there shouldn't be
any problems with buffered data not getting discarded.

Issue: #7477
PiperOrigin-RevId: 316871371
ojw28 pushed a commit that referenced this issue Jun 17, 2020
Ads can appear due to asynchronous ad tag requests completing after
earlier ads in a pod have loaded, so remove the requirement that the
ad count can't change. The MediaPeriodQueue should handling discarding
buffered content if an ad appears before already buffered content, so
I think this case is actually handled correctly by the core player
already.

Also remove the requirement that an ad URI can't change. This is a
defensive measure for now, but it's likely that a later fix in the IMA
SDK for an issue where loadAd is not called after preloading then
seeking before a preloaded ad plays will result in loadAd being called
more than once, and I think it's possible that the second call to
loadAd may have a different URI. Because the ad URI should only change
after an intermediate seek to another MediaPeriod, there shouldn't be
any problems with buffered data not getting discarded.

Issue: #7477
PiperOrigin-RevId: 316871371
@ojw28
Copy link
Contributor

ojw28 commented Jun 23, 2020

Fixed in the commits referenced above. This will be part of 2.11.6, which should be released today or tomorrow.

@ojw28 ojw28 closed this as completed Jun 23, 2020
@fpittersacc
Copy link
Author

Thanks, I can confirm this is working as intended.

@google google locked and limited conversation to collaborators Aug 23, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Projects
None yet
Development

No branches or pull requests

3 participants