Filter streams using Java 8 Stream's API instead of removing streams with list iterators and add a better toast when there is no audio stream for external players
This ensures to not remove streams from the StreamInfo lists themselves, and so to not have to create list copies. The toast shown in RouterActivity, when there is no audio stream available for external players, is now shown, in the same case, when pressing the background button in VideoDetailFragment.
This commit is contained in:
parent
73855cacb7
commit
036196a487
6 changed files with 123 additions and 132 deletions
|
|
@ -23,10 +23,10 @@ import java.util.Collections;
|
|||
import java.util.Comparator;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.Set;
|
||||
import java.util.function.Predicate;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public final class ListHelper {
|
||||
|
|
@ -116,27 +116,17 @@ public final class ListHelper {
|
|||
* Return a {@link Stream} list which uses the given delivery method from a {@link Stream}
|
||||
* list.
|
||||
*
|
||||
* @param streamList the original stream list
|
||||
* @param deliveryMethod the delivery method
|
||||
* @param streamList the original {@link Stream stream} list
|
||||
* @param deliveryMethod the {@link DeliveryMethod delivery method}
|
||||
* @param <S> the item type's class that extends {@link Stream}
|
||||
* @return a stream list which uses the given delivery method
|
||||
* @return a {@link Stream stream} list which uses the given delivery method
|
||||
*/
|
||||
@NonNull
|
||||
public static <S extends Stream> List<S> keepStreamsWithDelivery(
|
||||
@NonNull final List<S> streamList,
|
||||
public static <S extends Stream> List<S> getStreamsOfSpecifiedDelivery(
|
||||
final List<S> streamList,
|
||||
final DeliveryMethod deliveryMethod) {
|
||||
if (streamList.isEmpty()) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
final Iterator<S> streamListIterator = streamList.iterator();
|
||||
while (streamListIterator.hasNext()) {
|
||||
if (streamListIterator.next().getDeliveryMethod() != deliveryMethod) {
|
||||
streamListIterator.remove();
|
||||
}
|
||||
}
|
||||
|
||||
return streamList;
|
||||
return getFilteredStreamList(streamList,
|
||||
stream -> stream.getDeliveryMethod() == deliveryMethod);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -147,21 +137,10 @@ public final class ListHelper {
|
|||
* @return a stream list which only contains URL streams and non-torrent streams
|
||||
*/
|
||||
@NonNull
|
||||
public static <S extends Stream> List<S> removeNonUrlAndTorrentStreams(
|
||||
@NonNull final List<S> streamList) {
|
||||
if (streamList.isEmpty()) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
final Iterator<S> streamListIterator = streamList.iterator();
|
||||
while (streamListIterator.hasNext()) {
|
||||
final S stream = streamListIterator.next();
|
||||
if (!stream.isUrl() || stream.getDeliveryMethod() == DeliveryMethod.TORRENT) {
|
||||
streamListIterator.remove();
|
||||
}
|
||||
}
|
||||
|
||||
return streamList;
|
||||
public static <S extends Stream> List<S> getNonUrlAndNonTorrentStreams(
|
||||
final List<S> streamList) {
|
||||
return getFilteredStreamList(streamList,
|
||||
stream -> stream.isUrl() && stream.getDeliveryMethod() != DeliveryMethod.TORRENT);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -172,21 +151,10 @@ public final class ListHelper {
|
|||
* @return a stream list which only contains non-torrent streams
|
||||
*/
|
||||
@NonNull
|
||||
public static <S extends Stream> List<S> removeTorrentStreams(
|
||||
@NonNull final List<S> streamList) {
|
||||
if (streamList.isEmpty()) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
final Iterator<S> streamListIterator = streamList.iterator();
|
||||
while (streamListIterator.hasNext()) {
|
||||
final S stream = streamListIterator.next();
|
||||
if (stream.getDeliveryMethod() == DeliveryMethod.TORRENT) {
|
||||
streamListIterator.remove();
|
||||
}
|
||||
}
|
||||
|
||||
return streamList;
|
||||
public static <S extends Stream> List<S> getNonTorrentStreams(
|
||||
final List<S> streamList) {
|
||||
return getFilteredStreamList(streamList,
|
||||
stream -> stream.getDeliveryMethod() != DeliveryMethod.TORRENT);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -224,6 +192,26 @@ public final class ListHelper {
|
|||
// Utils
|
||||
//////////////////////////////////////////////////////////////////////////*/
|
||||
|
||||
/**
|
||||
* Get a filtered stream list, by using Java 8 Stream's API and the given predicate.
|
||||
*
|
||||
* @param streamList the stream list to filter
|
||||
* @param streamListPredicate the predicate which will be used to filter streams
|
||||
* @param <S> the item type's class that extends {@link Stream}
|
||||
* @return a new stream list filtered using the given predicate
|
||||
*/
|
||||
private static <S extends Stream> List<S> getFilteredStreamList(
|
||||
final List<S> streamList,
|
||||
final Predicate<S> streamListPredicate) {
|
||||
if (streamList == null) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
return streamList.stream()
|
||||
.filter(streamListPredicate)
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
private static String computeDefaultResolution(final Context context, final int key,
|
||||
final int value) {
|
||||
final SharedPreferences preferences
|
||||
|
|
|
|||
|
|
@ -63,7 +63,7 @@ import org.schabi.newpipe.util.external_communication.ShareUtils;
|
|||
|
||||
import java.util.List;
|
||||
|
||||
import static org.schabi.newpipe.util.ListHelper.removeNonUrlAndTorrentStreams;
|
||||
import static org.schabi.newpipe.util.ListHelper.getNonUrlAndNonTorrentStreams;
|
||||
|
||||
public final class NavigationHelper {
|
||||
public static final String MAIN_FRAGMENT_TAG = "main_fragment_tag";
|
||||
|
|
@ -221,39 +221,42 @@ public final class NavigationHelper {
|
|||
public static void playOnExternalAudioPlayer(@NonNull final Context context,
|
||||
@NonNull final StreamInfo info) {
|
||||
final List<AudioStream> audioStreams = info.getAudioStreams();
|
||||
if (audioStreams.isEmpty()) {
|
||||
if (audioStreams == null || audioStreams.isEmpty()) {
|
||||
Toast.makeText(context, R.string.audio_streams_empty, Toast.LENGTH_SHORT).show();
|
||||
return;
|
||||
}
|
||||
final List<AudioStream> audioStreamsForExternalPlayers = removeNonUrlAndTorrentStreams(
|
||||
audioStreams);
|
||||
|
||||
final List<AudioStream> audioStreamsForExternalPlayers =
|
||||
getNonUrlAndNonTorrentStreams(audioStreams);
|
||||
if (audioStreamsForExternalPlayers.isEmpty()) {
|
||||
Toast.makeText(context, R.string.no_audio_streams_available_for_external_players,
|
||||
Toast.LENGTH_SHORT).show();
|
||||
return;
|
||||
}
|
||||
final int index = ListHelper.getDefaultAudioFormat(context,
|
||||
audioStreamsForExternalPlayers);
|
||||
|
||||
final int index = ListHelper.getDefaultAudioFormat(context, audioStreamsForExternalPlayers);
|
||||
final AudioStream audioStream = audioStreamsForExternalPlayers.get(index);
|
||||
|
||||
playOnExternalPlayer(context, info.getName(), info.getUploaderName(), audioStream);
|
||||
}
|
||||
|
||||
public static void playOnExternalVideoPlayer(final Context context,
|
||||
@NonNull final StreamInfo info) {
|
||||
final List<VideoStream> videoStreams = info.getVideoStreams();
|
||||
if (videoStreams.isEmpty()) {
|
||||
if (videoStreams == null || videoStreams.isEmpty()) {
|
||||
Toast.makeText(context, R.string.video_streams_empty, Toast.LENGTH_SHORT).show();
|
||||
return;
|
||||
}
|
||||
|
||||
final List<VideoStream> videoStreamsForExternalPlayers =
|
||||
ListHelper.getSortedStreamVideosList(context,
|
||||
removeNonUrlAndTorrentStreams(videoStreams), null, false, false);
|
||||
getNonUrlAndNonTorrentStreams(videoStreams), null, false, false);
|
||||
if (videoStreamsForExternalPlayers.isEmpty()) {
|
||||
Toast.makeText(context, R.string.no_video_streams_available_for_external_players,
|
||||
Toast.LENGTH_SHORT).show();
|
||||
return;
|
||||
}
|
||||
|
||||
final int index = ListHelper.getDefaultResolutionIndex(context,
|
||||
videoStreamsForExternalPlayers);
|
||||
|
||||
|
|
@ -267,42 +270,41 @@ public final class NavigationHelper {
|
|||
@NonNull final Stream stream) {
|
||||
final DeliveryMethod deliveryMethod = stream.getDeliveryMethod();
|
||||
final String mimeType;
|
||||
if (deliveryMethod == DeliveryMethod.PROGRESSIVE_HTTP) {
|
||||
if (stream.getFormat() != null) {
|
||||
mimeType = stream.getFormat().getMimeType();
|
||||
} else {
|
||||
if (stream instanceof AudioStream) {
|
||||
mimeType = "audio/*";
|
||||
} else if (stream instanceof VideoStream) {
|
||||
mimeType = "video/*";
|
||||
|
||||
if (!stream.isUrl() || deliveryMethod == DeliveryMethod.TORRENT) {
|
||||
Toast.makeText(context, R.string.selected_stream_external_player_not_supported,
|
||||
Toast.LENGTH_SHORT).show();
|
||||
return;
|
||||
}
|
||||
|
||||
switch (deliveryMethod) {
|
||||
case PROGRESSIVE_HTTP:
|
||||
if (stream.getFormat() == null) {
|
||||
if (stream instanceof AudioStream) {
|
||||
mimeType = "audio/*";
|
||||
} else if (stream instanceof VideoStream) {
|
||||
mimeType = "video/*";
|
||||
} else {
|
||||
// This should never be reached, because subtitles are not opened in
|
||||
// external players
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
// This should never be reached, because subtitles are not opened in external
|
||||
// players
|
||||
return;
|
||||
mimeType = stream.getFormat().getMimeType();
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (!stream.isUrl() || deliveryMethod == DeliveryMethod.TORRENT) {
|
||||
Toast.makeText(context, R.string.selected_stream_external_player_not_supported,
|
||||
Toast.LENGTH_SHORT).show();
|
||||
return;
|
||||
} else {
|
||||
switch (deliveryMethod) {
|
||||
case HLS:
|
||||
mimeType = "application/x-mpegURL";
|
||||
break;
|
||||
case DASH:
|
||||
mimeType = "application/dash+xml";
|
||||
break;
|
||||
case SS:
|
||||
mimeType = "application/vnd.ms-sstr+xml";
|
||||
break;
|
||||
default:
|
||||
// Progressive HTTP streams are handled above and torrents streams are not
|
||||
// exposed to external players
|
||||
mimeType = "";
|
||||
}
|
||||
}
|
||||
break;
|
||||
case HLS:
|
||||
mimeType = "application/x-mpegURL";
|
||||
break;
|
||||
case DASH:
|
||||
mimeType = "application/dash+xml";
|
||||
break;
|
||||
case SS:
|
||||
mimeType = "application/vnd.ms-sstr+xml";
|
||||
break;
|
||||
default:
|
||||
// Torrent streams are not exposed to external players
|
||||
mimeType = "";
|
||||
}
|
||||
|
||||
final Intent intent = new Intent();
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue