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

How to set minimum amount of data/chunks to be buffered before start of playback #6697

Closed
krackjack234 opened this issue Nov 26, 2019 · 8 comments
Assignees
Labels

Comments

@krackjack234
Copy link

@krackjack234 krackjack234 commented Nov 26, 2019

[REQUIRED] Searched documentation but could not find direct answer

[REQUIRED] Question

We want to control the minimum number of chunks/data that the player should load before it should start playback

We changed the below values in CustomLoadControl and added it to exoplayer overriding default load control

public static final int DEFAULT_MIN_BUFFER_MS = 6000;
public static final int DEFAULT_MAX_BUFFER_MS = 1000;
public static final int DEFAULT_BUFFER_FOR_PLAYBACK_MS = 2500;
public static final int DEFAULT_BUFFER_FOR_PLAYBACK_AFTER_REBUFFER_MS = 5000;

For us, our HLS chunk duration is 5s.

When we set the DEFAULT_MAX_BUFFER_MS to 1000ms we see 2 chunk getting downloaded (one with smaller bitrate and then same chunk of a higher bitrate, since player is in ABR mode)
When we set DEFAULT_MAX_BUFFER_MS to 6000ms we see 4 chunks getting downloaded.

We want to know the following

  1. Is DEFAULT_MAX_BUFFER_MS variable to be used to set the minimum buffer size before player can start to play? Documentation says "For playbacks with video, this is also the default minimum duration of media that the player will attempt to ensure is buffered." The other param DEFAULT_MIN_BUFFER_MS seems to be only applied for playbacks without video.
  2. If yes, why do we see the number to chunks downloaded not matching our expectation as each chuck is of 5s
  3. Is there a way in Exoplayer to define the initial no. of chunks that player should download before starting playback (instead of defining the value in millisecs)?
  4. Initially we see a smaller bitrate chunk gets downloaded and the then player switches to a higher bitrate chunk. How can we avoid it?

Any pointers will be greatly appreciated.
Thanks.

@krackjack234 krackjack234 changed the title How to set minimum amount of data/chunks to be buffered data before start of playback How to set minimum amount of data/chunks to be buffered before start of playback Nov 27, 2019
@krackjack234
Copy link
Author

@krackjack234 krackjack234 commented Nov 28, 2019

Hi, Anyone has any thought on this?

@icbaker icbaker self-assigned this Dec 2, 2019
@icbaker
Copy link
Contributor

@icbaker icbaker commented Dec 2, 2019

We changed the below values in CustomLoadControl and added it to exoplayer overriding default load control.

Can you be a bit more specific here? Did you create a subclass of DefaultLoadControl? How did you then change those values such that they were read by your subclass? If you just redefined the same static constants, they won't be used by the superclass implementation.

I don't think you need to make a subclass btw (and maybe you didn't and I misunderstood) - I think you can use DefaultLoadControl.Builder#setBufferDurationMs() to create an instance with customised buffer durations.

For us, our HLS chunk duration is 5s.

When we set the DEFAULT_MAX_BUFFER_MS to 1000ms we see 2 chunk getting downloaded (one with smaller bitrate and then same chunk of a higher bitrate, since player is in ABR mode)
When we set DEFAULT_MAX_BUFFER_MS to 6000ms we see 4 chunks getting downloaded.

We want to know the following

  1. Is "DEFAULT_MAX_BUFFER_MS" variable to be used to set the minimum buffer size before player can start to play? Documentation says "For playbacks with video, this is also the default minimum duration of media that the player will attempt to ensure is buffered." The other param DEFAULT_MIN_BUFFER_MS seems to be only applied for playbacks without video.

Yes - as you've seen in the documentation, that constant is used for both min & max video playback. This was changed in 9725132. Note that if you use the Builder approach I suggested above, you can still set the min & max buffer durations for video separately.

  1. If yes, why do we see the number to chunks downloaded not matching our expectation as each chuck is of 5s

What's your expectation? It seems if you say "download up to 1000ms of video" but your video is in 5s chunks, then it's going to need to download at least a whole chunk. You've noticed yourself that it's downloading the same chunk twice at different bit rates due to ABR - so in a way (barring Q4 about the ABR behaviour) this seems expected. Same for 6000ms resulting in 4 chunks (presumably 2x low bitrate, 2x same chunks at higher bitrate?).

  1. Is there a way in Exoplayer to define the initial no. of chunks that player should download before starting playback (instead of defining the value in millisecs)?

Not out of the box - because (Default)LoadControl doesn't know your media is chunked (it's used for progressive playback too). You can write a custom implementation of LoadControl though and put whatever behaviour you want in shouldContinueLoading() and shouldStartPlayback() - so it should be possible to make this chunk-based if you can access the chunk duration info somehow.

  1. Initially we see a smaller bitrate chunk gets downloaded and the then player switches to a higher bitrate chunk. How can we avoid it?

I suspect this is likely due to how bandwidth is measured - @tonihei might have more info here.

@icbaker icbaker added need more info and removed needs triage labels Dec 2, 2019
@tonihei
Copy link
Contributor

