Prefer video-only streams to video streams

Prefering video-only streams to video streams for our player will allow us to make seamless transitions on 360 and 720p qualities on YouTube.
External players and the downloader are not affected by this change.
This commit is contained in:
TiA4f8R 2021-11-02 19:19:26 +01:00
parent 336f9f3813
commit 79f8270c35
No known key found for this signature in database
GPG Key ID: E6D3E7F5949450DD
8 changed files with 84 additions and 51 deletions

View File

@ -633,7 +633,7 @@ public class RouterActivity extends AppCompatActivity {
.subscribe(result -> {
final List<VideoStream> sortedVideoStreams = ListHelper
.getSortedStreamVideosList(this, result.getVideoStreams(),
result.getVideoOnlyStreams(), false);
result.getVideoOnlyStreams(), false, false);
final int selectedVideoStreamIndex = ListHelper
.getDefaultResolutionIndex(this, sortedVideoStreams);

View File

@ -151,7 +151,7 @@ public class DownloadDialog extends DialogFragment
public static DownloadDialog newInstance(final Context context, final StreamInfo info) {
final ArrayList<VideoStream> streamsList = new ArrayList<>(ListHelper
.getSortedStreamVideosList(context, info.getVideoStreams(),
info.getVideoOnlyStreams(), false));
info.getVideoOnlyStreams(), false, false));
final int selectedStreamIndex = ListHelper.getDefaultResolutionIndex(context, streamsList);
final DownloadDialog instance = newInstance(info);

View File

@ -1617,6 +1617,7 @@ public final class VideoDetailFragment
activity,
info.getVideoStreams(),
info.getVideoOnlyStreams(),
false,
false);
selectedVideoStreamIndex = ListHelper
.getDefaultResolutionIndex(activity, sortedVideoStreams);

View File

