Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added the ability to limit video quality if using mobile data. #1339

Merged
merged 2 commits into from
May 27, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -645,7 +645,7 @@ protected int getDefaultResolutionIndex(final List<VideoStream> sortedVideos) {
@Override
protected int getOverrideResolutionIndex(final List<VideoStream> sortedVideos,
final String playbackQuality) {
return ListHelper.getDefaultResolutionIndex(context, sortedVideos, playbackQuality);
return ListHelper.getResolutionIndex(context, sortedVideos, playbackQuality);
}

/*//////////////////////////////////////////////////////////////////////////
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -509,7 +509,7 @@ protected int getDefaultResolutionIndex(final List<VideoStream> sortedVideos) {
@Override
protected int getOverrideResolutionIndex(final List<VideoStream> sortedVideos,
final String playbackQuality) {
return ListHelper.getPopupDefaultResolutionIndex(context, sortedVideos, playbackQuality);
return ListHelper.getPopupResolutionIndex(context, sortedVideos, playbackQuality);
}

/*//////////////////////////////////////////////////////////////////////////
Expand Down
382 changes: 276 additions & 106 deletions app/src/main/java/org/schabi/newpipe/util/ListHelper.java

Large diffs are not rendered by default.

5 changes: 5 additions & 0 deletions app/src/main/res/values/settings_keys.xml
Original file line number Diff line number Diff line change
Expand Up @@ -851,4 +851,9 @@
<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>

</resources>
28 changes: 28 additions & 0 deletions app/src/main/res/values/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -466,4 +466,32 @@
<string name="unhook_checkbox">Unhook (may cause distortion)</string>
<string name="playback_nightcore">Nightcore</string>
<string name="playback_default">Default</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>
<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>
10 changes: 9 additions & 1 deletion app/src/main/res/xml/video_audio_settings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand All @@ -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"
Expand Down
124 changes: 113 additions & 11 deletions app/src/test/java/org/schabi/newpipe/util/ListHelperTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -129,11 +129,6 @@ public void getDefaultResolutionTest() throws Exception {
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));
Expand Down Expand Up @@ -174,19 +169,20 @@ public void getHighestQualityAudioFormatPreferredAbsent() throws Exception {
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
Expand All @@ -195,5 +191,111 @@ public void getHighestQualityAudioNull() throws Exception {
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));
}
}