fix conflict
This commit is contained in:
commit
c43ac7c869
7 changed files with 436 additions and 121 deletions
|
@ -647,7 +647,7 @@ public final class MainVideoPlayer extends AppCompatActivity
|
|||
@Override
|
||||
protected int getOverrideResolutionIndex(final List<VideoStream> sortedVideos,
|
||||
final String playbackQuality) {
|
||||
return ListHelper.getDefaultResolutionIndex(context, sortedVideos, playbackQuality);
|
||||
return ListHelper.getResolutionIndex(context, sortedVideos, playbackQuality);
|
||||
}
|
||||
|
||||
/*//////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
@ -517,7 +517,7 @@ public final class PopupVideoPlayer extends Service {
|
|||
@Override
|
||||
protected int getOverrideResolutionIndex(final List<VideoStream> sortedVideos,
|
||||
final String playbackQuality) {
|
||||
return ListHelper.getPopupDefaultResolutionIndex(context, sortedVideos, playbackQuality);
|
||||
return ListHelper.getPopupResolutionIndex(context, sortedVideos, playbackQuality);
|
||||
}
|
||||
|
||||
/*//////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
@ -2,6 +2,7 @@ package org.schabi.newpipe.util;
|
|||
|
||||
import android.content.Context;
|
||||
import android.content.SharedPreferences;
|
||||
import android.net.ConnectivityManager;
|
||||
import android.preference.PreferenceManager;
|
||||
import android.support.annotation.StringRes;
|
||||
|
||||
|
@ -13,56 +14,38 @@ import org.schabi.newpipe.extractor.stream.VideoStream;
|
|||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
|
||||
@SuppressWarnings("WeakerAccess")
|
||||
public final class ListHelper {
|
||||
|
||||
// Video format in order of quality. 0=lowest quality, n=highest quality
|
||||
private static final List<MediaFormat> VIDEO_FORMAT_QUALITY_RANKING =
|
||||
Arrays.asList(MediaFormat.v3GPP, MediaFormat.WEBM, MediaFormat.MPEG_4);
|
||||
|
||||
// Audio format in order of quality. 0=lowest quality, n=highest quality
|
||||
private static final List<MediaFormat> AUDIO_FORMAT_QUALITY_RANKING =
|
||||
Arrays.asList(MediaFormat.MP3, MediaFormat.WEBMA, MediaFormat.M4A);
|
||||
// Audio format in order of efficiency. 0=most efficient, n=least efficient
|
||||
private static final List<MediaFormat> AUDIO_FORMAT_EFFICIENCY_RANKING =
|
||||
Arrays.asList(MediaFormat.WEBMA, MediaFormat.M4A, MediaFormat.MP3);
|
||||
|
||||
private static final List<String> HIGH_RESOLUTION_LIST = Arrays.asList("1440p", "2160p", "1440p60", "2160p60");
|
||||
|
||||
/**
|
||||
* Return the index of the default stream in the list, based on the parameters
|
||||
* defaultResolution and defaultFormat
|
||||
*
|
||||
* @return index of the default resolution&format
|
||||
*/
|
||||
public static int getDefaultResolutionIndex(String defaultResolution, String bestResolutionKey, MediaFormat defaultFormat, List<VideoStream> videoStreams) {
|
||||
if (videoStreams == null || videoStreams.isEmpty()) return -1;
|
||||
|
||||
sortStreamList(videoStreams, false);
|
||||
if (defaultResolution.equals(bestResolutionKey)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int defaultStreamIndex = getDefaultStreamIndex(defaultResolution, defaultFormat, videoStreams);
|
||||
if (defaultStreamIndex == -1 && defaultResolution.contains("p60")) {
|
||||
defaultStreamIndex = getDefaultStreamIndex(defaultResolution.replace("p60", "p"), defaultFormat, videoStreams);
|
||||
}
|
||||
|
||||
// this is actually an error,
|
||||
// but maybe there is really no stream fitting to the default value.
|
||||
if (defaultStreamIndex == -1) return 0;
|
||||
|
||||
return defaultStreamIndex;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see #getDefaultResolutionIndex(String, String, MediaFormat, List)
|
||||
*/
|
||||
public static int getDefaultResolutionIndex(Context context, List<VideoStream> videoStreams) {
|
||||
SharedPreferences defaultPreferences = PreferenceManager.getDefaultSharedPreferences(context);
|
||||
if (defaultPreferences == null) return 0;
|
||||
|
||||
String defaultResolution = defaultPreferences.getString(context.getString(R.string.default_resolution_key), context.getString(R.string.default_resolution_value));
|
||||
return getDefaultResolutionIndex(context, videoStreams, defaultResolution);
|
||||
String defaultResolution = computeDefaultResolution(context,
|
||||
R.string.default_resolution_key, R.string.default_resolution_value);
|
||||
return getDefaultResolutionWithDefaultFormat(context, defaultResolution, videoStreams);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see #getDefaultResolutionIndex(String, String, MediaFormat, List)
|
||||
*/
|
||||
public static int getDefaultResolutionIndex(Context context, List<VideoStream> videoStreams, String defaultResolution) {
|
||||
public static int getResolutionIndex(Context context, List<VideoStream> videoStreams, String defaultResolution) {
|
||||
return getDefaultResolutionWithDefaultFormat(context, defaultResolution, videoStreams);
|
||||
}
|
||||
|
||||
|
@ -70,69 +53,29 @@ public final class ListHelper {
|
|||
* @see #getDefaultResolutionIndex(String, String, MediaFormat, List)
|
||||
*/
|
||||
public static int getPopupDefaultResolutionIndex(Context context, List<VideoStream> videoStreams) {
|
||||
SharedPreferences defaultPreferences = PreferenceManager.getDefaultSharedPreferences(context);
|
||||
if (defaultPreferences == null) return 0;
|
||||
|
||||
String defaultResolution = defaultPreferences.getString(context.getString(R.string.default_popup_resolution_key), context.getString(R.string.default_popup_resolution_value));
|
||||
return getPopupDefaultResolutionIndex(context, videoStreams, defaultResolution);
|
||||
String defaultResolution = computeDefaultResolution(context,
|
||||
R.string.default_popup_resolution_key, R.string.default_popup_resolution_value);
|
||||
return getDefaultResolutionWithDefaultFormat(context, defaultResolution, videoStreams);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see #getDefaultResolutionIndex(String, String, MediaFormat, List)
|
||||
*/
|
||||
public static int getPopupDefaultResolutionIndex(Context context, List<VideoStream> videoStreams, String defaultResolution) {
|
||||
public static int getPopupResolutionIndex(Context context, List<VideoStream> videoStreams, String defaultResolution) {
|
||||
return getDefaultResolutionWithDefaultFormat(context, defaultResolution, videoStreams);
|
||||
}
|
||||
|
||||
public static int getDefaultAudioFormat(Context context, List<AudioStream> audioStreams) {
|
||||
MediaFormat defaultFormat = getDefaultFormat(context, R.string.default_audio_format_key, R.string.default_audio_format_value);
|
||||
return getHighestQualityAudioIndex(defaultFormat, audioStreams);
|
||||
}
|
||||
MediaFormat defaultFormat = getDefaultFormat(context, R.string.default_audio_format_key,
|
||||
R.string.default_audio_format_value);
|
||||
|
||||
public static int getHighestQualityAudioIndex(List<AudioStream> audioStreams) {
|
||||
if (audioStreams == null || audioStreams.isEmpty()) return -1;
|
||||
|
||||
int highestQualityIndex = 0;
|
||||
if (audioStreams.size() > 1) for (int i = 1; i < audioStreams.size(); i++) {
|
||||
AudioStream audioStream = audioStreams.get(i);
|
||||
if (audioStream.getAverageBitrate() >= audioStreams.get(highestQualityIndex).getAverageBitrate()) highestQualityIndex = i;
|
||||
// If the user has chosen to limit resolution to conserve mobile data
|
||||
// usage then we should also limit our audio usage.
|
||||
if (isLimitingDataUsage(context)) {
|
||||
return getMostCompactAudioIndex(defaultFormat, audioStreams);
|
||||
} else {
|
||||
return getHighestQualityAudioIndex(defaultFormat, audioStreams);
|
||||
}
|
||||
return highestQualityIndex;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the audio from the list with the highest bitrate
|
||||
*
|
||||
* @param audioStreams list the audio streams
|
||||
* @return audio with highest average bitrate
|
||||
*/
|
||||
public static AudioStream getHighestQualityAudio(List<AudioStream> audioStreams) {
|
||||
if (audioStreams == null || audioStreams.isEmpty()) return null;
|
||||
|
||||
return audioStreams.get(getHighestQualityAudioIndex(audioStreams));
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the audio from the list with the highest bitrate
|
||||
*
|
||||
* @param audioStreams list the audio streams
|
||||
* @return index of the audio with the highest average bitrate of the default format
|
||||
*/
|
||||
public static int getHighestQualityAudioIndex(MediaFormat defaultFormat, List<AudioStream> audioStreams) {
|
||||
if (audioStreams == null || audioStreams.isEmpty() || defaultFormat == null) return -1;
|
||||
|
||||
int highestQualityIndex = -1;
|
||||
for (int i = 0; i < audioStreams.size(); i++) {
|
||||
AudioStream audioStream = audioStreams.get(i);
|
||||
if (highestQualityIndex == -1 && audioStream.getFormat() == defaultFormat) highestQualityIndex = i;
|
||||
|
||||
if (highestQualityIndex != -1 && audioStream.getFormat() == defaultFormat
|
||||
&& audioStream.getAverageBitrate() > audioStreams.get(highestQualityIndex).getAverageBitrate()) {
|
||||
highestQualityIndex = i;
|
||||
}
|
||||
}
|
||||
if (highestQualityIndex == -1) highestQualityIndex = getHighestQualityAudioIndex(audioStreams);
|
||||
return highestQualityIndex;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -154,6 +97,50 @@ public final class ListHelper {
|
|||
return getSortedStreamVideosList(defaultFormat, showHigherResolutions, videoStreams, videoOnlyStreams, ascendingOrder);
|
||||
}
|
||||
|
||||
/*//////////////////////////////////////////////////////////////////////////
|
||||
// Utils
|
||||
//////////////////////////////////////////////////////////////////////////*/
|
||||
|
||||
private static String computeDefaultResolution(Context context, int key, int value) {
|
||||
SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(context);
|
||||
|
||||
// Load the prefered resolution otherwise the best available
|
||||
String resolution = preferences != null
|
||||
? preferences.getString(context.getString(key), context.getString(value))
|
||||
: context.getString(R.string.best_resolution_key);
|
||||
|
||||
String maxResolution = getResolutionLimit(context);
|
||||
if (maxResolution != null && compareVideoStreamResolution(maxResolution, resolution) < 1){
|
||||
resolution = maxResolution;
|
||||
}
|
||||
return resolution;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the index of the default stream in the list, based on the parameters
|
||||
* defaultResolution and defaultFormat
|
||||
*
|
||||
* @return index of the default resolution&format
|
||||
*/
|
||||
static int getDefaultResolutionIndex(String defaultResolution, String bestResolutionKey,
|
||||
MediaFormat defaultFormat, List<VideoStream> videoStreams) {
|
||||
if (videoStreams == null || videoStreams.isEmpty()) return -1;
|
||||
|
||||
sortStreamList(videoStreams, false);
|
||||
if (defaultResolution.equals(bestResolutionKey)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int defaultStreamIndex = getVideoStreamIndex(defaultResolution, defaultFormat, videoStreams);
|
||||
|
||||
// this is actually an error,
|
||||
// but maybe there is really no stream fitting to the default value.
|
||||
if (defaultStreamIndex == -1) {
|
||||
return 0;
|
||||
}
|
||||
return defaultStreamIndex;
|
||||
}
|
||||
|
||||
/**
|
||||
* Join the two lists of video streams (video_only and normal videos), and sort them according with default format
|
||||
* chosen by the user
|
||||
|
@ -165,7 +152,7 @@ public final class ListHelper {
|
|||
* @param ascendingOrder true -> smallest to greatest | false -> greatest to smallest @return the sorted list
|
||||
* @return the sorted list
|
||||
*/
|
||||
public static List<VideoStream> getSortedStreamVideosList(MediaFormat defaultFormat, boolean showHigherResolutions, List<VideoStream> videoStreams, List<VideoStream> videoOnlyStreams, boolean ascendingOrder) {
|
||||
static List<VideoStream> getSortedStreamVideosList(MediaFormat defaultFormat, boolean showHigherResolutions, List<VideoStream> videoStreams, List<VideoStream> videoOnlyStreams, boolean ascendingOrder) {
|
||||
ArrayList<VideoStream> retList = new ArrayList<>();
|
||||
HashMap<String, VideoStream> hashMap = new HashMap<>();
|
||||
|
||||
|
@ -215,36 +202,138 @@ public final class ListHelper {
|
|||
* @param videoStreams list that the sorting will be applied
|
||||
* @param ascendingOrder true -> smallest to greatest | false -> greatest to smallest
|
||||
*/
|
||||
public static void sortStreamList(List<VideoStream> videoStreams, final boolean ascendingOrder) {
|
||||
Collections.sort(videoStreams, new Comparator<VideoStream>() {
|
||||
@Override
|
||||
public int compare(VideoStream o1, VideoStream o2) {
|
||||
int res1 = Integer.parseInt(o1.getResolution().replace("0p60", "1").replaceAll("[^\\d.]", ""));
|
||||
int res2 = Integer.parseInt(o2.getResolution().replace("0p60", "1").replaceAll("[^\\d.]", ""));
|
||||
|
||||
return ascendingOrder ? res1 - res2 : res2 - res1;
|
||||
}
|
||||
private static void sortStreamList(List<VideoStream> videoStreams, final boolean ascendingOrder) {
|
||||
Collections.sort(videoStreams, (o1, o2) -> {
|
||||
int result = compareVideoStreamResolution(o1, o2, VIDEO_FORMAT_QUALITY_RANKING);
|
||||
return result == 0 ? 0 : (ascendingOrder ? result : -result);
|
||||
});
|
||||
}
|
||||
|
||||
/*//////////////////////////////////////////////////////////////////////////
|
||||
// Utils
|
||||
//////////////////////////////////////////////////////////////////////////*/
|
||||
/**
|
||||
* Get the audio from the list with the highest quality. Format will be ignored if it yields
|
||||
* no results.
|
||||
*
|
||||
* @param audioStreams list the audio streams
|
||||
* @return index of the audio with the highest average bitrate of the default format
|
||||
*/
|
||||
static int getHighestQualityAudioIndex(MediaFormat format, List<AudioStream> audioStreams) {
|
||||
int result = -1;
|
||||
if (audioStreams != null) {
|
||||
while(result == -1) {
|
||||
AudioStream prevStream = null;
|
||||
for (int idx = 0; idx < audioStreams.size(); idx++) {
|
||||
AudioStream stream = audioStreams.get(idx);
|
||||
if ((format == null || stream.getFormat() == format) &&
|
||||
(prevStream == null || compareAudioStreamBitrate(prevStream, stream,
|
||||
AUDIO_FORMAT_QUALITY_RANKING) < 0)) {
|
||||
prevStream = stream;
|
||||
result = idx;
|
||||
}
|
||||
}
|
||||
if (result == -1 && format == null) {
|
||||
break;
|
||||
}
|
||||
format = null;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private static int getDefaultStreamIndex(String defaultResolution, MediaFormat defaultFormat, List<VideoStream> videoStreams) {
|
||||
int defaultStreamIndex = -1;
|
||||
for (int i = 0; i < videoStreams.size(); i++) {
|
||||
VideoStream stream = videoStreams.get(i);
|
||||
if (defaultStreamIndex == -1 && stream.getResolution().equals(defaultResolution)) defaultStreamIndex = i;
|
||||
/**
|
||||
* Get the audio from the list with the lowest bitrate and efficient format. Format will be
|
||||
* ignored if it yields no results.
|
||||
*
|
||||
* @param format The target format type or null if it doesn't matter
|
||||
* @param audioStreams list the audio streams
|
||||
* @return index of the audio stream that can produce the most compact results or -1 if not found.
|
||||
*/
|
||||
static int getMostCompactAudioIndex(MediaFormat format, List<AudioStream> audioStreams) {
|
||||
int result = -1;
|
||||
if (audioStreams != null) {
|
||||
while(result == -1) {
|
||||
AudioStream prevStream = null;
|
||||
for (int idx = 0; idx < audioStreams.size(); idx++) {
|
||||
AudioStream stream = audioStreams.get(idx);
|
||||
if ((format == null || stream.getFormat() == format) &&
|
||||
(prevStream == null || compareAudioStreamBitrate(prevStream, stream,
|
||||
AUDIO_FORMAT_EFFICIENCY_RANKING) > 0)) {
|
||||
prevStream = stream;
|
||||
result = idx;
|
||||
}
|
||||
}
|
||||
if (result == -1 && format == null) {
|
||||
break;
|
||||
}
|
||||
format = null;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
if (stream.getFormat() == defaultFormat && stream.getResolution().equals(defaultResolution)) {
|
||||
return i;
|
||||
/**
|
||||
* Locates a possible match for the given resolution and format in the provided list.
|
||||
* In this order:
|
||||
* 1. Find a format and resolution match
|
||||
* 2. Find a format and resolution match and ignore the refresh
|
||||
* 3. Find a resolution match
|
||||
* 4. Find a resolution match and ignore the refresh
|
||||
* 5. Find a resolution just below the requested resolution and ignore the refresh
|
||||
* 6. Give up
|
||||
*/
|
||||
static int getVideoStreamIndex(String targetResolution, MediaFormat targetFormat,
|
||||
List<VideoStream> videoStreams) {
|
||||
int fullMatchIndex = -1;
|
||||
int fullMatchNoRefreshIndex = -1;
|
||||
int resMatchOnlyIndex = -1;
|
||||
int resMatchOnlyNoRefreshIndex = -1;
|
||||
int lowerResMatchNoRefreshIndex = -1;
|
||||
String targetResolutionNoRefresh = targetResolution.replaceAll("p\\d+$", "p");
|
||||
|
||||
for (int idx = 0; idx < videoStreams.size(); idx++) {
|
||||
MediaFormat format = targetFormat == null ? null : videoStreams.get(idx).getFormat();
|
||||
String resolution = videoStreams.get(idx).getResolution();
|
||||
String resolutionNoRefresh = resolution.replaceAll("p\\d+$", "p");
|
||||
|
||||
if (format == targetFormat && resolution.equals(targetResolution)) {
|
||||
fullMatchIndex = idx;
|
||||
}
|
||||
|
||||
if (format == targetFormat && resolutionNoRefresh.equals(targetResolutionNoRefresh)) {
|
||||
fullMatchNoRefreshIndex = idx;
|
||||
}
|
||||
|
||||
if (resMatchOnlyIndex == -1 && resolution.equals(targetResolution)) {
|
||||
resMatchOnlyIndex = idx;
|
||||
}
|
||||
|
||||
if (resMatchOnlyNoRefreshIndex == -1 && resolutionNoRefresh.equals(targetResolutionNoRefresh)) {
|
||||
resMatchOnlyNoRefreshIndex = idx;
|
||||
}
|
||||
|
||||
if (lowerResMatchNoRefreshIndex == -1 && compareVideoStreamResolution(resolutionNoRefresh, targetResolutionNoRefresh) < 0) {
|
||||
lowerResMatchNoRefreshIndex = idx;
|
||||
}
|
||||
}
|
||||
|
||||
return defaultStreamIndex;
|
||||
if (fullMatchIndex != -1) {
|
||||
return fullMatchIndex;
|
||||
}
|
||||
if (fullMatchNoRefreshIndex != -1) {
|
||||
return fullMatchNoRefreshIndex;
|
||||
}
|
||||
if (resMatchOnlyIndex != -1) {
|
||||
return resMatchOnlyIndex;
|
||||
}
|
||||
if (resMatchOnlyNoRefreshIndex != -1) {
|
||||
return resMatchOnlyNoRefreshIndex;
|
||||
}
|
||||
return lowerResMatchNoRefreshIndex;
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetches the desired resolution or returns the default if it is not found. The resolution
|
||||
* will be reduced if video chocking is active.
|
||||
*/
|
||||
private static int getDefaultResolutionWithDefaultFormat(Context context, String defaultResolution, List<VideoStream> videoStreams) {
|
||||
MediaFormat defaultFormat = getDefaultFormat(context, R.string.default_video_format_key, R.string.default_video_format_value);
|
||||
return getDefaultResolutionIndex(defaultResolution, context.getString(R.string.best_resolution_key), defaultFormat, videoStreams);
|
||||
|
@ -280,4 +369,85 @@ public final class ListHelper {
|
|||
}
|
||||
return format;
|
||||
}
|
||||
|
||||
// Compares the quality of two audio streams
|
||||
private static int compareAudioStreamBitrate(AudioStream streamA, AudioStream streamB,
|
||||
List<MediaFormat> formatRanking) {
|
||||
if (streamA == null) {
|
||||
return -1;
|
||||
}
|
||||
if (streamB == null) {
|
||||
return 1;
|
||||
}
|
||||
if (streamA.getAverageBitrate() < streamB.getAverageBitrate()) {
|
||||
return -1;
|
||||
}
|
||||
if (streamA.getAverageBitrate() > streamB.getAverageBitrate()) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Same bitrate and format
|
||||
return formatRanking.indexOf(streamA.getFormat()) - formatRanking.indexOf(streamB.getFormat());
|
||||
}
|
||||
|
||||
private static int compareVideoStreamResolution(String r1, String r2) {
|
||||
int res1 = Integer.parseInt(r1.replaceAll("0p\\d+$", "1")
|
||||
.replaceAll("[^\\d.]", ""));
|
||||
int res2 = Integer.parseInt(r2.replaceAll("0p\\d+$", "1")
|
||||
.replaceAll("[^\\d.]", ""));
|
||||
return res1 - res2;
|
||||
}
|
||||
|
||||
// Compares the quality of two video streams.
|
||||
private static int compareVideoStreamResolution(VideoStream streamA, VideoStream streamB,
|
||||
List<MediaFormat> formatRanking) {
|
||||
if (streamA == null) {
|
||||
return -1;
|
||||
}
|
||||
if (streamB == null) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
int resComp = compareVideoStreamResolution(streamA.getResolution(), streamB.getResolution());
|
||||
if (resComp != 0) {
|
||||
return resComp;
|
||||
}
|
||||
|
||||
// Same bitrate and format
|
||||
return formatRanking.indexOf(streamA.getFormat()) - formatRanking.indexOf(streamB.getFormat());
|
||||
}
|
||||
|
||||
|
||||
|
||||
private static boolean isLimitingDataUsage(Context context) {
|
||||
return getResolutionLimit(context) != null;
|
||||
}
|
||||
|
||||
/**
|
||||
* The maximum resolution allowed
|
||||
* @param context App context
|
||||
* @return maximum resolution allowed or null if there is no maximum
|
||||
*/
|
||||
private static String getResolutionLimit(Context context) {
|
||||
String resolutionLimit = null;
|
||||
if (!isWifiActive(context)) {
|
||||
SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(context);
|
||||
String defValue = context.getString(R.string.limit_data_usage_none_key);
|
||||
String value = preferences.getString(
|
||||
context.getString(R.string.limit_mobile_data_usage_key), defValue);
|
||||
resolutionLimit = value.equals(defValue) ? null : value;
|
||||
}
|
||||
return resolutionLimit;
|
||||
}
|
||||
|
||||
/**
|
||||
* Are we connected to wifi?
|
||||
* @param context App context
|
||||
* @return True if connected to wifi
|
||||
*/
|
||||
private static boolean isWifiActive(Context context)
|
||||
{
|
||||
ConnectivityManager manager = (ConnectivityManager)context.getSystemService(Context.CONNECTIVITY_SERVICE);
|
||||
return manager.getActiveNetworkInfo().getType() == ConnectivityManager.TYPE_WIFI;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -853,4 +853,22 @@
|
|||
<item>ZM</item>
|
||||
<item>ZW</item>
|
||||
</string-array>
|
||||
|
||||
<!-- Limit mobile data usage -->
|
||||
<string name="limit_mobile_data_usage_key" translatable="false">limit_mobile_data_usage</string>
|
||||
<string name="limit_data_usage_none_key" translatable="false">limit_data_usage_none</string>
|
||||
|
||||
<string-array name="limit_data_usage_values_list">
|
||||
<item>@string/limit_data_usage_none_key</item>
|
||||
<item>1080p60</item>
|
||||
<item>1080p</item>
|
||||
<item>720p60</item>
|
||||
<item>720p</item>
|
||||
<item>480p</item>
|
||||
<item>360p</item>
|
||||
<item>240p</item>
|
||||
<item>144p</item>
|
||||
</string-array>
|
||||
|
||||
|
||||
</resources>
|
|
@ -483,8 +483,25 @@
|
|||
<string name="playback_nightcore">Nightcore</string>
|
||||
<string name="playback_default">Default</string>
|
||||
|
||||
<!-- Start dialogs -->
|
||||
<!-- GDPR dialog -->
|
||||
<string name="start_accept_privacy_policy">In order to comply with the European General Data Protection Regulation (GDPR), we herby draw your attention to NewPipe\'s privacy policy. Please read it carefully.\nYou must accept it to send us the bug report.</string>
|
||||
<string name="accept">Accept</string>
|
||||
<string name="decline">Decline</string>
|
||||
|
||||
<!-- Limit mobile data usage -->
|
||||
<string name="limit_data_usage_none_description">No limit</string>
|
||||
<string name="limit_mobile_data_usage_title">Limit resolution when using mobile data</string>
|
||||
<string name="limit_mobile_data_usage_value" translatable="false">@string/limit_data_usage_none_key</string>
|
||||
<string-array name="limit_data_usage_description_list">
|
||||
<item>@string/limit_data_usage_none_description</item>
|
||||
<item>1080p60</item>
|
||||
<item>1080p</item>
|
||||
<item>720p60</item>
|
||||
<item>720p</item>
|
||||
<item>480p</item>
|
||||
<item>360p</item>
|
||||
<item>240p</item>
|
||||
<item>144p</item>
|
||||
</string-array>
|
||||
|
||||
</resources>
|
||||
|
|
|
@ -19,6 +19,14 @@
|
|||
android:summary="%s"
|
||||
android:title="@string/default_popup_resolution_title"/>
|
||||
|
||||
<ListPreference
|
||||
android:defaultValue="@string/limit_mobile_data_usage_value"
|
||||
android:entries="@array/limit_data_usage_description_list"
|
||||
android:entryValues="@array/limit_data_usage_values_list"
|
||||
android:key="@string/limit_mobile_data_usage_key"
|
||||
android:summary="%s"
|
||||
android:title="@string/limit_mobile_data_usage_title" />
|
||||
|
||||
<SwitchPreference
|
||||
android:defaultValue="false"
|
||||
android:key="@string/show_higher_resolutions_key"
|
||||
|
@ -39,7 +47,7 @@
|
|||
android:entryValues="@array/audio_format_values_list"
|
||||
android:key="@string/default_audio_format_key"
|
||||
android:summary="%s"
|
||||
android:title="@string/default_audio_format_title"/>
|
||||
android:title="@string/default_audio_format_title" />
|
||||
|
||||
<PreferenceCategory
|
||||
android:layout="@layout/settings_category_header_layout"
|
||||
|
|
|
@ -129,11 +129,6 @@ public class ListHelperTest {
|
|||
assertEquals(MediaFormat.MPEG_4, result.getFormat());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getHighestQualityAudioTest() throws Exception {
|
||||
assertEquals(320, ListHelper.getHighestQualityAudio(audioStreamsTestList).average_bitrate);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getHighestQualityAudioFormatTest() throws Exception {
|
||||
AudioStream stream = audioStreamsTestList.get(ListHelper.getHighestQualityAudioIndex(MediaFormat.M4A, audioStreamsTestList));
|
||||
|
@ -174,19 +169,20 @@ public class ListHelperTest {
|
|||
new AudioStream("", MediaFormat.WEBMA, /**/ 192),
|
||||
new AudioStream("", MediaFormat.M4A, /**/ 192),
|
||||
new AudioStream("", MediaFormat.WEBMA, /**/ 192),
|
||||
new AudioStream("", MediaFormat.M4A, /**/ 192)));
|
||||
// List doesn't contains this format, it should fallback to the highest bitrate audio no matter what format it is
|
||||
// and as it have multiple with the same high value, the last one wins
|
||||
new AudioStream("", MediaFormat.M4A, /**/ 192),
|
||||
new AudioStream("", MediaFormat.WEBMA, /**/ 192)));
|
||||
// List doesn't contains this format, it should fallback to the highest bitrate audio and
|
||||
// the highest quality format.
|
||||
stream = testList.get(ListHelper.getHighestQualityAudioIndex(MediaFormat.MP3, testList));
|
||||
assertEquals(192, stream.average_bitrate);
|
||||
assertEquals(MediaFormat.M4A, stream.getFormat());
|
||||
|
||||
|
||||
// Again with a new element
|
||||
// Adding a new format and bitrate. Adding another stream will have no impact since
|
||||
// it's not a prefered format.
|
||||
testList.add(new AudioStream("", MediaFormat.WEBMA, /**/ 192));
|
||||
stream = testList.get(ListHelper.getHighestQualityAudioIndex(MediaFormat.MP3, testList));
|
||||
assertEquals(192, stream.average_bitrate);
|
||||
assertEquals(MediaFormat.WEBMA, stream.getFormat());
|
||||
assertEquals(MediaFormat.M4A, stream.getFormat());
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -195,5 +191,111 @@ public class ListHelperTest {
|
|||
assertEquals(-1, ListHelper.getHighestQualityAudioIndex(null, new ArrayList<AudioStream>()));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getLowestQualityAudioFormatTest() throws Exception {
|
||||
AudioStream stream = audioStreamsTestList.get(ListHelper.getMostCompactAudioIndex(MediaFormat.M4A, audioStreamsTestList));
|
||||
assertEquals(128, stream.average_bitrate);
|
||||
assertEquals(MediaFormat.M4A, stream.getFormat());
|
||||
|
||||
stream = audioStreamsTestList.get(ListHelper.getMostCompactAudioIndex(MediaFormat.WEBMA, audioStreamsTestList));
|
||||
assertEquals(64, stream.average_bitrate);
|
||||
assertEquals(MediaFormat.WEBMA, stream.getFormat());
|
||||
|
||||
stream = audioStreamsTestList.get(ListHelper.getMostCompactAudioIndex(MediaFormat.MP3, audioStreamsTestList));
|
||||
assertEquals(64, stream.average_bitrate);
|
||||
assertEquals(MediaFormat.MP3, stream.getFormat());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getLowestQualityAudioFormatPreferredAbsent() throws Exception {
|
||||
|
||||
//////////////////////////////////////////
|
||||
// Doesn't contain the preferred format //
|
||||
////////////////////////////////////////
|
||||
|
||||
List<AudioStream> testList = new ArrayList<>(Arrays.asList(
|
||||
new AudioStream("", MediaFormat.M4A, /**/ 128),
|
||||
new AudioStream("", MediaFormat.WEBMA, /**/ 192)));
|
||||
// List doesn't contains this format, it should fallback to the most compact audio no matter what format it is.
|
||||
AudioStream stream = testList.get(ListHelper.getMostCompactAudioIndex(MediaFormat.MP3, testList));
|
||||
assertEquals(128, stream.average_bitrate);
|
||||
assertEquals(MediaFormat.M4A, stream.getFormat());
|
||||
|
||||
// WEBMA is more compact than M4A
|
||||
testList.add(new AudioStream("", MediaFormat.WEBMA, /**/ 128));
|
||||
stream = testList.get(ListHelper.getMostCompactAudioIndex(MediaFormat.MP3, testList));
|
||||
assertEquals(128, stream.average_bitrate);
|
||||
assertEquals(MediaFormat.WEBMA, stream.getFormat());
|
||||
|
||||
////////////////////////////////////////////////////////
|
||||
// Multiple not-preferred-formats and equal bitrates //
|
||||
//////////////////////////////////////////////////////
|
||||
|
||||
testList = new ArrayList<>(Arrays.asList(
|
||||
new AudioStream("", MediaFormat.WEBMA, /**/ 192),
|
||||
new AudioStream("", MediaFormat.M4A, /**/ 192),
|
||||
new AudioStream("", MediaFormat.WEBMA, /**/ 256),
|
||||
new AudioStream("", MediaFormat.M4A, /**/ 192),
|
||||
new AudioStream("", MediaFormat.WEBMA, /**/ 192),
|
||||
new AudioStream("", MediaFormat.M4A, /**/ 192)));
|
||||
// List doesn't contains this format, it should fallback to the most compact audio no matter what format it is.
|
||||
stream = testList.get(ListHelper.getMostCompactAudioIndex(MediaFormat.MP3, testList));
|
||||
assertEquals(192, stream.average_bitrate);
|
||||
assertEquals(MediaFormat.WEBMA, stream.getFormat());
|
||||
|
||||
// Should be same as above
|
||||
stream = testList.get(ListHelper.getMostCompactAudioIndex(null, testList));
|
||||
assertEquals(192, stream.average_bitrate);
|
||||
assertEquals(MediaFormat.WEBMA, stream.getFormat());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getLowestQualityAudioNull() throws Exception {
|
||||
assertEquals(-1, ListHelper.getMostCompactAudioIndex(null, null));
|
||||
assertEquals(-1, ListHelper.getMostCompactAudioIndex(null, new ArrayList<AudioStream>()));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getVideoDefaultStreamIndexCombinations() throws Exception {
|
||||
List<VideoStream> testList = Arrays.asList(
|
||||
new VideoStream("", MediaFormat.MPEG_4, /**/ "1080p"),
|
||||
new VideoStream("", MediaFormat.MPEG_4, /**/ "720p60"),
|
||||
new VideoStream("", MediaFormat.MPEG_4, /**/ "720p"),
|
||||
new VideoStream("", MediaFormat.WEBM, /**/ "480p"),
|
||||
new VideoStream("", MediaFormat.MPEG_4, /**/ "360p"),
|
||||
new VideoStream("", MediaFormat.WEBM, /**/ "360p"),
|
||||
new VideoStream("", MediaFormat.v3GPP, /**/ "240p60"),
|
||||
new VideoStream("", MediaFormat.WEBM, /**/ "144p"));
|
||||
|
||||
// exact matches
|
||||
assertEquals(1, ListHelper.getVideoStreamIndex("720p60", MediaFormat.MPEG_4, testList));
|
||||
assertEquals(2, ListHelper.getVideoStreamIndex("720p", MediaFormat.MPEG_4, testList));
|
||||
|
||||
// match but not refresh
|
||||
assertEquals(0, ListHelper.getVideoStreamIndex("1080p60", MediaFormat.MPEG_4, testList));
|
||||
assertEquals(6, ListHelper.getVideoStreamIndex("240p", MediaFormat.v3GPP, testList));
|
||||
|
||||
// match but not format
|
||||
assertEquals(1, ListHelper.getVideoStreamIndex("720p60", MediaFormat.WEBM, testList));
|
||||
assertEquals(2, ListHelper.getVideoStreamIndex("720p", MediaFormat.WEBM, testList));
|
||||
assertEquals(1, ListHelper.getVideoStreamIndex("720p60", null, testList));
|
||||
assertEquals(2, ListHelper.getVideoStreamIndex("720p", null, testList));
|
||||
|
||||
// match but not format and not refresh
|
||||
assertEquals(0, ListHelper.getVideoStreamIndex("1080p60", MediaFormat.WEBM, testList));
|
||||
assertEquals(6, ListHelper.getVideoStreamIndex("240p", MediaFormat.WEBM, testList));
|
||||
assertEquals(0, ListHelper.getVideoStreamIndex("1080p60", null, testList));
|
||||
assertEquals(6, ListHelper.getVideoStreamIndex("240p", null, testList));
|
||||
|
||||
// match closest lower resolution
|
||||
assertEquals(7, ListHelper.getVideoStreamIndex("200p", MediaFormat.WEBM, testList));
|
||||
assertEquals(7, ListHelper.getVideoStreamIndex("200p60", MediaFormat.WEBM, testList));
|
||||
assertEquals(7, ListHelper.getVideoStreamIndex("200p", MediaFormat.MPEG_4, testList));
|
||||
assertEquals(7, ListHelper.getVideoStreamIndex("200p60", MediaFormat.MPEG_4, testList));
|
||||
assertEquals(7, ListHelper.getVideoStreamIndex("200p", null, testList));
|
||||
assertEquals(7, ListHelper.getVideoStreamIndex("200p60", null, testList));
|
||||
|
||||
// Can't find a match
|
||||
assertEquals(-1, ListHelper.getVideoStreamIndex("100p", null, testList));
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue