Skip to content

Commit dfba10f

Browse files
authored
Merge pull request #7005 from Redirion/exo14
Update ExoPlayer to 2.14.2
2 parents 18ce86c + 48a1ab6 commit dfba10f

8 files changed

Lines changed: 151 additions & 100 deletions

File tree

app/build.gradle

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,7 @@ ext {
105105
androidxRoomVersion = '2.3.0'
106106

107107
icepickVersion = '3.2.0'
108-
exoPlayerVersion = '2.12.3'
108+
exoPlayerVersion = '2.14.2'
109109
googleAutoServiceVersion = '1.0'
110110
groupieVersion = '2.10.0'
111111
markwonVersion = '4.6.2'

app/src/main/java/org/schabi/newpipe/player/Player.java

Lines changed: 31 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,13 @@
11
package org.schabi.newpipe.player;
22

3-
import static com.google.android.exoplayer2.Player.DISCONTINUITY_REASON_AD_INSERTION;
3+
import static com.google.android.exoplayer2.Player.DISCONTINUITY_REASON_AUTO_TRANSITION;
44
import static com.google.android.exoplayer2.Player.DISCONTINUITY_REASON_INTERNAL;
5-
import static com.google.android.exoplayer2.Player.DISCONTINUITY_REASON_PERIOD_TRANSITION;
5+
import static com.google.android.exoplayer2.Player.DISCONTINUITY_REASON_REMOVE;
66
import static com.google.android.exoplayer2.Player.DISCONTINUITY_REASON_SEEK;
77
import static com.google.android.exoplayer2.Player.DISCONTINUITY_REASON_SEEK_ADJUSTMENT;
8+
import static com.google.android.exoplayer2.Player.DISCONTINUITY_REASON_SKIP;
89
import static com.google.android.exoplayer2.Player.DiscontinuityReason;
9-
import static com.google.android.exoplayer2.Player.EventListener;
10+
import static com.google.android.exoplayer2.Player.Listener;
1011
import static com.google.android.exoplayer2.Player.REPEAT_MODE_ALL;
1112
import static com.google.android.exoplayer2.Player.REPEAT_MODE_OFF;
1213
import static com.google.android.exoplayer2.Player.REPEAT_MODE_ONE;
@@ -116,20 +117,22 @@
116117
import com.google.android.exoplayer2.DefaultRenderersFactory;
117118
import com.google.android.exoplayer2.ExoPlaybackException;
118119
import com.google.android.exoplayer2.PlaybackParameters;
120+
import com.google.android.exoplayer2.Player.PositionInfo;
119121
import com.google.android.exoplayer2.RenderersFactory;
120122
import com.google.android.exoplayer2.SimpleExoPlayer;
121123
import com.google.android.exoplayer2.Timeline;
122124
import com.google.android.exoplayer2.source.BehindLiveWindowException;
123125
import com.google.android.exoplayer2.source.MediaSource;
124126
import com.google.android.exoplayer2.source.TrackGroup;
125127
import com.google.android.exoplayer2.source.TrackGroupArray;
126-
import com.google.android.exoplayer2.text.CaptionStyleCompat;
128+
import com.google.android.exoplayer2.text.Cue;
127129
import com.google.android.exoplayer2.trackselection.TrackSelectionArray;
128130
import com.google.android.exoplayer2.ui.AspectRatioFrameLayout;
131+
import com.google.android.exoplayer2.ui.CaptionStyleCompat;
129132
import com.google.android.exoplayer2.ui.SubtitleView;
130133
import com.google.android.exoplayer2.upstream.DefaultBandwidthMeter;
131134
import com.google.android.exoplayer2.util.Util;
132-
import com.google.android.exoplayer2.video.VideoListener;
135+
import com.google.android.exoplayer2.video.VideoSize;
133136
import com.google.android.material.floatingactionbutton.FloatingActionButton;
134137
import com.squareup.picasso.Picasso;
135138
import com.squareup.picasso.Target;
@@ -174,12 +177,12 @@
174177
import org.schabi.newpipe.player.resolver.VideoPlaybackResolver;
175178
import org.schabi.newpipe.player.seekbarpreview.SeekbarPreviewThumbnailHelper;
176179
import org.schabi.newpipe.player.seekbarpreview.SeekbarPreviewThumbnailHolder;
177-
import org.schabi.newpipe.util.StreamTypeUtil;
178180
import org.schabi.newpipe.util.DeviceUtils;
179181
import org.schabi.newpipe.util.ListHelper;
180182
import org.schabi.newpipe.util.NavigationHelper;
181183
import org.schabi.newpipe.util.PicassoHelper;
182184
import org.schabi.newpipe.util.SerializedCache;
185+
import org.schabi.newpipe.util.StreamTypeUtil;
183186
import org.schabi.newpipe.util.external_communication.KoreUtils;
184187
import org.schabi.newpipe.util.external_communication.ShareUtils;
185188
import org.schabi.newpipe.views.ExpandableSurfaceView;
@@ -197,9 +200,8 @@
197200
import io.reactivex.rxjava3.disposables.SerialDisposable;
198201

199202
public final class Player implements
200-
EventListener,
201203
PlaybackListener,
202-
VideoListener,
204+
Listener,
203205
SeekBar.OnSeekBarChangeListener,
204206
View.OnClickListener,
205207
PopupMenu.OnMenuItemClickListener,
@@ -501,10 +503,6 @@ private void initPlayer(final boolean playOnReady) {
501503

502504
// Setup video view
503505
setupVideoSurface();
504-
simpleExoPlayer.addVideoListener(this);
505-
506-
// Setup subtitle view
507-
simpleExoPlayer.addTextOutput(binding.subtitleView);
508506

509507
// enable media tunneling
510508
if (DEBUG && PreferenceManager.getDefaultSharedPreferences(context)
@@ -513,7 +511,7 @@ private void initPlayer(final boolean playOnReady) {
513511
+ "media tunneling disabled in debug preferences");
514512
} else if (DeviceUtils.shouldSupportMediaTunneling()) {
515513
trackSelector.setParameters(trackSelector.buildUponParameters()
516-
.setTunnelingAudioSessionId(C.generateAudioSessionIdV21(context)));
514+
.setTunnelingEnabled(true));
517515
} else if (DEBUG) {
518516
Log.d(TAG, "[" + Util.DEVICE_DEBUG_INFO + "] does not support media tunneling");
519517
}
@@ -809,7 +807,6 @@ private void destroyPlayer() {
809807

810808
if (!exoPlayerIsNull()) {
811809
simpleExoPlayer.removeListener(this);
812-
simpleExoPlayer.removeVideoListener(this);
813810
simpleExoPlayer.stop();
814811
simpleExoPlayer.release();
815812
}
@@ -898,7 +895,7 @@ public void onPlaybackShutdown() {
898895

899896
public void smoothStopPlayer() {
900897
// Pausing would make transition from one stream to a new stream not smooth, so only stop
901-
simpleExoPlayer.stop(false);
898+
simpleExoPlayer.stop();
902899
}
903900
//endregion
904901

@@ -2437,7 +2434,9 @@ public void onPlaybackParametersChanged(@NonNull final PlaybackParameters playba
24372434
}
24382435

24392436
@Override
2440-
public void onPositionDiscontinuity(@DiscontinuityReason final int discontinuityReason) {
2437+
public void onPositionDiscontinuity(
2438+
final PositionInfo oldPosition, final PositionInfo newPosition,
2439+
@DiscontinuityReason final int discontinuityReason) {
24412440
if (DEBUG) {
24422441
Log.d(TAG, "ExoPlayer - onPositionDiscontinuity() called with "
24432442
+ "discontinuityReason = [" + discontinuityReason + "]");
@@ -2449,7 +2448,7 @@ public void onPositionDiscontinuity(@DiscontinuityReason final int discontinuity
24492448
// Refresh the playback if there is a transition to the next video
24502449
final int newWindowIndex = simpleExoPlayer.getCurrentWindowIndex();
24512450
switch (discontinuityReason) {
2452-
case DISCONTINUITY_REASON_PERIOD_TRANSITION:
2451+
case DISCONTINUITY_REASON_REMOVE:
24532452
// When player is in single repeat mode and a period transition occurs,
24542453
// we need to register a view count here since no metadata has changed
24552454
if (getRepeatMode() == REPEAT_MODE_ONE && newWindowIndex == playQueue.getIndex()) {
@@ -2470,7 +2469,8 @@ public void onPositionDiscontinuity(@DiscontinuityReason final int discontinuity
24702469
playQueue.setIndex(newWindowIndex);
24712470
}
24722471
break;
2473-
case DISCONTINUITY_REASON_AD_INSERTION:
2472+
case DISCONTINUITY_REASON_SKIP:
2473+
case DISCONTINUITY_REASON_AUTO_TRANSITION:
24742474
break; // only makes Android Studio linter happy, as there are no ads
24752475
}
24762476

@@ -2482,6 +2482,11 @@ public void onRenderedFirstFrame() {
24822482
//TODO check if this causes black screen when switching to fullscreen
24832483
animate(binding.surfaceForeground, false, DEFAULT_CONTROLS_DURATION);
24842484
}
2485+
2486+
@Override
2487+
public void onCues(final List<Cue> cues) {
2488+
binding.subtitleView.onCues(cues);
2489+
}
24852490
//endregion
24862491

24872492

@@ -2503,7 +2508,7 @@ public void onRenderedFirstFrame() {
25032508
* </ul>
25042509
*
25052510
* @see #processSourceError(IOException)
2506-
* @see com.google.android.exoplayer2.Player.EventListener#onPlayerError(ExoPlaybackException)
2511+
* @see com.google.android.exoplayer2.Player.Listener#onPlayerError(ExoPlaybackException)
25072512
*/
25082513
@Override
25092514
public void onPlayerError(@NonNull final ExoPlaybackException error) {
@@ -3867,19 +3872,17 @@ void onResizeClicked() {
38673872
}
38683873

38693874
@Override // exoplayer listener
3870-
public void onVideoSizeChanged(final int width, final int height,
3871-
final int unappliedRotationDegrees,
3872-
final float pixelWidthHeightRatio) {
3875+
public void onVideoSizeChanged(final VideoSize videoSize) {
38733876
if (DEBUG) {
38743877
Log.d(TAG, "onVideoSizeChanged() called with: "
3875-
+ "width / height = [" + width + " / " + height
3876-
+ " = " + (((float) width) / height) + "], "
3877-
+ "unappliedRotationDegrees = [" + unappliedRotationDegrees + "], "
3878-
+ "pixelWidthHeightRatio = [" + pixelWidthHeightRatio + "]");
3878+
+ "width / height = [" + videoSize.width + " / " + videoSize.height
3879+
+ " = " + (((float) videoSize.width) / videoSize.height) + "], "
3880+
+ "unappliedRotationDegrees = [" + videoSize.unappliedRotationDegrees + "], "
3881+
+ "pixelWidthHeightRatio = [" + videoSize.pixelWidthHeightRatio + "]");
38793882
}
38803883

3881-
binding.surfaceView.setAspectRatio(((float) width) / height);
3882-
isVerticalVideo = width < height;
3884+
binding.surfaceView.setAspectRatio(((float) videoSize.width) / videoSize.height);
3885+
isVerticalVideo = videoSize.width < videoSize.height;
38833886

38843887
if (globalScreenOrientationLocked(context)
38853888
&& isFullscreen

app/src/main/java/org/schabi/newpipe/player/helper/AudioReactor.java

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@
1616

1717
import com.google.android.exoplayer2.SimpleExoPlayer;
1818
import com.google.android.exoplayer2.analytics.AnalyticsListener;
19-
import com.google.android.exoplayer2.decoder.DecoderCounters;
2019

2120
public class AudioReactor implements AudioManager.OnAudioFocusChangeListener, AnalyticsListener {
2221

@@ -150,15 +149,9 @@ public void onAnimationEnd(final Animator animation) {
150149
//////////////////////////////////////////////////////////////////////////*/
151150

152151
@Override
153-
public void onAudioSessionId(final EventTime eventTime, final int audioSessionId) {
152+
public void onAudioSessionIdChanged(final EventTime eventTime, final int audioSessionId) {
154153
notifyAudioSessionUpdate(true, audioSessionId);
155154
}
156-
157-
@Override
158-
public void onAudioDisabled(final EventTime eventTime, final DecoderCounters counters) {
159-
notifyAudioSessionUpdate(false, player.getAudioSessionId());
160-
}
161-
162155
private void notifyAudioSessionUpdate(final boolean active, final int audioSessionId) {
163156
if (!PlayerHelper.isUsingDSP()) {
164157
return;

app/src/main/java/org/schabi/newpipe/player/helper/LoadController.java

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
import com.google.android.exoplayer2.LoadControl;
55
import com.google.android.exoplayer2.Renderer;
66
import com.google.android.exoplayer2.source.TrackGroupArray;
7-
import com.google.android.exoplayer2.trackselection.TrackSelectionArray;
7+
import com.google.android.exoplayer2.trackselection.ExoTrackSelection;
88
import com.google.android.exoplayer2.upstream.Allocator;
99

1010
public class LoadController implements LoadControl {
@@ -47,7 +47,7 @@ public void onPrepared() {
4747

4848
@Override
4949
public void onTracksSelected(final Renderer[] renderers, final TrackGroupArray trackGroups,
50-
final TrackSelectionArray trackSelections) {
50+
final ExoTrackSelection[] trackSelections) {
5151
internalLoadControl.onTracksSelected(renderers, trackGroups, trackSelections);
5252
}
5353

@@ -91,11 +91,12 @@ public boolean shouldContinueLoading(final long playbackPositionUs,
9191

9292
@Override
9393
public boolean shouldStartPlayback(final long bufferedDurationUs, final float playbackSpeed,
94-
final boolean rebuffering) {
94+
final boolean rebuffering, final long targetLiveOffsetUs) {
9595
final boolean isInitialPlaybackBufferFilled
9696
= bufferedDurationUs >= this.initialPlaybackBufferUs * playbackSpeed;
9797
final boolean isInternalStartingPlayback = internalLoadControl
98-
.shouldStartPlayback(bufferedDurationUs, playbackSpeed, rebuffering);
98+
.shouldStartPlayback(bufferedDurationUs, playbackSpeed, rebuffering,
99+
targetLiveOffsetUs);
99100
return isInitialPlaybackBufferFilled || isInternalStartingPlayback;
100101
}
101102

app/src/main/java/org/schabi/newpipe/player/helper/PlayerDataSource.java

Lines changed: 60 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,18 @@
11
package org.schabi.newpipe.player.helper;
22

33
import android.content.Context;
4+
import android.os.Build;
45

56
import androidx.annotation.NonNull;
67

8+
import com.google.android.exoplayer2.source.MediaParserExtractorAdapter;
79
import com.google.android.exoplayer2.source.ProgressiveMediaSource;
810
import com.google.android.exoplayer2.source.SingleSampleMediaSource;
11+
import com.google.android.exoplayer2.source.chunk.MediaParserChunkExtractor;
912
import com.google.android.exoplayer2.source.dash.DashMediaSource;
1013
import com.google.android.exoplayer2.source.dash.DefaultDashChunkSource;
1114
import com.google.android.exoplayer2.source.hls.HlsMediaSource;
15+
import com.google.android.exoplayer2.source.hls.MediaParserHlsMediaChunkExtractor;
1216
import com.google.android.exoplayer2.source.smoothstreaming.DefaultSsChunkSource;
1317
import com.google.android.exoplayer2.source.smoothstreaming.SsMediaSource;
1418
import com.google.android.exoplayer2.upstream.DataSource;
@@ -19,7 +23,7 @@
1923
public class PlayerDataSource {
2024
private static final int MANIFEST_MINIMUM_RETRY = 5;
2125
private static final int EXTRACTOR_MINIMUM_RETRY = Integer.MAX_VALUE;
22-
private static final int LIVE_STREAM_EDGE_GAP_MILLIS = 10000;
26+
public static final int LIVE_STREAM_EDGE_GAP_MILLIS = 10000;
2327

2428
private final DataSource.Factory cacheDataSourceFactory;
2529
private final DataSource.Factory cachelessDataSourceFactory;
@@ -32,51 +36,83 @@ public PlayerDataSource(@NonNull final Context context, @NonNull final String us
3236
}
3337

3438
public SsMediaSource.Factory getLiveSsMediaSourceFactory() {
35-
return new SsMediaSource.Factory(new DefaultSsChunkSource.Factory(
36-
cachelessDataSourceFactory), cachelessDataSourceFactory)
39+
return new SsMediaSource.Factory(
40+
new DefaultSsChunkSource.Factory(cachelessDataSourceFactory),
41+
cachelessDataSourceFactory
42+
)
3743
.setLoadErrorHandlingPolicy(
3844
new DefaultLoadErrorHandlingPolicy(MANIFEST_MINIMUM_RETRY))
3945
.setLivePresentationDelayMs(LIVE_STREAM_EDGE_GAP_MILLIS);
4046
}
4147

4248
public HlsMediaSource.Factory getLiveHlsMediaSourceFactory() {
43-
return new HlsMediaSource.Factory(cachelessDataSourceFactory)
44-
.setAllowChunklessPreparation(true)
45-
.setLoadErrorHandlingPolicy(
46-
new DefaultLoadErrorHandlingPolicy(MANIFEST_MINIMUM_RETRY));
49+
final HlsMediaSource.Factory factory =
50+
new HlsMediaSource.Factory(cachelessDataSourceFactory)
51+
.setAllowChunklessPreparation(true)
52+
.setLoadErrorHandlingPolicy(
53+
new DefaultLoadErrorHandlingPolicy(MANIFEST_MINIMUM_RETRY));
54+
55+
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
56+
factory.setExtractorFactory(MediaParserHlsMediaChunkExtractor.FACTORY);
57+
}
58+
59+
return factory;
4760
}
4861

4962
public DashMediaSource.Factory getLiveDashMediaSourceFactory() {
50-
return new DashMediaSource.Factory(new DefaultDashChunkSource.Factory(
51-
cachelessDataSourceFactory), cachelessDataSourceFactory)
63+
return new DashMediaSource.Factory(
64+
getDefaultDashChunkSourceFactory(cachelessDataSourceFactory),
65+
cachelessDataSourceFactory
66+
)
5267
.setLoadErrorHandlingPolicy(
53-
new DefaultLoadErrorHandlingPolicy(MANIFEST_MINIMUM_RETRY))
54-
.setLivePresentationDelayMs(LIVE_STREAM_EDGE_GAP_MILLIS, true);
68+
new DefaultLoadErrorHandlingPolicy(MANIFEST_MINIMUM_RETRY));
5569
}
5670

57-
public SsMediaSource.Factory getSsMediaSourceFactory() {
58-
return new SsMediaSource.Factory(new DefaultSsChunkSource.Factory(
59-
cacheDataSourceFactory), cacheDataSourceFactory);
71+
private DefaultDashChunkSource.Factory getDefaultDashChunkSourceFactory(
72+
final DataSource.Factory dataSourceFactory
73+
) {
74+
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
75+
return new DefaultDashChunkSource.Factory(
76+
MediaParserChunkExtractor.FACTORY,
77+
dataSourceFactory,
78+
1
79+
);
80+
}
81+
82+
return new DefaultDashChunkSource.Factory(dataSourceFactory);
6083
}
6184

6285
public HlsMediaSource.Factory getHlsMediaSourceFactory() {
63-
return new HlsMediaSource.Factory(cacheDataSourceFactory);
86+
final HlsMediaSource.Factory factory = new HlsMediaSource.Factory(cacheDataSourceFactory);
87+
88+
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.R) {
89+
return factory;
90+
}
91+
92+
// *** >= Android 11 / R / API 30 ***
93+
return factory.setExtractorFactory(MediaParserHlsMediaChunkExtractor.FACTORY);
6494
}
6595

6696
public DashMediaSource.Factory getDashMediaSourceFactory() {
67-
return new DashMediaSource.Factory(new DefaultDashChunkSource.Factory(
68-
cacheDataSourceFactory), cacheDataSourceFactory);
97+
return new DashMediaSource.Factory(
98+
getDefaultDashChunkSourceFactory(cacheDataSourceFactory),
99+
cacheDataSourceFactory
100+
);
69101
}
70102

71103
public ProgressiveMediaSource.Factory getExtractorMediaSourceFactory() {
72-
return new ProgressiveMediaSource.Factory(cacheDataSourceFactory)
73-
.setLoadErrorHandlingPolicy(
74-
new DefaultLoadErrorHandlingPolicy(EXTRACTOR_MINIMUM_RETRY));
75-
}
104+
final ProgressiveMediaSource.Factory factory;
105+
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
106+
factory = new ProgressiveMediaSource.Factory(
107+
cacheDataSourceFactory,
108+
MediaParserExtractorAdapter.FACTORY
109+
);
110+
} else {
111+
factory = new ProgressiveMediaSource.Factory(cacheDataSourceFactory);
112+
}
76113

77-
public ProgressiveMediaSource.Factory getExtractorMediaSourceFactory(
78-
@NonNull final String key) {
79-
return getExtractorMediaSourceFactory().setCustomCacheKey(key);
114+
return factory.setLoadErrorHandlingPolicy(
115+
new DefaultLoadErrorHandlingPolicy(EXTRACTOR_MINIMUM_RETRY));
80116
}
81117

82118
public SingleSampleMediaSource.Factory getSampleMediaSourceFactory() {

0 commit comments

Comments
 (0)