diff --git a/app/build.gradle b/app/build.gradle index 8e414379c60..ceb8179922a 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -105,7 +105,7 @@ ext { androidxRoomVersion = '2.3.0' icepickVersion = '3.2.0' - exoPlayerVersion = '2.12.3' + exoPlayerVersion = '2.11.8' googleAutoServiceVersion = '1.0-rc7' groupieVersion = '2.8.1' markwonVersion = '4.6.0' diff --git a/app/src/main/java/org/schabi/newpipe/player/Player.java b/app/src/main/java/org/schabi/newpipe/player/Player.java index 0a0ad619fa4..f0ed2aa4c9f 100644 --- a/app/src/main/java/org/schabi/newpipe/player/Player.java +++ b/app/src/main/java/org/schabi/newpipe/player/Player.java @@ -615,8 +615,7 @@ public void handleIntent(@NonNull final Intent intent) { final PlaybackParameters savedParameters = retrievePlaybackParametersFromPrefs(this); final float playbackSpeed = savedParameters.speed; final float playbackPitch = savedParameters.pitch; - final boolean playbackSkipSilence = getPrefs().getBoolean(getContext().getString( - R.string.playback_skip_silence_key), getPlaybackSkipSilence()); + final boolean playbackSkipSilence = savedParameters.skipSilence; final boolean samePlayQueue = playQueue != null && playQueue.equals(newQueue); final int repeatMode = intent.getIntExtra(REPEAT_MODE, getRepeatMode()); @@ -641,7 +640,7 @@ public void handleIntent(@NonNull final Intent intent) { // and we should retry in this case if (simpleExoPlayer.getPlaybackState() == com.google.android.exoplayer2.Player.STATE_IDLE) { - simpleExoPlayer.prepare(); + simpleExoPlayer.retry(); } simpleExoPlayer.seekTo(playQueue.getIndex(), newQueue.getItem().getRecoveryPosition()); simpleExoPlayer.setPlayWhenReady(playWhenReady); @@ -655,7 +654,7 @@ public void handleIntent(@NonNull final Intent intent) { // and we should retry in this case if (simpleExoPlayer.getPlaybackState() == com.google.android.exoplayer2.Player.STATE_IDLE) { - simpleExoPlayer.prepare(); + simpleExoPlayer.retry(); } simpleExoPlayer.setPlayWhenReady(playWhenReady); @@ -1536,8 +1535,7 @@ public float getPlaybackPitch() { } public boolean getPlaybackSkipSilence() { - return !exoPlayerIsNull() && simpleExoPlayer.getAudioComponent() != null - && simpleExoPlayer.getAudioComponent().getSkipSilenceEnabled(); + return getPlaybackParameters().skipSilence; } public PlaybackParameters getPlaybackParameters() { @@ -1562,10 +1560,7 @@ public void setPlaybackParameters(final float speed, final float pitch, savePlaybackParametersToPrefs(this, roundedSpeed, roundedPitch, skipSilence); simpleExoPlayer.setPlaybackParameters( - new PlaybackParameters(roundedSpeed, roundedPitch)); - if (simpleExoPlayer.getAudioComponent() != null) { - simpleExoPlayer.getAudioComponent().setSkipSilenceEnabled(skipSilence); - } + new PlaybackParameters(roundedSpeed, roundedPitch, skipSilence)); } //endregion @@ -1689,7 +1684,7 @@ public void onStartTrackingTouch(final SeekBar seekBar) { saveWasPlaying(); if (isPlaying()) { - simpleExoPlayer.pause(); + simpleExoPlayer.setPlayWhenReady(false); } showControls(0); @@ -1705,7 +1700,7 @@ public void onStopTrackingTouch(final SeekBar seekBar) { seekTo(seekBar.getProgress()); if (wasPlaying || simpleExoPlayer.getDuration() == seekBar.getProgress()) { - simpleExoPlayer.play(); + simpleExoPlayer.setPlayWhenReady(true); } binding.playbackCurrentTime.setText(getTimeString(seekBar.getProgress())); @@ -1946,7 +1941,7 @@ public void onPlayerStateChanged(final boolean playWhenReady, final int playback } @Override // exoplayer listener - public void onIsLoadingChanged(final boolean isLoading) { + public void onLoadingChanged(final boolean isLoading) { if (DEBUG) { Log.d(TAG, "ExoPlayer - onLoadingChanged() called with: " + "isLoading = [" + isLoading + "]"); @@ -1990,8 +1985,7 @@ public void onPlaybackUnblock(final MediaSource mediaSource) { if (currentState == STATE_BLOCKED) { changeState(STATE_BUFFERING); } - simpleExoPlayer.setMediaSource(mediaSource); - simpleExoPlayer.prepare(); + simpleExoPlayer.prepare(mediaSource); } public void changeState(final int state) { @@ -2694,7 +2688,7 @@ public void play() { } } - simpleExoPlayer.play(); + simpleExoPlayer.setPlayWhenReady(true); saveStreamProgressState(); } @@ -2707,7 +2701,7 @@ public void pause() { } audioReactor.abandonAudioFocus(); - simpleExoPlayer.pause(); + simpleExoPlayer.setPlayWhenReady(false); saveStreamProgressState(); } diff --git a/app/src/main/java/org/schabi/newpipe/player/helper/AudioReactor.java b/app/src/main/java/org/schabi/newpipe/player/helper/AudioReactor.java index 45b59332840..13ee24e16cf 100644 --- a/app/src/main/java/org/schabi/newpipe/player/helper/AudioReactor.java +++ b/app/src/main/java/org/schabi/newpipe/player/helper/AudioReactor.java @@ -103,13 +103,13 @@ private void onAudioFocusGain() { animateAudio(DUCK_AUDIO_TO, 1.0f); if (PlayerHelper.isResumeAfterAudioFocusGain(context)) { - player.play(); + player.setPlayWhenReady(true); } } private void onAudioFocusLoss() { Log.d(TAG, "onAudioFocusLoss() called"); - player.pause(); + player.setPlayWhenReady(false); } private void onAudioFocusLossCanDuck() { diff --git a/app/src/main/java/org/schabi/newpipe/player/helper/LoadController.java b/app/src/main/java/org/schabi/newpipe/player/helper/LoadController.java index e4ae2775090..5c4d1551d21 100644 --- a/app/src/main/java/org/schabi/newpipe/player/helper/LoadController.java +++ b/app/src/main/java/org/schabi/newpipe/player/helper/LoadController.java @@ -20,21 +20,19 @@ public class LoadController implements LoadControl { //////////////////////////////////////////////////////////////////////////*/ public LoadController() { - this(PlayerHelper.getPlaybackStartBufferMs(), - PlayerHelper.getPlaybackMinimumBufferMs(), - PlayerHelper.getPlaybackOptimalBufferMs()); + this(PlayerHelper.getPlaybackStartBufferMs()); } - private LoadController(final int initialPlaybackBufferMs, - final int minimumPlaybackBufferMs, - final int optimalPlaybackBufferMs) { + private LoadController(final int initialPlaybackBufferMs) { this.initialPlaybackBufferUs = initialPlaybackBufferMs * 1000; final DefaultLoadControl.Builder builder = new DefaultLoadControl.Builder(); - builder.setBufferDurationsMs(minimumPlaybackBufferMs, optimalPlaybackBufferMs, + builder.setBufferDurationsMs( + DefaultLoadControl.DEFAULT_MIN_BUFFER_MS, + DefaultLoadControl.DEFAULT_MAX_BUFFER_MS, initialPlaybackBufferMs, DefaultLoadControl.DEFAULT_BUFFER_FOR_PLAYBACK_AFTER_REBUFFER_MS); - internalLoadControl = builder.build(); + internalLoadControl = builder.createDefaultLoadControl(); } /*////////////////////////////////////////////////////////////////////////// @@ -81,14 +79,13 @@ public boolean retainBackBufferFromKeyframe() { } @Override - public boolean shouldContinueLoading(final long playbackPositionUs, - final long bufferedDurationUs, + public boolean shouldContinueLoading(final long bufferedDurationUs, final float playbackSpeed) { if (!preloadingEnabled) { return false; } return internalLoadControl.shouldContinueLoading( - playbackPositionUs, bufferedDurationUs, playbackSpeed); + bufferedDurationUs, playbackSpeed); } @Override diff --git a/app/src/main/java/org/schabi/newpipe/player/helper/PlayerHelper.java b/app/src/main/java/org/schabi/newpipe/player/helper/PlayerHelper.java index d60a14381e1..6d1eacaeffb 100644 --- a/app/src/main/java/org/schabi/newpipe/player/helper/PlayerHelper.java +++ b/app/src/main/java/org/schabi/newpipe/player/helper/PlayerHelper.java @@ -307,22 +307,6 @@ public static int getPlaybackStartBufferMs() { return 500; } - /** - * @return the minimum number of milliseconds the player always buffers to - * after starting playback. - */ - public static int getPlaybackMinimumBufferMs() { - return 25000; - } - - /** - * @return the maximum/optimal number of milliseconds the player will buffer to once the buffer - * hits the point of {@link #getPlaybackMinimumBufferMs()}. - */ - public static int getPlaybackOptimalBufferMs() { - return 60000; - } - public static TrackSelection.Factory getQualitySelector() { return new AdaptiveTrackSelection.Factory( 1000, @@ -495,7 +479,9 @@ public static PlaybackParameters retrievePlaybackParametersFromPrefs(final Playe R.string.playback_speed_key), player.getPlaybackSpeed()); final float pitch = player.getPrefs().getFloat(player.getContext().getString( R.string.playback_pitch_key), player.getPlaybackPitch()); - return new PlaybackParameters(speed, pitch); + final boolean skipSilence = player.getPrefs().getBoolean(player.getContext().getString( + R.string.playback_skip_silence_key), player.getPlaybackSkipSilence()); + return new PlaybackParameters(speed, pitch, skipSilence); } public static void savePlaybackParametersToPrefs(final Player player, diff --git a/app/src/main/java/org/schabi/newpipe/player/mediasource/FailedMediaSource.java b/app/src/main/java/org/schabi/newpipe/player/mediasource/FailedMediaSource.java index 7594f3a1600..c09a44c08e5 100644 --- a/app/src/main/java/org/schabi/newpipe/player/mediasource/FailedMediaSource.java +++ b/app/src/main/java/org/schabi/newpipe/player/mediasource/FailedMediaSource.java @@ -5,7 +5,6 @@ import androidx.annotation.NonNull; import androidx.annotation.Nullable; -import com.google.android.exoplayer2.MediaItem; import com.google.android.exoplayer2.source.BaseMediaSource; import com.google.android.exoplayer2.source.MediaPeriod; import com.google.android.exoplayer2.upstream.Allocator; @@ -55,14 +54,6 @@ private boolean canRetry() { return System.currentTimeMillis() >= retryTimestamp; } - /** - * Returns the {@link MediaItem} whose media is provided by the source. - */ - @Override - public MediaItem getMediaItem() { - return MediaItem.fromUri(playQueueItem.getUrl()); - } - @Override public void maybeThrowSourceInfoRefreshError() throws IOException { throw new IOException(error); diff --git a/app/src/main/java/org/schabi/newpipe/player/mediasource/LoadedMediaSource.java b/app/src/main/java/org/schabi/newpipe/player/mediasource/LoadedMediaSource.java index 746a9758156..cdbf8609b2b 100644 --- a/app/src/main/java/org/schabi/newpipe/player/mediasource/LoadedMediaSource.java +++ b/app/src/main/java/org/schabi/newpipe/player/mediasource/LoadedMediaSource.java @@ -5,8 +5,6 @@ import androidx.annotation.NonNull; import androidx.annotation.Nullable; -import com.google.android.exoplayer2.MediaItem; -import com.google.android.exoplayer2.drm.DrmSessionEventListener; import com.google.android.exoplayer2.source.MediaPeriod; import com.google.android.exoplayer2.source.MediaSource; import com.google.android.exoplayer2.source.MediaSourceEventListener; @@ -85,38 +83,6 @@ public void removeEventListener(final MediaSourceEventListener eventListener) { source.removeEventListener(eventListener); } - /** - * Adds a {@link DrmSessionEventListener} to the list of listeners which are notified of DRM - * events for this media source. - * - * @param handler A handler on the which listener events will be posted. - * @param eventListener The listener to be added. - */ - @Override - public void addDrmEventListener(final Handler handler, - final DrmSessionEventListener eventListener) { - source.addDrmEventListener(handler, eventListener); - } - - /** - * Removes a {@link DrmSessionEventListener} from the list of listeners which are notified of - * DRM events for this media source. - * - * @param eventListener The listener to be removed. - */ - @Override - public void removeDrmEventListener(final DrmSessionEventListener eventListener) { - source.removeDrmEventListener(eventListener); - } - - /** - * Returns the {@link MediaItem} whose media is provided by the source. - */ - @Override - public MediaItem getMediaItem() { - return source.getMediaItem(); - } - @Override public boolean shouldBeReplacedWith(@NonNull final PlayQueueItem newIdentity, final boolean isInterruptable) { diff --git a/app/src/main/java/org/schabi/newpipe/player/mediasource/PlaceholderMediaSource.java b/app/src/main/java/org/schabi/newpipe/player/mediasource/PlaceholderMediaSource.java index 1cd8556270b..f73a219d7e4 100644 --- a/app/src/main/java/org/schabi/newpipe/player/mediasource/PlaceholderMediaSource.java +++ b/app/src/main/java/org/schabi/newpipe/player/mediasource/PlaceholderMediaSource.java @@ -3,7 +3,6 @@ import androidx.annotation.NonNull; import androidx.annotation.Nullable; -import com.google.android.exoplayer2.MediaItem; import com.google.android.exoplayer2.source.BaseMediaSource; import com.google.android.exoplayer2.source.MediaPeriod; import com.google.android.exoplayer2.upstream.Allocator; @@ -12,14 +11,6 @@ import org.schabi.newpipe.player.playqueue.PlayQueueItem; public class PlaceholderMediaSource extends BaseMediaSource implements ManagedMediaSource { - /** - * Returns the {@link MediaItem} whose media is provided by the source. - */ - @Override - public MediaItem getMediaItem() { - return null; - } - // Do nothing, so this will stall the playback @Override public void maybeThrowSourceInfoRefreshError() { } diff --git a/app/src/main/java/org/schabi/newpipe/player/resolver/PlaybackResolver.java b/app/src/main/java/org/schabi/newpipe/player/resolver/PlaybackResolver.java index a6dcadd5eeb..e06c0ff82f6 100644 --- a/app/src/main/java/org/schabi/newpipe/player/resolver/PlaybackResolver.java +++ b/app/src/main/java/org/schabi/newpipe/player/resolver/PlaybackResolver.java @@ -7,7 +7,6 @@ import androidx.annotation.Nullable; import com.google.android.exoplayer2.C; -import com.google.android.exoplayer2.MediaItem; import com.google.android.exoplayer2.source.MediaSource; import com.google.android.exoplayer2.util.Util; @@ -44,13 +43,13 @@ default MediaSource buildLiveMediaSource(@NonNull final PlayerDataSource dataSou switch (type) { case C.TYPE_SS: return dataSource.getLiveSsMediaSourceFactory().setTag(metadata) - .createMediaSource(MediaItem.fromUri(uri)); + .createMediaSource(uri); case C.TYPE_DASH: return dataSource.getLiveDashMediaSourceFactory().setTag(metadata) - .createMediaSource(MediaItem.fromUri(uri)); + .createMediaSource(uri); case C.TYPE_HLS: return dataSource.getLiveHlsMediaSourceFactory().setTag(metadata) - .createMediaSource(MediaItem.fromUri(uri)); + .createMediaSource(uri); default: throw new IllegalStateException("Unsupported type: " + type); } @@ -69,16 +68,16 @@ default MediaSource buildMediaSource(@NonNull final PlayerDataSource dataSource, switch (type) { case C.TYPE_SS: return dataSource.getLiveSsMediaSourceFactory().setTag(metadata) - .createMediaSource(MediaItem.fromUri(uri)); + .createMediaSource(uri); case C.TYPE_DASH: return dataSource.getDashMediaSourceFactory().setTag(metadata) - .createMediaSource(MediaItem.fromUri(uri)); + .createMediaSource(uri); case C.TYPE_HLS: return dataSource.getHlsMediaSourceFactory().setTag(metadata) - .createMediaSource(MediaItem.fromUri(uri)); + .createMediaSource(uri); case C.TYPE_OTHER: return dataSource.getExtractorMediaSourceFactory(cacheKey).setTag(metadata) - .createMediaSource(MediaItem.fromUri(uri)); + .createMediaSource(uri); default: throw new IllegalStateException("Unsupported type: " + type); } diff --git a/app/src/main/java/org/schabi/newpipe/player/resolver/VideoPlaybackResolver.java b/app/src/main/java/org/schabi/newpipe/player/resolver/VideoPlaybackResolver.java index 245a85e7101..257ce6a4e74 100644 --- a/app/src/main/java/org/schabi/newpipe/player/resolver/VideoPlaybackResolver.java +++ b/app/src/main/java/org/schabi/newpipe/player/resolver/VideoPlaybackResolver.java @@ -6,7 +6,7 @@ import androidx.annotation.NonNull; import androidx.annotation.Nullable; -import com.google.android.exoplayer2.MediaItem; +import com.google.android.exoplayer2.Format; import com.google.android.exoplayer2.source.MediaSource; import com.google.android.exoplayer2.source.MergingMediaSource; @@ -22,6 +22,7 @@ import java.util.ArrayList; import java.util.List; +import static com.google.android.exoplayer2.C.SELECTION_FLAG_AUTOSELECT; import static com.google.android.exoplayer2.C.TIME_UNSET; public class VideoPlaybackResolver implements PlaybackResolver { @@ -100,12 +101,11 @@ public MediaSource resolve(@NonNull final StreamInfo info) { if (mimeType == null) { continue; } + final Format textFormat = Format.createTextSampleFormat(null, mimeType, + SELECTION_FLAG_AUTOSELECT, + PlayerHelper.captionLanguageOf(context, subtitle)); final MediaSource textSource = dataSource.getSampleMediaSourceFactory() - .createMediaSource( - new MediaItem.Subtitle(Uri.parse(subtitle.getUrl()), - mimeType, - PlayerHelper.captionLanguageOf(context, subtitle)), - TIME_UNSET); + .createMediaSource(Uri.parse(subtitle.getUrl()), textFormat, TIME_UNSET); mediaSources.add(textSource); } }