Open chladto1 opened 3 years ago
Hi @chladto1, I don't think we can allocate resources to help debugging app customizations. @tonihei do you see any way forward to efficiently assist with this?
As @AquilesCanta already pointed out, we can't really help you debug custom solutions in detail.
Is there any solution how to prevent from buffering when update AdPlaybackState?
Updating AdPlaybackState
causes the player to reevaluate its internal playback queue. In some cases, this means we need to reset the current rendering and cause a short buffering state. I'm not sure if that's what's causing your buffering, but it seems likely. For example, if the player is currently prebuffering an ad and some parts of this ad's media information has been sent to the decoders, we can't remove the ad without causing a complete decoder reset (and a buffering state). So, depending on when you see the buffering happen, you may be able to improve it by making the update earlier.
Can we implement this feature by another way?
We have some pending feature requests to support more flexible ad group position handling, for example #5067 and #5482. It's unlikely we get around to do any of these soon though. Generally, it's hard to modify the ad execution logic as it's handled internally by the player in a non-customizable component. The only way you have to influence the decision is to mark existing ads as skipped or failed, which I believe you are already doing.
mark existing ads as skipped or failed
Ads are marked as skipped (Exo) and getContentVideoProgressUpdate()
is returning VIDEO_TIME_NOT_READY
as content position (IMA). When conditions are met, skipped ads are replaced by new AdPlaybackState.AdGroup
and real content position is provided to IMA.
improve it by making the update earlier
In the test content above, getContentVideoProgressUpdate()
returns VIDEO_TIME_NOT_READY
for 20 seconds before ads position (IMA) and ads are marked as skipped 1 second before their position (Exo). At this moment, Exo doesn't have URL to load ads, so there is no content to buffering, right? Should I mark ads as skipped even earlier?
When conditions are met, skipped ads are replaced by new AdPlaybackState.AdGroup and real content position is provided to IMA.
There are probably some internal assumptions about "allowed" changes, for example that an ad group that was "skipped" can't suddenly become available for playback again. This may still work, but our internal code wasn't written under such assumptions and may not work correctly in all cases if you that.
In the test content above, getContentVideoProgressUpdate() returns VIDEO_TIME_NOT_READY for 20 seconds before ads position (IMA)
I'm not sure why you need to fake the video progress update. Marking the ad break as skipped should be enough for the player to not play it.
At this moment, Exo doesn't have URL to load ads, so there is no content to buffering, right? Should I mark ads as skipped even earlier?
Your original description didn't make it very clear where and when the buffering is happening exactly. There may also be other reasons, e.g. if the player originally planned to play an ad at a certain position, it may have already clipped the content. While theoretically possible, we don't currently extend this clipping when the ad group is suddenly marked as skipped, but instead you'll see a short buffering at the point where the ad group should have been. If you want to avoid that, you'd need to mark the ad group as skipped before the content that ends at the ad group even starts loading.
I'm not sure why you need to fake the video progress update.
Because of IMA. If I send the real position, IMA start preloading ads and they will be timeouted, because Exo didn't start playing them.
Your original description didn't make it very clear where and when the buffering is happening exactly.
Sorry, buffering will occur when is called AdTagLoader.updateAdPlaybackState()
with newly skipped ads. It cause call AdsMediaSource.maybeUpdateSourceInfo()
and BaseMediaSource.refreshSourceInfo()
which I think the problem is.
If I understood correctly, at the moment, marking ads as skipped without short buffering is not possible, right?
If I understood correctly, at the moment, marking ads as skipped without short buffering is not possible, right?
Not in the setup you describe. I think you could avoid this by marking it as skipped earlier (e.g. while the previous ad is still playing)
I'm not sure why you need to fake the video progress update.
Because of IMA. If I send the real position, IMA start preloading ads and they will be timeouted, because Exo didn't start playing them.
Just a side note on this: calling [AdsManager.discardAdBreak
](https://developers.google.com/interactive-media-ads/docs/sdks/android/client-side/api/reference/com/google/ads/interactivemedia/v3/api/AdsManager.html#discardAdBreak()) when no ad is playing is supposed to discard the next ad break, so may work as an alternative workaround. (I don't know exactly what callbacks happen next but it may also be necessary to mark the ad break as skipped on the ExoPlayer side when doing this.)
I think you could avoid this by marking it as skipped earlier (e.g. while the previous ad is still playing)
When previous ad is playing, I don't know if a user will seek behind another ad in time threshold. If I do it, I must unset skipped state which probably cause buffering too. I think, in a real situation this probably cause more buffering. In the current implementation, unsetting skipped state is happening only when a user seeking, so additional buffering is invisible to a user.
calling AdsManager.discardAdBreak when no ad is playing is supposed to discard the next ad break
Calling AdsManager.discardAdBreak
will discard ad break forever, in our solution ads should be skipped only temporary. It's mean, when a user seeks before previously skipped ads, they should be again playable.
I'll mark this issue as an enhancement to track that skipped midrolls cause short buffering. This may be solvable independent of #5067 and #5482 (e.g. by updating the clip end position of the content).
We modified ImaAdsLoader to support feature we called Smart seek. It means, ads will not start when another ad was played within defined amount of time. In other words, timeline has 5 ad breaks, when you seek between first and second one, IMA will start playing first ad break. Immediately after the end of the ad you seek between second and third one, but at this time, ad will start because media playback does not exceed time threshold to play next ads.
I sent you source code of modified ImaAdsLoader on email. All my modifications are marked with MARK TOM. Please set adWatchThreshold to 25 seconds (25000) and use this VMAP that has ad breaks every 20 seconds. Player plays the preroll, skips first midroll and plays second midroll. We need to update AdPlaybackState before the first midroll and that cause 1 second buffering that is unacceptable for our client.
Could you please help us? Is there any solution how to prevent from buffering when update AdPlaybackState? Can we implement this feature by another way?
Thanks!