Skip to content

Why Exoplayer downloads content manifest before pre-roll manifest? #1358

Closed

Description

@mayurk2

We are using Exoplayer 2.16.1 in our application. We are seeing video startup time is high with pre-roll ads and we are checking different options to reduce it.
Our application is using custom ads loader but the implementation sequence is similar to IMA Ads loader.

We are doing the CustomAdsLoader.requestAds() before the player.prepare() as recommended in different Exoplayer threads. So we have the ads URL while making the player.prepare() call.

We noticed that once the player.prepare() call is made,

  1. Exoplayer first makes call to content's master manifest.
  2. Later it makes call to AdsLoader.start(AdsMediaSource adsMediaSource, DataSpec adTagDataSpec, Object adsId, AdViewProvider adViewProvider, EventListener eventListener)

The CustomAdsLoader can provide the ad URLs to Exoplayer using the eventListener.onAdPlaybackState(adPlaybackState) only after the AdsLoader.start() call from Exoplayer.
We think this is causing some playback delay.

So my questions are,

  1. Why content manifest call is made before AdsLoader.start() when AdsMediaSource is used?
  2. Is there anyway we can force pre-roll manifest and segment download calls before content manifest call?

I checked these questions, did not get answer to my questions:

  1. Is there any way to do the preloading of the preroll ad in the Media3? #1040
  2. Is it possible to pre load preroll ads using ImaAdsLoader in a video list? google/ExoPlayer#3636

Activity

  1. changed the title [-]Why Exoplayer downloads content master manifest before pre-roll manifest?[/-] [+]Why Exoplayer downloads content manifest before pre-roll manifest?[/+] on May 9, 2024
  2. tonihei commented on May 10, 2024

    @tonihei
    Collaborator

    Thanks for your questions!

    Why content manifest call is made before AdsLoader.start() when AdsMediaSource is used?

    As far as I see, the content media, ads loader and ad media are all prepared in parallel. Just by the way the code is structured, you probably see the content manifest load being triggered just before the ads loader init, but both are executed in parallel.

    Playback can start if the the AdsLoader returned the AdPlaybackState and the first media to be played is ready (either content or ad, depending on whether there is a preroll).

    Overall, this looks like the most efficient way of loading the required data for playback (everything in parallel + start playback as soon as data for first element is available). Does that match your observations too and if not, could you suggest in more detail what you would like to change or where the delay is coming from in your set up?

    Is there anyway we can force pre-roll manifest and segment download calls before content manifest call?

    If you know the ad manifest URL, you can use caching to download the segments in advance. See https://developer.android.com/media/media3/exoplayer/downloading-media for more details (you probably don't need a Service if you trigger downloads ion background while your app has a Activity). On a lower level, you can also use CacheWriter directly to load individual segments or manifests. During playback, you can then access the same cache to play the already downloaded bytes. See https://developer.android.com/media/media3/exoplayer/network-stacks#caching

  3. mayurk2 commented on May 10, 2024

    @mayurk2
    ContributorAuthor

    @tonihei thanks for the explanation.

    As far as I see, the content media, ads loader and ad media are all prepared in parallel. Just by the way the code is structured, you probably see the content manifest load being triggered just before the ads loader init, but both are executed in parallel.

    I understand maybe due to actual code structure the content manifest loading is triggered first.
    But looks like they are not fully parallel. For testing purpose I throttled content manifest request heavily. I do not see parallel requests going for Ads manifest even after AdsLoader returned the AdPlaybackState.

    Is it because same thread is used to load the Ads manifest? In that case, is there any way I can change the order?

    Basically with pre-roll I think the Content manifest request is unnecessary before start playing the ads. So in slower network cases, it is delaying or slowing down the ads manifest request and hence increasing the overall startup time.

  4. tonihei commented on May 10, 2024

    @tonihei
    Collaborator

    I can see both content loading and ads loader preparation happening in parallel. Could you check that your throttling is just done in a DataSource for example to ensure it's on the background loading thread?

    If you are using IMA, you may also find that the extension itself waits for the content manifest before loading ads data as it needs to know the content start position before the IMA SDK asks to load an ad. Given you use your own ads loader, could you check that it returns an AdPlaybackState very soon after the ads loader is started? When this AdPlaybackState contains ad URLS, these will be prepared immediately, even if the content is not prepared yet.

  5. mayurk2 commented on May 10, 2024

    @mayurk2
    ContributorAuthor

    I can see both content loading and ads loader preparation happening in parallel. Could you check that your throttling is just done in a DataSource for example to ensure it's on the background loading thread?

    @tonihei I did not understand it fully. I routing the network calls from phone through PC. I am running Charles tool on PC and doing the throttling only to content master manifest URL.

    Given you use your own ads loader, could you check that it returns an AdPlaybackState very soon after the ads loader is started?

    Can you give more info on what do you mean by ads loader is started here?
    Is it when AdsLoader.start(AdsMediaSource adsMediaSource, DataSpec adTagDataSpec, Object adsId, AdViewProvider adViewProvider, EventListener eventListener) is called?
    Yes, we are giving the AdPlaybackState in this call or soon after this call. But the problem is AdsLoader.start() itself is called after starting content manifest request.
    Also, I do not see request for ads manifest till the content manifest is fetched.

  6. tonihei commented on May 10, 2024

    @tonihei
    Collaborator

    Also, I do not see request for ads manifest till the content manifest is fetched

    Thanks for explaining this again. I think this part might be the main area for improvement. I was testing with progressive content media before which has no manifest to load, so I didn't notice this part.

    I'll see whether we can let the ads source prepare while the main manifest is still loading to speed it up slightly.

    I think the Content manifest request is unnecessary before start playing the ads

    One further note: we need to wait for the initial content manifest to generate the right media structure, for example to know when exactly media start playing in live streams.

  7. mayurk2 commented on May 16, 2024

    @mayurk2
    ContributorAuthor

    @tonihei Is this issue fixed now?
    Just saw the change - d27c36a

    Do you think it can be taken to 2.16.1?

  8. tonihei commented on May 16, 2024

    @tonihei
    Collaborator

    Yes, it should work to load both content and preroll ad in parallel now.

    The change will be in Media3 1.4.0. I assume 2.16.1 refers to an old ExoPlayer version? We are no longer updating the ExoPlayer repository with new releases.

  9. locked and limited conversation to collaborators on Jul 16, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions