Skip to content

Commit 9f3d07a

Browse files
committed
Add extractor engine setting
1 parent d914447 commit 9f3d07a

7 files changed

Lines changed: 166 additions & 6 deletions

File tree

app/src/main/java/org/schabi/newpipe/App.kt

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -30,12 +30,12 @@ import org.acra.ACRA.init
3030
import org.acra.ACRA.isACRASenderServiceProcess
3131
import org.acra.config.CoreConfigurationBuilder
3232
import org.schabi.newpipe.error.ReCaptchaActivity
33-
import org.schabi.newpipe.extractor.NewPipe
3433
import org.schabi.newpipe.extractor.downloader.Downloader
3534
import org.schabi.newpipe.extractor.services.youtube.extractors.YoutubeStreamExtractor
3635
import org.schabi.newpipe.ktx.hasAssignableCause
3736
import org.schabi.newpipe.settings.NewPipeSettings
3837
import org.schabi.newpipe.util.BridgeStateSaverInitializer
38+
import org.schabi.newpipe.util.ExtractorEngineHelper
3939
import org.schabi.newpipe.util.Localization
4040
import org.schabi.newpipe.util.ServiceHelper
4141
import org.schabi.newpipe.util.StateSaver
@@ -100,11 +100,7 @@ open class App :
100100
NewPipeSettings.initSettings(this)
101101
applyDynamicColorsIfAvailable()
102102

103-
NewPipe.init(
104-
getDownloader(),
105-
Localization.getPreferredLocalization(this),
106-
Localization.getPreferredContentCountry(this)
107-
)
103+
ExtractorEngineHelper.initSelectedEngine(this, getDownloader())
108104
Localization.initPrettyTime(Localization.resolvePrettyTime())
109105

110106
BridgeStateSaverInitializer.init(this)

app/src/main/java/org/schabi/newpipe/settings/VideoAudioSettingsFragment.java

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package org.schabi.newpipe.settings;
22

3+
import android.app.Activity;
34
import android.content.SharedPreferences;
45
import android.content.res.Resources;
56
import android.os.Bundle;
@@ -9,10 +10,12 @@
910

1011
import androidx.preference.ListPreference;
1112

13+
import com.google.android.material.dialog.MaterialAlertDialogBuilder;
1214
import com.google.android.material.snackbar.Snackbar;
1315

1416
import org.schabi.newpipe.R;
1517
import org.schabi.newpipe.util.ListHelper;
18+
import org.schabi.newpipe.util.NavigationHelper;
1619
import org.schabi.newpipe.util.PermissionHelper;
1720

1821
import java.util.LinkedList;
@@ -49,10 +52,28 @@ public void onCreatePreferences(final Bundle savedInstanceState, final String ro
4952
updateSeekOptions();
5053
} else if (getString(R.string.show_higher_resolutions_key).equals(key)) {
5154
updateResolutionOptions();
55+
} else if (getString(R.string.extractor_engine_key).equals(key)) {
56+
showExtractorEngineRestartDialog();
5257
}
5358
};
5459
}
5560

61+
private void showExtractorEngineRestartDialog() {
62+
final Activity activity = getActivity();
63+
if (activity == null) {
64+
return;
65+
}
66+
67+
new MaterialAlertDialogBuilder(activity)
68+
.setTitle(R.string.extractor_engine_restart_dialog_title)
69+
.setMessage(R.string.extractor_engine_restart_dialog_message)
70+
.setPositiveButton(R.string.extractor_engine_restart_now,
71+
(dialog, which) -> NavigationHelper.restartApp(activity))
72+
.setNegativeButton(R.string.extractor_engine_restart_later,
73+
(dialog, which) -> dialog.dismiss())
74+
.show();
75+
}
76+
5677
/**
5778
* Update default resolution, default popup resolution & mobile data resolution options.
5879
* <br />
Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
package org.schabi.newpipe.util
2+
3+
import android.content.Context
4+
import android.content.SharedPreferences
5+
import android.util.Log
6+
import androidx.preference.PreferenceManager
7+
import org.schabi.newpipe.R
8+
import org.schabi.newpipe.extractor.NewPipe
9+
import org.schabi.newpipe.extractor.downloader.Downloader
10+
11+
object ExtractorEngineHelper {
12+
private const val TAG = "ExtractorEngineHelper"
13+
14+
enum class Engine {
15+
NEWPIPE,
16+
PIPEPIPE
17+
}
18+
19+
@JvmStatic
20+
fun parsePreferenceValue(
21+
value: String?,
22+
newPipeValue: String,
23+
pipePipeValue: String
24+
): Engine = when (value) {
25+
pipePipeValue -> Engine.PIPEPIPE
26+
newPipeValue -> Engine.NEWPIPE
27+
else -> Engine.NEWPIPE
28+
}
29+
30+
@JvmStatic
31+
fun getSelectedEngine(context: Context): Engine = getSelectedEngine(
32+
context,
33+
PreferenceManager.getDefaultSharedPreferences(context)
34+
)
35+
36+
@JvmStatic
37+
fun getSelectedEngine(context: Context, preferences: SharedPreferences): Engine {
38+
val newPipeValue = context.getString(R.string.extractor_engine_newpipe_value)
39+
val selectedValue = preferences.getString(
40+
context.getString(R.string.extractor_engine_key),
41+
context.getString(R.string.extractor_engine_default_value)
42+
)
43+
return parsePreferenceValue(
44+
selectedValue,
45+
newPipeValue,
46+
context.getString(R.string.extractor_engine_pipepipe_value)
47+
).also { engine ->
48+
if (engine == Engine.NEWPIPE && selectedValue != null && selectedValue != newPipeValue) {
49+
Log.w(TAG, "Unknown extractor engine preference '$selectedValue'; using NewPipe Extractor")
50+
}
51+
}
52+
}
53+
54+
@JvmStatic
55+
fun initSelectedEngine(context: Context, downloader: Downloader) {
56+
val localization = Localization.getPreferredLocalization(context)
57+
val contentCountry = Localization.getPreferredContentCountry(context)
58+
when (getSelectedEngine(context)) {
59+
Engine.NEWPIPE -> NewPipe.init(downloader, localization, contentCountry)
60+
61+
Engine.PIPEPIPE -> {
62+
Log.w(
63+
TAG,
64+
"PipePipe Extractor cannot be initialized from the current classpath " +
65+
"because the verified PipePipeExtractor source uses the same " +
66+
"org.schabi.newpipe.extractor packages/classes as NewPipe Extractor; " +
67+
"falling back to NewPipe Extractor"
68+
)
69+
try {
70+
NewPipe.init(downloader, localization, contentCountry)
71+
} catch (throwable: Throwable) {
72+
Log.e(TAG, "Fallback NewPipe Extractor initialization failed", throwable)
73+
throw throwable
74+
}
75+
}
76+
}
77+
}
78+
}

app/src/main/res/values/settings_keys.xml

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,19 @@
120120
<item>@string/dont_show</item>
121121
</string-array>
122122

123+
<string name="extractor_engine_key">extractor_engine</string>
124+
<string name="extractor_engine_default_value">newpipe</string>
125+
<string name="extractor_engine_newpipe_value">newpipe</string>
126+
<string name="extractor_engine_pipepipe_value">pipepipe</string>
127+
<string-array name="extractor_engine_entries">
128+
<item>@string/extractor_engine_newpipe</item>
129+
<item>@string/extractor_engine_pipepipe</item>
130+
</string-array>
131+
<string-array name="extractor_engine_values">
132+
<item>@string/extractor_engine_newpipe_value</item>
133+
<item>@string/extractor_engine_pipepipe_value</item>
134+
</string-array>
135+
123136
<string name="default_resolution_key">default_resolution</string>
124137
<string name="default_resolution_value">720p60</string>
125138
<string name="show_higher_resolutions_key">show_higher_resolutions</string>

app/src/main/res/values/strings.xml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,13 @@
4747
<string name="download_path_audio_title">Audio download folder</string>
4848
<string name="download_path_audio_summary">Downloaded audio files are stored here</string>
4949
<string name="download_path_audio_dialog_title">Choose download folder for audio files</string>
50+
<string name="extractor_engine_title">Engine</string>
51+
<string name="extractor_engine_newpipe">NewPipe Extractor</string>
52+
<string name="extractor_engine_pipepipe">PipePipe Extractor</string>
53+
<string name="extractor_engine_restart_dialog_title">Restart required</string>
54+
<string name="extractor_engine_restart_dialog_message">The selected engine has been saved. Restart the app to apply this change.</string>
55+
<string name="extractor_engine_restart_now">Restart now</string>
56+
<string name="extractor_engine_restart_later">Later</string>
5057
<string name="default_resolution_title">Default resolution</string>
5158
<string name="default_popup_resolution_title">Default popup resolution</string>
5259
<string name="show_higher_resolutions_title">Show higher resolutions</string>

app/src/main/res/xml/video_audio_settings.xml

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,16 @@
33
xmlns:app="http://schemas.android.com/apk/res-auto"
44
android:title="@string/settings_category_video_audio_title">
55

6+
<ListPreference
7+
android:defaultValue="@string/extractor_engine_default_value"
8+
android:entries="@array/extractor_engine_entries"
9+
android:entryValues="@array/extractor_engine_values"
10+
android:key="@string/extractor_engine_key"
11+
android:title="@string/extractor_engine_title"
12+
app:singleLineTitle="false"
13+
app:iconSpaceReserved="false"
14+
app:useSimpleSummaryProvider="true" />
15+
616
<ListPreference
717
android:defaultValue="@string/default_resolution_value"
818
android:entries="@array/resolution_list_description"
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
package org.schabi.newpipe.util
2+
3+
import org.junit.Assert.assertEquals
4+
import org.junit.Test
5+
6+
class ExtractorEngineHelperTest {
7+
@Test
8+
fun parsePreferenceValueDefaultsToNewPipeWhenMissing() {
9+
assertEquals(
10+
ExtractorEngineHelper.Engine.NEWPIPE,
11+
ExtractorEngineHelper.parsePreferenceValue(null, NEWPIPE_VALUE, PIPEPIPE_VALUE)
12+
)
13+
}
14+
15+
@Test
16+
fun parsePreferenceValueFallsBackToNewPipeWhenInvalid() {
17+
assertEquals(
18+
ExtractorEngineHelper.Engine.NEWPIPE,
19+
ExtractorEngineHelper.parsePreferenceValue("unexpected", NEWPIPE_VALUE, PIPEPIPE_VALUE)
20+
)
21+
}
22+
23+
@Test
24+
fun parsePreferenceValueParsesPipePipe() {
25+
assertEquals(
26+
ExtractorEngineHelper.Engine.PIPEPIPE,
27+
ExtractorEngineHelper.parsePreferenceValue(PIPEPIPE_VALUE, NEWPIPE_VALUE, PIPEPIPE_VALUE)
28+
)
29+
}
30+
31+
companion object {
32+
private const val NEWPIPE_VALUE = "newpipe"
33+
private const val PIPEPIPE_VALUE = "pipepipe"
34+
}
35+
}

0 commit comments

Comments
 (0)