@ -58,7 +58,7 @@ public class VideoPlaybackResolver implements PlaybackResolver {
// Create video stream source
final List<VideoStream> videos = ListHelper.getSortedStreamVideosList(context,
info.getVideoStreams(), info.getVideoOnlyStreams(), false);
info.getVideoStreams(), info.getVideoOnlyStreams(), false, true);
final int index;
if (videos.isEmpty()) {
index = -1;

View File

@ -4,6 +4,7 @@ import android.content.Context;
import android.content.SharedPreferences;
import android.net.ConnectivityManager;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.StringRes;
import androidx.core.content.ContextCompat;
@ -108,17 +109,21 @@ public final class ListHelper {
* Join the two lists of video streams (video_only and normal videos),
* and sort them according with default format chosen by the user.
*
* @param context context to search for the format to give preference
* @param videoStreams normal videos list
* @param videoOnlyStreams video only stream list
* @param context the context to search for the format to give preference
* @param videoStreams the normal videos list
* @param videoOnlyStreams the video-only stream list
* @param ascendingOrder true -> smallest to greatest | false -> greatest to smallest
* @param preferVideoOnlyStreams if video-only streams should preferred when both video-only
* streams and normal video streams are available
* @return the sorted list
*/
public static List<VideoStream> getSortedStreamVideosList(final Context context,
final List<VideoStream> videoStreams,
final List<VideoStream>
videoOnlyStreams,
final boolean ascendingOrder) {
@NonNull
public static List<VideoStream> getSortedStreamVideosList(
@NonNull final Context context,
@Nullable final List<VideoStream> videoStreams,
@Nullable final List<VideoStream> videoOnlyStreams,
final boolean ascendingOrder,
final boolean preferVideoOnlyStreams) {
final SharedPreferences preferences
= PreferenceManager.getDefaultSharedPreferences(context);
@ -128,7 +133,7 @@ public final class ListHelper {
R.string.default_video_format_key, R.string.default_video_format_value);
return getSortedStreamVideosList(defaultFormat, showHigherResolutions, videoStreams,
videoOnlyStreams, ascendingOrder);
videoOnlyStreams, ascendingOrder, preferVideoOnlyStreams);
}
/*//////////////////////////////////////////////////////////////////////////
@ -197,20 +202,45 @@ public final class ListHelper {
* @param videoStreams normal videos list
* @param videoOnlyStreams video only stream list
* @param ascendingOrder true -> smallest to greatest | false -> greatest to smallest
* @param preferVideoOnlyStreams if video-only streams should preferred when both video-only
* streams and normal video streams are available
* @return the sorted list
*/
static List<VideoStream> getSortedStreamVideosList(final MediaFormat defaultFormat,
@NonNull
static List<VideoStream> getSortedStreamVideosList(
@Nullable final MediaFormat defaultFormat,
final boolean showHigherResolutions,
final List<VideoStream> videoStreams,
final List<VideoStream> videoOnlyStreams,
final boolean ascendingOrder) {
@Nullable final List<VideoStream> videoStreams,
@Nullable final List<VideoStream> videoOnlyStreams,
final boolean ascendingOrder,
final boolean preferVideoOnlyStreams) {
final ArrayList<VideoStream> retList = new ArrayList<>();
final HashMap<String, VideoStream> hashMap = new HashMap<>();
if (preferVideoOnlyStreams) {
if (videoStreams != null) {
for (final VideoStream stream : videoStreams) {
if (!showHigherResolutions && HIGH_RESOLUTION_LIST.contains(
stream.getResolution())) {
continue;
}
retList.add(stream);
}
}
if (videoOnlyStreams != null) {
for (final VideoStream stream : videoOnlyStreams) {
if (!showHigherResolutions
&& HIGH_RESOLUTION_LIST.contains(stream.getResolution())) {
if (!showHigherResolutions && HIGH_RESOLUTION_LIST.contains(
stream.getResolution())) {
continue;
}
retList.add(stream);
}
}
} else {
if (videoOnlyStreams != null) {
for (final VideoStream stream : videoOnlyStreams) {
if (!showHigherResolutions && HIGH_RESOLUTION_LIST.contains(
stream.getResolution())) {
continue;
}
retList.add(stream);
@ -218,13 +248,14 @@ public final class ListHelper {
}
if (videoStreams != null) {
for (final VideoStream stream : videoStreams) {
if (!showHigherResolutions
&& HIGH_RESOLUTION_LIST.contains(stream.getResolution())) {
if (!showHigherResolutions && HIGH_RESOLUTION_LIST.contains(
stream.getResolution())) {
continue;
}
retList.add(stream);
}
}
}
// Add all to the hashmap
for (final VideoStream videoStream : retList) {

View File

@ -214,7 +214,8 @@ public final class NavigationHelper {
// External Players
//////////////////////////////////////////////////////////////////////////*/
public static void playOnExternalAudioPlayer(final Context context, final StreamInfo info) {
public static void playOnExternalAudioPlayer(@NonNull final Context context,
@NonNull final StreamInfo info) {
final int index = ListHelper.getDefaultAudioFormat(context, info.getAudioStreams());
if (index == -1) {
@ -226,9 +227,11 @@ public final class NavigationHelper {
playOnExternalPlayer(context, info.getName(), info.getUploaderName(), audioStream);
}
public static void playOnExternalVideoPlayer(final Context context, final StreamInfo info) {
public static void playOnExternalVideoPlayer(@NonNull final Context context,
@NonNull final StreamInfo info) {
final ArrayList<VideoStream> videoStreamsList = new ArrayList<>(
ListHelper.getSortedStreamVideosList(context, info.getVideoStreams(), null, false));
ListHelper.getSortedStreamVideosList(context, info.getVideoStreams(), null, false,
false));
final int index = ListHelper.getDefaultResolutionIndex(context, videoStreamsList);
if (index == -1) {
@ -240,8 +243,10 @@ public final class NavigationHelper {
playOnExternalPlayer(context, info.getName(), info.getUploaderName(), videoStream);
}
public static void playOnExternalPlayer(final Context context, final String name,
final String artist, final Stream stream) {
public static void playOnExternalPlayer(@NonNull final Context context,
@Nullable final String name,
@Nullable final String artist,
@NonNull final Stream stream) {
final Intent intent = new Intent();
intent.setAction(Intent.ACTION_VIEW);
intent.setDataAndType(Uri.parse(stream.getUrl()), stream.getFormat().getMimeType());
@ -253,7 +258,8 @@ public final class NavigationHelper {
resolveActivityOrAskToInstall(context, intent);
}
public static void resolveActivityOrAskToInstall(final Context context, final Intent intent) {
public static void resolveActivityOrAskToInstall(@NonNull final Context context,
@NonNull final Intent intent) {
if (intent.resolveActivity(context.getPackageManager()) != null) {
ShareUtils.openIntentInApp(context, intent, false);
} else {

View File

@ -47,15 +47,10 @@ public class ListHelperTest {
@Test
public void getSortedStreamVideosListTest() {
List<VideoStream> result = ListHelper.getSortedStreamVideosList(MediaFormat.MPEG_4, true,
VIDEO_STREAMS_TEST_LIST, VIDEO_ONLY_STREAMS_TEST_LIST, true);
VIDEO_STREAMS_TEST_LIST, VIDEO_ONLY_STREAMS_TEST_LIST, true, false);
List<String> expected = Arrays.asList("144p", "240p", "360p", "480p", "720p", "720p60",
"1080p", "1080p60", "1440p60", "2160p", "2160p60");
// for (VideoStream videoStream : result) {
// System.out.println(videoStream.resolution + " > "
// + MediaFormat.getSuffixById(videoStream.format) + " > "
// + videoStream.isVideoOnly);
// }
assertEquals(result.size(), expected.size());
for (int i = 0; i < result.size(); i++) {
@ -67,7 +62,7 @@ public class ListHelperTest {
//////////////////
result = ListHelper.getSortedStreamVideosList(MediaFormat.MPEG_4, true,
VIDEO_STREAMS_TEST_LIST, VIDEO_ONLY_STREAMS_TEST_LIST, false);
VIDEO_STREAMS_TEST_LIST, VIDEO_ONLY_STREAMS_TEST_LIST, false, false);
expected = Arrays.asList("2160p60", "2160p", "1440p60", "1080p60", "1080p", "720p60",
"720p", "480p", "360p", "240p", "144p");
assertEquals(result.size(), expected.size());
@ -83,7 +78,7 @@ public class ListHelperTest {
//////////////////////////////////
final List<VideoStream> result = ListHelper.getSortedStreamVideosList(MediaFormat.MPEG_4,
false, VIDEO_STREAMS_TEST_LIST, VIDEO_ONLY_STREAMS_TEST_LIST, false);
false, VIDEO_STREAMS_TEST_LIST, VIDEO_ONLY_STREAMS_TEST_LIST, false, false);
final List<String> expected = Arrays.asList(
"1080p60", "1080p", "720p60", "720p", "480p", "360p", "240p", "144p");
assertEquals(result.size(), expected.size());

View File

@ -9,7 +9,7 @@
<suppress checks="FinalParameters"
files="ListHelper.java"
lines="280,312"/>
lines="311,343"/>
<suppress checks="EmptyBlock"
files="ContentSettingsFragment.java"