Skip to content
This repository was archived by the owner on Feb 11, 2022. It is now read-only.

Commit ecfe867

Browse files
authored
Merge pull request #215 from novoda/develop
Prepare for release 4.5.4
2 parents 99d6d47 + 182e928 commit ecfe867

File tree

17 files changed

+291
-19
lines changed

17 files changed

+291
-19
lines changed

build.gradle

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
allprojects {
2-
version = '4.5.3'
2+
version = '4.5.4'
33
}
44

55
def teamPropsFile(propsFile) {

core/src/main/java/com/novoda/noplayer/NoPlayer.java

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,12 +32,16 @@ public interface NoPlayer extends PlayerState {
3232
void play() throws IllegalStateException;
3333

3434
/**
35-
* Plays content of a prepared Player at a given position.
35+
* Deprecated: This does not perform the way it was originally intended. A seek can, and most likely will,
36+
* occur after the content has already started playing. This can lead to some unexpected behaviour.
37+
* Plays content of a prepared Player at a given position. Use {@link #loadVideo(Uri, Options)} passing
38+
* a initial position to the {@link Options}.
3639
*
3740
* @param positionInMillis to start playing content from.
3841
* @throws IllegalStateException - if called before {@link NoPlayer#loadVideo(Uri, Options)}.
3942
* @see NoPlayer.PreparedListener
4043
*/
44+
@Deprecated
4145
void playAt(long positionInMillis) throws IllegalStateException;
4246

4347
/**
@@ -223,6 +227,18 @@ public interface NoPlayer extends PlayerState {
223227
@FloatRange(from = 0.0f, to = 1.0f)
224228
float getVolume() throws IllegalStateException;
225229

230+
/**
231+
* Clears the maximum video bitrate, if set.
232+
*/
233+
void clearMaxVideoBitrate();
234+
235+
/**
236+
* Sets a maximum video bitrate. If the content is playing, the video will switch to a different quality.
237+
*
238+
* @param maxVideoBitrate The maximum video bitrate in bit per second.
239+
*/
240+
void setMaxVideoBitrate(int maxVideoBitrate);
241+
226242
interface PlayerError {
227243

228244
PlayerErrorType type();

core/src/main/java/com/novoda/noplayer/Options.java

Lines changed: 52 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,46 @@
11
package com.novoda.noplayer;
22

3+
import com.novoda.noplayer.internal.utils.Optional;
4+
5+
/**
6+
* Options to customise the underlying player.
7+
*/
38
public class Options {
49

510
private final ContentType contentType;
611
private final int minDurationBeforeQualityIncreaseInMillis;
712
private final int maxInitialBitrate;
13+
private final int maxVideoBitrate;
14+
private final Optional<Long> initialPositionInMillis;
15+
16+
/**
17+
* Creates a {@link OptionsBuilder} from this Options.
18+
*
19+
* @return a new instance of {@link OptionsBuilder}.
20+
*/
21+
public OptionsBuilder toOptionsBuilder() {
22+
OptionsBuilder optionsBuilder = new OptionsBuilder()
23+
.withContentType(contentType)
24+
.withMinDurationBeforeQualityIncreaseInMillis(minDurationBeforeQualityIncreaseInMillis)
25+
.withMaxInitialBitrate(maxInitialBitrate)
26+
.withMaxVideoBitrate(maxVideoBitrate);
827

9-
Options(ContentType contentType, int minDurationBeforeQualityIncreaseInMillis, int maxInitialBitrate) {
28+
if (initialPositionInMillis.isPresent()) {
29+
optionsBuilder = optionsBuilder.withInitialPositionInMillis(initialPositionInMillis.get());
30+
}
31+
return optionsBuilder;
32+
}
33+
34+
Options(ContentType contentType,
35+
int minDurationBeforeQualityIncreaseInMillis,
36+
int maxInitialBitrate,
37+
int maxVideoBitrate,
38+
Optional<Long> initialPositionInMillis) {
1039
this.contentType = contentType;
1140
this.minDurationBeforeQualityIncreaseInMillis = minDurationBeforeQualityIncreaseInMillis;
1241
this.maxInitialBitrate = maxInitialBitrate;
42+
this.maxVideoBitrate = maxVideoBitrate;
43+
this.initialPositionInMillis = initialPositionInMillis;
1344
}
1445

1546
public ContentType contentType() {
@@ -24,6 +55,14 @@ public int maxInitialBitrate() {
2455
return maxInitialBitrate;
2556
}
2657

58+
public int maxVideoBitrate() {
59+
return maxVideoBitrate;
60+
}
61+
62+
public Optional<Long> getInitialPositionInMillis() {
63+
return initialPositionInMillis;
64+
}
65+
2766
@Override
2867
public boolean equals(Object o) {
2968
if (this == o) {
@@ -41,14 +80,23 @@ public boolean equals(Object o) {
4180
if (maxInitialBitrate != options.maxInitialBitrate) {
4281
return false;
4382
}
44-
return contentType == options.contentType;
83+
if (maxVideoBitrate != options.maxVideoBitrate) {
84+
return false;
85+
}
86+
if (contentType != options.contentType) {
87+
return false;
88+
}
89+
return initialPositionInMillis != null
90+
? initialPositionInMillis.equals(options.initialPositionInMillis) : options.initialPositionInMillis == null;
4591
}
4692

4793
@Override
4894
public int hashCode() {
4995
int result = contentType != null ? contentType.hashCode() : 0;
5096
result = 31 * result + minDurationBeforeQualityIncreaseInMillis;
5197
result = 31 * result + maxInitialBitrate;
98+
result = 31 * result + maxVideoBitrate;
99+
result = 31 * result + (initialPositionInMillis != null ? initialPositionInMillis.hashCode() : 0);
52100
return result;
53101
}
54102

@@ -58,6 +106,8 @@ public String toString() {
58106
+ "contentType=" + contentType
59107
+ ", minDurationBeforeQualityIncreaseInMillis=" + minDurationBeforeQualityIncreaseInMillis
60108
+ ", maxInitialBitrate=" + maxInitialBitrate
109+
+ ", maxVideoBitrate=" + maxVideoBitrate
110+
+ ", initialPositionInMillis=" + initialPositionInMillis
61111
+ '}';
62112
}
63113
}

core/src/main/java/com/novoda/noplayer/OptionsBuilder.java

Lines changed: 39 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,17 +2,22 @@
22

33
import android.net.Uri;
44

5+
import com.novoda.noplayer.internal.utils.Optional;
6+
57
/**
68
* Builds instances of {@link Options} for {@link NoPlayer#loadVideo(Uri, Options)}.
79
*/
810
public class OptionsBuilder {
911

1012
private static final int DEFAULT_MIN_DURATION_FOR_QUALITY_INCREASE_MS = 10000;
1113
private static final int DEFAULT_MAX_INITIAL_BITRATE = 800000;
14+
private static final int DEFAULT_MAX_VIDEO_BITRATE = Integer.MAX_VALUE;
1215

1316
private ContentType contentType = ContentType.H264;
1417
private int minDurationBeforeQualityIncreaseInMillis = DEFAULT_MIN_DURATION_FOR_QUALITY_INCREASE_MS;
1518
private int maxInitialBitrate = DEFAULT_MAX_INITIAL_BITRATE;
19+
private int maxVideoBitrate = DEFAULT_MAX_VIDEO_BITRATE;
20+
private Optional<Long> initialPositionInMillis = Optional.absent();
1621

1722
/**
1823
* Sets {@link OptionsBuilder} to build {@link Options} with a given {@link ContentType}.
@@ -44,19 +49,51 @@ public OptionsBuilder withMinDurationBeforeQualityIncreaseInMillis(int minDurati
4449
* allows the player to choose a higher quality video track at the beginning.
4550
*
4651
* @param maxInitialBitrate maximum bitrate that limits the initial track selection.
47-
* @return {@link OptionsBuilder}
52+
* @return {@link OptionsBuilder}.
4853
*/
4954
public OptionsBuilder withMaxInitialBitrate(int maxInitialBitrate) {
5055
this.maxInitialBitrate = maxInitialBitrate;
5156
return this;
5257
}
5358

59+
/**
60+
* Sets {@link OptionsBuilder} to build {@link Options} with given maximum video bitrate in order to
61+
* control what is the maximum video quality with which {@link NoPlayer} starts the playback. Setting a higher value
62+
* allows the player to choose a higher quality video track.
63+
*
64+
* @param maxVideoBitrate maximum bitrate that limits the initial track selection.
65+
* @return {@link OptionsBuilder}
66+
*/
67+
public OptionsBuilder withMaxVideoBitrate(int maxVideoBitrate) {
68+
this.maxVideoBitrate = maxVideoBitrate;
69+
return this;
70+
}
71+
72+
/**
73+
* Sets {@link OptionsBuilder} to build {@link Options} with given initial position in millis in order
74+
* to specify the start position of the content that will be played. Omitting to set this will start
75+
* playback at the beginning of the content.
76+
*
77+
* @param initialPositionInMillis position that the content should begin playback at.
78+
* @return {@link OptionsBuilder}.
79+
*/
80+
public OptionsBuilder withInitialPositionInMillis(long initialPositionInMillis) {
81+
this.initialPositionInMillis = Optional.of(initialPositionInMillis);
82+
return this;
83+
}
84+
5485
/**
5586
* Builds a new {@link Options} instance.
5687
*
5788
* @return a {@link Options} instance.
5889
*/
5990
public Options build() {
60-
return new Options(contentType, minDurationBeforeQualityIncreaseInMillis, maxInitialBitrate);
91+
return new Options(
92+
contentType,
93+
minDurationBeforeQualityIncreaseInMillis,
94+
maxInitialBitrate,
95+
maxVideoBitrate,
96+
initialPositionInMillis
97+
);
6198
}
6299
}

core/src/main/java/com/novoda/noplayer/internal/exoplayer/CompositeTrackSelector.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,4 +77,12 @@ List<PlayerSubtitleTrack> getSubtitleTracks(RendererTypeRequester rendererTypeRe
7777
boolean clearSubtitleTrack(RendererTypeRequester rendererTypeRequester) {
7878
return subtitleTrackSelector.clearSubtitleTrack(rendererTypeRequester);
7979
}
80+
81+
void clearMaxVideoBitrate() {
82+
videoTrackSelector.clearMaxVideoBitrate();
83+
}
84+
85+
void setMaxVideoBitrate(int maxVideoBitrate) {
86+
videoTrackSelector.setMaxVideoBitrate(maxVideoBitrate);
87+
}
8088
}

core/src/main/java/com/novoda/noplayer/internal/exoplayer/CompositeTrackSelectorCreator.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,10 @@ CompositeTrackSelector create(Options options, DefaultBandwidthMeter bandwidthMe
2525
Clock.DEFAULT
2626
);
2727
DefaultTrackSelector trackSelector = new DefaultTrackSelector(adaptiveTrackSelectionFactory);
28+
DefaultTrackSelector.Parameters trackSelectorParameters = trackSelector.buildUponParameters()
29+
.setMaxVideoBitrate(options.maxVideoBitrate())
30+
.build();
31+
trackSelector.setParameters(trackSelectorParameters);
2832

2933
ExoPlayerTrackSelector exoPlayerTrackSelector = ExoPlayerTrackSelector.newInstance(trackSelector);
3034
ExoPlayerAudioTrackSelector audioTrackSelector = new ExoPlayerAudioTrackSelector(exoPlayerTrackSelector);

core/src/main/java/com/novoda/noplayer/internal/exoplayer/ExoPlayerFacade.java

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,6 @@
2626

2727
class ExoPlayerFacade {
2828

29-
private static final boolean RESET_POSITION = true;
3029
private static final boolean DO_NOT_RESET_STATE = false;
3130

3231
private final BandwidthMeterCreator bandwidthMeterCreator;
@@ -136,7 +135,14 @@ void loadVideo(PlayerSurfaceHolder playerSurfaceHolder,
136135
bandwidthMeter
137136
);
138137
attachToSurface(playerSurfaceHolder);
139-
exoPlayer.prepare(mediaSource, RESET_POSITION, DO_NOT_RESET_STATE);
138+
139+
boolean hasInitialPosition = options.getInitialPositionInMillis().isPresent();
140+
if (hasInitialPosition) {
141+
Long initialPositionInMillis = options.getInitialPositionInMillis().get();
142+
exoPlayer.seekTo(initialPositionInMillis);
143+
}
144+
145+
exoPlayer.prepare(mediaSource, !hasInitialPosition, DO_NOT_RESET_STATE);
140146
}
141147

142148
private void setMovieAudioAttributes(SimpleExoPlayer exoPlayer) {
@@ -231,10 +237,19 @@ float getVolume() {
231237
return exoPlayer.getVolume();
232238
}
233239

240+
void clearMaxVideoBitrate() {
241+
assertVideoLoaded();
242+
compositeTrackSelector.clearMaxVideoBitrate();
243+
}
244+
245+
void setMaxVideoBitrate(int maxVideoBitrate) {
246+
assertVideoLoaded();
247+
compositeTrackSelector.setMaxVideoBitrate(maxVideoBitrate);
248+
}
249+
234250
private void assertVideoLoaded() {
235251
if (exoPlayer == null) {
236252
throw new IllegalStateException("Video must be loaded before trying to interact with the player");
237253
}
238254
}
239-
240255
}

core/src/main/java/com/novoda/noplayer/internal/exoplayer/ExoPlayerTwoImpl.java

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -136,6 +136,16 @@ public float getVolume() {
136136
return exoPlayer.getVolume();
137137
}
138138

139+
@Override
140+
public void clearMaxVideoBitrate() {
141+
exoPlayer.clearMaxVideoBitrate();
142+
}
143+
144+
@Override
145+
public void setMaxVideoBitrate(int maxVideoBitrate) {
146+
exoPlayer.setMaxVideoBitrate(maxVideoBitrate);
147+
}
148+
139149
@Override
140150
public Listeners getListeners() {
141151
return listenersHolder;

core/src/main/java/com/novoda/noplayer/internal/exoplayer/mediasource/ExoPlayerTrackSelector.java

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,4 +80,20 @@ boolean supportsTrackSwitching(TrackType trackType,
8080
&& trackGroups.get(groupIndex).length > 0
8181
&& trackInfo().getAdaptiveSupport(audioRendererIndex.get(), groupIndex, false) != RendererCapabilities.ADAPTIVE_NOT_SUPPORTED;
8282
}
83+
84+
void clearMaxVideoBitrate() {
85+
setMaxVideoBitrateParameter(Integer.MAX_VALUE);
86+
}
87+
88+
void setMaxVideoBitrate(int maxVideoBitrate) {
89+
setMaxVideoBitrateParameter(maxVideoBitrate);
90+
}
91+
92+
private void setMaxVideoBitrateParameter(int maxValue) {
93+
trackSelector.setParameters(
94+
trackSelector.buildUponParameters()
95+
.setMaxVideoBitrate(maxValue)
96+
.build()
97+
);
98+
}
8399
}

core/src/main/java/com/novoda/noplayer/internal/exoplayer/mediasource/ExoPlayerVideoTrackSelector.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,4 +87,12 @@ private Optional<PlayerVideoTrack> findSelectedVideoTrack(Format selectedVideoFo
8787
public boolean clearVideoTrack(RendererTypeRequester rendererTypeRequester) {
8888
return trackSelector.clearSelectionOverrideFor(VIDEO, rendererTypeRequester);
8989
}
90+
91+
public void clearMaxVideoBitrate() {
92+
trackSelector.clearMaxVideoBitrate();
93+
}
94+
95+
public void setMaxVideoBitrate(int maxVideoBitrate) {
96+
trackSelector.setMaxVideoBitrate(maxVideoBitrate);
97+
}
9098
}

core/src/main/java/com/novoda/noplayer/internal/mediaplayer/AndroidMediaPlayerFacade.java

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,8 @@
2626
import static com.novoda.noplayer.internal.mediaplayer.PlaybackStateChecker.PlaybackState.PAUSED;
2727
import static com.novoda.noplayer.internal.mediaplayer.PlaybackStateChecker.PlaybackState.PLAYING;
2828

29+
// Not much we can do, wrapping MediaPlayer is a lot of work
30+
@SuppressWarnings("PMD.GodClass")
2931
class AndroidMediaPlayerFacade {
3032

3133
private static final Map<String, String> NO_HEADERS = null;
@@ -322,4 +324,14 @@ float getVolume() {
322324
assertIsInPlaybackState();
323325
return volume;
324326
}
327+
328+
void clearMaxVideoBitrate() {
329+
assertIsInPlaybackState();
330+
NoPlayerLog.w("Tried to clear max video bitrate but has not been implemented for MediaPlayer.");
331+
}
332+
333+
void setMaxVideoBitrate(int maxVideoBitrate) {
334+
assertIsInPlaybackState();
335+
NoPlayerLog.w("Tried to set max video bitrate but has not been implemented for MediaPlayer.");
336+
}
325337
}

core/src/main/java/com/novoda/noplayer/internal/mediaplayer/AndroidMediaPlayerImpl.java

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
import android.view.Surface;
66
import android.view.SurfaceHolder;
77
import android.view.View;
8+
89
import com.novoda.noplayer.Listeners;
910
import com.novoda.noplayer.NoPlayer;
1011
import com.novoda.noplayer.Options;
@@ -366,6 +367,16 @@ public List<PlayerSubtitleTrack> getSubtitleTracks() throws IllegalStateExceptio
366367
return mediaPlayer.getSubtitleTracks();
367368
}
368369

370+
@Override
371+
public void clearMaxVideoBitrate() {
372+
mediaPlayer.clearMaxVideoBitrate();
373+
}
374+
375+
@Override
376+
public void setMaxVideoBitrate(int maxVideoBitrate) {
377+
mediaPlayer.setMaxVideoBitrate(maxVideoBitrate);
378+
}
379+
369380
@Override
370381
public void stop() {
371382
reset();

0 commit comments

Comments
 (0)