Merge 2d1823f2a15262a16be62f29f57a8b19229024e0 into 4481dd7fe6dd8c9bd116c391aed544de6239c640
This commit is contained in:
commit
53f150e46b
@ -26,7 +26,8 @@ class DebugApp : App() {
|
||||
override fun getDownloader(): Downloader {
|
||||
val downloader = DownloaderImpl.init(
|
||||
OkHttpClient.Builder()
|
||||
.addNetworkInterceptor(StethoInterceptor())
|
||||
.addNetworkInterceptor(StethoInterceptor()),
|
||||
this
|
||||
)
|
||||
setCookiesToDownloader(downloader)
|
||||
return downloader
|
||||
|
||||
@ -141,7 +141,7 @@ public class App extends Application {
|
||||
}
|
||||
|
||||
protected Downloader getDownloader() {
|
||||
final DownloaderImpl downloader = DownloaderImpl.init(null);
|
||||
final DownloaderImpl downloader = DownloaderImpl.init(null, this);
|
||||
setCookiesToDownloader(downloader);
|
||||
return downloader;
|
||||
}
|
||||
|
||||
@ -11,6 +11,7 @@ import org.schabi.newpipe.extractor.downloader.Downloader;
|
||||
import org.schabi.newpipe.extractor.downloader.Request;
|
||||
import org.schabi.newpipe.extractor.downloader.Response;
|
||||
import org.schabi.newpipe.extractor.exceptions.ReCaptchaException;
|
||||
import org.schabi.newpipe.util.ProxyManager;
|
||||
import org.schabi.newpipe.util.InfoCache;
|
||||
|
||||
import java.io.IOException;
|
||||
@ -52,11 +53,18 @@ public final class DownloaderImpl extends Downloader {
|
||||
* It's recommended to call exactly once in the entire lifetime of the application.
|
||||
*
|
||||
* @param builder if null, default builder will be used
|
||||
* @param context the context to use
|
||||
* @return a new instance of {@link DownloaderImpl}
|
||||
*/
|
||||
public static DownloaderImpl init(@Nullable final OkHttpClient.Builder builder) {
|
||||
instance = new DownloaderImpl(
|
||||
builder != null ? builder : new OkHttpClient.Builder());
|
||||
public static DownloaderImpl init(@Nullable final OkHttpClient.Builder builder,
|
||||
final Context context) {
|
||||
final OkHttpClient.Builder builderToUse = builder != null ? builder
|
||||
: new OkHttpClient.Builder();
|
||||
final ProxyManager proxyManager = new ProxyManager(context);
|
||||
if (proxyManager.isProxyEnabled()) {
|
||||
builderToUse.proxy(proxyManager.getProxy());
|
||||
}
|
||||
instance = new DownloaderImpl(builderToUse);
|
||||
return instance;
|
||||
}
|
||||
|
||||
|
||||
@ -20,6 +20,7 @@ import static org.schabi.newpipe.extractor.services.youtube.YoutubeParsingHelper
|
||||
import static org.schabi.newpipe.extractor.services.youtube.YoutubeParsingHelper.isWebEmbeddedPlayerStreamingUrl;
|
||||
import static java.lang.Math.min;
|
||||
|
||||
import android.content.Context;
|
||||
import android.net.Uri;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
@ -45,6 +46,7 @@ import com.google.common.collect.Sets;
|
||||
import com.google.common.net.HttpHeaders;
|
||||
|
||||
import org.schabi.newpipe.DownloaderImpl;
|
||||
import org.schabi.newpipe.util.ProxyManager;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
@ -54,6 +56,7 @@ import java.lang.reflect.Method;
|
||||
import java.net.HttpURLConnection;
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.NoRouteToHostException;
|
||||
import java.net.Proxy;
|
||||
import java.net.URL;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
@ -84,6 +87,7 @@ public final class YoutubeHttpDataSource extends BaseDataSource implements HttpD
|
||||
*/
|
||||
public static final class Factory implements HttpDataSource.Factory {
|
||||
|
||||
private final Context context;
|
||||
private final RequestProperties defaultRequestProperties;
|
||||
|
||||
@Nullable
|
||||
@ -100,8 +104,10 @@ public final class YoutubeHttpDataSource extends BaseDataSource implements HttpD
|
||||
|
||||
/**
|
||||
* Creates an instance.
|
||||
* @param context the context to use
|
||||
*/
|
||||
public Factory() {
|
||||
public Factory(final Context context) {
|
||||
this.context = context;
|
||||
defaultRequestProperties = new RequestProperties();
|
||||
connectTimeoutMs = DEFAULT_CONNECT_TIMEOUT_MILLIS;
|
||||
readTimeoutMs = DEFAULT_READ_TIMEOUT_MILLIS;
|
||||
@ -220,7 +226,6 @@ public final class YoutubeHttpDataSource extends BaseDataSource implements HttpD
|
||||
* <p>The default is {@code null}.
|
||||
*
|
||||
* <p>See {@link DataSource#addTransferListener(TransferListener)}.
|
||||
*
|
||||
* @param transferListenerToUse The listener that will be used.
|
||||
* @return This factory.
|
||||
*/
|
||||
@ -247,6 +252,7 @@ public final class YoutubeHttpDataSource extends BaseDataSource implements HttpD
|
||||
@Override
|
||||
public YoutubeHttpDataSource createDataSource() {
|
||||
final YoutubeHttpDataSource dataSource = new YoutubeHttpDataSource(
|
||||
context,
|
||||
connectTimeoutMs,
|
||||
readTimeoutMs,
|
||||
allowCrossProtocolRedirects,
|
||||
@ -272,6 +278,7 @@ public final class YoutubeHttpDataSource extends BaseDataSource implements HttpD
|
||||
private static final String YOUTUBE_BASE_URL = "https://www.youtube.com";
|
||||
private static final byte[] POST_BODY = new byte[] {0x78, 0};
|
||||
|
||||
private final Context context;
|
||||
private final boolean allowCrossProtocolRedirects;
|
||||
private final boolean rangeParameterEnabled;
|
||||
private final boolean rnParameterEnabled;
|
||||
@ -299,7 +306,8 @@ public final class YoutubeHttpDataSource extends BaseDataSource implements HttpD
|
||||
private long requestNumber;
|
||||
|
||||
@SuppressWarnings("checkstyle:ParameterNumber")
|
||||
private YoutubeHttpDataSource(final int connectTimeoutMillis,
|
||||
private YoutubeHttpDataSource(final Context context,
|
||||
final int connectTimeoutMillis,
|
||||
final int readTimeoutMillis,
|
||||
final boolean allowCrossProtocolRedirects,
|
||||
final boolean rangeParameterEnabled,
|
||||
@ -308,6 +316,7 @@ public final class YoutubeHttpDataSource extends BaseDataSource implements HttpD
|
||||
@Nullable final Predicate<String> contentTypePredicate,
|
||||
final boolean keepPostFor302Redirects) {
|
||||
super(true);
|
||||
this.context = context;
|
||||
this.connectTimeoutMillis = connectTimeoutMillis;
|
||||
this.readTimeoutMillis = readTimeoutMillis;
|
||||
this.allowCrossProtocolRedirects = allowCrossProtocolRedirects;
|
||||
@ -708,6 +717,11 @@ public final class YoutubeHttpDataSource extends BaseDataSource implements HttpD
|
||||
* @return an {@link HttpURLConnection} created with the {@code url}
|
||||
*/
|
||||
private HttpURLConnection openConnection(@NonNull final URL url) throws IOException {
|
||||
final ProxyManager proxyManager = new ProxyManager(context);
|
||||
final Proxy proxy = proxyManager.getProxy();
|
||||
if (proxy != null) {
|
||||
return (HttpURLConnection) url.openConnection(proxy);
|
||||
}
|
||||
return (HttpURLConnection) url.openConnection();
|
||||
}
|
||||
|
||||
@ -1006,4 +1020,3 @@ public final class YoutubeHttpDataSource extends BaseDataSource implements HttpD
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -18,12 +18,10 @@ import com.google.android.exoplayer2.source.smoothstreaming.DefaultSsChunkSource
|
||||
import com.google.android.exoplayer2.source.smoothstreaming.SsMediaSource;
|
||||
import com.google.android.exoplayer2.upstream.DataSource;
|
||||
import com.google.android.exoplayer2.upstream.DefaultDataSource;
|
||||
import com.google.android.exoplayer2.upstream.DefaultHttpDataSource;
|
||||
import com.google.android.exoplayer2.upstream.TransferListener;
|
||||
import com.google.android.exoplayer2.upstream.cache.LeastRecentlyUsedCacheEvictor;
|
||||
import com.google.android.exoplayer2.upstream.cache.SimpleCache;
|
||||
|
||||
import org.schabi.newpipe.DownloaderImpl;
|
||||
import org.schabi.newpipe.extractor.services.youtube.dashmanifestcreators.YoutubeOtfDashManifestCreator;
|
||||
import org.schabi.newpipe.extractor.services.youtube.dashmanifestcreators.YoutubePostLiveStreamDvrDashManifestCreator;
|
||||
import org.schabi.newpipe.extractor.services.youtube.dashmanifestcreators.YoutubeProgressiveDashManifestCreator;
|
||||
@ -86,20 +84,22 @@ public class PlayerDataSource {
|
||||
// make sure the static cache was created: needed by CacheFactories below
|
||||
instantiateCacheIfNeeded(context);
|
||||
|
||||
// generic data source factories use DefaultHttpDataSource.Factory
|
||||
// generic data source factories now use YoutubeHttpDataSource.Factory to support proxies
|
||||
final YoutubeHttpDataSource.Factory youtubeHttpDataSourceFactory =
|
||||
getYoutubeHttpDataSourceFactory(context, false, false);
|
||||
cachelessDataSourceFactory = new DefaultDataSource.Factory(context,
|
||||
new DefaultHttpDataSource.Factory().setUserAgent(DownloaderImpl.USER_AGENT))
|
||||
youtubeHttpDataSourceFactory)
|
||||
.setTransferListener(transferListener);
|
||||
cacheDataSourceFactory = new CacheFactory(context, transferListener, cache,
|
||||
new DefaultHttpDataSource.Factory().setUserAgent(DownloaderImpl.USER_AGENT));
|
||||
youtubeHttpDataSourceFactory);
|
||||
|
||||
// YouTube-specific data source factories use getYoutubeHttpDataSourceFactory()
|
||||
ytHlsCacheDataSourceFactory = new CacheFactory(context, transferListener, cache,
|
||||
getYoutubeHttpDataSourceFactory(false, false));
|
||||
getYoutubeHttpDataSourceFactory(context, false, false));
|
||||
ytDashCacheDataSourceFactory = new CacheFactory(context, transferListener, cache,
|
||||
getYoutubeHttpDataSourceFactory(true, true));
|
||||
getYoutubeHttpDataSourceFactory(context, true, true));
|
||||
ytProgressiveDashCacheDataSourceFactory = new CacheFactory(context, transferListener, cache,
|
||||
getYoutubeHttpDataSourceFactory(false, true));
|
||||
getYoutubeHttpDataSourceFactory(context, false, true));
|
||||
|
||||
// set the maximum size to manifest creators
|
||||
YoutubeProgressiveDashManifestCreator.getCache().setMaximumSize(MAX_MANIFEST_CACHE_SIZE);
|
||||
@ -198,9 +198,10 @@ public class PlayerDataSource {
|
||||
}
|
||||
|
||||
private static YoutubeHttpDataSource.Factory getYoutubeHttpDataSourceFactory(
|
||||
final Context context,
|
||||
final boolean rangeParameterEnabled,
|
||||
final boolean rnParameterEnabled) {
|
||||
return new YoutubeHttpDataSource.Factory()
|
||||
return new YoutubeHttpDataSource.Factory(context)
|
||||
.setRangeParameterEnabled(rangeParameterEnabled)
|
||||
.setRnParameterEnabled(rnParameterEnabled);
|
||||
}
|
||||
|
||||
@ -0,0 +1,70 @@
|
||||
package org.schabi.newpipe.settings;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.app.AlertDialog;
|
||||
import android.content.SharedPreferences;
|
||||
import android.os.Bundle;
|
||||
import androidx.annotation.Nullable;
|
||||
import org.schabi.newpipe.R;
|
||||
import org.schabi.newpipe.util.NavigationHelper;
|
||||
|
||||
/**
|
||||
* A fragment that displays proxy settings.
|
||||
*/
|
||||
public class ProxySettingsFragment extends BasePreferenceFragment {
|
||||
|
||||
private boolean preferencesChanged = false;
|
||||
private SharedPreferences.OnSharedPreferenceChangeListener preferenceChangeListener;
|
||||
|
||||
@Override
|
||||
public void onCreatePreferences(@Nullable final Bundle savedInstanceState,
|
||||
@Nullable final String rootKey) {
|
||||
//addPreferencesFromResource(R.xml.proxy_settings);
|
||||
addPreferencesFromResourceRegistry();
|
||||
preferenceChangeListener = (sharedPreferences, key) -> {
|
||||
preferencesChanged = true;
|
||||
};
|
||||
getPreferenceScreen().getSharedPreferences()
|
||||
.registerOnSharedPreferenceChangeListener(preferenceChangeListener);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStop() {
|
||||
super.onStop();
|
||||
if (preferencesChanged && getActivity() != null && !getActivity().isFinishing()) {
|
||||
showRestartDialog();
|
||||
}
|
||||
}
|
||||
|
||||
private void showRestartDialog() {
|
||||
// Show Alert Dialogue
|
||||
final Activity activity = getActivity();
|
||||
if (activity == null) {
|
||||
return;
|
||||
}
|
||||
final AlertDialog.Builder builder = new AlertDialog.Builder(getContext());
|
||||
builder.setMessage(R.string.restart_app_message);
|
||||
builder.setTitle(R.string.restart_app_title);
|
||||
builder.setCancelable(true);
|
||||
builder.setPositiveButton(R.string.ok, (dialogInterface, i) -> {
|
||||
// Restarts the app
|
||||
if (activity == null) {
|
||||
return;
|
||||
}
|
||||
NavigationHelper.restartApp(activity);
|
||||
});
|
||||
builder.setNegativeButton(R.string.cancel, (dialogInterface, i) -> {
|
||||
});
|
||||
final android.app.AlertDialog alertDialog = builder.create();
|
||||
alertDialog.show();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDestroy() {
|
||||
super.onDestroy();
|
||||
if (preferenceChangeListener != null && getPreferenceScreen() != null) {
|
||||
getPreferenceScreen().getSharedPreferences()
|
||||
.unregisterOnSharedPreferenceChangeListener(preferenceChangeListener);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -42,6 +42,7 @@ public final class SettingsResourceRegistry {
|
||||
add(VideoAudioSettingsFragment.class, R.xml.video_audio_settings);
|
||||
add(ExoPlayerSettingsFragment.class, R.xml.exoplayer_settings);
|
||||
add(BackupRestoreSettingsFragment.class, R.xml.backup_restore_settings);
|
||||
add(ProxySettingsFragment.class, R.xml.proxy_settings);
|
||||
}
|
||||
|
||||
private SettingRegistryEntry add(
|
||||
|
||||
79
app/src/main/java/org/schabi/newpipe/util/ProxyManager.java
Normal file
79
app/src/main/java/org/schabi/newpipe/util/ProxyManager.java
Normal file
@ -0,0 +1,79 @@
|
||||
package org.schabi.newpipe.util;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.SharedPreferences;
|
||||
|
||||
import androidx.preference.PreferenceManager;
|
||||
|
||||
import java.net.InetSocketAddress;
|
||||
import java.net.Proxy;
|
||||
|
||||
/**
|
||||
* A class to manage proxy settings.
|
||||
*/
|
||||
public class ProxyManager {
|
||||
|
||||
private final SharedPreferences sharedPreferences;
|
||||
|
||||
/**
|
||||
* Creates a new ProxyManager.
|
||||
* @param context the context to use
|
||||
*/
|
||||
public ProxyManager(final Context context) {
|
||||
this.sharedPreferences =
|
||||
PreferenceManager.getDefaultSharedPreferences(context.getApplicationContext());
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the proxy is enabled.
|
||||
* @return true if the proxy is enabled, false otherwise
|
||||
*/
|
||||
public boolean isProxyEnabled() {
|
||||
return sharedPreferences.getBoolean("use_proxy", false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the proxy host.
|
||||
* @return the proxy host
|
||||
*/
|
||||
public String getProxyHost() {
|
||||
return sharedPreferences.getString("proxy_host", "127.0.0.1");
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the proxy port.
|
||||
* @return the proxy port
|
||||
*/
|
||||
public int getProxyPort() {
|
||||
final String portString = sharedPreferences.getString("proxy_port", "1080");
|
||||
try {
|
||||
return Integer.parseInt(portString);
|
||||
} catch (final NumberFormatException e) {
|
||||
return 1080;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the proxy type.
|
||||
* @return the proxy type
|
||||
*/
|
||||
public Proxy.Type getProxyType() {
|
||||
final String type = sharedPreferences.getString("proxy_type", "SOCKS");
|
||||
if ("SOCKS".equals(type)) {
|
||||
return Proxy.Type.SOCKS;
|
||||
} else {
|
||||
return Proxy.Type.HTTP;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the proxy.
|
||||
* @return the proxy, or null if the proxy is not enabled
|
||||
*/
|
||||
public Proxy getProxy() {
|
||||
if (!isProxyEnabled()) {
|
||||
return null;
|
||||
}
|
||||
return new Proxy(getProxyType(), new InetSocketAddress(getProxyHost(), getProxyPort()));
|
||||
}
|
||||
}
|
||||
@ -23,6 +23,7 @@ import com.squareup.picasso.Transformation;
|
||||
|
||||
import org.schabi.newpipe.R;
|
||||
import org.schabi.newpipe.extractor.Image;
|
||||
import org.schabi.newpipe.util.ProxyManager;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
@ -49,12 +50,17 @@ public final class PicassoHelper {
|
||||
|
||||
public static void init(final Context context) {
|
||||
picassoCache = new LruCache(10 * 1024 * 1024);
|
||||
picassoDownloaderClient = new OkHttpClient.Builder()
|
||||
final ProxyManager proxyManager = new ProxyManager(context);
|
||||
final OkHttpClient.Builder builder = new OkHttpClient.Builder()
|
||||
.cache(new okhttp3.Cache(new File(context.getExternalCacheDir(), "picasso"),
|
||||
50L * 1024L * 1024L))
|
||||
// this should already be the default timeout in OkHttp3, but just to be sure...
|
||||
.callTimeout(15, TimeUnit.SECONDS)
|
||||
.build();
|
||||
.callTimeout(15, TimeUnit.SECONDS);
|
||||
|
||||
if (proxyManager.isProxyEnabled()) {
|
||||
builder.proxy(proxyManager.getProxy());
|
||||
}
|
||||
picassoDownloaderClient = builder.build();
|
||||
|
||||
picassoInstance = new Picasso.Builder(context)
|
||||
.memoryCache(picassoCache) // memory cache
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
package us.shandian.giga.get;
|
||||
|
||||
import android.content.Context;
|
||||
import android.os.Handler;
|
||||
import android.system.ErrnoException;
|
||||
import android.system.OsConstants;
|
||||
@ -17,6 +18,7 @@ import java.io.InterruptedIOException;
|
||||
import java.io.Serializable;
|
||||
import java.net.ConnectException;
|
||||
import java.net.HttpURLConnection;
|
||||
import java.net.Proxy;
|
||||
import java.net.SocketTimeoutException;
|
||||
import java.net.URL;
|
||||
import java.net.UnknownHostException;
|
||||
@ -25,6 +27,7 @@ import java.util.Objects;
|
||||
|
||||
import javax.net.ssl.SSLException;
|
||||
|
||||
import org.schabi.newpipe.util.ProxyManager;
|
||||
import org.schabi.newpipe.streams.io.StoredFileHelper;
|
||||
import us.shandian.giga.postprocessing.Postprocessing;
|
||||
import us.shandian.giga.service.DownloadManagerService;
|
||||
@ -34,7 +37,7 @@ import static org.schabi.newpipe.BuildConfig.DEBUG;
|
||||
|
||||
public class DownloadMission extends Mission {
|
||||
private static final long serialVersionUID = 6L;// last bump: 07 october 2019
|
||||
|
||||
private final Context context;
|
||||
static final int BUFFER_SIZE = 64 * 1024;
|
||||
static final int BLOCK_SIZE = 512 * 1024;
|
||||
|
||||
@ -153,9 +156,10 @@ public class DownloadMission extends Mission {
|
||||
public transient Thread[] threads = new Thread[0];
|
||||
public transient Thread init = null;
|
||||
|
||||
public DownloadMission(String[] urls, StoredFileHelper storage, char kind, Postprocessing psInstance) {
|
||||
public DownloadMission(final Context context, String[] urls, StoredFileHelper storage, char kind, Postprocessing psInstance) {
|
||||
if (Objects.requireNonNull(urls).length < 1)
|
||||
throw new IllegalArgumentException("urls array is empty");
|
||||
this.context = context;
|
||||
this.urls = urls;
|
||||
this.kind = kind;
|
||||
this.offsets = new long[urls.length];
|
||||
@ -164,6 +168,7 @@ public class DownloadMission extends Mission {
|
||||
this.storage = storage;
|
||||
this.psAlgorithm = psInstance;
|
||||
|
||||
|
||||
if (DEBUG && psInstance == null && urls.length > 1) {
|
||||
Log.w(TAG, "mission created with multiple urls ¿missing post-processing algorithm?");
|
||||
}
|
||||
@ -219,7 +224,14 @@ public class DownloadMission extends Mission {
|
||||
}
|
||||
|
||||
HttpURLConnection openConnection(String url, boolean headRequest, long rangeStart, long rangeEnd) throws IOException {
|
||||
HttpURLConnection conn = (HttpURLConnection) new URL(url).openConnection();
|
||||
final ProxyManager proxyManager = new ProxyManager(context);
|
||||
final Proxy proxy = proxyManager.getProxy();
|
||||
final HttpURLConnection conn;
|
||||
if (proxy != null) {
|
||||
conn = (HttpURLConnection) new URL(url).openConnection(proxy);
|
||||
} else {
|
||||
conn = (HttpURLConnection) new URL(url).openConnection();
|
||||
}
|
||||
conn.setInstanceFollowRedirects(true);
|
||||
conn.setRequestProperty("User-Agent", DownloaderImpl.USER_AGENT);
|
||||
conn.setRequestProperty("Accept", "*/*");
|
||||
|
||||
@ -408,7 +408,7 @@ public class DownloadManagerService extends Service {
|
||||
else
|
||||
ps = Postprocessing.getAlgorithm(psName, psArgs, streamInfo);
|
||||
|
||||
final DownloadMission mission = new DownloadMission(urls, storage, kind, ps);
|
||||
final DownloadMission mission = new DownloadMission(this, urls, storage, kind, ps);
|
||||
mission.threadCount = threads;
|
||||
mission.source = streamInfo.getUrl();
|
||||
mission.nearLength = nearLength;
|
||||
|
||||
@ -34,6 +34,14 @@
|
||||
<string name="use_external_video_player_title">Внешний видеоплеер</string>
|
||||
<string name="use_external_audio_player_title">Внешний аудиоплеер</string>
|
||||
<string name="background_player_playing_toast">Воспроизведение в фоновом режиме</string>
|
||||
<string name="proxy_settings_title">Настройки прокси</string>
|
||||
<string name="use_proxy">Использовать прокси</string>
|
||||
<string name="use_proxy_summary">Перенаправлять трафик через прокси</string>
|
||||
<string name="proxy_host">Хост прокси</string>
|
||||
<string name="proxy_host_summary">Имя хоста или IP-адрес прокси</string>
|
||||
<string name="proxy_port">Порт прокси</string>
|
||||
<string name="proxy_port_summary">Номер порта прокси</string>
|
||||
<string name="proxy_port_dialog_message">Введите номер порта прокси</string>
|
||||
<string name="theme_title">Тема</string>
|
||||
<string name="dark_theme_title">Тёмная</string>
|
||||
<string name="light_theme_title">Светлая</string>
|
||||
@ -868,4 +876,6 @@
|
||||
<string name="youtube_player_http_403">Во время воспроизведения получена ошибка HTTP 403 от сервера, вероятно, вызванная блокировкой IP-адреса или проблемами деобфускации URL-адреса потоковой передачи</string>
|
||||
<string name="sign_in_confirm_not_bot_error">%1$s отказался предоставить данные, запросив логин для подтверждения, что запросчик не бот.\n\nВозможно, ваш IP-адрес временно заблокирован %1$s. Вы можете подождать некоторое время или переключиться на другой IP-адрес (например, включив/выключив VPN или переключившись с Wi-Fi на мобильный интернет).</string>
|
||||
<string name="unsupported_content_in_country">Этот контент недоступен для выбранной страны контента.\n\nИзмените свой выбор в разделе «Настройки > Контент > Страна контента по умолчанию».</string>
|
||||
<string name="restart_app_title">Перезапуск приложения</string>
|
||||
<string name="restart_app_message">Настройки прокси изменены. Для применения изменений требуется перезапуск приложения.</string>
|
||||
</resources>
|
||||
|
||||
@ -159,6 +159,23 @@
|
||||
<string name="settings_category_player_notification_title">Player notification</string>
|
||||
<string name="settings_category_player_notification_summary">Configure current playing stream notification</string>
|
||||
<string name="settings_category_backup_restore_title">Backup and restore</string>
|
||||
<string name="proxy_settings_title">Proxy Settings</string>
|
||||
<string name="use_proxy">Use proxy</string>
|
||||
<string name="use_proxy_summary">Redirect traffic through a proxy</string>
|
||||
<string name="proxy_host">Proxy host</string>
|
||||
<string name="proxy_host_summary">Hostname or IP address of the proxy</string>
|
||||
<string name="proxy_port">Proxy port</string>
|
||||
<string name="proxy_port_summary">Port number of the proxy</string>
|
||||
<string name="proxy_port_dialog_message">Enter the proxy port number</string>
|
||||
<string name="proxy_type">Proxy type</string>
|
||||
<string-array name="proxy_type_entries">
|
||||
<item>HTTP</item>
|
||||
<item>SOCKS</item>
|
||||
</string-array>
|
||||
<string-array name="proxy_type_values">
|
||||
<item>HTTP</item>
|
||||
<item>SOCKS</item>
|
||||
</string-array>
|
||||
<string name="background_player_playing_toast">Playing in background</string>
|
||||
<string name="popup_playing_toast">Playing in popup mode</string>
|
||||
<string name="content">Content</string>
|
||||
@ -882,4 +899,6 @@
|
||||
<string name="youtube_player_http_403">HTTP error 403 received from server while playing, likely caused by an IP ban or streaming URL deobfuscation issues</string>
|
||||
<string name="sign_in_confirm_not_bot_error">%1$s refused to provide data, asking for a login to confirm the requester is not a bot.\n\nYour IP might have been temporarily banned by %1$s, you can wait some time or switch to a different IP (for example by turning on/off a VPN, or by switching from WiFi to mobile data).</string>
|
||||
<string name="unsupported_content_in_country">This content is not available for the currently selected content country.\n\nChange your selection from \"Settings > Content > Default content country\".</string>
|
||||
<string name="restart_app_title">Restart application</string>
|
||||
<string name="restart_app_message">The proxy settings have been changed. A restart of the application is required for the changes to take effect.</string>
|
||||
</resources>
|
||||
|
||||
@ -16,6 +16,12 @@
|
||||
android:title="@string/settings_category_downloads_title"
|
||||
app:iconSpaceReserved="false" />
|
||||
|
||||
<PreferenceScreen
|
||||
android:fragment="org.schabi.newpipe.settings.ProxySettingsFragment"
|
||||
android:icon="@drawable/ic_cloud_download"
|
||||
android:title="@string/proxy_settings_title"
|
||||
app:iconSpaceReserved="false" />
|
||||
|
||||
<PreferenceScreen
|
||||
android:fragment="org.schabi.newpipe.settings.AppearanceSettingsFragment"
|
||||
android:icon="@drawable/ic_palette"
|
||||
|
||||
37
app/src/main/res/xml/proxy_settings.xml
Normal file
37
app/src/main/res/xml/proxy_settings.xml
Normal file
@ -0,0 +1,37 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
app:title="@string/proxy_settings_title">
|
||||
|
||||
<SwitchPreferenceCompat
|
||||
app:key="use_proxy"
|
||||
app:title="@string/use_proxy"
|
||||
app:summary="@string/use_proxy_summary"
|
||||
app:defaultValue="false" />
|
||||
|
||||
<ListPreference
|
||||
app:key="proxy_type"
|
||||
app:title="@string/proxy_type"
|
||||
app:summary="%s"
|
||||
app:entries="@array/proxy_type_entries"
|
||||
app:entryValues="@array/proxy_type_values"
|
||||
app:defaultValue="HTTP"
|
||||
app:dependency="use_proxy" />
|
||||
|
||||
<EditTextPreference
|
||||
app:key="proxy_host"
|
||||
app:title="@string/proxy_host"
|
||||
app:summary="@string/proxy_host_summary"
|
||||
app:defaultValue="127.0.0.1"
|
||||
app:dependency="use_proxy" />
|
||||
|
||||
<EditTextPreference
|
||||
app:key="proxy_port"
|
||||
app:title="@string/proxy_port"
|
||||
app:summary="@string/proxy_port_summary"
|
||||
app:defaultValue="1080"
|
||||
app:dependency="use_proxy"
|
||||
app:dialogMessage="@string/proxy_port_dialog_message"
|
||||
android:inputType="number" />
|
||||
|
||||
</PreferenceScreen>
|
||||
Loading…
x
Reference in New Issue
Block a user