diff --git a/.github/CONTRIBUTING.md b/.github/CONTRIBUTING.md index 311e5248c..d08ae9051 100644 --- a/.github/CONTRIBUTING.md +++ b/.github/CONTRIBUTING.md @@ -68,7 +68,7 @@ The [checkStyle](https://github.com/checkstyle/checkstyle) plugin verifies that - Go to `File -> Settings -> Plugins`, search for `checkstyle` and install `CheckStyle-IDEA`. - Go to `File -> Settings -> Tools -> Checkstyle`. - Add NewPipe's configuration file by clicking the `+` in the right toolbar of the "Configuration File" list. -- Under the "Use a local Checkstyle file" bullet, click on `Browse` and pick the file named `checkstyle.xml` in the project's root folder. +- Under the "Use a local Checkstyle file" bullet, click on `Browse` and, enter `checkstyle` folder under the project's root path and pick the file named `checkstyle.xml`. - Enable "Store relative to project location" so that moving the directory around does not create issues. - Insert a description in the top bar, then click `Next` and then `Finish`. - Activate the configuration file you just added by enabling the checkbox on the left. diff --git a/app/src/main/java/org/schabi/newpipe/local/dialog/PlaylistAppendDialog.java b/app/src/main/java/org/schabi/newpipe/local/dialog/PlaylistAppendDialog.java index 2db7e0153..a874cdd62 100644 --- a/app/src/main/java/org/schabi/newpipe/local/dialog/PlaylistAppendDialog.java +++ b/app/src/main/java/org/schabi/newpipe/local/dialog/PlaylistAppendDialog.java @@ -33,8 +33,16 @@ public final class PlaylistAppendDialog extends PlaylistDialog { private final CompositeDisposable playlistDisposables = new CompositeDisposable(); - public PlaylistAppendDialog(final List streamEntities) { - super(streamEntities); + /** + * Create a new instance of {@link PlaylistAppendDialog}. + * + * @param streamEntities a list of {@link StreamEntity} to be added to playlists + * @return a new instance of {@link PlaylistAppendDialog} + */ + public static PlaylistAppendDialog newInstance(final List streamEntities) { + final PlaylistAppendDialog dialog = new PlaylistAppendDialog(); + dialog.setStreamEntities(streamEntities); + return dialog; } /*////////////////////////////////////////////////////////////////////////// @@ -103,13 +111,14 @@ public final class PlaylistAppendDialog extends PlaylistDialog { // Helper //////////////////////////////////////////////////////////////////////////*/ + /** Display create playlist dialog. */ public void openCreatePlaylistDialog() { if (getStreamEntities() == null || !isAdded()) { return; } final PlaylistCreationDialog playlistCreationDialog = - new PlaylistCreationDialog(getStreamEntities()); + PlaylistCreationDialog.newInstance(getStreamEntities()); // Move the dismissListener to the new dialog. playlistCreationDialog.setOnDismissListener(this.getOnDismissListener()); this.setOnDismissListener(null); diff --git a/app/src/main/java/org/schabi/newpipe/local/dialog/PlaylistCreationDialog.java b/app/src/main/java/org/schabi/newpipe/local/dialog/PlaylistCreationDialog.java index 6664144cd..0c09f3f0d 100644 --- a/app/src/main/java/org/schabi/newpipe/local/dialog/PlaylistCreationDialog.java +++ b/app/src/main/java/org/schabi/newpipe/local/dialog/PlaylistCreationDialog.java @@ -21,8 +21,17 @@ import java.util.List; import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers; public final class PlaylistCreationDialog extends PlaylistDialog { - public PlaylistCreationDialog(final List streamEntities) { - super(streamEntities); + + /** + * Create a new instance of {@link PlaylistCreationDialog}. + * + * @param streamEntities a list of {@link StreamEntity} to be added to playlists + * @return a new instance of {@link PlaylistCreationDialog} + */ + public static PlaylistCreationDialog newInstance(final List streamEntities) { + final PlaylistCreationDialog dialog = new PlaylistCreationDialog(); + dialog.setStreamEntities(streamEntities); + return dialog; } /*////////////////////////////////////////////////////////////////////////// diff --git a/app/src/main/java/org/schabi/newpipe/local/dialog/PlaylistDialog.java b/app/src/main/java/org/schabi/newpipe/local/dialog/PlaylistDialog.java index d43a0981c..f568ef81a 100644 --- a/app/src/main/java/org/schabi/newpipe/local/dialog/PlaylistDialog.java +++ b/app/src/main/java/org/schabi/newpipe/local/dialog/PlaylistDialog.java @@ -31,10 +31,6 @@ public abstract class PlaylistDialog extends DialogFragment implements StateSave private org.schabi.newpipe.util.SavedState savedState; - public PlaylistDialog(final List streamEntities) { - this.streamEntities = streamEntities; - } - /*////////////////////////////////////////////////////////////////////////// // LifeCycle //////////////////////////////////////////////////////////////////////////*/ @@ -120,6 +116,10 @@ public abstract class PlaylistDialog extends DialogFragment implements StateSave this.onDismissListener = onDismissListener; } + protected void setStreamEntities(final List streamEntities) { + this.streamEntities = streamEntities; + } + /*////////////////////////////////////////////////////////////////////////// // Dialog creation //////////////////////////////////////////////////////////////////////////*/ @@ -143,8 +143,8 @@ public abstract class PlaylistDialog extends DialogFragment implements StateSave .observeOn(AndroidSchedulers.mainThread()) .subscribe(hasPlaylists -> onExec.accept(hasPlaylists - ? new PlaylistAppendDialog(streamEntities) - : new PlaylistCreationDialog(streamEntities)) + ? PlaylistAppendDialog.newInstance(streamEntities) + : PlaylistCreationDialog.newInstance(streamEntities)) ); } } 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 c4205124c..2c8be5d78 100644 --- a/app/src/main/java/org/schabi/newpipe/player/Player.java +++ b/app/src/main/java/org/schabi/newpipe/player/Player.java @@ -116,6 +116,7 @@ import androidx.appcompat.content.res.AppCompatResources; import androidx.appcompat.view.ContextThemeWrapper; import androidx.appcompat.widget.AppCompatImageButton; import androidx.appcompat.widget.PopupMenu; +import androidx.collection.ArraySet; import androidx.core.content.ContextCompat; import androidx.core.graphics.Insets; import androidx.core.view.GestureDetectorCompat; @@ -4217,21 +4218,21 @@ public final class Player implements // in livestreams) so we will be not able to execute the block below. // Reload the play queue manager in this case, which is the behavior when we don't know the // index of the video renderer or playQueueManagerReloadingNeeded returns true. - if (!getCurrentStreamInfo().isPresent()) { + final Optional optCurrentStreamInfo = getCurrentStreamInfo(); + if (!optCurrentStreamInfo.isPresent()) { reloadPlayQueueManager(); setRecovery(); return; } - final int videoRenderIndex = getVideoRendererIndex(); - final StreamInfo info = getCurrentStreamInfo().get(); + final StreamInfo info = optCurrentStreamInfo.get(); // In the case we don't know the source type, fallback to the one with video with audio or // audio-only source. final SourceType sourceType = videoResolver.getStreamSourceType().orElse( SourceType.VIDEO_WITH_AUDIO_OR_AUDIO_ONLY); - if (playQueueManagerReloadingNeeded(sourceType, info, videoRenderIndex)) { + if (playQueueManagerReloadingNeeded(sourceType, info, getVideoRendererIndex())) { reloadPlayQueueManager(); } else { final StreamType streamType = info.getStreamType(); @@ -4242,19 +4243,22 @@ public final class Player implements return; } - final TrackGroupArray videoTrackGroupArray = Objects.requireNonNull( - trackSelector.getCurrentMappedTrackInfo()).getTrackGroups(videoRenderIndex); + final DefaultTrackSelector.ParametersBuilder parametersBuilder = + trackSelector.buildUponParameters(); + if (videoEnabled) { - // Clearing the null selection override enable again the video stream (and its - // fetching). - trackSelector.setParameters(trackSelector.buildUponParameters() - .clearSelectionOverride(videoRenderIndex, videoTrackGroupArray)); + // Enable again the video track and the subtitles, if there is one selected + parametersBuilder.setDisabledTrackTypes(Collections.emptySet()); } else { - // Using setRendererDisabled still fetch the video stream in background, contrary - // to setSelectionOverride with a null override. - trackSelector.setParameters(trackSelector.buildUponParameters() - .setSelectionOverride(videoRenderIndex, videoTrackGroupArray, null)); + // Disable the video track and the ability to select subtitles + // Use an ArraySet because we can't use Set.of() on all supported APIs by the app + final ArraySet disabledTracks = new ArraySet<>(); + disabledTracks.add(C.TRACK_TYPE_TEXT); + disabledTracks.add(C.TRACK_TYPE_VIDEO); + parametersBuilder.setDisabledTrackTypes(disabledTracks); } + + trackSelector.setParameters(parametersBuilder); } setRecovery(); diff --git a/app/src/main/java/org/schabi/newpipe/util/SparseItemUtil.java b/app/src/main/java/org/schabi/newpipe/util/SparseItemUtil.java index 5daf7f073..b8cd4ef69 100644 --- a/app/src/main/java/org/schabi/newpipe/util/SparseItemUtil.java +++ b/app/src/main/java/org/schabi/newpipe/util/SparseItemUtil.java @@ -54,6 +54,7 @@ public final class SparseItemUtil { // if the duration is >= 0 (provided that the item is not a livestream) and there is an // uploader url, probably all info is already there, so there is no need to fetch it callback.accept(new SinglePlayQueue(item)); + return; } // either the duration or the uploader url are not available, so fetch more info @@ -80,12 +81,12 @@ public final class SparseItemUtil { @NonNull final String url, @Nullable final String uploaderUrl, @NonNull final Consumer callback) { - if (isNullOrEmpty(uploaderUrl)) { - fetchStreamInfoAndSaveToDatabase(context, serviceId, url, - streamInfo -> callback.accept(streamInfo.getUploaderUrl())); - } else { + if (!isNullOrEmpty(uploaderUrl)) { callback.accept(uploaderUrl); + return; } + fetchStreamInfoAndSaveToDatabase(context, serviceId, url, + streamInfo -> callback.accept(streamInfo.getUploaderUrl())); } /**