diff --git a/app/src/main/java/org/schabi/newpipe/fragments/detail/VideoDetailFragment.java b/app/src/main/java/org/schabi/newpipe/fragments/detail/VideoDetailFragment.java index abb995ecd..d32b694d7 100644 --- a/app/src/main/java/org/schabi/newpipe/fragments/detail/VideoDetailFragment.java +++ b/app/src/main/java/org/schabi/newpipe/fragments/detail/VideoDetailFragment.java @@ -2423,23 +2423,20 @@ public final class VideoDetailFragment // helpers to check the state of player and playerService boolean isPlayerAvailable() { - return (player != null); + return player != null; } boolean isPlayerServiceAvailable() { - return (playerService != null); + return playerService != null; } boolean isPlayerAndPlayerServiceAvailable() { - return (player != null && playerService != null); + return player != null && playerService != null; } public Optional getRoot() { - if (player == null) { - return Optional.empty(); - } - - return player.UIs().get(VideoPlayerUi.class) + return Optional.ofNullable(player) + .flatMap(player1 -> player1.UIs().get(VideoPlayerUi.class)) .map(playerUi -> playerUi.getBinding().getRoot()); } 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 da337b394..cc95d6be3 100644 --- a/app/src/main/java/org/schabi/newpipe/player/Player.java +++ b/app/src/main/java/org/schabi/newpipe/player/Player.java @@ -1877,21 +1877,16 @@ public final class Player implements PlaybackListener, Listener { @Nullable public VideoStream getSelectedVideoStream() { - @Nullable final MediaItemTag.Quality quality = Optional.ofNullable(currentMetadata) + return Optional.ofNullable(currentMetadata) .flatMap(MediaItemTag::getMaybeQuality) + .filter(quality -> { + final int selectedStreamIndex = quality.getSelectedVideoStreamIndex(); + return selectedStreamIndex >= 0 + && selectedStreamIndex < quality.getSortedVideoStreams().size(); + }) + .map(quality -> quality.getSortedVideoStreams() + .get(quality.getSelectedVideoStreamIndex())) .orElse(null); - if (quality == null) { - return null; - } - - final List availableStreams = quality.getSortedVideoStreams(); - final int selectedStreamIndex = quality.getSelectedVideoStreamIndex(); - - if (selectedStreamIndex >= 0 && availableStreams.size() > selectedStreamIndex) { - return availableStreams.get(selectedStreamIndex); - } else { - return null; - } } //endregion diff --git a/app/src/main/java/org/schabi/newpipe/player/mediaitem/MediaItemTag.java b/app/src/main/java/org/schabi/newpipe/player/mediaitem/MediaItemTag.java index d23dd4574..f08086287 100644 --- a/app/src/main/java/org/schabi/newpipe/player/mediaitem/MediaItemTag.java +++ b/app/src/main/java/org/schabi/newpipe/player/mediaitem/MediaItemTag.java @@ -61,12 +61,11 @@ public interface MediaItemTag { @NonNull static Optional from(@Nullable final MediaItem mediaItem) { - if (mediaItem == null || mediaItem.localConfiguration == null - || !(mediaItem.localConfiguration.tag instanceof MediaItemTag)) { - return Optional.empty(); - } - - return Optional.of((MediaItemTag) mediaItem.localConfiguration.tag); + return Optional.ofNullable(mediaItem) + .map(item -> item.localConfiguration) + .map(localConfiguration -> localConfiguration.tag) + .filter(MediaItemTag.class::isInstance) + .map(MediaItemTag.class::cast); } @NonNull diff --git a/app/src/main/java/org/schabi/newpipe/player/playback/MediaSourceManager.java b/app/src/main/java/org/schabi/newpipe/player/playback/MediaSourceManager.java index f58aa6e91..6d9fb8a1c 100644 --- a/app/src/main/java/org/schabi/newpipe/player/playback/MediaSourceManager.java +++ b/app/src/main/java/org/schabi/newpipe/player/playback/MediaSourceManager.java @@ -7,8 +7,6 @@ import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.collection.ArraySet; -import com.google.android.exoplayer2.source.MediaSource; - import org.reactivestreams.Subscriber; import org.reactivestreams.Subscription; import org.schabi.newpipe.extractor.exceptions.ExtractionException; @@ -27,6 +25,7 @@ import org.schabi.newpipe.util.ServiceHelper; import java.util.Collection; import java.util.Collections; +import java.util.Optional; import java.util.Set; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicBoolean; @@ -422,21 +421,24 @@ public class MediaSourceManager { private Single getLoadedMediaSource(@NonNull final PlayQueueItem stream) { return stream.getStream().map(streamInfo -> { - final MediaSource source = playbackListener.sourceOf(stream, streamInfo); - if (source == null || MediaItemTag.from(source.getMediaItem()).isEmpty()) { - final String message = "Unable to resolve source from stream info. " - + "URL: " + stream.getUrl() + ", " - + "audio count: " + streamInfo.getAudioStreams().size() + ", " - + "video count: " + streamInfo.getVideoOnlyStreams().size() + ", " - + streamInfo.getVideoStreams().size(); - return (ManagedMediaSource) - FailedMediaSource.of(stream, new MediaSourceResolutionException(message)); - } + final var source = playbackListener.sourceOf(stream, streamInfo); - final MediaItemTag tag = MediaItemTag.from(source.getMediaItem()).get(); - final long expiration = System.currentTimeMillis() - + ServiceHelper.getCacheExpirationMillis(streamInfo.getServiceId()); - return new LoadedMediaSource(source, tag, stream, expiration); + return Optional.ofNullable(source) + .flatMap(source1 -> MediaItemTag.from(source1.getMediaItem())) + .map(tag -> { + final long expiration = System.currentTimeMillis() + + ServiceHelper.getCacheExpirationMillis(streamInfo.getServiceId()); + return new LoadedMediaSource(source, tag, stream, expiration); + }) + .orElseGet(() -> { + final String message = "Unable to resolve source from stream info. " + + "URL: " + stream.getUrl() + ", " + + "audio count: " + streamInfo.getAudioStreams().size() + ", " + + "video count: " + streamInfo.getVideoOnlyStreams().size() + ", " + + streamInfo.getVideoStreams().size(); + return FailedMediaSource.of(stream, new MediaSourceResolutionException( + message)); + }); }).onErrorReturn(throwable -> { if (throwable instanceof ExtractionException) { return FailedMediaSource.of(stream, new StreamInfoLoadException(throwable)); diff --git a/app/src/main/java/org/schabi/newpipe/player/seekbarpreview/SeekbarPreviewThumbnailHelper.java b/app/src/main/java/org/schabi/newpipe/player/seekbarpreview/SeekbarPreviewThumbnailHelper.java index b7441c272..28856d606 100644 --- a/app/src/main/java/org/schabi/newpipe/player/seekbarpreview/SeekbarPreviewThumbnailHelper.java +++ b/app/src/main/java/org/schabi/newpipe/player/seekbarpreview/SeekbarPreviewThumbnailHelper.java @@ -90,9 +90,8 @@ public final class SeekbarPreviewThumbnailHelper { final float scaleFactor = (float) newWidth / srcWidth; final int newHeight = (int) (previewThumbnail.getHeight() * scaleFactor); - currentSeekbarPreviewThumbnail.setImageBitmap( - BitmapCompat.createScaledBitmap(previewThumbnail, newWidth, newHeight, null, - true)); + currentSeekbarPreviewThumbnail.setImageBitmap(BitmapCompat + .createScaledBitmap(previewThumbnail, newWidth, newHeight, null, true)); } catch (final Exception ex) { Log.e(TAG, "Failed to resize and set seekbar preview thumbnail", ex); currentSeekbarPreviewThumbnail.setVisibility(View.GONE); diff --git a/app/src/main/java/org/schabi/newpipe/player/ui/MainPlayerUi.java b/app/src/main/java/org/schabi/newpipe/player/ui/MainPlayerUi.java index eadb1ac99..683629c25 100644 --- a/app/src/main/java/org/schabi/newpipe/player/ui/MainPlayerUi.java +++ b/app/src/main/java/org/schabi/newpipe/player/ui/MainPlayerUi.java @@ -862,14 +862,11 @@ public final class MainPlayerUi extends VideoPlayerUi implements View.OnLayoutCh @Override protected void onPlaybackSpeedClicked() { - final AppCompatActivity activity = getParentActivity().orElse(null); - if (activity == null) { - return; - } - - PlaybackParameterDialog.newInstance(player.getPlaybackSpeed(), player.getPlaybackPitch(), - player.getPlaybackSkipSilence(), player::setPlaybackParameters) - .show(activity.getSupportFragmentManager(), null); + getParentActivity().ifPresent(activity -> + PlaybackParameterDialog.newInstance(player.getPlaybackSpeed(), + player.getPlaybackPitch(), player.getPlaybackSkipSilence(), + player::setPlaybackParameters) + .show(activity.getSupportFragmentManager(), null)); } @Override @@ -969,22 +966,22 @@ public final class MainPlayerUi extends VideoPlayerUi implements View.OnLayoutCh //////////////////////////////////////////////////////////////////////////*/ //region Getters + private Optional getParentContext() { + return Optional.ofNullable(binding.getRoot().getParent()) + .filter(ViewGroup.class::isInstance) + .map(parent -> ((ViewGroup) parent).getContext()); + } + public Optional getParentActivity() { - final ViewParent rootParent = binding.getRoot().getParent(); - if (rootParent instanceof ViewGroup) { - final Context activity = ((ViewGroup) rootParent).getContext(); - if (activity instanceof AppCompatActivity) { - return Optional.of((AppCompatActivity) activity); - } - } - return Optional.empty(); + return getParentContext() + .filter(AppCompatActivity.class::isInstance) + .map(AppCompatActivity.class::cast); } public boolean isLandscape() { // DisplayMetrics from activity context knows about MultiWindow feature // while DisplayMetrics from app context doesn't - return DeviceUtils.isLandscape( - getParentActivity().map(Context.class::cast).orElse(player.getService())); + return DeviceUtils.isLandscape(getParentContext().orElse(player.getService())); } //endregion }