diff --git a/.gitignore b/.gitignore
index 42caadb93..2b3c40d66 100644
--- a/.gitignore
+++ b/.gitignore
@@ -7,3 +7,4 @@
/app/app.iml
/.idea
/*.iml
+gradle.properties
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index 149c4ba54..ede4461a9 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -1,11 +1,11 @@
-#Contributing
+#Contribution
This document contains guidelines on making contributions to NewPipe.
## Programming
* Follow the [Google Style Guidelines](https://google.github.io/styleguide/javaguide.html)
-* Make a new feature on a seperate branch, not on the master branch
+* Make a new feature on a separate branch, not on the master branch
* Make a [pull request](https://github.com/theScrabi/NewPipe/pulls) if you're done with your changes
* When submitting changes, you agree that your code will be GPLv3 licensed
@@ -16,7 +16,7 @@ This document contains guidelines on making contributions to NewPipe.
compatibility with all git tools
* [This guide](http://chris.beams.io/posts/git-commit/) goes more in depth on what makes a good commit message
-## Translating
+## Translation
* NewPipe can be translated on [weblate](https://hosted.weblate.org/projects/newpipe/strings/)
@@ -30,4 +30,4 @@ This document contains guidelines on making contributions to NewPipe.
## Communication
* For the time being, [Slack](http://invite.chschtsch.ml/) is being used for project communication
-* Feel free to post suggestions, changes ideas etc!
+* Feel free to post suggestions, changes, ideas etc!
diff --git a/README.md b/README.md
index e6d1d9498..b24ed14af 100644
--- a/README.md
+++ b/README.md
@@ -36,6 +36,7 @@ NewPipe does not use any Google framework libraries, or the YouTube API. It only
* Open a video in Kodi
* Show Next/Related videos
* Search YouTube in a specific language
+* Orbot/Tor support (no streaming yet)
### Coming Features
diff --git a/app/build.gradle b/app/build.gradle
index 871a98a9d..5eaf3a6c4 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -8,8 +8,8 @@ android {
applicationId "org.schabi.newpipe"
minSdkVersion 15
targetSdkVersion 23
- versionCode 9
- versionName "0.7.0"
+ versionCode 11
+ versionName "0.7.2"
}
buildTypes {
release {
@@ -17,7 +17,7 @@ android {
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
-
+
lintOptions {
checkReleaseBuilds false
// Or, if you prefer, you can continue to check for errors in release builds,
@@ -35,4 +35,5 @@ dependencies {
compile 'com.android.support:recyclerview-v7:23.1.1'
compile 'org.jsoup:jsoup:1.8.3'
compile 'org.mozilla:rhino:1.7.7'
+ compile 'info.guardianproject.netcipher:netcipher:1.2'
}
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index 05eda83c5..2f2ec061b 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -7,6 +7,7 @@
+
-
+
+
+
+
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
+ android:label="@string/background_player_name"
+ android:exported="false" />
+ android:label="@string/settings_activity_title" >
+
+
+
+
+
+
+
diff --git a/app/src/main/java/org/schabi/newpipe/ActionBarHandler.java b/app/src/main/java/org/schabi/newpipe/ActionBarHandler.java
index c8b4061f7..490b8d6f4 100644
--- a/app/src/main/java/org/schabi/newpipe/ActionBarHandler.java
+++ b/app/src/main/java/org/schabi/newpipe/ActionBarHandler.java
@@ -99,8 +99,8 @@ class ActionBarHandler {
defaultPreferences = PreferenceManager.getDefaultSharedPreferences(activity);
String[] itemArray = new String[videoStreams.length];
String defaultResolution = defaultPreferences
- .getString(activity.getString(R.string.defaultResolutionPreference),
- activity.getString(R.string.defaultResolutionListItem));
+ .getString(activity.getString(R.string.default_resolution_key),
+ activity.getString(R.string.default_resolution_value));
int defaultResolutionPos = 0;
for(int i = 0; i < videoStreams.length; i++) {
@@ -124,7 +124,7 @@ class ActionBarHandler {
// set audioStream
audioStream = null;
String preferedFormat = defaultPreferences
- .getString(activity.getString(R.string.defaultAudioFormatPreference), "webm");
+ .getString(activity.getString(R.string.default_audio_format_key), "webm");
if(preferedFormat.equals("webm")) {
for(VideoInfo.AudioStream s : audioStreams) {
if(s.format == MediaFormat.WEBMA.id) {
@@ -158,7 +158,7 @@ class ActionBarHandler {
MenuItem castItem = menu.findItem(R.id.action_play_with_kodi);
castItem.setVisible(defaultPreferences
- .getBoolean(activity.getString(R.string.showPlayWithKodiPreference), false));
+ .getBoolean(activity.getString(R.string.show_play_with_kodi_key), false));
}
public boolean onItemSelected(MenuItem item) {
@@ -170,7 +170,7 @@ class ActionBarHandler {
intent.setAction(Intent.ACTION_SEND);
intent.putExtra(Intent.EXTRA_TEXT, websiteUrl);
intent.setType("text/plain");
- activity.startActivity(Intent.createChooser(intent, activity.getString(R.string.shareDialogTitle)));
+ activity.startActivity(Intent.createChooser(intent, activity.getString(R.string.share_dialog_title)));
return true;
}
case R.id.menu_item_openInBrowser: {
@@ -210,7 +210,7 @@ class ActionBarHandler {
// ----------- THE MAGIC MOMENT ---------------
if(!videoTitle.isEmpty()) {
if (PreferenceManager.getDefaultSharedPreferences(activity)
- .getBoolean(activity.getString(R.string.useExternalVideoPlayer), false)) {
+ .getBoolean(activity.getString(R.string.use_external_video_player_key), false)) {
// External Player
Intent intent = new Intent();
@@ -226,13 +226,13 @@ class ActionBarHandler {
} catch (Exception e) {
e.printStackTrace();
AlertDialog.Builder builder = new AlertDialog.Builder(activity);
- builder.setMessage(R.string.noPlayerFound)
- .setPositiveButton(R.string.installStreamPlayer, new DialogInterface.OnClickListener() {
+ builder.setMessage(R.string.no_player_found)
+ .setPositiveButton(R.string.install, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
Intent intent = new Intent();
intent.setAction(Intent.ACTION_VIEW);
- intent.setData(Uri.parse(activity.getString(R.string.fdroidVLCurl)));
+ intent.setData(Uri.parse(activity.getString(R.string.fdroid_vlc_url)));
activity.startActivity(intent);
}
})
@@ -284,7 +284,7 @@ class ActionBarHandler {
intent.setAction(Intent.ACTION_VIEW);
intent.setData(Uri.parse(websiteUrl));
- activity.startActivity(Intent.createChooser(intent, activity.getString(R.string.chooseBrowser)));
+ activity.startActivity(Intent.createChooser(intent, activity.getString(R.string.choose_browser)));
}
}
@@ -298,13 +298,13 @@ class ActionBarHandler {
} catch (Exception e) {
e.printStackTrace();
AlertDialog.Builder builder = new AlertDialog.Builder(activity);
- builder.setMessage(R.string.koreNotFound)
- .setPositiveButton(R.string.installeKore, new DialogInterface.OnClickListener() {
+ builder.setMessage(R.string.kore_not_found)
+ .setPositiveButton(R.string.install, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
Intent intent = new Intent();
intent.setAction(Intent.ACTION_VIEW);
- intent.setData(Uri.parse(activity.getString(R.string.fdroidKoreUrl)));
+ intent.setData(Uri.parse(activity.getString(R.string.fdroid_kore_url)));
activity.startActivity(intent);
}
})
@@ -322,7 +322,7 @@ class ActionBarHandler {
public void playAudio() {
boolean externalAudioPlayer = PreferenceManager.getDefaultSharedPreferences(activity)
- .getBoolean(activity.getString(R.string.useExternalAudioPlayer), false);
+ .getBoolean(activity.getString(R.string.use_external_audio_player_key), false);
Intent intent;
if (!externalAudioPlayer && android.os.Build.VERSION.SDK_INT >= 18) {
@@ -356,13 +356,13 @@ class ActionBarHandler {
} catch (Exception e) {
e.printStackTrace();
AlertDialog.Builder builder = new AlertDialog.Builder(activity);
- builder.setMessage(R.string.noPlayerFound)
- .setPositiveButton(R.string.installStreamPlayer, new DialogInterface.OnClickListener() {
+ builder.setMessage(R.string.no_player_found)
+ .setPositiveButton(R.string.install, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
Intent intent = new Intent();
intent.setAction(Intent.ACTION_VIEW);
- intent.setData(Uri.parse(activity.getString(R.string.fdroidVLCurl)));
+ intent.setData(Uri.parse(activity.getString(R.string.fdroid_vlc_url)));
activity.startActivity(intent);
}
})
diff --git a/app/src/main/java/org/schabi/newpipe/App.java b/app/src/main/java/org/schabi/newpipe/App.java
new file mode 100644
index 000000000..d842e3f0a
--- /dev/null
+++ b/app/src/main/java/org/schabi/newpipe/App.java
@@ -0,0 +1,71 @@
+package org.schabi.newpipe;
+
+import android.app.Application;
+import android.content.Context;
+import android.content.SharedPreferences;
+import android.preference.PreferenceManager;
+
+import info.guardianproject.netcipher.NetCipher;
+import info.guardianproject.netcipher.proxy.OrbotHelper;
+
+/**
+ * Copyright (C) Hans-Christoph Steiner 2016
+ * App.java is part of NewPipe.
+ *
+ * NewPipe is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * NewPipe is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with NewPipe. If not, see .
+ */
+
+public class App extends Application {
+
+ private static boolean useTor;
+
+ @Override
+ public void onCreate() {
+ super.onCreate();
+
+ SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);
+ if(prefs.getBoolean(getString(R.string.use_tor_key), false)) {
+ OrbotHelper.requestStartTor(this);
+ configureTor(true);
+ } else {
+ configureTor(false);
+ }
+
+ // DO NOT REMOVE THIS FUNCTION!!!
+ // Otherwise downloadPathPreference has invalid value.
+ SettingsActivity.initSettings(this);
+ }
+
+ /**
+ * Set the proxy settings based on whether Tor should be enabled or not.
+ */
+ static void configureTor(boolean enabled) {
+ useTor = enabled;
+ if (useTor) {
+ NetCipher.useTor();
+ } else {
+ NetCipher.setProxy(null);
+ }
+ }
+
+ static void checkStartTor(Context context) {
+ if (useTor) {
+ OrbotHelper.requestStartTor(context);
+ }
+ }
+
+ static boolean isUsingTor() {
+ return useTor;
+ }
+}
diff --git a/app/src/main/java/org/schabi/newpipe/BackgroundPlayer.java b/app/src/main/java/org/schabi/newpipe/BackgroundPlayer.java
index 5573e2771..cf0f88d05 100644
--- a/app/src/main/java/org/schabi/newpipe/BackgroundPlayer.java
+++ b/app/src/main/java/org/schabi/newpipe/BackgroundPlayer.java
@@ -17,6 +17,7 @@ import android.os.IBinder;
import android.os.PowerManager;
import android.support.v7.app.NotificationCompat;
import android.util.Log;
+import android.widget.RemoteViews;
import android.widget.Toast;
import java.io.IOException;
@@ -74,7 +75,7 @@ public class BackgroundPlayer extends Service /*implements MediaPlayer.OnPrepare
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
- Toast.makeText(this, R.string.backgroundPlayerStartPlayingToast,
+ Toast.makeText(this, R.string.background_player_playing_toast,
Toast.LENGTH_SHORT).show();
String source = intent.getDataString();
@@ -113,9 +114,9 @@ public class BackgroundPlayer extends Service /*implements MediaPlayer.OnPrepare
private int noteID = TAG.hashCode();
private BackgroundPlayer owner;
private NotificationManager noteMgr;
- private NotificationCompat.Builder noteBuilder;
private WifiManager.WifiLock wifiLock;
private Bitmap videoThumbnail = null;
+ private NotificationCompat.Builder noteBuilder;
public PlayerThread(String src, String title, BackgroundPlayer owner) {
this.source = src;
@@ -124,10 +125,9 @@ public class BackgroundPlayer extends Service /*implements MediaPlayer.OnPrepare
mediaPlayer = new MediaPlayer();
mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
}
+
@Override
public void run() {
- Resources res = getApplicationContext().getResources();
-
mediaPlayer.setWakeMode(getApplicationContext(), PowerManager.PARTIAL_WAKE_LOCK);//cpu lock
try {
mediaPlayer.setDataSource(source);
@@ -135,9 +135,6 @@ public class BackgroundPlayer extends Service /*implements MediaPlayer.OnPrepare
//so calling the blocking prepare() method should be ok
mediaPlayer.prepare();
- //alternatively:
- //mediaPlayer.setOnPreparedListener(this);
- //mediaPlayer.prepareAsync(); //prepare async to not block main thread
} catch (IOException ioe) {
ioe.printStackTrace();
Log.e(TAG, "video source:" + source);
@@ -177,63 +174,7 @@ public class BackgroundPlayer extends Service /*implements MediaPlayer.OnPrepare
filter.addAction(ACTION_STOP);
registerReceiver(broadcastReceiver, filter);
- PendingIntent playPI = PendingIntent.getBroadcast(owner, noteID,
- new Intent(ACTION_PLAYPAUSE), PendingIntent.FLAG_UPDATE_CURRENT);
-
- NotificationCompat.Action playButton = new NotificationCompat.Action.Builder
- (R.drawable.ic_play_arrow_white_48dp, "Play", playPI).build();
-
- /*
- NotificationCompat.Action pauseButton = new NotificationCompat.Action.Builder
- (R.drawable.ic_pause_white_24dp, "Pause", playPI).build();
- */
-
- PendingIntent stopPI = PendingIntent.getBroadcast(owner, noteID,
- new Intent(ACTION_STOP), PendingIntent.FLAG_UPDATE_CURRENT);
-
- noteBuilder = new NotificationCompat.Builder(owner);
- noteBuilder
- .setContentTitle(title)
- //really? Id like to put something more helpful here.
- //.setContentText("NewPipe is playing in the background")
- .setContentText(channelName)
- //.setAutoCancel(!mediaPlayer.isPlaying())
- .setOngoing(true)
- .setDeleteIntent(stopPI)
- //doesn't fit with Notification.MediaStyle
- //.setProgress(vidLength, 0, false)
- .setSmallIcon(R.drawable.ic_play_circle_filled_white_24dp)
- .setLargeIcon(videoThumbnail)
- .setTicker(
- String.format(res.getString(
- R.string.backgroundPlayerTickerText), title))
- .addAction(playButton);
- //.setVisibility(NotificationCompat.VISIBILITY_PUBLIC)
- //.setLargeIcon(cover)
- if(android.os.Build.VERSION.SDK_INT >= 16)
- noteBuilder.setPriority(Notification.PRIORITY_LOW);
- if(android.os.Build.VERSION.SDK_INT >= 21)
- noteBuilder.setCategory(Notification.CATEGORY_TRANSPORT);
-
- noteBuilder.setStyle(new NotificationCompat.MediaStyle()
- //.setMediaSession(mMediaSession.getSessionToken())
- .setShowActionsInCompactView(new int[]{0})
- .setShowCancelButton(true)
- .setCancelButtonIntent(stopPI));
- if(videoThumbnail != null) {
- noteBuilder.setLargeIcon(videoThumbnail);
- }
-
- Notification note = noteBuilder.build();
-
- Intent openDetailView = new Intent(getApplicationContext(),
- VideoItemDetailActivity.class);
- openDetailView.putExtra(VideoItemDetailFragment.STREAMING_SERVICE, serviceId);
- openDetailView.putExtra(VideoItemDetailFragment.VIDEO_URL, webUrl);
- openDetailView.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
- note.contentIntent = PendingIntent.getActivity(getApplicationContext(),
- noteID, openDetailView,
- PendingIntent.FLAG_UPDATE_CURRENT);
+ Notification note = buildNotification();
startForeground(noteID, note);
@@ -252,9 +193,9 @@ public class BackgroundPlayer extends Service /*implements MediaPlayer.OnPrepare
Log.d(TAG, "sleep failure");
}
}*/
-
}
+ /**Handles button presses from the notification. */
private final BroadcastReceiver broadcastReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
@@ -265,7 +206,7 @@ public class BackgroundPlayer extends Service /*implements MediaPlayer.OnPrepare
mediaPlayer.pause();
}
else {
- //reacquire CPU lock after releasing it on pause
+ //reacquire CPU lock after auto-releasing it on pause
mediaPlayer.setWakeMode(getApplicationContext(), PowerManager.PARTIAL_WAKE_LOCK);
mediaPlayer.start();
}
@@ -279,8 +220,9 @@ public class BackgroundPlayer extends Service /*implements MediaPlayer.OnPrepare
};
private void afterPlayCleanup() {
- //noteBuilder.setProgress(0, 0, false);
//remove progress bar
+ //noteBuilder.setProgress(0, 0, false);
+
//remove notification
noteMgr.cancel(noteID);
unregisterReceiver(broadcastReceiver);
@@ -289,7 +231,7 @@ public class BackgroundPlayer extends Service /*implements MediaPlayer.OnPrepare
//release wifilock
wifiLock.release();
- //remove foreground status of service; make us killable
+ //remove foreground status of service; make BackgroundPlayer killable
stopForeground(true);
stopSelf();
@@ -306,5 +248,110 @@ public class BackgroundPlayer extends Service /*implements MediaPlayer.OnPrepare
afterPlayCleanup();
}
}
+
+ private Notification buildNotification() {
+ Notification note;
+ Resources res = getApplicationContext().getResources();
+ noteBuilder = new NotificationCompat.Builder(owner);
+
+ PendingIntent playPI = PendingIntent.getBroadcast(owner, noteID,
+ new Intent(ACTION_PLAYPAUSE), PendingIntent.FLAG_UPDATE_CURRENT);
+ PendingIntent stopPI = PendingIntent.getBroadcast(owner, noteID,
+ new Intent(ACTION_STOP), PendingIntent.FLAG_UPDATE_CURRENT);
+ /*
+ NotificationCompat.Action pauseButton = new NotificationCompat.Action.Builder
+ (R.drawable.ic_pause_white_24dp, "Pause", playPI).build();
+ */
+
+ //build intent to return to video, on tapping notification
+ Intent openDetailView = new Intent(getApplicationContext(),
+ VideoItemDetailActivity.class);
+ openDetailView.putExtra(VideoItemDetailFragment.STREAMING_SERVICE, serviceId);
+ openDetailView.putExtra(VideoItemDetailFragment.VIDEO_URL, webUrl);
+ openDetailView.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+
+ noteBuilder
+ .setOngoing(true)
+ .setDeleteIntent(stopPI)
+ //doesn't fit with Notification.MediaStyle
+ //.setProgress(vidLength, 0, false)
+ .setSmallIcon(R.drawable.ic_play_circle_filled_white_24dp)
+ .setTicker(
+ String.format(res.getString(
+ R.string.background_player_time_text), title))
+ .setContentIntent(PendingIntent.getActivity(getApplicationContext(),
+ noteID, openDetailView,
+ PendingIntent.FLAG_UPDATE_CURRENT));
+
+
+ if (android.os.Build.VERSION.SDK_INT < 21) {
+
+ NotificationCompat.Action playButton = new NotificationCompat.Action.Builder
+ (R.drawable.ic_play_arrow_white_48dp,
+ res.getString(R.string.play_btn_text), playPI).build();
+
+ noteBuilder
+ .setContentTitle(title)
+ //really? Id like to put something more helpful here.
+ //was more of a placeholder than anything else. -medavox
+ //.setContentText("NewPipe is playing in the background")
+ .setContentText(channelName)
+ //.setAutoCancel(!mediaPlayer.isPlaying())
+ .setDeleteIntent(stopPI)
+ //doesn't fit with Notification.MediaStyle
+ //.setProgress(vidLength, 0, false)
+ .setLargeIcon(videoThumbnail)
+ .addAction(playButton);
+ //.setVisibility(NotificationCompat.VISIBILITY_PUBLIC)
+ //.setLargeIcon(cover)
+
+ //is wrapping this in an SDK version check really necessary,
+ // if we're using NotificationCompat?
+ // the compat libraries should handle this, right? -medavox
+ if (android.os.Build.VERSION.SDK_INT >= 16)
+ noteBuilder.setPriority(Notification.PRIORITY_LOW);
+
+ noteBuilder.setStyle(new NotificationCompat.MediaStyle()
+ //.setMediaSession(mMediaSession.getSessionToken())
+ .setShowActionsInCompactView(new int[]{0})
+ .setShowCancelButton(true)
+ .setCancelButtonIntent(stopPI));
+ if (videoThumbnail != null) {
+ noteBuilder.setLargeIcon(videoThumbnail);
+ }
+ note = noteBuilder.build();
+ } else {
+ RemoteViews view =
+ new RemoteViews(BuildConfig.APPLICATION_ID, R.layout.player_notification);
+ view.setImageViewBitmap(R.id.backgroundCover, videoThumbnail);
+ view.setTextViewText(R.id.backgroundSongName, title);
+ view.setTextViewText(R.id.backgroundArtist, channelName);
+ view.setOnClickPendingIntent(R.id.backgroundStop, stopPI);
+ view.setOnClickPendingIntent(R.id.backgroundPlayPause, playPI);
+
+ //possibly found the expandedView problem,
+ //but can't test it as I don't have a 5.0 device. -medavox
+ RemoteViews expandedView =
+ new RemoteViews(BuildConfig.APPLICATION_ID, R.layout.player_notification_expanded);
+ expandedView.setImageViewBitmap(R.id.backgroundCover, videoThumbnail);
+ expandedView.setTextViewText(R.id.backgroundSongName, title);
+ expandedView.setTextViewText(R.id.backgroundArtist, channelName);
+ expandedView.setOnClickPendingIntent(R.id.backgroundStop, stopPI);
+ expandedView.setOnClickPendingIntent(R.id.backgroundPlayPause, playPI);
+
+ noteBuilder.setCategory(Notification.CATEGORY_TRANSPORT);
+
+ //Make notification appear on lockscreen
+ noteBuilder.setVisibility(Notification.VISIBILITY_PUBLIC);
+
+ note = noteBuilder.build();
+ note.contentView = view;
+
+ //todo: This never shows up. I was not able to figure out why:
+ note.bigContentView = expandedView;
+ }
+
+ return note;
+ }
}
}
diff --git a/app/src/main/java/org/schabi/newpipe/DownloadDialog.java b/app/src/main/java/org/schabi/newpipe/DownloadDialog.java
index 903251e58..aa56c9349 100644
--- a/app/src/main/java/org/schabi/newpipe/DownloadDialog.java
+++ b/app/src/main/java/org/schabi/newpipe/DownloadDialog.java
@@ -52,49 +52,58 @@ public class DownloadDialog extends DialogFragment {
arguments = getArguments();
super.onCreateDialog(savedInstanceState);
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
- builder.setTitle(R.string.downloadDialogTitle)
- .setItems(R.array.downloadOptions, new DialogInterface.OnClickListener() {
+ builder.setTitle(R.string.download_dialog_title)
+ .setItems(R.array.download_options, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
Context context = getActivity();
- SharedPreferences defaultPreferences = PreferenceManager.getDefaultSharedPreferences(context);
+ SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
String suffix = "";
String title = arguments.getString(TITLE);
String url = "";
+ String downloadFolder = Environment.DIRECTORY_DOWNLOADS;
switch(which) {
case 0: // Video
suffix = arguments.getString(FILE_SUFFIX_VIDEO);
url = arguments.getString(VIDEO_URL);
+ downloadFolder = Environment.DIRECTORY_MOVIES;
break;
case 1:
suffix = arguments.getString(FILE_SUFFIX_AUDIO);
url = arguments.getString(AUDIO_URL);
+ downloadFolder = Environment.DIRECTORY_MUSIC;
break;
default:
Log.d(TAG, "lolz");
}
- //to avoid hard-coded string like "/storage/emulated/0/NewPipe"
- final File dir = new File(defaultPreferences.getString(
- "download_path_preference",
- Environment.getExternalStorageDirectory().getAbsolutePath() + "/NewPipe"));
+ //to avoid hard-coded string like "/storage/emulated/0/Movies"
+ String downloadPath = prefs.getString(getString(R.string.download_path_key),
+ Environment.getExternalStorageDirectory().getAbsolutePath() + "/" + downloadFolder);
+ final File dir = new File(downloadPath);
if(!dir.exists()) {
- boolean mkdir = dir.mkdir(); //attempt to create directory
+ //attempt to create directory
+ boolean mkdir = dir.mkdir();
if(!mkdir && !dir.isDirectory()) {
Log.e(TAG, "Cant' create directory named " + dir.toString());
//TODO notify user "download directory should be changed" ?
}
}
- DownloadManager dm = (DownloadManager) context.getSystemService(Context.DOWNLOAD_SERVICE);
- DownloadManager.Request request = new DownloadManager.Request(
- Uri.parse(url));
- request.setDestinationUri(Uri.fromFile(new File(
- defaultPreferences.getString("download_path_preference", "/storage/emulated/0/NewPipe")
- + "/" + title + suffix)));
- request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED);
- try {
- dm.enqueue(request);
- } catch (Exception e) {
- e.printStackTrace();
+
+ String saveFilePath = dir + "/" + title + suffix;
+ if (App.isUsingTor()) {
+ // if using Tor, do not use DownloadManager because the proxy cannot be set
+ Downloader.downloadFile(getContext(), url, saveFilePath);
+ } else {
+ DownloadManager dm = (DownloadManager) context.getSystemService(Context.DOWNLOAD_SERVICE);
+ DownloadManager.Request request = new DownloadManager.Request(
+ Uri.parse(url));
+ request.setDestinationUri(Uri.fromFile(new File(saveFilePath)));
+ request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED);
+ try {
+ dm.enqueue(request);
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
}
}
});
diff --git a/app/src/main/java/org/schabi/newpipe/Downloader.java b/app/src/main/java/org/schabi/newpipe/Downloader.java
index f0a19cfc5..cbc4c26c2 100644
--- a/app/src/main/java/org/schabi/newpipe/Downloader.java
+++ b/app/src/main/java/org/schabi/newpipe/Downloader.java
@@ -1,12 +1,30 @@
package org.schabi.newpipe;
+
+import android.app.NotificationManager;
+import android.content.Context;
+import android.content.SharedPreferences;
+import android.graphics.drawable.BitmapDrawable;
+import android.graphics.drawable.Drawable;
+import android.os.AsyncTask;
+import android.preference.PreferenceManager;
+import android.support.v4.app.NotificationCompat;
+import android.util.Log;
+
+import java.io.BufferedInputStream;
import java.io.BufferedReader;
+import java.io.FileOutputStream;
import java.io.IOException;
+import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.UnknownHostException;
+import javax.net.ssl.HttpsURLConnection;
+
+import info.guardianproject.netcipher.NetCipher;
+
/**
* Created by Christian Schabesberger on 14.08.15.
*
@@ -28,7 +46,7 @@ import java.net.UnknownHostException;
*/
public class Downloader {
-
+ public static final String TAG = "Downloader";
private static final String USER_AGENT = "Mozilla/5.0";
/**Download the text file at the supplied URL as in download(String),
@@ -40,7 +58,7 @@ public class Downloader {
String ret = "";
try {
URL url = new URL(siteUrl);
- HttpURLConnection con = (HttpURLConnection) url.openConnection();
+ HttpsURLConnection con = (HttpsURLConnection) url.openConnection();
con.setRequestProperty("Accept-Language", language);
ret = dl(con);
}
@@ -49,8 +67,9 @@ public class Downloader {
}
return ret;
}
+
/**Common functionality between download(String url) and download(String url, String language)*/
- private static String dl(HttpURLConnection con) throws IOException {
+ private static String dl(HttpsURLConnection con) throws IOException {
StringBuilder response = new StringBuilder();
try {
@@ -84,7 +103,7 @@ public class Downloader {
try {
URL url = new URL(siteUrl);
- HttpURLConnection con = (HttpURLConnection) url.openConnection();
+ HttpsURLConnection con = NetCipher.getHttpsURLConnection(url);
ret = dl(con);
}
catch(Exception e) {
@@ -93,4 +112,92 @@ public class Downloader {
return ret;
}
+
+ /**
+ * Downloads a file from a URL in the background using an {@link AsyncTask}.
+ *
+ * @param fileURL HTTP URL of the file to be downloaded
+ * @param saveFilePath path of the directory to save the file
+ * @throws IOException
+ */
+ public static void downloadFile(final Context context, final String fileURL, final String saveFilePath) {
+ new AsyncTask() {
+
+ private NotificationManager nm;
+ private NotificationCompat.Builder builder;
+ private int notifyId = 0x1234;
+ private int fileSize = 0xffffffff;
+
+ @Override
+ protected void onPreExecute() {
+ super.onPreExecute();
+ nm = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
+ Drawable icon = context.getResources().getDrawable(R.mipmap.ic_launcher);
+ builder = new NotificationCompat.Builder(context)
+ .setSmallIcon(android.R.drawable.stat_sys_download)
+ .setLargeIcon(((BitmapDrawable) icon).getBitmap())
+ .setContentTitle(saveFilePath.substring(saveFilePath.lastIndexOf('/') + 1))
+ .setContentText(saveFilePath)
+ .setProgress(fileSize, 0, false);
+ nm.notify(notifyId, builder.build());
+ }
+
+ @Override
+ protected Void doInBackground(Void... voids) {
+ HttpsURLConnection con = null;
+ try {
+ con = NetCipher.getHttpsURLConnection(fileURL);
+ int responseCode = con.getResponseCode();
+
+ // always check HTTP response code first
+ if (responseCode == HttpURLConnection.HTTP_OK) {
+ fileSize = con.getContentLength();
+ InputStream inputStream = new BufferedInputStream(con.getInputStream());
+ FileOutputStream outputStream = new FileOutputStream(saveFilePath);
+
+ int bufferSize = 8192;
+ int downloaded = 0;
+
+ int bytesRead = -1;
+ byte[] buffer = new byte[bufferSize];
+ while ((bytesRead = inputStream.read(buffer)) != -1) {
+ outputStream.write(buffer, 0, bytesRead);
+ downloaded += bytesRead;
+ if (downloaded % 50000 < bufferSize) {
+ publishProgress(downloaded);
+ }
+ }
+
+ outputStream.close();
+ inputStream.close();
+ publishProgress(bufferSize);
+
+ } else {
+ Log.i(TAG, "No file to download. Server replied HTTP code: " + responseCode);
+ }
+ } catch (IOException e) {
+ e.printStackTrace();
+ } finally {
+ if (con != null) {
+ con.disconnect();
+ con = null;
+ }
+ }
+ return null;
+ }
+
+ @Override
+ protected void onProgressUpdate(Integer... progress) {
+ builder.setProgress(fileSize, progress[0], false);
+ nm.notify(notifyId, builder.build());
+ }
+
+ @Override
+ protected void onPostExecute(Void aVoid) {
+ super.onPostExecute(aVoid);
+ nm.cancel(notifyId);
+ }
+ }.execute();
+ }
+
}
diff --git a/app/src/main/java/org/schabi/newpipe/ExitActivity.java b/app/src/main/java/org/schabi/newpipe/ExitActivity.java
new file mode 100644
index 000000000..6e14cfd9f
--- /dev/null
+++ b/app/src/main/java/org/schabi/newpipe/ExitActivity.java
@@ -0,0 +1,54 @@
+
+package org.schabi.newpipe;
+
+import android.annotation.SuppressLint;
+import android.app.Activity;
+import android.content.Intent;
+import android.os.Build;
+import android.os.Bundle;
+
+/**
+ * Copyright (C) Hans-Christoph Steiner 2016
+ * ExitActivity.java is part of NewPipe.
+ *
+ * NewPipe is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * NewPipe is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with NewPipe. If not, see .
+ */
+
+public class ExitActivity extends Activity {
+
+ @SuppressLint("NewApi")
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+
+ if (Build.VERSION.SDK_INT >= 21) {
+ finishAndRemoveTask();
+ } else {
+ finish();
+ }
+
+ System.exit(0);
+ }
+
+ public static void exitAndRemoveFromRecentApps(Activity activity) {
+ Intent intent = new Intent(activity, ExitActivity.class);
+
+ intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK
+ | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS
+ | Intent.FLAG_ACTIVITY_CLEAR_TASK
+ | Intent.FLAG_ACTIVITY_NO_ANIMATION);
+
+ activity.startActivity(intent);
+ }
+}
diff --git a/app/src/main/java/org/schabi/newpipe/Localization.java b/app/src/main/java/org/schabi/newpipe/Localization.java
new file mode 100644
index 000000000..0f448777e
--- /dev/null
+++ b/app/src/main/java/org/schabi/newpipe/Localization.java
@@ -0,0 +1,93 @@
+package org.schabi.newpipe;
+
+import android.content.Context;
+import android.content.SharedPreferences;
+import android.content.res.Resources;
+import android.preference.PreferenceManager;
+
+import java.text.DateFormat;
+import java.text.NumberFormat;
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.Locale;
+
+/**
+ * Created by chschtsch on 12/29/15.
+ *
+ * Copyright (C) Gregory Arkhipov 2015
+ * Localization.java is part of NewPipe.
+ *
+ * NewPipe is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * NewPipe is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with NewPipe. If not, see .
+ */
+
+public class Localization {
+
+ public static Locale getPreferredLocale(Context context) {
+ SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(context);
+
+ String languageCode = sp.getString(String.valueOf(R.string.search_language_key),
+ context.getString(R.string.default_language_value));
+
+ if(languageCode.length() == 2) {
+ return new Locale(languageCode);
+ }
+ else if(languageCode.contains("_")) {
+ String country = languageCode
+ .substring(languageCode.indexOf("_"), languageCode.length());
+ return new Locale(languageCode.substring(0, 2), country);
+ }
+ return Locale.getDefault();
+ }
+
+ public static String localizeViewCount(long viewCount, Context context) {
+ Locale locale = getPreferredLocale(context);
+
+ Resources res = context.getResources();
+ String viewsString = res.getString(R.string.view_count_text);
+
+ NumberFormat nf = NumberFormat.getInstance(locale);
+ String formattedViewCount = nf.format(viewCount);
+ return String.format(viewsString, formattedViewCount);
+ }
+
+ public static String localizeNumber(long number, Context context) {
+ Locale locale = getPreferredLocale(context);
+ NumberFormat nf = NumberFormat.getInstance(locale);
+ return nf.format(number);
+ }
+
+ private static String formatDate(String date, Context context) {
+ Locale locale = getPreferredLocale(context);
+ SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");
+ Date datum = null;
+ try {
+ datum = formatter.parse(date);
+ } catch (ParseException e) {
+ e.printStackTrace();
+ }
+
+ DateFormat df = DateFormat.getDateInstance(DateFormat.MEDIUM, locale);
+
+ return df.format(datum);
+ }
+
+ public static String localizeDate(String date, Context context) {
+ Resources res = context.getResources();
+ String dateString = res.getString(R.string.upload_date_text);
+
+ String formattedDate = formatDate(date, context);
+ return String.format(dateString, formattedDate);
+ }
+}
diff --git a/app/src/main/java/org/schabi/newpipe/PanicResponderActivity.java b/app/src/main/java/org/schabi/newpipe/PanicResponderActivity.java
new file mode 100644
index 000000000..8a36f5d5e
--- /dev/null
+++ b/app/src/main/java/org/schabi/newpipe/PanicResponderActivity.java
@@ -0,0 +1,50 @@
+
+package org.schabi.newpipe;
+
+import android.annotation.SuppressLint;
+import android.app.Activity;
+import android.content.Intent;
+import android.os.Build;
+import android.os.Bundle;
+
+/**
+ * Copyright (C) Hans-Christoph Steiner 2016
+ * PanicResponderActivity.java is part of NewPipe.
+ *
+ * NewPipe is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * NewPipe is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with NewPipe. If not, see .
+ */
+
+public class PanicResponderActivity extends Activity {
+
+ public static final String PANIC_TRIGGER_ACTION = "info.guardianproject.panic.action.TRIGGER";
+
+ @SuppressLint("NewApi")
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+
+ Intent intent = getIntent();
+ if (intent != null && PANIC_TRIGGER_ACTION.equals(intent.getAction())) {
+ // TODO explicitly clear the search results once they are restored when the app restarts
+ // or if the app reloads the current video after being killed, that should be cleared also
+ ExitActivity.exitAndRemoveFromRecentApps(this);
+ }
+
+ if (Build.VERSION.SDK_INT >= 21) {
+ finishAndRemoveTask();
+ } else {
+ finish();
+ }
+ }
+}
diff --git a/app/src/main/java/org/schabi/newpipe/PlayVideoActivity.java b/app/src/main/java/org/schabi/newpipe/PlayVideoActivity.java
index d5fea8c3e..ce1cf64cd 100644
--- a/app/src/main/java/org/schabi/newpipe/PlayVideoActivity.java
+++ b/app/src/main/java/org/schabi/newpipe/PlayVideoActivity.java
@@ -187,6 +187,18 @@ public class PlayVideoActivity extends AppCompatActivity {
videoView.pause();
}
+ @Override
+ public void onResume() {
+ super.onResume();
+ App.checkStartTor(this);
+ }
+
+ @Override
+ protected void onDestroy() {
+ super.onDestroy();
+ prefs = getPreferences(Context.MODE_PRIVATE);
+ }
+
@Override
public boolean onOptionsItemSelected(MenuItem item) {
int id = item.getItemId();
@@ -199,7 +211,7 @@ public class PlayVideoActivity extends AppCompatActivity {
intent.setAction(Intent.ACTION_SEND);
intent.putExtra(Intent.EXTRA_TEXT, videoUrl);
intent.setType("text/plain");
- startActivity(Intent.createChooser(intent, getString(R.string.shareDialogTitle)));
+ startActivity(Intent.createChooser(intent, getString(R.string.share_dialog_title)));
break;
case R.id.menu_item_screen_rotation:
toggleOrientation();
diff --git a/app/src/main/java/org/schabi/newpipe/SettingsActivity.java b/app/src/main/java/org/schabi/newpipe/SettingsActivity.java
index b434b53d8..52f4a17a3 100644
--- a/app/src/main/java/org/schabi/newpipe/SettingsActivity.java
+++ b/app/src/main/java/org/schabi/newpipe/SettingsActivity.java
@@ -1,10 +1,15 @@
package org.schabi.newpipe;
+import android.app.Activity;
import android.content.Context;
+import android.content.Intent;
import android.content.SharedPreferences;
import android.content.res.Configuration;
import android.os.Bundle;
import android.os.Environment;
+import android.preference.CheckBoxPreference;
+import android.preference.EditTextPreference;
+import android.preference.ListPreference;
import android.preference.PreferenceActivity;
import android.preference.PreferenceFragment;
import android.preference.PreferenceManager;
@@ -17,6 +22,8 @@ import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
+import info.guardianproject.netcipher.proxy.OrbotHelper;
+
/**
* Created by Christian Schabesberger on 31.08.15.
*
@@ -37,8 +44,9 @@ import android.view.ViewGroup;
* along with NewPipe. If not, see .
*/
-public class SettingsActivity extends PreferenceActivity {
+public class SettingsActivity extends PreferenceActivity {
+ private static final int REQUEST_INSTALL_ORBOT = 0x1234;
private AppCompatDelegate mDelegate = null;
@Override
@@ -55,12 +63,100 @@ public class SettingsActivity extends PreferenceActivity {
}
- public static class SettingsFragment extends PreferenceFragment {
+ public static class SettingsFragment extends PreferenceFragment{
+ SharedPreferences.OnSharedPreferenceChangeListener prefListener;
+
+ // get keys
+ String DEFAULT_RESOLUTION_PREFERENCE;
+ String DEFAULT_AUDIO_FORMAT_PREFERENCE;
+ String SEARCH_LANGUAGE_PREFERENCE;
+ String DOWNLOAD_PATH_PREFERENCE;
+ String USE_TOR_KEY;
+
+ private ListPreference defaultResolutionPreference;
+ private ListPreference defaultAudioFormatPreference;
+ private ListPreference searchLanguagePreference;
+ private EditTextPreference downloadPathPreference;
+ private CheckBoxPreference useTorCheckBox;
+ private SharedPreferences defaultPreferences;
+
+
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
- addPreferencesFromResource(R.xml.settings_screen);
+ addPreferencesFromResource(R.xml.settings);
+
+ final Activity activity = getActivity();
+
+ defaultPreferences = PreferenceManager.getDefaultSharedPreferences(activity);
+
+ // get keys
+ DEFAULT_RESOLUTION_PREFERENCE =getString(R.string.default_resolution_key);
+ DEFAULT_AUDIO_FORMAT_PREFERENCE =getString(R.string.default_audio_format_key);
+ SEARCH_LANGUAGE_PREFERENCE =getString(R.string.search_language_key);
+ DOWNLOAD_PATH_PREFERENCE = getString(R.string.download_path_key);
+ USE_TOR_KEY = getString(R.string.use_tor_key);
+
+ // get pref objects
+ defaultResolutionPreference =
+ (ListPreference) findPreference(DEFAULT_RESOLUTION_PREFERENCE);
+ defaultAudioFormatPreference =
+ (ListPreference) findPreference(DEFAULT_AUDIO_FORMAT_PREFERENCE);
+ searchLanguagePreference =
+ (ListPreference) findPreference(SEARCH_LANGUAGE_PREFERENCE);
+ downloadPathPreference =
+ (EditTextPreference) findPreference(DOWNLOAD_PATH_PREFERENCE);
+ useTorCheckBox = (CheckBoxPreference) findPreference(USE_TOR_KEY);
+
+ prefListener = new SharedPreferences.OnSharedPreferenceChangeListener() {
+ @Override
+ public void onSharedPreferenceChanged(SharedPreferences sharedPreferences,
+ String key) {
+ Activity a = getActivity();
+ updateSummary();
+
+ if (defaultPreferences.getBoolean(USE_TOR_KEY, false)) {
+ if (OrbotHelper.isOrbotInstalled(a)) {
+ App.configureTor(true);
+ OrbotHelper.requestStartTor(a);
+ } else {
+ Intent intent = OrbotHelper.getOrbotInstallIntent(a);
+ a.startActivityForResult(intent, REQUEST_INSTALL_ORBOT);
+ }
+ } else {
+ App.configureTor(false);
+ }
+ }
+ };
+ defaultPreferences.registerOnSharedPreferenceChangeListener(prefListener);
+
+ updateSummary();
}
+
+ // This is used to show the status of some preference in the description
+ private void updateSummary() {
+ defaultResolutionPreference.setSummary(
+ defaultPreferences.getString(DEFAULT_RESOLUTION_PREFERENCE,
+ getString(R.string.default_resolution_value)));
+ defaultAudioFormatPreference.setSummary(
+ defaultPreferences.getString(DEFAULT_AUDIO_FORMAT_PREFERENCE,
+ getString(R.string.default_audio_format_value)));
+ searchLanguagePreference.setSummary(
+ defaultPreferences.getString(SEARCH_LANGUAGE_PREFERENCE,
+ getString(R.string.default_language_value)));
+ downloadPathPreference.setSummary(
+ defaultPreferences.getString(DOWNLOAD_PATH_PREFERENCE,
+ getString(R.string.download_path_summary)));
+ }
+ }
+
+ @Override
+ protected void onActivityResult(int requestCode, int resultCode, Intent data) {
+ super.onActivityResult(requestCode, resultCode, data);
+ // try to start tor regardless of resultCode since clicking back after
+ // installing the app does not necessarily return RESULT_OK
+ App.configureTor(requestCode == REQUEST_INSTALL_ORBOT
+ && OrbotHelper.requestStartTor(this));
}
@Override
@@ -150,13 +246,13 @@ public class SettingsActivity extends PreferenceActivity {
}
public static void initSettings(Context context) {
- PreferenceManager.setDefaultValues(context, R.xml.settings_screen, false);
+ PreferenceManager.setDefaultValues(context, R.xml.settings, false);
SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(context);
- if(sp.getString(context.getString(R.string.downloadPathPreference), "").isEmpty()){
+ if(sp.getString(context.getString(R.string.download_path_key), "").isEmpty()){
SharedPreferences.Editor spEditor = sp.edit();
String newPipeDownloadStorage =
Environment.getExternalStorageDirectory().getAbsolutePath() + "/NewPipe";
- spEditor.putString(context.getString(R.string.downloadPathPreference)
+ spEditor.putString(context.getString(R.string.download_path_key)
, newPipeDownloadStorage);
spEditor.apply();
}
diff --git a/app/src/main/java/org/schabi/newpipe/VideoInfoItemViewCreator.java b/app/src/main/java/org/schabi/newpipe/VideoInfoItemViewCreator.java
index b7eaa4285..c2bbb069e 100644
--- a/app/src/main/java/org/schabi/newpipe/VideoInfoItemViewCreator.java
+++ b/app/src/main/java/org/schabi/newpipe/VideoInfoItemViewCreator.java
@@ -1,5 +1,6 @@
package org.schabi.newpipe;
+import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
@@ -33,7 +34,7 @@ class VideoInfoItemViewCreator {
this.inflater = inflater;
}
- public View getViewFromVideoInfoItem(View convertView, ViewGroup parent, VideoPreviewInfo info) {
+ public View getViewFromVideoInfoItem(View convertView, ViewGroup parent, VideoPreviewInfo info, Context context) {
ViewHolder holder;
if(convertView == null) {
convertView = inflater.inflate(R.layout.video_item, parent, false);
@@ -59,8 +60,7 @@ class VideoInfoItemViewCreator {
if(!info.upload_date.isEmpty()) {
holder.itemUploadDateView.setText(info.upload_date);
} else {
- //tweak if necessary: This is a hack to prevent having white space in the layout :P
- holder.itemUploadDateView.setText(String.format("%d", info.view_count));
+ holder.itemUploadDateView.setText(Localization.localizeViewCount(info.view_count, context));
}
return convertView;
diff --git a/app/src/main/java/org/schabi/newpipe/VideoItemDetailActivity.java b/app/src/main/java/org/schabi/newpipe/VideoItemDetailActivity.java
index 4a553241f..bf28549b3 100644
--- a/app/src/main/java/org/schabi/newpipe/VideoItemDetailActivity.java
+++ b/app/src/main/java/org/schabi/newpipe/VideoItemDetailActivity.java
@@ -80,7 +80,7 @@ public class VideoItemDetailActivity extends AppCompatActivity {
}
}
if(currentStreamingService == -1) {
- Toast.makeText(this, R.string.urlNotSupportedText, Toast.LENGTH_LONG)
+ Toast.makeText(this, R.string.url_not_supported_toast, Toast.LENGTH_LONG)
.show();
}
//arguments.putString(VideoItemDetailFragment.VIDEO_URL,
@@ -89,7 +89,7 @@ public class VideoItemDetailActivity extends AppCompatActivity {
arguments.putBoolean(VideoItemDetailFragment.AUTO_PLAY,
PreferenceManager.getDefaultSharedPreferences(this)
- .getBoolean(getString(R.string.autoPlayThroughIntent), false));
+ .getBoolean(getString(R.string.autoplay_through_intent_key), false));
} else {
videoUrl = getIntent().getStringExtra(VideoItemDetailFragment.VIDEO_URL);
currentStreamingService = getIntent().getIntExtra(VideoItemDetailFragment.STREAMING_SERVICE, -1);
@@ -113,6 +113,12 @@ public class VideoItemDetailActivity extends AppCompatActivity {
.commit();
}
+ @Override
+ public void onResume() {
+ super.onResume();
+ App.checkStartTor(this);
+ }
+
@Override
public void onSaveInstanceState(Bundle outState) {
outState.putString(VideoItemDetailFragment.VIDEO_URL, videoUrl);
diff --git a/app/src/main/java/org/schabi/newpipe/VideoItemDetailFragment.java b/app/src/main/java/org/schabi/newpipe/VideoItemDetailFragment.java
index 0173c07de..03ec4e5aa 100644
--- a/app/src/main/java/org/schabi/newpipe/VideoItemDetailFragment.java
+++ b/app/src/main/java/org/schabi/newpipe/VideoItemDetailFragment.java
@@ -1,9 +1,7 @@
package org.schabi.newpipe;
-import android.annotation.SuppressLint;
import android.app.Activity;
import android.content.Intent;
-import android.content.SharedPreferences;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
@@ -35,13 +33,7 @@ import android.view.MenuItem;
import android.widget.Toast;
import java.net.URL;
-import java.text.DateFormat;
-import java.text.NumberFormat;
-import java.text.ParseException;
-import java.text.SimpleDateFormat;
import java.util.ArrayList;
-import java.util.Date;
-import java.util.Locale;
import java.util.Vector;
import org.schabi.newpipe.services.VideoExtractor;
@@ -235,7 +227,7 @@ public class VideoItemDetailFragment extends Fragment {
switch (info.errorCode) {
case VideoInfo.NO_ERROR: {
View nextVideoView = videoItemViewCreator
- .getViewFromVideoInfoItem(null, nextVideoFrame, info.nextVideo);
+ .getViewFromVideoInfoItem(null, nextVideoFrame, info.nextVideo, getContext());
nextVideoFrame.addView(nextVideoView);
@@ -253,31 +245,20 @@ public class VideoItemDetailFragment extends Fragment {
uploaderView.setText(info.uploader);
actionBarHandler.setChannelName(info.uploader);
- Locale locale = getPreferredLocale();
- NumberFormat nf = NumberFormat.getInstance(locale);
- String localisedViewCount = nf.format(info.view_count);
- viewCountView.setText(
- String.format(
- res.getString(R.string.viewCountText), localisedViewCount));
+ String localizedViewCount = Localization.localizeViewCount(info.view_count, getContext());
+ viewCountView.setText(localizedViewCount);
- thumbsUpView.setText(nf.format(info.like_count));
- thumbsDownView.setText(nf.format(info.dislike_count));
+ String localizedLikeCount = Localization.localizeNumber(info.like_count, getContext());
+ thumbsUpView.setText(localizedLikeCount);
- @SuppressLint("SimpleDateFormat")
- SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");
- Date datum = null;
- try {
- datum = formatter.parse(info.upload_date);
- } catch (ParseException e) {
- e.printStackTrace();
- }
+ String localizedDislikeCount = Localization.localizeNumber(info.dislike_count, getContext());
+ thumbsDownView.setText(localizedDislikeCount);
- DateFormat df = DateFormat.getDateInstance(DateFormat.MEDIUM, locale);
+ String localizedDate = Localization.localizeDate(info.upload_date, getContext());
+ uploadDateView.setText(localizedDate);
- String localisedDate = df.format(datum);
- uploadDateView.setText(
- String.format(res.getString(R.string.uploadDateText), localisedDate));
descriptionView.setText(Html.fromHtml(info.description));
+
descriptionView.setMovementMethod(LinkMovementMethod.getInstance());
actionBarHandler.setServiceId(streamingServiceId);
@@ -306,7 +287,7 @@ public class VideoItemDetailFragment extends Fragment {
VideoItemDetailFragment.ARG_ITEM_ID, currentVideoInfo.nextVideo.id); */
detailIntent.putExtra(
VideoItemDetailFragment.VIDEO_URL, currentVideoInfo.nextVideo.webpage_url);
- //todo: make id dynamic the following line is crap
+
detailIntent.putExtra(VideoItemDetailFragment.STREAMING_SERVICE, streamingServiceId);
startActivity(detailIntent);
}
@@ -315,13 +296,13 @@ public class VideoItemDetailFragment extends Fragment {
break;
case VideoInfo.ERROR_BLOCKED_BY_GEMA:
thumbnailView.setImageBitmap(BitmapFactory.decodeResource(
- getResources(), R.drawable.gruese_die_gema_unangebracht));
+ getResources(), R.drawable.gruese_die_gema));
backgroundButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent();
intent.setAction(Intent.ACTION_VIEW);
- intent.setData(Uri.parse(activity.getString(R.string.c3sUrl)));
+ intent.setData(Uri.parse(activity.getString(R.string.c3s_url)));
activity.startActivity(intent);
}
});
@@ -364,7 +345,7 @@ public class VideoItemDetailFragment extends Fragment {
super.onCreate(savedInstanceState);
activity = (AppCompatActivity) getActivity();
showNextVideoItem = PreferenceManager.getDefaultSharedPreferences(getActivity())
- .getBoolean(activity.getString(R.string.showNextVideo), true);
+ .getBoolean(activity.getString(R.string.show_next_video_key), true);
}
@@ -458,30 +439,6 @@ public class VideoItemDetailFragment extends Fragment {
}
}
-
-
- /**Returns the java.util.Locale object which corresponds to the locale set in NewPipe's preferences.
- * Currently not affected by the device's locale.*/
- private Locale getPreferredLocale() {
- SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(getContext());
- String languageKey = getContext().getString(R.string.searchLanguage);
- //i know the following line defaults languageCode to "en", but java is picky about uninitialised values
- // Schabi: well lint tels me the value is redundant. I'll suppress it for now.
- @SuppressWarnings("UnusedAssignment")
- String languageCode = "en";
- languageCode = sp.getString(languageKey, "en");
-
- if(languageCode.length() == 2) {
- return new Locale(languageCode);
- }
- else if(languageCode.contains("_")) {
- String country = languageCode
- .substring(languageCode.indexOf("_"), languageCode.length());
- return new Locale(languageCode.substring(0, 2), country);
- }
- return Locale.getDefault();
- }
-
private boolean checkIfLandscape() {
DisplayMetrics displayMetrics = new DisplayMetrics();
getActivity().getWindowManager().getDefaultDisplay().getMetrics(displayMetrics);
diff --git a/app/src/main/java/org/schabi/newpipe/VideoItemListActivity.java b/app/src/main/java/org/schabi/newpipe/VideoItemListActivity.java
index 6aaf10d41..446b916b5 100644
--- a/app/src/main/java/org/schabi/newpipe/VideoItemListActivity.java
+++ b/app/src/main/java/org/schabi/newpipe/VideoItemListActivity.java
@@ -3,6 +3,7 @@ package org.schabi.newpipe;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
+import android.preference.PreferenceManager;
import android.support.v4.app.NavUtils;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.SearchView;
@@ -171,7 +172,13 @@ public class VideoItemListActivity extends AppCompatActivity
}
}
- SettingsActivity.initSettings(this);
+ PreferenceManager.setDefaultValues(this, R.xml.settings, false);
+ }
+
+ @Override
+ public void onResume() {
+ super.onResume();
+ App.checkStartTor(this);
}
/**
diff --git a/app/src/main/java/org/schabi/newpipe/VideoItemListFragment.java b/app/src/main/java/org/schabi/newpipe/VideoItemListFragment.java
index 93c6074b2..bea1c6111 100644
--- a/app/src/main/java/org/schabi/newpipe/VideoItemListFragment.java
+++ b/app/src/main/java/org/schabi/newpipe/VideoItemListFragment.java
@@ -66,6 +66,9 @@ public class VideoItemListFragment extends ListFragment {
private View footer;
+ // used to suppress request for loading a new page while another page is already loading.
+ private boolean loadingNextPage = true;
+
private class ResultRunnable implements Runnable {
private final SearchEngine.Result result;
private final int requestId;
@@ -76,6 +79,9 @@ public class VideoItemListFragment extends ListFragment {
@Override
public void run() {
updateListOnResult(result, requestId);
+ if (android.os.Build.VERSION.SDK_INT >= 19) {
+ getListView().removeFooterView(footer);
+ }
}
}
@@ -84,7 +90,7 @@ public class VideoItemListFragment extends ListFragment {
private final String query;
private final int page;
final Handler h = new Handler();
- private volatile boolean run = true;
+ private volatile boolean runs = true;
private final int requestId;
public SearchRunnable(SearchEngine engine, String query, int page, int requestId) {
this.engine = engine;
@@ -93,17 +99,18 @@ public class VideoItemListFragment extends ListFragment {
this.requestId = requestId;
}
void terminate() {
- run = false;
+ runs = false;
}
@Override
public void run() {
try {
SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(getContext());
- String searchLanguageKey = getContext().getString(R.string.searchLanguage);
- String searchLanguage = sp.getString(searchLanguageKey, "en");
+ String searchLanguageKey = getContext().getString(R.string.search_language_key);
+ String searchLanguage = sp.getString(searchLanguageKey,
+ getString(R.string.default_language_value));
SearchEngine.Result result = engine.search(query, page, searchLanguage);
Log.i(TAG, "language code passed:\""+searchLanguage+"\"");
- if(run) {
+ if(runs) {
h.post(new ResultRunnable(result, requestId));
}
} catch(Exception e) {
@@ -111,19 +118,11 @@ public class VideoItemListFragment extends ListFragment {
h.post(new Runnable() {
@Override
public void run() {
- Toast.makeText(getActivity(), "Network Error", Toast.LENGTH_SHORT).show();
+ Toast.makeText(getActivity(), getString(R.string.network_error),
+ Toast.LENGTH_SHORT).show();
}
});
}
- getActivity().runOnUiThread(new Runnable() {
- @Override
- public void run() {
- if (android.os.Build.VERSION.SDK_INT >= 19) {
- getListView().removeFooterView(footer);
- }
- }
- });
-
}
}
@@ -203,8 +202,9 @@ public class VideoItemListFragment extends ListFragment {
}
private void nextPage() {
+ loadingNextPage = true;
lastPage++;
- Log.d(TAG, getString(R.string.searchPage) + Integer.toString(lastPage));
+ Log.d(TAG, getString(R.string.search_page) + Integer.toString(lastPage));
startSearch(query, lastPage);
}
@@ -228,7 +228,7 @@ public class VideoItemListFragment extends ListFragment {
Toast.makeText(getActivity(), result.errorMessage, Toast.LENGTH_LONG).show();
} else {
if (!result.suggestion.isEmpty()) {
- Toast.makeText(getActivity(), getString(R.string.didYouMean) + result.suggestion + " ?",
+ Toast.makeText(getActivity(), getString(R.string.did_you_mean) + result.suggestion + " ?",
Toast.LENGTH_LONG).show();
}
updateList(result.resultList);
@@ -248,6 +248,8 @@ public class VideoItemListFragment extends ListFragment {
Log.w(TAG, "Trying to set value while activity doesn't exist anymore.");
} catch(Exception e) {
e.printStackTrace();
+ } finally {
+ loadingNextPage = false;
}
}
@@ -297,7 +299,8 @@ public class VideoItemListFragment extends ListFragment {
super.onViewCreated(view, savedInstanceState);
list = getListView();
videoListAdapter = new VideoListAdapter(getActivity(), this);
- footer = ((LayoutInflater) getActivity().getSystemService(Context.LAYOUT_INFLATER_SERVICE)).inflate(R.layout.paginate_footer, null, false);
+ footer = ((LayoutInflater) getActivity().getSystemService(Context.LAYOUT_INFLATER_SERVICE))
+ .inflate(R.layout.paginate_footer, null, false);
setListAdapter(videoListAdapter);
@@ -318,13 +321,15 @@ public class VideoItemListFragment extends ListFragment {
}
@Override
- public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
+ public void onScroll(AbsListView view, int firstVisibleItem,
+ int visibleItemCount, int totalItemCount) {
if (mode != PRESENT_VIDEOS_MODE
&& list.getChildAt(0) != null
&& list.getLastVisiblePosition() == list.getAdapter().getCount() - 1
&& list.getChildAt(list.getChildCount() - 1).getBottom() <= list.getHeight()) {
long time = System.currentTimeMillis();
- if ((time - lastScrollDate) > 200) {
+ if ((time - lastScrollDate) > 200
+ && !loadingNextPage) {
lastScrollDate = time;
getListView().addFooterView(footer);
nextPage();
diff --git a/app/src/main/java/org/schabi/newpipe/VideoListAdapter.java b/app/src/main/java/org/schabi/newpipe/VideoListAdapter.java
index e85e74e22..de08b2f03 100644
--- a/app/src/main/java/org/schabi/newpipe/VideoListAdapter.java
+++ b/app/src/main/java/org/schabi/newpipe/VideoListAdapter.java
@@ -96,10 +96,10 @@ class VideoListAdapter extends BaseAdapter {
@Override
public View getView(int position, View convertView, ViewGroup parent) {
- convertView = viewCreator.getViewFromVideoInfoItem(convertView, parent, videoList.get(position));
+ convertView = viewCreator.getViewFromVideoInfoItem(convertView, parent, videoList.get(position), context);
if(listView.isItemChecked(position)) {
- convertView.setBackgroundColor(ContextCompat.getColor(context,R.color.primaryColorYoutube));
+ convertView.setBackgroundColor(ContextCompat.getColor(context,R.color.light_youtube_primary_color));
} else {
convertView.setBackgroundColor(0);
}
diff --git a/app/src/main/java/org/schabi/newpipe/services/VideoExtractor.java b/app/src/main/java/org/schabi/newpipe/services/VideoExtractor.java
index 7fd8a58cc..f57ef0894 100644
--- a/app/src/main/java/org/schabi/newpipe/services/VideoExtractor.java
+++ b/app/src/main/java/org/schabi/newpipe/services/VideoExtractor.java
@@ -106,7 +106,7 @@ public abstract class VideoExtractor {
return videoInfo;
}
-
+ //todo: add licence field
public abstract int getErrorCode();
public abstract String getErrorMessage();
diff --git a/app/src/main/res/drawable-hdpi/ic_close_white_24dp.png b/app/src/main/res/drawable-hdpi/ic_close_white_24dp.png
new file mode 100644
index 000000000..ceb1a1eeb
Binary files /dev/null and b/app/src/main/res/drawable-hdpi/ic_close_white_24dp.png differ
diff --git a/app/src/main/res/drawable-mdpi/ic_close_white_24dp.png b/app/src/main/res/drawable-mdpi/ic_close_white_24dp.png
new file mode 100644
index 000000000..af7f8288d
Binary files /dev/null and b/app/src/main/res/drawable-mdpi/ic_close_white_24dp.png differ
diff --git a/app/src/main/res/drawable-nodpi/gruese_die_gema.png b/app/src/main/res/drawable-nodpi/gruese_die_gema.png
new file mode 100644
index 000000000..d6e2af3d5
Binary files /dev/null and b/app/src/main/res/drawable-nodpi/gruese_die_gema.png differ
diff --git a/app/src/main/res/drawable-nodpi/gruese_die_gema_unangebracht.png b/app/src/main/res/drawable-nodpi/gruese_die_gema_unangebracht.png
deleted file mode 100644
index e19491b7b..000000000
Binary files a/app/src/main/res/drawable-nodpi/gruese_die_gema_unangebracht.png and /dev/null differ
diff --git a/app/src/main/res/drawable-xhdpi/ic_close_white_24dp.png b/app/src/main/res/drawable-xhdpi/ic_close_white_24dp.png
new file mode 100644
index 000000000..b7c7ffd0e
Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/ic_close_white_24dp.png differ
diff --git a/app/src/main/res/drawable-xxhdpi/ic_close_white_24dp.png b/app/src/main/res/drawable-xxhdpi/ic_close_white_24dp.png
new file mode 100644
index 000000000..6b717e0dd
Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/ic_close_white_24dp.png differ
diff --git a/app/src/main/res/drawable-xxxhdpi/ic_close_white_24dp.png b/app/src/main/res/drawable-xxxhdpi/ic_close_white_24dp.png
new file mode 100644
index 000000000..396419219
Binary files /dev/null and b/app/src/main/res/drawable-xxxhdpi/ic_close_white_24dp.png differ
diff --git a/app/src/main/res/layout-v18/fragment_videoitem_detail.xml b/app/src/main/res/layout-v18/fragment_videoitem_detail.xml
index 91cfea986..cbb5652ca 100644
--- a/app/src/main/res/layout-v18/fragment_videoitem_detail.xml
+++ b/app/src/main/res/layout-v18/fragment_videoitem_detail.xml
@@ -11,7 +11,7 @@
android:id="@+id/videoitem_detail">
@@ -69,7 +69,7 @@
android:layout_height="wrap_content"
android:padding="@dimen/video_item_detail_info_text_padding"
android:layout_below="@id/detailVideoThumbnailWindowLayout"
- android:background="@color/background_gray">
+ android:background="@color/light_background_color">
+ android:text="@string/similar_videos_btn_text"/>
diff --git a/app/src/main/res/layout-v21/fragment_videoitem_detail.xml b/app/src/main/res/layout-v21/fragment_videoitem_detail.xml
index 8d19e1fee..b7919dbe8 100644
--- a/app/src/main/res/layout-v21/fragment_videoitem_detail.xml
+++ b/app/src/main/res/layout-v21/fragment_videoitem_detail.xml
@@ -11,7 +11,7 @@
android:id="@+id/videoitem_detail">
@@ -71,7 +71,7 @@
android:layout_height="wrap_content"
android:padding="@dimen/video_item_detail_info_text_padding"
android:layout_below="@id/detailVideoThumbnailWindowLayout"
- android:background="@color/background_gray">
+ android:background="@color/light_background_color">
+ android:text="@string/similar_videos_btn_text"/>
diff --git a/app/src/main/res/layout/fragment_videoitem_detail.xml b/app/src/main/res/layout/fragment_videoitem_detail.xml
index 987c416ec..611a5aa14 100644
--- a/app/src/main/res/layout/fragment_videoitem_detail.xml
+++ b/app/src/main/res/layout/fragment_videoitem_detail.xml
@@ -28,7 +28,7 @@
android:background="?attr/selectableItemBackground">
@@ -69,7 +69,7 @@
android:layout_height="wrap_content"
android:padding="@dimen/video_item_detail_info_text_padding"
android:layout_below="@id/detailVideoThumbnailWindowLayout"
- android:background="@color/background_gray">
+ android:background="@color/light_background_color">
+ android:text="@string/similar_videos_btn_text"/>
diff --git a/app/src/main/res/layout/paginate_footer.xml b/app/src/main/res/layout/paginate_footer.xml
index 8e5d7571d..b3757c1af 100644
--- a/app/src/main/res/layout/paginate_footer.xml
+++ b/app/src/main/res/layout/paginate_footer.xml
@@ -8,7 +8,7 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/player_notification_expanded.xml b/app/src/main/res/layout/player_notification_expanded.xml
new file mode 100644
index 000000000..3fd379a6b
--- /dev/null
+++ b/app/src/main/res/layout/player_notification_expanded.xml
@@ -0,0 +1,80 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/video_item.xml b/app/src/main/res/layout/video_item.xml
index 1c7caac60..cff3a4224 100644
--- a/app/src/main/res/layout/video_item.xml
+++ b/app/src/main/res/layout/video_item.xml
@@ -32,7 +32,7 @@
tools:ignore="RtlHardcoded">
+ android:background="@color/duration_dackground_color"
+ android:textColor="@color/duration_text_color"/>
diff --git a/app/src/main/res/menu/video_player.xml b/app/src/main/res/menu/video_player.xml
index f82730139..c79217adc 100644
--- a/app/src/main/res/menu/video_player.xml
+++ b/app/src/main/res/menu/video_player.xml
@@ -3,7 +3,7 @@
xmlns:app="http://schemas.android.com/apk/res-auto">
\ No newline at end of file
diff --git a/app/src/main/res/menu/videoitem_detail.xml b/app/src/main/res/menu/videoitem_detail.xml
index 4fed67637..f10a0a63e 100644
--- a/app/src/main/res/menu/videoitem_detail.xml
+++ b/app/src/main/res/menu/videoitem_detail.xml
@@ -3,7 +3,7 @@
xmlns:app="http://schemas.android.com/apk/res-auto">
@@ -18,7 +18,7 @@
android:icon="@drawable/ic_share_black"/>
diff --git a/app/src/main/res/values-de/strings.xml b/app/src/main/res/values-de/strings.xml
index d17fae7bd..fdef2ba3e 100644
--- a/app/src/main/res/values-de/strings.xml
+++ b/app/src/main/res/values-de/strings.xml
@@ -1,53 +1,59 @@
- %1$s Aufrufe
- Hochgeladen am %1$s
- Keinen Streamplayer gefunden. Vielleicht möchtest du einen installieren.
- Jetzt installieren
+ %1$s Aufrufe
+ Hochgeladen am %1$s
+ Keinen Streamplayer gefunden. Vielleicht möchtest du einen installieren.
+ Jetzt installieren
Abbrechen
In Browser öffnen
Teilen
Download
Suchen
Einstellungen
- Meintest du:
- Suchseite:
- Teilen mit:
- Browser:
- Rotation
- Einstellungen
+ Meintest du:
+ Suchseite:
+ Teilen mit:
+ Browser:
+ Rotation
+ Einstellungen
Externen Player benutzen
- Downloadverzeichnis
- Verzeichnis in dem heruntergeladene Videos gespeichert werden.
- Download Verzeichnis eingeben
- Automatisches Abspielen durch Intent
- Startet ein Video automatisch wenn es von einer anderen App aufgerufen wurde.
- Standard Auflösung
- Mit Kodi abspielen
- Kore app wurde nicht gefunden. Kore wird benötigt, um Videos mit Kodi wieder zu geben.
+ Downloadverzeichnis
+ Verzeichnis in dem heruntergeladene Videos gespeichert werden.
+ Download Verzeichnis eingeben
+ Automatisches Abspielen durch Intent
+ Startet ein Video automatisch wenn es von einer anderen App aufgerufen wurde.
+ Standard Auflösung
+ Mit Kodi abspielen
+ Kore app wurde nicht gefunden. Kore wird benötigt, um Videos mit Kodi wieder zu geben.
Kore installieren
- Zeige \"Mit Kodi abspielen\" Option
- Zeigt eine Option an, über die man Videos mit dem Kodi Mediacenter abspielen kann.
- Audio
- Bevorzugtes Audio Format
- WebM - freies Format
- m4a - bessere Qualität
- Herunterladen
+ Zeige \"Mit Kodi abspielen\" Option
+ Zeigt eine Option an, über die man Videos mit dem Kodi Mediacenter abspielen kann.
+ Audio
+ Bevorzugtes Audio Format
+ WebM — freies Format
+ m4a — bessere Qualität
+ Herunterladen
- Video
- Audio
- Nächstes Video
- Zeige nächstes und ähnliche Videos
- URL wird nicht unterstützt.
- Ähnliche Videos
- VIDEO & AUDIO
- INFO
- ETC
-Bevorzugte Sprache
- Video-Vorschau-Bild
- Video-Vorschau-Bild
- Nutzerbild
- gefällt nicht
- gefällt
+ Nächstes Video
+ Zeige nächstes und ähnliche Videos
+ URL wird nicht unterstützt.
+ Ähnliche Videos
+ Video & Audio
+ Bevorzugte Sprache des Inhalts
+ Video-Vorschau-Bild
+ Video-Vorschau-Bild
+ Nutzerbild
+ Gefällt nicht
+ Gefällt
+ Lade
+ Benutze externen Videoabspieler
+ Benutze externen Audioabspieler
+ Spiele im Hintergrund ab
+ Abspielen
+
+ Benutze TOR
+ Erzwinge das Herunterladen durch TOR für verbesserte Privatsphäre (Videostream noch nicht unterstützt)
diff --git a/app/src/main/res/values-es/strings.xml b/app/src/main/res/values-es/strings.xml
index bcf25e8fa..3b91eb0d4 100644
--- a/app/src/main/res/values-es/strings.xml
+++ b/app/src/main/res/values-es/strings.xml
@@ -1,39 +1,39 @@
- %1$s visitas
- Subido el %1$s
- No se ha encontrado ningún reproductor de vídeo. Quizás quieras instalar alguno.
- Instalarlo
+ %1$s visitas
+ Subido el %1$s
+ No se ha encontrado ningún reproductor de vídeo. Quizás quieras instalar alguno.
+ Instalarlo
Cancelar
Abrir en el navegador
Compartir
Descargar
Buscar
Ajustes
- "¿Querías decir?: "
- Buscar página:
- Compartir con:
- Selecciona navegador:
- rotación
- Ajustes
+ "¿Querías decir?: "
+ Buscar página:
+ Compartir con:
+ Selecciona navegador:
+ rotación
+ Ajustes
Usar reproductor externo
- Descargar en…
- Ruta donde guardar los vídeos descargados.
- Localización del directorio de descargas
- Reproducción automática
- Reproducir los vídeos automaticamente cuando se llama desde otra aplicación.
- Resolución por defecto
- Reproducir con Kodi
- Aplicación Kore no encontrada. Kore es necesario para reproducir vídeos con Kodi media center.
+ Descargar en…
+ Ruta donde guardar los vídeos descargados.
+ Localización del directorio de descargas
+ Reproducción automática
+ Reproducir los vídeos automaticamente cuando se llama desde otra aplicación.
+ Resolución por defecto
+ Reproducir con Kodi
+ Aplicación Kore no encontrada. Kore es necesario para reproducir vídeos con Kodi media center.
Instalar Kore
- Mostrar la opción \"Reproducir con Kodi\"
- Muestra una opción para reproducir el vídeo con Kodi media center.
- Audio
- Formato de audio por defecto
- WebM - formato libre
- m4a - mejor calidad
- Descargar
- Siguiente vídeo
- URL no soportada.
- Vídeos similares
+ Mostrar la opción \"Reproducir con Kodi\"
+ Muestra una opción para reproducir el vídeo con Kodi media center.
+ Audio
+ Formato de audio por defecto
+ WebM — formato libre
+ m4a — mejor calidad
+ Descargar
+ Siguiente vídeo
+ URL no soportada.
+ Vídeos similares
diff --git a/app/src/main/res/values-eu/strings.xml b/app/src/main/res/values-eu/strings.xml
new file mode 100644
index 000000000..7d0a7710e
--- /dev/null
+++ b/app/src/main/res/values-eu/strings.xml
@@ -0,0 +1,54 @@
+
+%1$s ikustaldi
+ Argitaratze-data: %1$s
+ Instalatu
+ Utzi
+ Nabigatzailean ireki
+ Partekatu
+ Kargatzen
+ Deskargatu
+ Bilatu
+ Ezarpenak
+ Partekatu honekin:
+ Nabigatzailea aukeratu:
+ biratzea
+ Ezarpenak
+ Deskargatzeko kokapena
+ Deskargatutako bideoak gordetzeko lekua.
+ Sar ezazu deskargatzeko lekua
+ Lehenetsitako bereizmena
+ Kodirekin erreproduzitu
+ Kore aplikazioa ez da aurkitu. Kore beharrezkoa da Kodi multimedia zentroarekin bideoak erreproduzitzeko.
+ Kore instalatu
+ \"Kodirekin erreproduzitu\" aukera erakutsi
+ Kodi multimedia zentroarekin bideoa erreproduzitzeko aukera erakusten du.
+ Audioa
+ Audio formatu lehenetsia
+ WebM — formatu askea
+ m4a — kalitate hobea
+ Deskargatu
+ Hurrengo bideoa
+ Hurrengo bideoa eta antzekoak erakutsi
+ URLa ez da onartzen.
+ Antzeko bideoak
+ Edukiaren hizkuntz lehenetsia
+ Bideoa eta Audioa
+ Erreproduzitu
+
+ Bideoaren aurreikuspen argazkitxoa
+ Bideoaren aurreikuspen argazkitxoa
+ Igotzailearen argazkitxoa
+ Ez dute gustoko
+ Gustoko dute
+ Tor erabili
+ Trafikoa Tor bidez deskargatzea behartzen du pribatutasuna hobetzeko (jario bideoak ez daude oraindik onartuta)
+ NewPipe atzeko planoko erreproduzitzailea
+ Jario erreproduzitzailerik ez da aurkitu. Agian bat instalatu nahi dezakezu.
+ "Hau esan nahi al zenuen: "
+ "Orrialdea bilatu: "
+ Kanpoko bideo erreproduzitzailea erabili
+ Kanpoko audio erreproduzitzailea erabili
+ Intent bidez automatikoki erreproduzitu
+ Bideoa automatikoki hasten du beste aplikazio batetik deitu denean.
+ Atzeko planoan erreproduzitzen
+
diff --git a/app/src/main/res/values-fa/strings.xml b/app/src/main/res/values-fa/strings.xml
index 8951a6ee4..0d9b54a04 100644
--- a/app/src/main/res/values-fa/strings.xml
+++ b/app/src/main/res/values-fa/strings.xml
@@ -1,42 +1,42 @@
- %1$s نماها
- بارگذاریشده در: %1$s
- هیچ پخشکنندهی جریانی یافت نشد. ممکن است بخواهید یکی نصب کنید.
- نصب کنید
+ %1$s نماها
+ بارگذاریشده در: %1$s
+ هیچ پخشکنندهی جریانی یافت نشد. ممکن است بخواهید یکی نصب کنید.
+ نصب کنید
انصراف
بازکردن در مرورگر
همرسانی
بارگیری
جستجو
تنظیمات
- منظورتان این است:
- صفحهی جستجو:
- همرسانی با:
- مرورگر را برگزینید:
- چرخش
- تنظیمات
+ منظورتان این است:
+ صفحهی جستجو:
+ همرسانی با:
+ مرورگر را برگزینید:
+ چرخش
+ تنظیمات
استفاده از پخشکنندهی خارجی
- محل بارگیری
- مسیری که ویدئوهای دریافت شده در آن ذخیره میشوند.
- مسیر دریافت را وارد کنید
- پخش خودکار از Intent
- ویدئو هنگامی که از برنامهی دیگری فراخوانده شد خودکار پخش میشود.
- وضوح پیشفرض
- پخش با Kodi
- برنامهی Kore نصب نیست. برای پخش کردن ویدئوها با مرکز رسانهی Kodi، به Kore نیاز دارید.
+ محل بارگیری
+ مسیری که ویدئوهای دریافت شده در آن ذخیره میشوند.
+ مسیر دریافت را وارد کنید
+ پخش خودکار از Intent
+ ویدئو هنگامی که از برنامهی دیگری فراخوانده شد خودکار پخش میشود.
+ وضوح پیشفرض
+ پخش با Kodi
+ برنامهی Kore نصب نیست. برای پخش کردن ویدئوها با مرکز رسانهی Kodi، به Kore نیاز دارید.
نصب Kore
- نمایش گزینهی «پخش با Kodi»
- گزینهای برای پخش کردن ویدئو با مرکز رسانهی Kodi نشان میدهد.
- صدا
- قالب پیشفرض صدا
- WebM - قالبی آزاد
- m4a - کیفیت بهتر
- دریافت
+ نمایش گزینهی «پخش با Kodi»
+ گزینهای برای پخش کردن ویدئو با مرکز رسانهی Kodi نشان میدهد.
+ صدا
+ قالب پیشفرض صدا
+ WebM — قالبی آزاد
+ m4a — کیفیت بهتر
+ دریافت
- ویدئو
- صدا
- ویدئوی بعدی
- پیوند پشتیبانی نمیشود.
+ ویدئوی بعدی
+ پیوند پشتیبانی نمیشود.
diff --git a/app/src/main/res/values-fr/strings.xml b/app/src/main/res/values-fr/strings.xml
index 4800a7493..d0d04db68 100644
--- a/app/src/main/res/values-fr/strings.xml
+++ b/app/src/main/res/values-fr/strings.xml
@@ -1,52 +1,58 @@
- Démarrer automatiquement la vidéo si elle a été appelée depuis une autre application.
+ Démarrer automatiquement la vidéo si elle a été appelée depuis une autre application.
Annuler
- Choisir un navigateur :
- Résolution par défaut
- "S\'agirait-il de : "
+ Choisir un navigateur :
+ Résolution par défaut
+ "S\'agirait-il de : "
Télécharger
- Emplacement des téléchargements
- Entrez l\'emplacement du téléchargement
- Emplacement des vidéos téléchargées.
- Installer
+ Emplacement des téléchargements
+ Entrez l\'emplacement du téléchargement
+ Emplacement des vidéos téléchargées.
+ Installer
Installer Kore
- L\'application Kore est introuvable. Kore est nécessaire afin de lire des vidéos dans Kodi media center.
- Aucun lecteur de streaming détecté. Vous devriez en installer un.
+ L\'application Kore est introuvable. Kore est nécessaire afin de lire des vidéos dans Kodi media center.
+ Aucun lecteur de streaming détecté. Vous devriez en installer un.
Ouvrir dans le navigateur
- Lecture automatique via Intent
- Lire avec Kodi
- rotation
+ Lecture automatique via Intent
+ Lire avec Kodi
+ rotation
Rechercher
- "Rechercher dans la page : "
+ "Rechercher dans la page : "
Paramètres
Partager
- Partager avec :
- Afficher une option pour lire la vidéo avec Kodi media center.
- Afficher l\'option \"Lire avec Kodi\"
- Paramètres
- Mise en ligne le %1$s
+ Partager avec :
+ Afficher une option pour lire la vidéo avec Kodi media center.
+ Afficher l\'option \"Lire avec Kodi\"
+ Paramètres
+ Mise en ligne le %1$s
Utiliser un lecteur externe
- %1$s vues
- Audio
- Format audio par défaut
- WebM- format libre
- m4a - meilleur qualité
- Télécharger
- Vidéo suivante
- Afficher les vidéos suivantes et similaires
- URL non supportée.
- Vidéos similaires
- VIDÉO & AUDIO
- INFORMATION
- DIVERS
+ %1$s vues
+ Audio
+ Format audio par défaut
+ WebM — format libre
+ m4a — meilleur qualité
+ Télécharger
+ Vidéo suivante
+ Afficher les vidéos suivantes et similaires
+ URL non supportée.
+ Vidéos similaires
+ Vidéo & Audio
+ Divers
- Miniature d\'aperçu vidéo
- Miniature d\'aperçu vidéo
- Je n\'aime pas
- J\'aime
-Langue du contenu
- Avatar de l\'utilisateur
- Utiliser un lecteur vidéo externe
- Utiliser un lecteur audio externe
-
+ Miniature d\'aperçu vidéo
+ Miniature d\'aperçu vidéo
+ Je n\'aime pas
+ J\'aime
+ Langue du contenu
+ Avatar de l\'utilisateur
+ Utiliser un lecteur vidéo externe
+ Utiliser un lecteur audio externe
+ Lecture en arrière-plan
+ Lecteur en arrière-plan NewPipe
+ Chargement
+ Lecture
+
+ Utiliser Tor
+ Forcer le trafic de téléchargement via Tor pour plus de confidentialité (vidéos streaming non supporté)
+
diff --git a/app/src/main/res/values-he/strings.xml b/app/src/main/res/values-he/strings.xml
new file mode 100644
index 000000000..060b70ede
--- /dev/null
+++ b/app/src/main/res/values-he/strings.xml
@@ -0,0 +1,10 @@
+
+%1$s צפיות
+ הועלה בתאריך %1$s
+ שתף
+ חפש
+ הבא
+ הורדה
+ הגדרות
+ הגדרות
+
diff --git a/app/src/main/res/values-hu/strings.xml b/app/src/main/res/values-hu/strings.xml
index d6dc6d25f..330b387ff 100644
--- a/app/src/main/res/values-hu/strings.xml
+++ b/app/src/main/res/values-hu/strings.xml
@@ -1,43 +1,43 @@
- %1$s megtekintés
- Feltöltve: %1$s
- Nem található lejátszó. Telepítsen egyet!
- Telepítsen egyet
+ %1$s megtekintés
+ Feltöltve: %1$s
+ Nem található lejátszó. Telepítsen egyet!
+ Telepítsen egyet
Mégse
Megnyitás böngészőben
Megosztás
Letöltés
Keresés
Beállítások
- Erre gondolt:
- Keresési lap:
- Megosztás ezzel:
- Válasszon böngészőt:
- forgatás
- Beállítások
+ Erre gondolt:
+ Keresési lap:
+ Megosztás ezzel:
+ Válasszon böngészőt:
+ forgatás
+ Beállítások
Külső lejátszó használata
- Letöltések helye
- Útvonal a letöltött videók tárolásához
- Adja meg a letöltési útvonalat
- Automatikus lejátszás Intent-en keresztül
- Automatikusan elindítja a videót, ha az külső alkalmazásból volt hívva
- Alapértelmezett felbontás
- Lejátszás Kodi-val
- A Kore alkalmazás nem található. A Kore szükséges a videók Kodi médiaközponttal való lejátszásához.
+ Letöltések helye
+ Útvonal a letöltött videók tárolásához
+ Adja meg a letöltési útvonalat
+ Automatikus lejátszás Intent-en keresztül
+ Automatikusan elindítja a videót, ha az külső alkalmazásból volt hívva
+ Alapértelmezett felbontás
+ Lejátszás Kodi-val
+ A Kore alkalmazás nem található. A Kore szükséges a videók Kodi médiaközponttal való lejátszásához.
Kore telepítése
- \"Lejátszás Kodi-val\" opció mutatása
- Mutat egy opciót a videók Kodi médiaközponttal való lejátszására
- Hang
- Alapértelmezett hang formátum
- WebM - szabad formátum
- m4a - jobb minőség
- Letöltés
+ \"Lejátszás Kodi-val\" opció mutatása
+ Mutat egy opciót a videók Kodi médiaközponttal való lejátszására
+ Hang
+ Alapértelmezett hang formátum
+ WebM — szabad formátum
+ m4a — jobb minőség
+ Letöltés
- Videó
- Hang
-Következő videó
- A webcím nem támogatott.
-Hasonló videók
-
+ Következő videó
+ A webcím nem támogatott.
+ Hasonló videók
+
diff --git a/app/src/main/res/values-id b/app/src/main/res/values-id
new file mode 120000
index 000000000..9ea8dda4b
--- /dev/null
+++ b/app/src/main/res/values-id
@@ -0,0 +1 @@
+values-in
\ No newline at end of file
diff --git a/app/src/main/res/values-in/strings.xml b/app/src/main/res/values-in/strings.xml
new file mode 100644
index 000000000..9c5ad89af
--- /dev/null
+++ b/app/src/main/res/values-in/strings.xml
@@ -0,0 +1,3 @@
+
+
+
diff --git a/app/src/main/res/values-it/strings.xml b/app/src/main/res/values-it/strings.xml
index 931afc6c2..95c7815c3 100644
--- a/app/src/main/res/values-it/strings.xml
+++ b/app/src/main/res/values-it/strings.xml
@@ -1,49 +1,49 @@
-%1$s visite
- Caricato in %1$s
- Nessun riproduttore trovato. Dovresti installarne uno.
- Installa
+%1$s visite
+ Caricato in %1$s
+ Nessun riproduttore trovato. Dovresti installarne uno.
+ Installa
Cancella
Apri nel browser
Condividi
Scarica
Cerca
Impostazioni
- "Intendevi: "
- "Cerca pagina: "
- Condividi con:
- Scegli browser:
- rotazione
- Impostazioni
+ "Intendevi: "
+ "Cerca pagina: "
+ Condividi con:
+ Scegli browser:
+ rotazione
+ Impostazioni
Usa un riproduttore video esterno
- Cartella di download
- Percorso dove memorizzare i video scaricati.
- Inserisci il percorso di download
- Auto riproduzione attraverso internet
- Avvia automaticamente un video quando è stato chiamato da un\'altra applicazione.
- Risoluzione predefinita
- Riproduci con Kodi
- Kore app non trovata. Kore è richiesto per riprodurre video con Kodi media center.
+ Cartella di download
+ Percorso dove memorizzare i video scaricati.
+ Inserisci il percorso di download
+ Auto riproduzione attraverso internet
+ Avvia automaticamente un video quando è stato chiamato da un\'altra applicazione.
+ Risoluzione predefinita
+ Riproduci con Kodi
+ Kore app non trovata. Kore è richiesto per riprodurre video con Kodi media center.
Installa Kore
- Mostra l\'opzione \"Riproduci con Kodi\"
- Mostra un opzione per riprodurre un video attraverso Kodi media center.
- Audio
- Formato audio predefinito
- WedM - formato libero
- m4a - qualità migliore
- Scarica
- Prossimo video
- Mostra i video successivi e simili
- URL non supportato.
- Video simili
- Lingua preferita dei contenuti
- VIDEO & AUDIO
+ Mostra l\'opzione \"Riproduci con Kodi\"
+ Mostra un opzione per riprodurre un video attraverso Kodi media center.
+ Audio
+ Formato audio predefinito
+ WedM — formato libero
+ m4a — qualità migliore
+ Scarica
+ Prossimo video
+ Mostra i video successivi e simili
+ URL non supportato.
+ Video simili
+ Lingua preferita dei contenuti
+ VIDEO & AUDIO
INFO
ETC
- Anteprima video
- Anteprima video
- Miniatura caricata
- Non mi piace
- Mi piace
+ Anteprima video
+ Anteprima video
+ Miniatura caricata
+ Non mi piace
+ Mi piace
diff --git a/app/src/main/res/values-iw b/app/src/main/res/values-iw
new file mode 120000
index 000000000..57bf91954
--- /dev/null
+++ b/app/src/main/res/values-iw
@@ -0,0 +1 @@
+values-he
\ No newline at end of file
diff --git a/app/src/main/res/values-ja/strings.xml b/app/src/main/res/values-ja/strings.xml
index 558918270..aca6ff616 100644
--- a/app/src/main/res/values-ja/strings.xml
+++ b/app/src/main/res/values-ja/strings.xml
@@ -1,53 +1,57 @@
- "アップロード: "%1$s
- StreamPlayer が見つかりませんでした。インストールが必要になるかもしれません。
- インストール
+ "アップロード: "%1$s
+ StreamPlayer が見つかりませんでした。インストールが必要になるかもしれません。
+ インストール
取り消し
ブラウザーで開く
共有
ダウンロード
検索
設定
- "この意味ですか: "
- "検索ページ: "
- …共有:
- ブラウザーを選択:
- 回転
- 設定
+ "この意味ですか: "
+ "検索ページ: "
+ …共有:
+ ブラウザーを選択:
+ 回転
+ 設定
外部プレーヤーを使用する
- ダウンロードする場所
- ダウンロードした動画を保存する場所のパス。
- ダウンロードのパスを入力してください。
- インテントで自動再生
- 他のアプリケーションから呼び出されたとき、自動的に動画再生を開始します。
- 基本の解像度
- Kodi で再生
- Kore アプリが見つかりません。 Kodi メディアセンターで動画を再生するには、 Kore が必要です。
+ ダウンロードする場所
+ ダウンロードした動画を保存する場所のパス。
+ ダウンロードのパスを入力してください。
+ インテントで自動再生
+ 他のアプリケーションから呼び出されたとき、自動的に動画再生を開始します。
+ 基本の解像度
+ Kodi で再生
+ Kore アプリが見つかりません。 Kodi メディアセンターで動画を再生するには、 Kore が必要です。
Kore をインストール
- \"Kodi で再生\" 設定を表示
- Kodi メディアセンター経由で動画を再生するための設定を表示します.
- オーディオ
- 基本のオーディオフォーマット
- .WebM - フリーフォーマット
- .m4a - より良い品質
- ダウンロード
- 次の動画
- 次の同様の動画を表示します。
- URL は使用できません。
- 同様の動画
- 優先される言語
- 動画とオーディオ
- 情報
- その他
-%1$s ビュー
- ビデオ プレビュー サムネイル
- ビデオ プレビュー サムネイル
- アップローダー サムネイル
- 残念だね
- いいね
-外部ビデオ プレイヤーを使用する
- 外部オーディオ プレイヤーを使用する
- バックグラウンドで再生しています
+ \"Kodi で再生\" 設定を表示
+ Kodi メディアセンター経由で動画を再生するための設定を表示します.
+ オーディオ
+ 基本のオーディオフォーマット
+ WebM — フリーフォーマット
+ m4a — より良い品質
+ ダウンロード
+ 次の動画
+ 次の同様の動画を表示します。
+ URL は使用できません。
+ 同様の動画
+ 優先される言語
+ 動画とオーディオ
+ %1$s ビュー
+ ビデオ プレビュー サムネイル
+ ビデオ プレビュー サムネイル
+ アップローダー サムネイル
+ 残念だね
+ いいね
+ 外部ビデオ プレイヤーを使用する
+ 外部オーディオ プレイヤーを使用する
+ バックグラウンドで再生しています
-
+ NewPipe バックグラウンド プレーヤー
+ 読み込み中
+ 再生
+
+ Tor を使用する
+ 強制的に Tor を経由したプライバシーを高めたトラフィックでダウンロードします (ビデオのストリーミングはまだサポートされていません)
+
diff --git a/app/src/main/res/values-ko/strings.xml b/app/src/main/res/values-ko/strings.xml
index bdb8b1084..ceaf8df6f 100644
--- a/app/src/main/res/values-ko/strings.xml
+++ b/app/src/main/res/values-ko/strings.xml
@@ -1,49 +1,49 @@
-시청 횟수 %1$s
- %1$s에 업로드됨
- 스트리밍 플레이어가 발견되지 않았습니다. 플레이어를 설치하시기 바랍니다.
- 설치
+시청 횟수 %1$s
+ %1$s에 업로드됨
+ 스트리밍 플레이어가 발견되지 않았습니다. 플레이어를 설치하시기 바랍니다.
+ 설치
취소
브라우저에서 열기
공유
다운로드
검색
설정
- "혹시 이것을 검색하셨습니까? "
- "검색 페이지: "
- 다음으로 공유:
- 브라우저 선택:
- 회전
- 설정
+ "혹시 이것을 검색하셨습니까? "
+ "검색 페이지: "
+ 다음으로 공유:
+ 브라우저 선택:
+ 회전
+ 설정
외부 플레이어 사용
- 다운로드 위치
- 다운로드된 비디오가 저장될 경로를 선택하세요.
- 다운로드 경로 입력
- 인텐트로 경유할 경우 자동 재생
- 다른 앱으로부터 호출되었을 경우에 비디오를 자동으로 재생합니다.
- 기본 해상도
- Kodi로 재생
- Kore 앱이 발견되지 않았습니다. Kodi media center로 비디오를 재생하려면 Kore가 필요합니다.
+ 다운로드 위치
+ 다운로드된 비디오가 저장될 경로를 선택하세요.
+ 다운로드 경로 입력
+ 인텐트로 경유할 경우 자동 재생
+ 다른 앱으로부터 호출되었을 경우에 비디오를 자동으로 재생합니다.
+ 기본 해상도
+ Kodi로 재생
+ Kore 앱이 발견되지 않았습니다. Kodi media center로 비디오를 재생하려면 Kore가 필요합니다.
Kore 설치
- \"Kodi로 재생\" 옵션 표시
- 비디오를 Kodi media center를 사용해 재생하는 옵션을 표시합니다.
- 오디오
- 기본 오디오 포맷
- WebM - 무료 자유 포맷입니다
- m4a - 보다 나은 품질
- 다운로드
- 다음 비디오
- 다음 및 유사한 비디오 표시
- 지원하지 않는 URL 입니다.
- 유사한 비디오
- 선호하는 컨텐츠 언어
- 비디오 & 오디오
+ \"Kodi로 재생\" 옵션 표시
+ 비디오를 Kodi media center를 사용해 재생하는 옵션을 표시합니다.
+ 오디오
+ 기본 오디오 포맷
+ WebM — 무료 자유 포맷입니다
+ m4a — 보다 나은 품질
+ 다운로드
+ 다음 비디오
+ 다음 및 유사한 비디오 표시
+ 지원하지 않는 URL 입니다.
+ 유사한 비디오
+ 선호하는 컨텐츠 언어
+ 비디오 & 오디오
정보
기타
- 비디오 미리보기 썸네일
- 비디오 미리보기 썸네일
- 업로더 썸네일
- 싫어요
- 좋아요
+ 비디오 미리보기 썸네일
+ 비디오 미리보기 썸네일
+ 업로더 썸네일
+ 싫어요
+ 좋아요
diff --git a/app/src/main/res/values-nl/strings.xml b/app/src/main/res/values-nl/strings.xml
index 0cf3b0dec..b63369b49 100644
--- a/app/src/main/res/values-nl/strings.xml
+++ b/app/src/main/res/values-nl/strings.xml
@@ -1,51 +1,49 @@
- %1$s keer bekeken
- Geüpload op %1$s
- Geen speler met streaming ondersteuning gevonden. Misschien wil je er een installeren.
- Installeer speler
+ %1$s keer bekeken
+ Geüpload op %1$s
+ Geen speler met streaming ondersteuning gevonden. Misschien wil je er een installeren.
+ Installeer speler
Annuleer
Open in browser
Deel
Download
Zoek
Instellingen
- Bedoelde je:
- Zoekpagina:
- Deel met:
- Kies browser:
- rotatie
- Instellingen
+ Bedoelde je:
+ Zoekpagina:
+ Deel met:
+ Kies browser:
+ rotatie
+ Instellingen
Gebruik externe speler
- Downloadlocatie
- Locatie om gedownloadde videos in op te slaan.
- Voer downloadlocatie is
- Speel automatisch via Intent
- Speel een video automatisch af indien geopend vanuit een andere app.
- Standaardresolutie
- Speel af met Kodi
- Kore app niet gevonden. Kore is nodig om videos op Kodi af te spelen.
+ Downloadlocatie
+ Locatie om gedownloadde videos in op te slaan.
+ Voer downloadlocatie is
+ Speel automatisch via Intent
+ Speel een video automatisch af indien geopend vanuit een andere app.
+ Standaardresolutie
+ Speel af met Kodi
+ Kore app niet gevonden. Kore is nodig om videos op Kodi af te spelen.
Installeer Kore
- Toon \"Speel af met Kodi\" optie
- Toont een optie om een video op een Kodi media center af te spelen.
- Audio
- Standaard audio formaat
- Webam - open formaat
- m4a - betere kwaliteit
- Download
- Volgende video
- URL wordt niet ondersteund.
- Vergelijkbare videos
- Laat volgende en vergelijkbare videos zien
- Voorkeurs content taal
-Gebruik externe videospeler
- Gebruik externe audiospeler
- VIDEO & GELUID
- INFO
- ETC.
+ Toon \"Speel af met Kodi\" optie
+ Toont een optie om een video op een Kodi media center af te spelen.
+ Audio
+ Standaard audio formaat
+ WebM — open formaat
+ m4a — betere kwaliteit
+ Download
+ Volgende video
+ URL wordt niet ondersteund.
+ Vergelijkbare videos
+ Laat volgende en vergelijkbare videos zien
+ Voorkeurs content taal
+ Gebruik externe videospeler
+ Gebruik externe audiospeler
+ Video & Geluid
- Videovoorbeeld thumbnail
- Videovoorbeeld thumbnail
- Uploader miniatuur
- Dislikes
+ Videovoorbeeld thumbnail
+ Videovoorbeeld thumbnail
+ Uploader miniatuur
+ Dislikes
diff --git a/app/src/main/res/values-pl/strings.xml b/app/src/main/res/values-pl/strings.xml
index 348a2e689..9142bca7f 100644
--- a/app/src/main/res/values-pl/strings.xml
+++ b/app/src/main/res/values-pl/strings.xml
@@ -1,51 +1,50 @@
- Nie znaleziono odtwarzacza strumieniowego.
- Zainstaluj
+ Nie znaleziono odtwarzacza strumieniowego.
+ Zainstaluj
Anuluj
Otwórz w przeglądarce
Udostępnij
Pobierz
Szukaj
Ustawienia
- "Czy chodziło Ci o: "
- Udostępnij za pośrednictwem:
- Wybierz przeglądarkę:
- obrót
- Ustawienia
+ "Czy chodziło Ci o: "
+ Udostępnij za pośrednictwem:
+ Wybierz przeglądarkę:
+ obrót
+ Ustawienia
Użyj zewnętrznego odtwarzacza
- Miejsce zapisu pobieranych plików
- Ścieżka folderu do zapisywania pobieranego wideo.
- Wprowadź ścieżkę folderu dla pobieranych plików
- Automatycznie odtwarzaj przez Intent
- Automatycznie odtwarza wideo po wywołaniu z innej aplikacji.
- Domyślna rozdzielczość
- Odtwarzaj za pośrednictwem Kodi
- Aplikacja Kore nie została znaleziona. Wymagana jest do odtwarzania w Kodi.
+ Miejsce zapisu pobieranych plików
+ Ścieżka folderu do zapisywania pobieranego wideo.
+ Wprowadź ścieżkę folderu dla pobieranych plików
+ Automatycznie odtwarzaj przez Intent
+ Automatycznie odtwarza wideo po wywołaniu z innej aplikacji.
+ Domyślna rozdzielczość
+ Odtwarzaj za pośrednictwem Kodi
+ Aplikacja Kore nie została znaleziona. Wymagana jest do odtwarzania w Kodi.
Zainstaluj Kore
- Wyświetlaj opcję \"Odtwarzaj za pośrednictwem Kodi\"
- Wyświetla opcję do odtwarzania wideo przez aplikację Kodi.
- Dźwięk
- Domyślny format dźwięku
- WebM - otwarty format
- m4a - lepsza jakość
- Pobierz
- Następne wideo
- Wyświetl następne i podobne wideo
- Niewspierany URL.
- Podobne wideo
- Preferowany język zawartości
- WIDEO & DŹWIĘK
- INFO
- INNE
-"Szukaj strony: "
- %1$s wyświetleń
- Opublikowany %1$s
- Miniaturka podglądowa wideo
- Miniaturka podglądowa wideo
- Miniaturka wysyłającego
- łapek w dół
- Polubień
-Użyj zewnętrznego odtwarzacza wideo
- Użyj zewnętrznego odtwarzacza audio
-
+ Wyświetlaj opcję \"Odtwarzaj za pośrednictwem Kodi\"
+ Wyświetla opcję do odtwarzania wideo przez aplikację Kodi.
+ Dźwięk
+ Domyślny format dźwięku
+ WebM — otwarty format
+ m4a — lepsza jakość
+ Pobierz
+ Następne wideo
+ Wyświetl następne i podobne wideo
+ Niewspierany URL.
+ Podobne wideo
+ Preferowany język zawartości
+ Wideo & Dźwięk
+
+ "Szukaj strony: "
+ %1$s wyświetleń
+ Opublikowany %1$s
+ Miniaturka podglądowa wideo
+ Miniaturka podglądowa wideo
+ Miniaturka wysyłającego
+ łapek w dół
+ Polubień
+ Użyj zewnętrznego odtwarzacza wideo
+ Użyj zewnętrznego odtwarzacza audio
+
diff --git a/app/src/main/res/values-pt/strings.xml b/app/src/main/res/values-pt/strings.xml
index 0a6cbe3c4..d78107d70 100644
--- a/app/src/main/res/values-pt/strings.xml
+++ b/app/src/main/res/values-pt/strings.xml
@@ -1,50 +1,50 @@
-%1$s visualizações
- Carregado em %1$s
- Reprodutor não disponível. Deve instalar um reprodutor.
- Instalar
+%1$s visualizações
+ Carregado em %1$s
+ Reprodutor não disponível. Deve instalar um reprodutor.
+ Instalar
Cancelar
Abrir no navegador
Partilhar
Descarregar
Pesquisar
Definições
- "Será que queria dizer: "
- "Página de pesquisa: "
- Partilhar com:
- Escolher navegador:
- rotação
- Definições
- Utilizar reprodutor de vídeo externo
- Utilizar reprodutor de áudio externo
- Local para a descarga
- Local para guardar os vídeos descarregados.
- Digite o caminho
- Reproduzir via Intent
- Iniciar automaticamente o vídeo se for invocado por outra aplicação.
- Resolução padrão
- Reproduzir com Kodi
- Aplicação não encontrada. Necessita do Kore para reproduzir vídeos no Kodi.
+ "Será que queria dizer: "
+ "Página de pesquisa: "
+ Partilhar com:
+ Escolher navegador:
+ rotação
+ Definições
+ Utilizar reprodutor de vídeo externo
+ Utilizar reprodutor de áudio externo
+ Local para a descarga
+ Local para guardar os vídeos descarregados.
+ Digite o caminho
+ Reproduzir via Intent
+ Iniciar automaticamente o vídeo se for invocado por outra aplicação.
+ Resolução padrão
+ Reproduzir com Kodi
+ Aplicação não encontrada. Necessita do Kore para reproduzir vídeos no Kodi.
Instalar o Kore
- Mostrar opção \"Reproduzir com Kodi\"
- Mostra uma opção para reproduzir o vídeo com o Kodi.
- Áudio
- Formato áudio padrão
- WebM - formato livre
- m4a - melhor qualidade
- Descarregar
- Vídeo seguinte
- Mostrar vídeos seguintes e similares
- URL não suportado.
- Vídeos similares
- Idioma preferencial do conteúdo
- Vídeo e áudio
+ Mostrar opção \"Reproduzir com Kodi\"
+ Mostra uma opção para reproduzir o vídeo com o Kodi.
+ Áudio
+ Formato áudio padrão
+ WebM — formato livre
+ m4a — melhor qualidade
+ Descarregar
+ Vídeo seguinte
+ Mostrar vídeos seguintes e similares
+ URL não suportado.
+ Vídeos similares
+ Idioma preferencial do conteúdo
+ Vídeo e áudio
Informações
Outras
- Miniatura de vídeos
- Miniatura de vídeos
- Carregador de miniaturas
- Não gosto
- Gosto
+ Miniatura de vídeos
+ Miniatura de vídeos
+ Carregador de miniaturas
+ Não gosto
+ Gosto
diff --git a/app/src/main/res/values-ru/strings.xml b/app/src/main/res/values-ru/strings.xml
index a2dbdd50f..8d8da5a8e 100644
--- a/app/src/main/res/values-ru/strings.xml
+++ b/app/src/main/res/values-ru/strings.xml
@@ -1,54 +1,57 @@
- %1$s просмотров
- Опубликовано %1$s
- Ни одного потокового проигрывателя не было найдено. Установить?
- Установить
+ %1$s просмотров
+ Опубликовано %1$s
+ Ни одного потокового проигрывателя не было найдено. Установить?
+ Установить
Отмена
Открыть в браузере
Поделиться
Скачать
Найти
Настройки
- Возможно, вы имели в виду:
- Страница поиска:
- Поделиться с помощью:
- Выбрать браузер:
- поворот
- Настройки
+ Возможно, вы имели в виду:
+ Страница поиска:
+ Поделиться с помощью:
+ Выбрать браузер:
+ поворот
+ Настройки
Использовать внешний проигрыватель
- Место для загрузок
- Папка для хранения загруженных файлов.
- Введите путь к папке для загрузок
- Автопроигрывание через интернет
- Автоматически воспроизводить видео когда оно открыто через другое приложение.
- Разрешение по-умолчанию
- Воспроизвести с помощью Kodi
- Приложение Kore не наидено. Чтобы проигрывать видео через Kodi media center, нужен Kore.
+ Место для загрузок
+ Папка для хранения загруженных файлов.
+ Введите путь к папке для загрузок
+ Автопроигрывание через интернет
+ Автоматически воспроизводить видео когда оно открыто через другое приложение.
+ Разрешение по-умолчанию
+ Воспроизвести с помощью Kodi
+ Приложение Kore не наидено. Чтобы проигрывать видео через Kodi media center, нужен Kore.
Установить Kore
- Показывать опцию \"Воспроизвести с помощью Kodi\"
- Показать опцию воспроизведения видео через Kodi media center.
- Аудио
- Формат аудио по-умолчанию
- WebM - свободный формат
- m4a - лучшее качество
- Скачать
+ Показывать опцию \"Воспроизвести с помощью Kodi\"
+ Показать опцию воспроизведения видео через Kodi media center.
+ Аудио
+ Формат аудио по-умолчанию
+ WebM — свободный формат
+ m4a — лучшее качество
+ Скачать
- Видео
- Аудио
- Следующее видео
- URL не поддерживается.
- Похожие видео
- Показывать следующее и предложенные видео
- Предпочитаемый язык контента
-ВИДЕО И АУДИО
- ИНФОРМАЦИЯ
- ПРОЧЕЕ
+ Следующее видео
+ URL не поддерживается.
+ Похожие видео
+ Показывать следующее и предложенные видео
+ Предпочитаемый язык контента
+ Видео и Аудио
+ Внешний вид
+ Другое
- Миниатюра видео-превью
- Миниатюра видео-превью
- Миниатюра аватара пользователся
- Дислайки
- Лайки
-
+ Миниатюра видео-превью
+ Миниатюра видео-превью
+ Миниатюра аватара пользователся
+ Дислайки
+ Лайки
+Использовать внешний проигрыватель для видео
+ Использовать внешний проигрыватель для аудио
+ Проигрывание в фоновом режиме
+
diff --git a/app/src/main/res/values-sl/strings.xml b/app/src/main/res/values-sl/strings.xml
index 91f54dc11..7a557d8a7 100644
--- a/app/src/main/res/values-sl/strings.xml
+++ b/app/src/main/res/values-sl/strings.xml
@@ -1,50 +1,64 @@
-%1$s pogledov
- Poslano %1$s
- Predvajalnika pretoka ni mogoče najti. Tak program lahko namestite ločeno.
- Namesti
+%1$s pogledov
+ Poslano %1$s
+ Predvajalnika pretoka ni mogoče najti. Tak program lahko namestite ločeno.
+ Namesti
Prekliči
Odpri v brskalniku
Omogoči souporabo
Prejmi
Poišči
Nastavitve
- "Ste mislili vpisati: "
- "Stran iskanja: "
- Omogoči souporabo z:
- Izbor brskalnika:
- usmerjenost
- Nastavitve
- Uporabi zunanji predvajalnik videa
- Uporabi zunanji predvajalnik zvoka
- Mapa za prejem
- Pot do mape za prejem datotek.
- Vpis poti za prejem
- Privzeta ločljivost
- Predvajaj s Kodi
- Programa Kore ni mogoče najti. Program omogoča predvajanje video posnetkov prek predstavnega središča Kodi.
+ "Ste mislili vpisati: "
+ "Stran iskanja: "
+ Omogoči souporabo z:
+ Izbor brskalnika:
+ usmerjenost
+ Nastavitve
+ Uporabi zunanji predvajalnik videa
+ Uporabi zunanji predvajalnik zvoka
+ Mapa za prejem
+ Pot do mape za prejem datotek.
+ Vpis poti za prejem
+ Privzeta ločljivost
+ Predvajaj s Kodi
+ Programa Kore ni mogoče najti. Program omogoča predvajanje video posnetkov prek predstavnega središča Kodi.
Namesti program Kore
- Pokaži možnost \"Predvajaj s Kodi\"
- Privzet zapis zvoka
- Zvok
- WebM - prost zapis
- m4a - višja kakovost posnetkov
- Prejem
- Naslednji video
- Pokaži naslednji video in podobne posnetke
- Zapis naslova URL ni podprt.
- Podobni posnetki
- Prednostni jezik vsebine
- Video in Zvok
- Podrobnosti
- Sličica predogleda videa
- Sličica predogleda videa
- Sličica pošiljalnika
- Samodejno predvajaj prek vmesnika Intent
- Začne samodejno predvajanje videa, ko je zagnan prek drugega programa.
- Pokaže možnost predvajanja videa preko predstavnega središča Kodi.
+ Pokaži možnost \"Predvajaj s Kodi\"
+ Privzet zapis zvoka
+ Zvok
+ WebM — prost zapis
+ m4a — višja kakovost posnetkov
+ Prejem
+ Naslednji video
+ Pokaži naslednji video in podobne posnetke
+ Zapis naslova URL ni podprt.
+ Podobni posnetki
+ Prednostni jezik vsebine
+ Video in Zvok
+ Sličica predogleda videa
+ Sličica predogleda videa
+ Sličica pošiljalnika
+ Samodejno predvajaj prek vmesnika Intent
+ Začne samodejno predvajanje videa, ko je zagnan prek drugega programa.
+ Pokaže možnost predvajanja videa preko predstavnega središča Kodi.
Drugo
- Všeč mi je
-Ni mi všeč
-
+ Všeč mi je
+Ni mi všeč
+ Ozadnji predvajalnik NewPipe
+ Nalaganje ...
+ Predvajanje v ozadju
+ Predvajaj
+
+ Tema
+ Temna
+ Svetla
+
+ Videz
+ Drugo
+ Omrežna napaka
+
+ Uporabi Tor
+ Vsili prenos prejema preko sistema Tor za povečanje zasebnosti (pretakanje videa ni še podprto)
+
diff --git a/app/src/main/res/values-sr/strings.xml b/app/src/main/res/values-sr/strings.xml
index 7ab3d8eaa..d58914743 100644
--- a/app/src/main/res/values-sr/strings.xml
+++ b/app/src/main/res/values-sr/strings.xml
@@ -1,57 +1,69 @@
- %1$s приказа
- "Отпремљен "%1$s
- Нема плејера токова. Можда желите да га инсталирате.
- Инсталирај
+ %1$s приказа
+ "Отпремљен "%1$s
+ Нема плејера токова. Можда желите да га инсталирате.
+ Инсталирај
Одустани
Отвори у прегледачу
Дели
Преузми
Тражи
Поставке
- Да ли сте мислили:
- Страница претраге:
- Подели помоћу:
- Отвори помоћу:
- ротација
- Поставке
+ Да ли сте мислили:
+ Страница претраге:
+ Подели помоћу:
+ Отвори помоћу:
+ ротација
+ Поставке
Користи спољашњи плејер
- Одредиште преузимања
- Путања за упис преузетих видеа.
- Унесите путању за преузимања
- Аутопуштање преко Интента
- Аутоматски почиње пушта видео по позиву из друге апликације.
- Подразумевана резолуција
- Пусти помоћу Кодија
- Апликација Кор није нађена. Кор (Kore) је потребан да бисте пуштали видее у Коди медија центру.
+ Одредиште преузимања
+ Путања за упис преузетих видеа.
+ Унесите путању за преузимања
+ Аутопуштање преко Интента
+ Аутоматски почиње пушта видео по позиву из друге апликације.
+ Подразумевана резолуција
+ Пусти помоћу Кодија
+ Апликација Кор није нађена. Кор (Kore) је потребан да бисте пуштали видее у Коди медија центру.
Инсталирај Кор
- Прикажи „Пусти помоћу Кодија“
- Приказ опције за пуштање видеа у Коди медија центру.
- Аудио
- Подразумевани формат звука
- WebM - слободни формат
- m4a - бољи квалитет
- Преузми
+ Прикажи „Пусти помоћу Кодија“
+ Приказ опције за пуштање видеа у Коди медија центру.
+ Аудио
+ Подразумевани формат звука
+ WebM — слободни формат
+ m4a — бољи квалитет
+ Преузми
- Видео
- Аудио
- Следећи видео
- УРЛ није подржан.
- Прикажи следећи и слични видео
- Слични видео
- Пожељни језик садржаја
-ВИДЕО И АУДИО
- ПОДАЦИ
- ОСТАЛО
-Сличица видео прегледа
- Сличица видео прегледа
- Сличица отпремаоца
- Несвиђања
- Свиђања
-Користи спољашњи видео плејер
- Користи спољашњи аудио плејер
- Пуштам у позадини
+ Следећи видео
+ УРЛ није подржан.
+ Прикажи следећи и слични видео
+ Слични видео
+ Пожељни језик садржаја
+ Видео и Аудио
+ Остало
+ Сличица видео прегледа
+ Сличица видео прегледа
+ Сличица отпремаоца
+ Несвиђања
+ Свиђања
+ Користи спољашњи видео плејер
+ Користи спољашњи аудио плејер
+ Пуштам у позадини
+
+ Позадински плејер за Јутјуб цев
+ Учитавам
+ Пусти
+
+ Користи Тор
+ Принудно преусмерење саобраћаја кроз Тор за доданту приватност (токови још нису подржани)
+Тема
+ Тамна
+ Светла
+
+ Изглед
+ Грешка мреже
diff --git a/app/src/main/res/values-v21/styles.xml b/app/src/main/res/values-v21/styles.xml
index 1f056cfb5..75d058e50 100644
--- a/app/src/main/res/values-v21/styles.xml
+++ b/app/src/main/res/values-v21/styles.xml
@@ -3,18 +3,18 @@
\ No newline at end of file
diff --git a/app/src/main/res/values/colors.xml b/app/src/main/res/values/colors.xml
index e14ee9606..963a49bcc 100644
--- a/app/src/main/res/values/colors.xml
+++ b/app/src/main/res/values/colors.xml
@@ -1,10 +1,20 @@
- #cd322e
- #bc211d
- #000
- #a000
- #efff
- #6000
- #EEEEEE
+
+ #EEEEEE
+ #CD322E
+ #BC211D
+ #000000
+
+
+ #222222
+ #CD322E
+ #BC211D
+ #FFFFFF
+
+
+ #AA000000
+ #EEFFFFFF
+ #66000000
+ #323232
\ No newline at end of file
diff --git a/app/src/main/res/values/settings_keys.xml b/app/src/main/res/values/settings_keys.xml
index 8d33b8cbe..6f83e31a5 100644
--- a/app/src/main/res/values/settings_keys.xml
+++ b/app/src/main/res/values/settings_keys.xml
@@ -1,38 +1,54 @@
- settings_categoery_video_audio
- settings_category_video_info
- settings_category_etc
+ settings_category_video_audio
+ settings_category_appearance
+ settings_category_other
- download_path_preference
- use_external_video_player
- use_external_audio_player
- autoplay_through_intent
- default_resolution_preference
-
+ download_path
+ use_external_video_player
+ use_external_audio_player
+ autoplay_through_intent
+
+ default_resolution_preference
+ 360p
+
- 720p
- 360p
- 240p
- 144p
- 360p
- show_play_with_kodi_preference
- default_audio_format
-
- - @string/webMAudioDescription
- - @string/m4aAudioDescription
+
+ show_play_with_kodi
+
+ theme
+ 0
+
+ - @string/dark_theme_title
+ - @string/light_theme_title
-
+
+ - 0
+ - 1
+
+
+ default_audio_format
+ m4a
+
+ - @string/webm_description
+ - @string/m4a_description
+
+
- webm
- m4a
- m4a
- show_next_video
- search_language
+
+ show_next_video
+ en
+ search_language
-
+
- af
- az
- id
@@ -71,6 +87,7 @@
- sl
- fi
- sv
+ - bo
- vi
- tr
- bg
@@ -110,7 +127,7 @@
- ja
- ko
-
+
- Afrikaans
- Azərbaycan
- Bahasa Indonesia
@@ -149,6 +166,7 @@
- Slovenščina
- Suomi
- Svenska
+ - Tibetan བོད་སྐད།
- Tiếng Việt
- Türkçe
- Български
@@ -188,4 +206,5 @@
- 日本語
- 한국어
+ use_tor
\ No newline at end of file
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index 177280277..d7a551fcd 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -1,63 +1,72 @@
NewPipe
+ NewPipe Background Player
NewPipe
- %1$s views
- Uploaded on %1$s
- No stream player found. You may want to install one.
- Install
+ %1$s views
+ Uploaded on %1$s
+ No stream player found. Install VLC?
+ Install
Cancel
- https://f-droid.org/repository/browse/?fdfilter=vlc&fdid=org.videolan.vlc
+ https://f-droid.org/repository/browse/?fdfilter=vlc&fdid=org.videolan.vlc
Open in browser
Share
+ Loading
Download
Search
Settings
- Did you mean:
- Search page:
- Share with:
- Choose browser:
- rotation
- Settings
- Use external video player
- Use external audio player
- Download location
- Path to store downloaded videos in.
- Enter download path
- Autoplay through Intent
- Automatically starts a video when it was called from another app.
- Default Resolution
- Play with Kodi
- Kore app not found. Kore is needed to play videos with Kodi media center.
- Install Kore
- https://f-droid.org/repository/browse/?fdfilter=Kore&fdid=org.xbmc.kore
- Show \"Play with Kodi\" option
- Displays an option to play a video via Kodi media center.
- Audio
- Default audio format
- WebM - free format
- m4a - better quality
- Download
-
+ Did you mean:
+ Search page:
+ Share with:
+ Choose browser:
+ rotation
+ Settings
+ Use external video player
+ Use external audio player
+ Download path
+ Path to store downloaded videos in
+ Enter download path
+ Autoplay through Intent
+ Automatically play a video when it\'s called from another app
+ Default Resolution
+ Play with Kodi
+ Kore app not found. Install Kore?
+ https://f-droid.org/repository/browse/?fdfilter=Kore&fdid=org.xbmc.kore
+ Show \"Play with Kodi\" option
+ Display an option to play a video via Kodi media center
+ Audio
+ Default audio format
+ WebM — free format
+ m4a — better quality
+ Theme
+ Dark
+ Light
+
+ Download
+
- Video
- Audio
- Next video
- Show next and similar videos
- URL not supported.
- Similar videos
- Preferable content language
- VIDEO & AUDIO
- INFO
- ETC
- %1$s - NewPipe
- Playing in background
- https://www.c3s.cc/
+ Next video
+ Show next and similar videos
+ URL not supported
+ Similar videos
+ Preferable content language
+ Video & Audio
+ Appearance
+ Other
+ %1$s - NewPipe
+ Playing in background
+ https://www.c3s.cc/
+ Play
+ Network Error
- Video preview thumbnail
- Video preview thumbnail
- Uploader thumbnail
- Dislikes
- Likes
+ Video preview thumbnail
+ Video preview thumbnail
+ Uploader\'s userpic thumbnail
+ Likes
+ Dislikes
+ Use Tor
+ Force download traffic through Tor for increased privacy (streaming videos not yet supported)
diff --git a/app/src/main/res/values/styles.xml b/app/src/main/res/values/styles.xml
index 8d27cc3df..8abacc2e8 100644
--- a/app/src/main/res/values/styles.xml
+++ b/app/src/main/res/values/styles.xml
@@ -3,17 +3,17 @@
\ No newline at end of file
diff --git a/app/src/main/res/xml/settings.xml b/app/src/main/res/xml/settings.xml
new file mode 100644
index 000000000..22f9644fe
--- /dev/null
+++ b/app/src/main/res/xml/settings.xml
@@ -0,0 +1,97 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/app/src/main/res/xml/settings_screen.xml b/app/src/main/res/xml/settings_screen.xml
deleted file mode 100644
index 98399f778..000000000
--- a/app/src/main/res/xml/settings_screen.xml
+++ /dev/null
@@ -1,77 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/assets/gruese_die_gema.svg b/assets/gruese_die_gema.svg
index 48ebc8db0..eace7bf44 100644
--- a/assets/gruese_die_gema.svg
+++ b/assets/gruese_die_gema.svg
@@ -7,7 +7,6 @@
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
- xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="426"
@@ -16,7 +15,10 @@
id="svg2"
version="1.1"
inkscape:version="0.91 r13725"
- sodipodi:docname="gruese_die_gema_unangebracht.svg">
+ sodipodi:docname="gruese_die_gema.svg"
+ inkscape:export-filename="/home/the-scrabi/Projects/NewPipe/assets/gruese_die_gema.png"
+ inkscape:export-xdpi="216.33803"
+ inkscape:export-ydpi="216.33803">
+ inkscape:window-width="1015"
+ inkscape:window-height="417"
+ inkscape:window-x="287"
+ inkscape:window-y="491"
+ inkscape:window-maximized="0" />
@@ -46,7 +48,7 @@
image/svg+xml
-
+
@@ -56,129 +58,155 @@
id="layer1"
transform="translate(0,-812.36212)">
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+ id="g4230"
+ transform="matrix(0.67525011,0,0,0.67525011,-14.086916,282.00859)">
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+ Genervt? Gib der Alternative c3s
+
+ eine Chance.
diff --git a/gradle.properties b/gradle.properties
deleted file mode 100644
index 1d3591c8a..000000000
--- a/gradle.properties
+++ /dev/null
@@ -1,18 +0,0 @@
-# Project-wide Gradle settings.
-
-# IDE (e.g. Android Studio) users:
-# Gradle settings configured through the IDE *will override*
-# any settings specified in this file.
-
-# For more details on how to configure your build environment visit
-# http://www.gradle.org/docs/current/userguide/build_environment.html
-
-# Specifies the JVM arguments used for the daemon process.
-# The setting is particularly useful for tweaking memory settings.
-# Default value: -Xmx10248m -XX:MaxPermSize=256m
-# org.gradle.jvmargs=-Xmx2048m -XX:MaxPermSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8
-
-# When configured, Gradle will run in incubating parallel mode.
-# This option should only be used with decoupled projects. More details, visit
-# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
-# org.gradle.parallel=true
\ No newline at end of file