Reputation: 15
I'm trying to set video bitrate in Exoplayer. I had already set it like this:
trackSelector = new DefaultTrackSelector(factory);
DefaultTrackSelector.Parameters parameters = trackSelector.getParameters();
parameters.withMaxVideoBitrate(maxBitrate);
parameters.withExceedRendererCapabilitiesIfNecessary(false);
parameters.withExceedVideoConstraintsIfNecessary(false);
trackSelector.setParameters(parameters);
but it doesn't work. Everywhere I found something about this I've found people were using HlsChunk source which is private in Exoplayer 2.6. Can anyone help me, pls?
Upvotes: 1
Views: 1832
Reputation: 749
For those who need to set HLS quality according to their needs this is how it could be made, considering that about this topic there are several post on SO but no one is very clear.
As I write in 2019 I assume everyone is using ExoPlayer2.
This is the solution which gave us the best result.
DataSource.Factory dataSourceFactory = new DefaultDataSourceFactory(Objects.requireNonNull(getContext()),
Util.getUserAgent(this.getContext(), getResources().getString(R.string.app_name)));
trackSelector = new CustomTrackSelector();
videoSource = new HlsMediaSource.Factory(dataSourceFactory).createMediaSource(mp4VideoUri);
player = ExoPlayerFactory.newSimpleInstance(this.getContext(), trackSelector);
so what you should is just override the behavior of the custom track selector, overriding the selectTrack method
public class CustomTrackSelector extends DefaultTrackSelector
{
public CustomTrackSelector()
{
super();
}
protected @Nullable
TrackSelection selectVideoTrack(
TrackGroupArray groups,
int[][] formatSupports,
int mixedMimeTypeAdaptationSupports,
Parameters params,
@Nullable TrackSelection.Factory adaptiveTrackSelectionFactory)
throws ExoPlaybackException
{
AdaptiveTrackSelection adaptiveTrackSelection = null;
if (groups.length > 0)
{
for (int groupIndex = 0; groupIndex < groups.length; groupIndex++)
{
TrackGroup trackGroup = groups.get(groupIndex);
int[] tracks = new int[trackGroup.length];
//creation of indexes array
for (int i = 0; i < trackGroup.length; i++)
{
tracks[i] = i;
}
adaptiveTrackSelection = new AdaptiveTrackSelection(
trackGroup,
tracks,
new DefaultBandwidthMeter(),
AdaptiveTrackSelection.DEFAULT_MIN_DURATION_FOR_QUALITY_INCREASE_MS,
AdaptiveTrackSelection.DEFAULT_MAX_DURATION_FOR_QUALITY_DECREASE_MS,
AdaptiveTrackSelection.DEFAULT_MIN_DURATION_TO_RETAIN_AFTER_DISCARD_MS,
AdaptiveTrackSelection.DEFAULT_BANDWIDTH_FRACTION,
AdaptiveTrackSelection.DEFAULT_BUFFERED_FRACTION_TO_LIVE_EDGE_FOR_QUALITY_INCREASE,
AdaptiveTrackSelection.DEFAULT_MIN_TIME_BETWEEN_BUFFER_REEVALUTATION_MS,
Clock.DEFAULT);
for (int i = 0; i < tracks.length; i++)
{
Format format = trackGroup.getFormat(tracks[i]);
if (format.width < MIN_WIDTH)
{
Logger.log(this, "Video track blacklisted with width = " + format.width);
adaptiveTrackSelection.blacklist(tracks[i], BLACKLIST_DURATION);
} else
{
Logger.log(this, "Video track NOT blacklisted with width = " + format.width);
}
}
}
}
return adaptiveTrackSelection;
}
}
The above method just blacklist the track that you don't want to select, allowing the player to choose just between those that are not blacklisted.
We have blacklisted tracks according to width parameter, but obviously you can filter them using bitRate.
With this behavior the player will start with the track you allow it to use, and after a period of time (BLACKLIST TIME) it can switch back to use all the tracks in case of need. If you want to exclude a track for all the time just use Integer.MAX_VALUE as blacklist time.
I hope that this will help who is searching for this feature.
Upvotes: 1