@tonihei tonihei commented Dec 2, 2019

  1. Is "DEFAULT_MAX_BUFFER_MS" variable to be used to set the minimum buffer size before player can start to play?

Actually no. This buffer is the maximum the player attempts to load in total. This unrelated to the start of the playback. The buffer needed to start playback is called bufferForPlaybackMs and the buffer needed to restart after playback stalled is called bufferForPlaybackAfterRebufferMs.

  1. If yes, why do we see the number to chunks downloaded not matching our expectation as each chuck is of 5s

Looks like this is why it downloads more chunks than you expect.

  1. Is there a way in Exoplayer to define the initial no. of chunks that player should download before starting playback (instead of defining the value in millisecs)?

Could you explain why you can`t define the time in milliseconds? It seems preferable to use a time-based constraint that is independent of the chunk size. The player will continue the load the next chunk anyway, so the buffer needed for playback start is not really related to any chunk boundaries. And as @icbaker pointed out, some media isn't chunk-based and can only use milliseconds anyway.

  1. Initially we see a smaller bitrate chunk gets downloaded and the then player switches to a higher bitrate chunk. How can we avoid it?

The selected format is based on the bitrate estimate of the network. If no other information is available, the bitrate is estimated based on the country and the network type of the user. You can overwrite the estimates at multiple levels of granularity in DefaultBandwidthMeter.Builder to provide your own values if you want. Ideally, use the same bandwidth meter for all playbacks to keep the previously calculated estimate for the next playback. This is done by default, but you need to ensure this yourself if you provide your own BandwidthMeter instance.

@krackjack234
Copy link
Author

@krackjack234 krackjack234 commented Dec 13, 2019

Hi,

We are using the CustomLoadControl code (explained here https://github.com/Sriharia/ExoPlayer-StatsForNerds/blob/master/demo/src/main/java/com/google/android/exoplayer2/demo/CustomLoadControl.java) to configure the buffer durations

Below is our code

CustomLoadControl customLoadControl = 
        new CustomLoadControl(new CustomLoadControl.EventListener() {
  @Override
  public void onBufferedDurationSample(long bufferedDurationUs){}}, null);

if(initialBitrate > 0)
{
    DefaultBandwidthMeter bandwidthMeter = new DefaultBandwidthMeter.Builder()
                        .setInitialBitrateEstimate(initialBitrate)
                        .build();
     player =  ExoPlayerFactory.newSimpleInstance(context, renderersFactory, trackSelector, 
                     customLoadControl, drmSessionManager, bandwidthMeter);
   }
else
 {
     player =  ExoPlayerFactory.newSimpleInstance(context, renderersFactory, trackSelector, 
                     customLoadControl, drmSessionManager);
  }

We have defined the buffer durations in the custom load control.

So as I understand from the above comments, downloading of same chunks of different bitrates is expected as the player is in ABR mode.

We are also using the BandwidthMeter to set the initial bitrate.

So, If we set the initial bitrate to say 900k and the value of bufferForPlaybackMs to duration of 1 chunk (in our case 5s), will the player start playing immediately after downloading the first chuck, whatever bitrate it may be ?

@tonihei
Copy link
Contributor

@tonihei tonihei commented Dec 13, 2019

So as I understand from the above comments, downloading of same chunks of different bitrates is expected as the player is in ABR mode.

That's not expected and only happens in certain cases where HLS media playlist don't contain independent segments.

So, If we set the initial bitrate to say 900k and the value of bufferForPlaybackMs to duration of 1 chunk (in our case 5s), will the player start playing immediately after downloading the first chuck, whatever bitrate it may be ?

Yes, if you set the bufferForPlaybackMs to 5 seconds, playback starts as soon as 5 seconds of media has been buffered (which may be one chunk in your case).

@icbaker
Copy link
Contributor

@icbaker icbaker commented Dec 13, 2019

Thanks for the link to CustomLoadControl.

Since that's not owned or maintained by ExoPlayer Team, we can't really answer questions about its behaviour (including the meaning of bufferForPlaybackMs). I suspect those questions are best directed at the maintainers of ExoPlayer-StatsForNerds.

We can help you with questions about the behaviour of DefaultLoadControl and the expectations of the LoadControl interface - since those are owned by us. So if you're able to re-frame your questions in those terms, we can help provide answers.

@icbaker icbaker added need more info and removed needs triage labels Dec 13, 2019
@krackjack234
Copy link
Author

@krackjack234 krackjack234 commented Dec 13, 2019

Thanks for the replies.

@google-oss-bot
Copy link
Collaborator

@google-oss-bot google-oss-bot commented Dec 28, 2019

Hey @krackjack234. We need more information to resolve this issue but there hasn't been an update in 14 days. I'm marking the issue as stale and if there are no new updates in the next 7 days I will close it automatically.

If you have more information that will help us get to the bottom of this, just add a comment!

@ojw28 ojw28 removed the need more info label Jan 2, 2020
@ojw28 ojw28 closed this Jan 2, 2020
@google google locked and limited conversation to collaborators Mar 3, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Linked pull requests

Successfully merging a pull request may close this issue.

None yet
5 participants