diff --git a/.gitignore b/.gitignore
index 5c6962be1..40e7d2c03 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,15 +1,15 @@
-.gitignore
-.gradle
-/local.properties
+.gradle/
+local.properties
.DS_Store
-/build
-/captures
-/app/app.iml
-/.idea
-/*.iml
+build/
+captures/
+.idea/
+*.iml
*~
.weblate
*.class
+**/debug/
+**/release/
# vscode / eclipse files
*.classpath
diff --git a/app/.gitignore b/app/.gitignore
deleted file mode 100644
index 53edac5e4..000000000
--- a/app/.gitignore
+++ /dev/null
@@ -1,3 +0,0 @@
-.gitignore
-/build
-*.iml
diff --git a/app/build.gradle b/app/build.gradle
index 468006578..35bdd998e 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -17,8 +17,8 @@ android {
resValue "string", "app_name", "NewPipe"
minSdkVersion 19
targetSdkVersion 29
- versionCode 979
- versionName "0.21.13"
+ versionCode 980
+ versionName "0.21.14"
multiDexEnabled true
@@ -105,9 +105,9 @@ ext {
androidxRoomVersion = '2.3.0'
icepickVersion = '3.2.0'
- exoPlayerVersion = '2.12.3'
+ exoPlayerVersion = '2.14.2'
googleAutoServiceVersion = '1.0'
- groupieVersion = '2.9.0'
+ groupieVersion = '2.10.0'
markwonVersion = '4.6.2'
leakCanaryVersion = '2.5'
@@ -189,7 +189,7 @@ dependencies {
// name and the commit hash with the commit hash of the (pushed) commit you want to test
// This works thanks to JitPack: https://jitpack.io/
implementation 'com.github.TeamNewPipe:nanojson:1d9e1aea9049fc9f85e68b43ba39fe7be1c1f751'
- implementation 'com.github.TeamNewPipe:NewPipeExtractor:v0.21.11'
+ implementation 'com.github.TeamNewPipe:NewPipeExtractor:v0.21.12'
/** Checkstyle **/
checkstyle "com.puppycrawl.tools:checkstyle:${checkstyleVersion}"
@@ -208,14 +208,17 @@ dependencies {
implementation "androidx.lifecycle:lifecycle-livedata:${androidxLifecycleVersion}"
implementation "androidx.lifecycle:lifecycle-viewmodel:${androidxLifecycleVersion}"
implementation 'androidx.localbroadcastmanager:localbroadcastmanager:1.0.0'
- implementation 'androidx.media:media:1.3.1'
+ implementation 'androidx.media:media:1.4.3'
implementation 'androidx.multidex:multidex:2.0.1'
implementation 'androidx.preference:preference:1.1.1'
- implementation 'androidx.recyclerview:recyclerview:1.1.0'
+ implementation 'androidx.recyclerview:recyclerview:1.2.1'
implementation "androidx.room:room-runtime:${androidxRoomVersion}"
implementation "androidx.room:room-rxjava3:${androidxRoomVersion}"
kapt "androidx.room:room-compiler:${androidxRoomVersion}"
implementation 'androidx.swiperefreshlayout:swiperefreshlayout:1.1.0'
+ // Newer version specified to prevent accessibility regressions with RecyclerView, see:
+ // https://developer.android.com/jetpack/androidx/releases/viewpager2#1.1.0-alpha01
+ implementation 'androidx.viewpager2:viewpager2:1.1.0-beta01'
implementation 'androidx.webkit:webkit:1.4.0'
implementation 'com.google.android.material:material:1.2.1'
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index d92d0b5bf..cc631af7a 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -256,6 +256,21 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -325,8 +340,12 @@
+
+
+
+
diff --git a/app/src/main/java/androidx/fragment/app/FragmentStatePagerAdapterMenuWorkaround.java b/app/src/main/java/androidx/fragment/app/FragmentStatePagerAdapterMenuWorkaround.java
index 433c155c2..639443377 100644
--- a/app/src/main/java/androidx/fragment/app/FragmentStatePagerAdapterMenuWorkaround.java
+++ b/app/src/main/java/androidx/fragment/app/FragmentStatePagerAdapterMenuWorkaround.java
@@ -51,8 +51,12 @@ import java.util.ArrayList;
*
{@link #saveState()}
* {@link #restoreState(Parcelable, ClassLoader)}
*
+ *
+ * @deprecated Switch to {@link androidx.viewpager2.widget.ViewPager2} and use
+ * {@link androidx.viewpager2.adapter.FragmentStateAdapter} instead.
*/
@SuppressWarnings("deprecation")
+@Deprecated
public abstract class FragmentStatePagerAdapterMenuWorkaround extends PagerAdapter {
private static final String TAG = "FragmentStatePagerAdapt";
private static final boolean DEBUG = false;
@@ -86,9 +90,10 @@ public abstract class FragmentStatePagerAdapterMenuWorkaround extends PagerAdapt
private final int mBehavior;
private FragmentTransaction mCurTransaction = null;
- private final ArrayList mSavedState = new ArrayList();
- private final ArrayList mFragments = new ArrayList();
+ private final ArrayList mSavedState = new ArrayList<>();
+ private final ArrayList mFragments = new ArrayList<>();
private Fragment mCurrentPrimaryItem = null;
+ private boolean mExecutingFinishUpdate;
/**
* Constructor for {@link FragmentStatePagerAdapterMenuWorkaround}
@@ -208,7 +213,7 @@ public abstract class FragmentStatePagerAdapterMenuWorkaround extends PagerAdapt
mFragments.set(position, null);
mCurTransaction.remove(fragment);
- if (fragment == mCurrentPrimaryItem) {
+ if (fragment.equals(mCurrentPrimaryItem)) {
mCurrentPrimaryItem = null;
}
}
@@ -247,7 +252,19 @@ public abstract class FragmentStatePagerAdapterMenuWorkaround extends PagerAdapt
@Override
public void finishUpdate(@NonNull final ViewGroup container) {
if (mCurTransaction != null) {
- mCurTransaction.commitNowAllowingStateLoss();
+ // We drop any transactions that attempt to be committed
+ // from a re-entrant call to finishUpdate(). We need to
+ // do this as a workaround for Robolectric running measure/layout
+ // calls inline rather than allowing them to be posted
+ // as they would on a real device.
+ if (!mExecutingFinishUpdate) {
+ try {
+ mExecutingFinishUpdate = true;
+ mCurTransaction.commitNowAllowingStateLoss();
+ } finally {
+ mExecutingFinishUpdate = false;
+ }
+ }
mCurTransaction = null;
}
}
diff --git a/app/src/main/java/org/schabi/newpipe/BaseFragment.java b/app/src/main/java/org/schabi/newpipe/BaseFragment.java
index 0be427648..16ddb8376 100644
--- a/app/src/main/java/org/schabi/newpipe/BaseFragment.java
+++ b/app/src/main/java/org/schabi/newpipe/BaseFragment.java
@@ -21,7 +21,6 @@ public abstract class BaseFragment extends Fragment {
//These values are used for controlling fragments when they are part of the frontpage
@State
protected boolean useAsFrontPage = false;
- private boolean mIsVisibleToUser = false;
public void useAsFrontPage(final boolean value) {
useAsFrontPage = value;
@@ -85,12 +84,6 @@ public abstract class BaseFragment extends Fragment {
AppWatcher.INSTANCE.getObjectWatcher().watch(this);
}
- @Override
- public void setUserVisibleHint(final boolean isVisibleToUser) {
- super.setUserVisibleHint(isVisibleToUser);
- mIsVisibleToUser = isVisibleToUser;
- }
-
/*//////////////////////////////////////////////////////////////////////////
// Init
//////////////////////////////////////////////////////////////////////////*/
@@ -109,8 +102,7 @@ public abstract class BaseFragment extends Fragment {
if (DEBUG) {
Log.d(TAG, "setTitle() called with: title = [" + title + "]");
}
- if ((!useAsFrontPage || mIsVisibleToUser)
- && (activity != null && activity.getSupportActionBar() != null)) {
+ if (!useAsFrontPage && activity != null && activity.getSupportActionBar() != null) {
activity.getSupportActionBar().setDisplayShowTitleEnabled(true);
activity.getSupportActionBar().setTitle(title);
}
diff --git a/app/src/main/java/org/schabi/newpipe/CheckForNewAppVersion.java b/app/src/main/java/org/schabi/newpipe/CheckForNewAppVersion.java
index 9c392be1e..9e43394ac 100644
--- a/app/src/main/java/org/schabi/newpipe/CheckForNewAppVersion.java
+++ b/app/src/main/java/org/schabi/newpipe/CheckForNewAppVersion.java
@@ -7,7 +7,6 @@ import android.content.Intent;
import android.content.SharedPreferences;
import android.content.pm.PackageManager;
import android.content.pm.Signature;
-import android.net.ConnectivityManager;
import android.net.Uri;
import android.util.Log;
@@ -15,7 +14,6 @@ import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.core.app.NotificationCompat;
import androidx.core.app.NotificationManagerCompat;
-import androidx.core.content.ContextCompat;
import androidx.core.content.pm.PackageInfoCompat;
import androidx.preference.PreferenceManager;
@@ -48,7 +46,8 @@ public final class CheckForNewAppVersion extends IntentService {
private static final boolean DEBUG = MainActivity.DEBUG;
private static final String TAG = CheckForNewAppVersion.class.getSimpleName();
- private static final String GITHUB_APK_SHA1
+ // Public key of the certificate that is used in NewPipe release versions
+ private static final String RELEASE_CERT_PUBLIC_KEY_SHA1
= "B0:2E:90:7C:1C:D6:FC:57:C3:35:F0:88:D0:8F:50:5F:94:E4:D2:15";
private static final String NEWPIPE_API_URL = "https://newpipe.net/api/data.json";
@@ -129,44 +128,37 @@ public final class CheckForNewAppVersion extends IntentService {
final String versionName,
final String apkLocationUrl,
final int versionCode) {
- final int notificationId = 2000;
-
- if (BuildConfig.VERSION_CODE < versionCode) {
- // A pending intent to open the apk location url in the browser.
- final Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(apkLocationUrl));
- intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
- final PendingIntent pendingIntent
- = PendingIntent.getActivity(application, 0, intent, 0);
-
- final String channelId = application
- .getString(R.string.app_update_notification_channel_id);
- final NotificationCompat.Builder notificationBuilder
- = new NotificationCompat.Builder(application, channelId)
- .setSmallIcon(R.drawable.ic_newpipe_update)
- .setVisibility(NotificationCompat.VISIBILITY_PUBLIC)
- .setContentIntent(pendingIntent)
- .setAutoCancel(true)
- .setContentTitle(application
- .getString(R.string.app_update_notification_content_title))
- .setContentText(application
- .getString(R.string.app_update_notification_content_text)
- + " " + versionName);
-
- final NotificationManagerCompat notificationManager
- = NotificationManagerCompat.from(application);
- notificationManager.notify(notificationId, notificationBuilder.build());
+ if (BuildConfig.VERSION_CODE >= versionCode) {
+ return;
}
+
+ // A pending intent to open the apk location url in the browser.
+ final Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(apkLocationUrl));
+ intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+ final PendingIntent pendingIntent
+ = PendingIntent.getActivity(application, 0, intent, 0);
+
+ final String channelId = application
+ .getString(R.string.app_update_notification_channel_id);
+ final NotificationCompat.Builder notificationBuilder
+ = new NotificationCompat.Builder(application, channelId)
+ .setSmallIcon(R.drawable.ic_newpipe_update)
+ .setVisibility(NotificationCompat.VISIBILITY_PUBLIC)
+ .setContentIntent(pendingIntent)
+ .setAutoCancel(true)
+ .setContentTitle(application
+ .getString(R.string.app_update_notification_content_title))
+ .setContentText(application
+ .getString(R.string.app_update_notification_content_text)
+ + " " + versionName);
+
+ final NotificationManagerCompat notificationManager
+ = NotificationManagerCompat.from(application);
+ notificationManager.notify(2000, notificationBuilder.build());
}
- private static boolean isConnected(@NonNull final App app) {
- final ConnectivityManager connectivityManager =
- ContextCompat.getSystemService(app, ConnectivityManager.class);
- return connectivityManager != null && connectivityManager.getActiveNetworkInfo() != null
- && connectivityManager.getActiveNetworkInfo().isConnected();
- }
-
- public static boolean isGithubApk(@NonNull final App app) {
- return getCertificateSHA1Fingerprint(app).equals(GITHUB_APK_SHA1);
+ public static boolean isReleaseApk(@NonNull final App app) {
+ return getCertificateSHA1Fingerprint(app).equals(RELEASE_CERT_PUBLIC_KEY_SHA1);
}
private void checkNewVersion() throws IOException, ReCaptchaException {
@@ -175,9 +167,8 @@ public final class CheckForNewAppVersion extends IntentService {
final SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(app);
final NewVersionManager manager = new NewVersionManager();
- // Check if user has enabled/disabled update checking
- // and if the current apk is a github one or not.
- if (!prefs.getBoolean(app.getString(R.string.update_app_key), true) || !isGithubApk(app)) {
+ // Check if the current apk is a github one or not.
+ if (!isReleaseApk(app)) {
return;
}
@@ -213,6 +204,7 @@ public final class CheckForNewAppVersion extends IntentService {
// Parse the json from the response.
try {
+
final JsonObject githubStableObject = JsonParser.object()
.from(response.responseBody()).getObject("flavors")
.getObject("github").getObject("stable");
diff --git a/app/src/main/java/org/schabi/newpipe/MainActivity.java b/app/src/main/java/org/schabi/newpipe/MainActivity.java
index 2a8872e26..0a49e00e4 100644
--- a/app/src/main/java/org/schabi/newpipe/MainActivity.java
+++ b/app/src/main/java/org/schabi/newpipe/MainActivity.java
@@ -169,13 +169,54 @@ public class MainActivity extends AppCompatActivity {
@Override
protected void onPostCreate(final Bundle savedInstanceState) {
super.onPostCreate(savedInstanceState);
- // Start the service which is checking all conditions
- // and eventually searching for a new version.
- // The service searching for a new NewPipe version must not be started in background.
- startNewVersionCheckService();
+
+ final App app = App.getApp();
+ final SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(app);
+
+ if (prefs.getBoolean(app.getString(R.string.update_app_key), true)) {
+ // Start the service which is checking all conditions
+ // and eventually searching for a new version.
+ // The service searching for a new NewPipe version must not be started in background.
+ startNewVersionCheckService();
+ }
}
- private void setupDrawer() throws Exception {
+ private void setupDrawer() throws ExtractionException {
+ addDrawerMenuForCurrentService();
+
+ toggle = new ActionBarDrawerToggle(this, mainBinding.getRoot(),
+ toolbarLayoutBinding.toolbar, R.string.drawer_open, R.string.drawer_close);
+ toggle.syncState();
+ mainBinding.getRoot().addDrawerListener(toggle);
+ mainBinding.getRoot().addDrawerListener(new DrawerLayout.SimpleDrawerListener() {
+ private int lastService;
+
+ @Override
+ public void onDrawerOpened(final View drawerView) {
+ lastService = ServiceHelper.getSelectedServiceId(MainActivity.this);
+ }
+
+ @Override
+ public void onDrawerClosed(final View drawerView) {
+ if (servicesShown) {
+ toggleServices();
+ }
+ if (lastService != ServiceHelper.getSelectedServiceId(MainActivity.this)) {
+ ActivityCompat.recreate(MainActivity.this);
+ }
+ }
+ });
+
+ drawerLayoutBinding.navigation.setNavigationItemSelectedListener(this::drawerItemSelected);
+ setupDrawerHeader();
+ }
+
+ /**
+ * Builds the drawer menu for the current service.
+ *
+ * @throws ExtractionException
+ */
+ private void addDrawerMenuForCurrentService() throws ExtractionException {
//Tabs
final int currentServiceId = ServiceHelper.getSelectedServiceId(this);
final StreamingService service = NewPipe.getService(currentServiceId);
@@ -214,32 +255,6 @@ public class MainActivity extends AppCompatActivity {
drawerLayoutBinding.navigation.getMenu()
.add(R.id.menu_options_about_group, ITEM_ID_ABOUT, ORDER, R.string.tab_about)
.setIcon(R.drawable.ic_info_outline);
-
- toggle = new ActionBarDrawerToggle(this, mainBinding.getRoot(),
- toolbarLayoutBinding.toolbar, R.string.drawer_open, R.string.drawer_close);
- toggle.syncState();
- mainBinding.getRoot().addDrawerListener(toggle);
- mainBinding.getRoot().addDrawerListener(new DrawerLayout.SimpleDrawerListener() {
- private int lastService;
-
- @Override
- public void onDrawerOpened(final View drawerView) {
- lastService = ServiceHelper.getSelectedServiceId(MainActivity.this);
- }
-
- @Override
- public void onDrawerClosed(final View drawerView) {
- if (servicesShown) {
- toggleServices();
- }
- if (lastService != ServiceHelper.getSelectedServiceId(MainActivity.this)) {
- ActivityCompat.recreate(MainActivity.this);
- }
- }
- });
-
- drawerLayoutBinding.navigation.setNavigationItemSelectedListener(this::drawerItemSelected);
- setupDrawerHeader();
}
private boolean drawerItemSelected(final MenuItem item) {
@@ -347,11 +362,15 @@ public class MainActivity extends AppCompatActivity {
drawerLayoutBinding.navigation.getMenu().removeGroup(R.id.menu_tabs_group);
drawerLayoutBinding.navigation.getMenu().removeGroup(R.id.menu_options_about_group);
+ // Show up or down arrow
+ drawerHeaderBinding.drawerArrow.setImageResource(
+ servicesShown ? R.drawable.ic_arrow_drop_up : R.drawable.ic_arrow_drop_down);
+
if (servicesShown) {
showServices();
} else {
try {
- showTabs();
+ addDrawerMenuForCurrentService();
} catch (final Exception e) {
ErrorActivity.reportUiErrorInSnackbar(this, "Showing main page tabs", e);
}
@@ -359,8 +378,6 @@ public class MainActivity extends AppCompatActivity {
}
private void showServices() {
- drawerHeaderBinding.drawerArrow.setImageResource(R.drawable.ic_arrow_drop_up);
-
for (final StreamingService s : NewPipe.getServices()) {
final String title = s.getServiceInfo().getName()
+ (ServiceHelper.isBeta(s) ? " (beta)" : "");
@@ -424,48 +441,6 @@ public class MainActivity extends AppCompatActivity {
menuItem.setActionView(spinner);
}
- private void showTabs() throws ExtractionException {
- drawerHeaderBinding.drawerArrow.setImageResource(R.drawable.ic_arrow_drop_down);
-
- //Tabs
- final int currentServiceId = ServiceHelper.getSelectedServiceId(this);
- final StreamingService service = NewPipe.getService(currentServiceId);
-
- int kioskId = 0;
-
- for (final String ks : service.getKioskList().getAvailableKiosks()) {
- drawerLayoutBinding.navigation.getMenu()
- .add(R.id.menu_tabs_group, kioskId, ORDER,
- KioskTranslator.getTranslatedKioskName(ks, this))
- .setIcon(KioskTranslator.getKioskIcon(ks, this));
- kioskId++;
- }
-
- drawerLayoutBinding.navigation.getMenu()
- .add(R.id.menu_tabs_group, ITEM_ID_SUBSCRIPTIONS, ORDER, R.string.tab_subscriptions)
- .setIcon(R.drawable.ic_tv);
- drawerLayoutBinding.navigation.getMenu()
- .add(R.id.menu_tabs_group, ITEM_ID_FEED, ORDER, R.string.fragment_feed_title)
- .setIcon(R.drawable.ic_rss_feed);
- drawerLayoutBinding.navigation.getMenu()
- .add(R.id.menu_tabs_group, ITEM_ID_BOOKMARKS, ORDER, R.string.tab_bookmarks)
- .setIcon(R.drawable.ic_bookmark);
- drawerLayoutBinding.navigation.getMenu()
- .add(R.id.menu_tabs_group, ITEM_ID_DOWNLOADS, ORDER, R.string.downloads)
- .setIcon(R.drawable.ic_file_download);
- drawerLayoutBinding.navigation.getMenu()
- .add(R.id.menu_tabs_group, ITEM_ID_HISTORY, ORDER, R.string.action_history)
- .setIcon(R.drawable.ic_history);
-
- //Settings and About
- drawerLayoutBinding.navigation.getMenu()
- .add(R.id.menu_options_about_group, ITEM_ID_SETTINGS, ORDER, R.string.settings)
- .setIcon(R.drawable.ic_settings);
- drawerLayoutBinding.navigation.getMenu()
- .add(R.id.menu_options_about_group, ITEM_ID_ABOUT, ORDER, R.string.tab_about)
- .setIcon(R.drawable.ic_info_outline);
- }
-
@Override
protected void onDestroy() {
super.onDestroy();
diff --git a/app/src/main/java/org/schabi/newpipe/QueueItemMenuUtil.java b/app/src/main/java/org/schabi/newpipe/QueueItemMenuUtil.java
index 9105ff992..fcad0b612 100644
--- a/app/src/main/java/org/schabi/newpipe/QueueItemMenuUtil.java
+++ b/app/src/main/java/org/schabi/newpipe/QueueItemMenuUtil.java
@@ -9,8 +9,8 @@ import android.widget.PopupMenu;
import androidx.fragment.app.FragmentManager;
-import org.schabi.newpipe.local.dialog.PlaylistAppendDialog;
-import org.schabi.newpipe.local.dialog.PlaylistCreationDialog;
+import org.schabi.newpipe.database.stream.model.StreamEntity;
+import org.schabi.newpipe.local.dialog.PlaylistDialog;
import org.schabi.newpipe.player.playqueue.PlayQueue;
import org.schabi.newpipe.player.playqueue.PlayQueueItem;
import org.schabi.newpipe.util.NavigationHelper;
@@ -18,6 +18,9 @@ import org.schabi.newpipe.util.NavigationHelper;
import java.util.Collections;
public final class QueueItemMenuUtil {
+ private QueueItemMenuUtil() {
+ }
+
public static void openPopupMenu(final PlayQueue playQueue,
final PlayQueueItem item,
final View view,
@@ -47,13 +50,22 @@ public final class QueueItemMenuUtil {
false);
return true;
case R.id.menu_item_append_playlist:
- final PlaylistAppendDialog d = PlaylistAppendDialog.fromPlayQueueItems(
- Collections.singletonList(item)
+ PlaylistDialog.createCorrespondingDialog(
+ context,
+ Collections.singletonList(new StreamEntity(item)),
+ dialog -> dialog.show(
+ fragmentManager,
+ "QueueItemMenuUtil@append_playlist"
+ )
);
- PlaylistAppendDialog.onPlaylistFound(context,
- () -> d.show(fragmentManager, "QueueItemMenuUtil@append_playlist"),
- () -> PlaylistCreationDialog.newInstance(d)
- .show(fragmentManager, "QueueItemMenuUtil@append_playlist"));
+
+ return true;
+ case R.id.menu_item_channel_details:
+ // An intent must be used here.
+ // Opening with FragmentManager transactions is not working,
+ // as PlayQueueActivity doesn't use fragments.
+ NavigationHelper.openChannelFragmentUsingIntent(context, item.getServiceId(),
+ item.getUploaderUrl(), item.getUploader());
return true;
case R.id.menu_item_share:
shareText(context, item.getTitle(), item.getUrl(),
@@ -65,6 +77,4 @@ public final class QueueItemMenuUtil {
popupMenu.show();
}
-
- private QueueItemMenuUtil() { }
}
diff --git a/app/src/main/java/org/schabi/newpipe/RouterActivity.java b/app/src/main/java/org/schabi/newpipe/RouterActivity.java
index feb9e029d..4e96f3bb6 100644
--- a/app/src/main/java/org/schabi/newpipe/RouterActivity.java
+++ b/app/src/main/java/org/schabi/newpipe/RouterActivity.java
@@ -1,5 +1,8 @@
package org.schabi.newpipe;
+import static org.schabi.newpipe.extractor.StreamingService.ServiceInfo.MediaCapability.AUDIO;
+import static org.schabi.newpipe.extractor.StreamingService.ServiceInfo.MediaCapability.VIDEO;
+
import android.annotation.SuppressLint;
import android.app.IntentService;
import android.content.Context;
@@ -30,6 +33,7 @@ import androidx.core.widget.TextViewCompat;
import androidx.fragment.app.FragmentManager;
import androidx.preference.PreferenceManager;
+import org.schabi.newpipe.database.stream.model.StreamEntity;
import org.schabi.newpipe.databinding.ListRadioIconItemBinding;
import org.schabi.newpipe.databinding.SingleChoiceDialogViewBinding;
import org.schabi.newpipe.download.DownloadDialog;
@@ -56,6 +60,7 @@ import org.schabi.newpipe.extractor.playlist.PlaylistInfo;
import org.schabi.newpipe.extractor.stream.StreamInfo;
import org.schabi.newpipe.extractor.stream.VideoStream;
import org.schabi.newpipe.ktx.ExceptionUtils;
+import org.schabi.newpipe.local.dialog.PlaylistDialog;
import org.schabi.newpipe.player.MainPlayer;
import org.schabi.newpipe.player.helper.PlayerHelper;
import org.schabi.newpipe.player.helper.PlayerHolder;
@@ -69,14 +74,15 @@ import org.schabi.newpipe.util.ExtractorHelper;
import org.schabi.newpipe.util.ListHelper;
import org.schabi.newpipe.util.NavigationHelper;
import org.schabi.newpipe.util.PermissionHelper;
-import org.schabi.newpipe.util.external_communication.ShareUtils;
import org.schabi.newpipe.util.ThemeHelper;
+import org.schabi.newpipe.util.external_communication.ShareUtils;
import org.schabi.newpipe.util.urlfinder.UrlFinder;
import org.schabi.newpipe.views.FocusOverlayView;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Arrays;
+import java.util.Collections;
import java.util.List;
import icepick.Icepick;
@@ -89,9 +95,6 @@ import io.reactivex.rxjava3.disposables.Disposable;
import io.reactivex.rxjava3.functions.Consumer;
import io.reactivex.rxjava3.schedulers.Schedulers;
-import static org.schabi.newpipe.extractor.StreamingService.ServiceInfo.MediaCapability.AUDIO;
-import static org.schabi.newpipe.extractor.StreamingService.ServiceInfo.MediaCapability.VIDEO;
-
/**
* Get the url from the intent and open it in the chosen preferred player.
*/
@@ -107,6 +110,7 @@ public class RouterActivity extends AppCompatActivity {
protected String currentUrl;
private StreamingService currentService;
private boolean selectionIsDownload = false;
+ private boolean selectionIsAddToPlaylist = false;
private AlertDialog alertDialogChoice = null;
@Override
@@ -350,7 +354,7 @@ public class RouterActivity extends AppCompatActivity {
.setNegativeButton(R.string.just_once, dialogButtonsClickListener)
.setPositiveButton(R.string.always, dialogButtonsClickListener)
.setOnDismissListener((dialog) -> {
- if (!selectionIsDownload) {
+ if (!selectionIsDownload && !selectionIsAddToPlaylist) {
finish();
}
})
@@ -446,6 +450,10 @@ public class RouterActivity extends AppCompatActivity {
final AdapterChoiceItem backgroundPlayer = new AdapterChoiceItem(
getString(R.string.background_player_key), getString(R.string.background_player),
R.drawable.ic_headset);
+ final AdapterChoiceItem addToPlaylist = new AdapterChoiceItem(
+ getString(R.string.add_to_playlist_key), getString(R.string.add_to_playlist),
+ R.drawable.ic_add);
+
if (linkType == LinkType.STREAM) {
if (isExtVideoEnabled) {
@@ -482,6 +490,10 @@ public class RouterActivity extends AppCompatActivity {
getString(R.string.download),
R.drawable.ic_file_download));
+ // Add to playlist is not necessary for CHANNEL and PLAYLIST linkType since those can
+ // not be added to a playlist
+ returnList.add(addToPlaylist);
+
} else {
returnList.add(showInfo);
if (capabilities.contains(VIDEO) && !isExtVideoEnabled) {
@@ -547,6 +559,12 @@ public class RouterActivity extends AppCompatActivity {
return;
}
+ if (selectedChoiceKey.equals(getString(R.string.add_to_playlist_key))) {
+ selectionIsAddToPlaylist = true;
+ openAddToPlaylistDialog();
+ return;
+ }
+
// stop and bypass FetcherService if InfoScreen was selected since
// StreamDetailFragment can fetch data itself
if (selectedChoiceKey.equals(getString(R.string.show_info_key))) {
@@ -572,6 +590,41 @@ public class RouterActivity extends AppCompatActivity {
finish();
}
+ private void openAddToPlaylistDialog() {
+ // Getting the stream info usually takes a moment
+ // Notifying the user here to ensure that no confusion arises
+ Toast.makeText(
+ getApplicationContext(),
+ getString(R.string.processing_may_take_a_moment),
+ Toast.LENGTH_SHORT)
+ .show();
+
+ disposables.add(ExtractorHelper.getStreamInfo(currentServiceId, currentUrl, false)
+ .subscribeOn(Schedulers.io())
+ .observeOn(AndroidSchedulers.mainThread())
+ .subscribe(
+ info -> PlaylistDialog.createCorrespondingDialog(
+ getThemeWrapperContext(),
+ Collections.singletonList(new StreamEntity(info)),
+ playlistDialog -> {
+ playlistDialog.setOnDismissListener(dialog -> finish());
+
+ playlistDialog.show(
+ this.getSupportFragmentManager(),
+ "addToPlaylistDialog"
+ );
+ }
+ ),
+ throwable -> handleError(this, new ErrorInfo(
+ throwable,
+ UserAction.REQUESTED_STREAM,
+ "Tried to add " + currentUrl + " to a playlist",
+ currentService.getServiceId())
+ )
+ )
+ );
+ }
+
@SuppressLint("CheckResult")
private void openDownloadDialog() {
disposables.add(ExtractorHelper.getStreamInfo(currentServiceId, currentUrl, true)
diff --git a/app/src/main/java/org/schabi/newpipe/database/feed/dao/FeedDAO.kt b/app/src/main/java/org/schabi/newpipe/database/feed/dao/FeedDAO.kt
index 689f1ead6..72692a9f5 100644
--- a/app/src/main/java/org/schabi/newpipe/database/feed/dao/FeedDAO.kt
+++ b/app/src/main/java/org/schabi/newpipe/database/feed/dao/FeedDAO.kt
@@ -7,6 +7,7 @@ import androidx.room.Query
import androidx.room.Transaction
import androidx.room.Update
import io.reactivex.rxjava3.core.Flowable
+import io.reactivex.rxjava3.core.Maybe
import org.schabi.newpipe.database.feed.model.FeedEntity
import org.schabi.newpipe.database.feed.model.FeedLastUpdatedEntity
import org.schabi.newpipe.database.stream.StreamWithState
@@ -37,7 +38,7 @@ abstract class FeedDAO {
LIMIT 500
"""
)
- abstract fun getAllStreams(): Flowable>
+ abstract fun getAllStreams(): Maybe>
@Query(
"""
@@ -62,7 +63,7 @@ abstract class FeedDAO {
LIMIT 500
"""
)
- abstract fun getAllStreamsForGroup(groupId: Long): Flowable>
+ abstract fun getAllStreamsForGroup(groupId: Long): Maybe>
/**
* @see StreamStateEntity.isFinished()
@@ -97,7 +98,7 @@ abstract class FeedDAO {
LIMIT 500
"""
)
- abstract fun getLiveOrNotPlayedStreams(): Flowable>
+ abstract fun getLiveOrNotPlayedStreams(): Maybe>
/**
* @see StreamStateEntity.isFinished()
@@ -137,7 +138,7 @@ abstract class FeedDAO {
LIMIT 500
"""
)
- abstract fun getLiveOrNotPlayedStreamsForGroup(groupId: Long): Flowable>
+ abstract fun getLiveOrNotPlayedStreamsForGroup(groupId: Long): Maybe>
@Query(
"""
diff --git a/app/src/main/java/org/schabi/newpipe/error/EnsureExceptionSerializable.java b/app/src/main/java/org/schabi/newpipe/error/EnsureExceptionSerializable.java
new file mode 100644
index 000000000..db94de5e5
--- /dev/null
+++ b/app/src/main/java/org/schabi/newpipe/error/EnsureExceptionSerializable.java
@@ -0,0 +1,103 @@
+package org.schabi.newpipe.error;
+
+import android.util.Log;
+
+import androidx.annotation.NonNull;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.ObjectOutputStream;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+/**
+ * Ensures that a Exception is serializable.
+ * This is
+ */
+public final class EnsureExceptionSerializable {
+ private static final String TAG = "EnsureExSerializable";
+
+ private EnsureExceptionSerializable() {
+ // No instance
+ }
+
+ /**
+ * Ensures that an exception is serializable.
+ *
+ * If that is not the case a {@link WorkaroundNotSerializableException} is created.
+ *
+ * @param exception
+ * @return if an exception is not serializable a new {@link WorkaroundNotSerializableException}
+ * otherwise the exception from the parameter
+ */
+ public static Exception ensureSerializable(@NonNull final Exception exception) {
+ return checkIfSerializable(exception)
+ ? exception
+ : WorkaroundNotSerializableException.create(exception);
+ }
+
+ public static boolean checkIfSerializable(@NonNull final Exception exception) {
+ try {
+ // Check by creating a new ObjectOutputStream which does the serialization
+ try (ByteArrayOutputStream bos = new ByteArrayOutputStream();
+ ObjectOutputStream oos = new ObjectOutputStream(bos)
+ ) {
+ oos.writeObject(exception);
+ oos.flush();
+
+ bos.toByteArray();
+ }
+
+ return true;
+ } catch (final IOException ex) {
+ Log.d(TAG, "Exception is not serializable", ex);
+ return false;
+ }
+ }
+
+ public static class WorkaroundNotSerializableException extends Exception {
+ protected WorkaroundNotSerializableException(
+ final Throwable notSerializableException,
+ final Throwable cause) {
+ super(notSerializableException.toString(), cause);
+ setStackTrace(notSerializableException.getStackTrace());
+ }
+
+ protected WorkaroundNotSerializableException(final Throwable notSerializableException) {
+ super(notSerializableException.toString());
+ setStackTrace(notSerializableException.getStackTrace());
+ }
+
+ public static WorkaroundNotSerializableException create(
+ @NonNull final Exception notSerializableException
+ ) {
+ // Build a list of the exception + all causes
+ final List throwableList = new ArrayList<>();
+
+ int pos = 0;
+ Throwable throwableToProcess = notSerializableException;
+
+ while (throwableToProcess != null) {
+ throwableList.add(throwableToProcess);
+
+ pos++;
+ throwableToProcess = throwableToProcess.getCause();
+ }
+
+ // Reverse list so that it starts with the last one
+ Collections.reverse(throwableList);
+
+ // Build exception stack
+ WorkaroundNotSerializableException cause = null;
+ for (final Throwable t : throwableList) {
+ cause = cause == null
+ ? new WorkaroundNotSerializableException(t)
+ : new WorkaroundNotSerializableException(t, cause);
+ }
+
+ return cause;
+ }
+
+ }
+}
diff --git a/app/src/main/java/org/schabi/newpipe/error/ErrorActivity.java b/app/src/main/java/org/schabi/newpipe/error/ErrorActivity.java
index c0d88c8ec..db3a92d4f 100644
--- a/app/src/main/java/org/schabi/newpipe/error/ErrorActivity.java
+++ b/app/src/main/java/org/schabi/newpipe/error/ErrorActivity.java
@@ -77,6 +77,16 @@ public class ErrorActivity extends AppCompatActivity {
private ActivityErrorBinding activityErrorBinding;
+ /**
+ * Reports a new error by starting a new activity.
+ *
+ * Ensure that the data within errorInfo is serializable otherwise
+ * an exception will be thrown!
+ * {@link EnsureExceptionSerializable} might help.
+ *
+ * @param context
+ * @param errorInfo
+ */
public static void reportError(final Context context, final ErrorInfo errorInfo) {
final Intent intent = new Intent(context, ErrorActivity.class);
intent.putExtra(ERROR_INFO, errorInfo);
diff --git a/app/src/main/java/org/schabi/newpipe/fragments/BlankFragment.java b/app/src/main/java/org/schabi/newpipe/fragments/BlankFragment.java
index 0cccfa4fe..fe4eef37a 100644
--- a/app/src/main/java/org/schabi/newpipe/fragments/BlankFragment.java
+++ b/app/src/main/java/org/schabi/newpipe/fragments/BlankFragment.java
@@ -20,8 +20,8 @@ public class BlankFragment extends BaseFragment {
}
@Override
- public void setUserVisibleHint(final boolean isVisibleToUser) {
- super.setUserVisibleHint(isVisibleToUser);
+ public void onResume() {
+ super.onResume();
setTitle("NewPipe");
// leave this inline. Will make it harder for copy cats.
// If you are a Copy cat FUCK YOU.
diff --git a/app/src/main/java/org/schabi/newpipe/fragments/detail/VideoDetailFragment.java b/app/src/main/java/org/schabi/newpipe/fragments/detail/VideoDetailFragment.java
index 437cb2fdb..8c6e01537 100644
--- a/app/src/main/java/org/schabi/newpipe/fragments/detail/VideoDetailFragment.java
+++ b/app/src/main/java/org/schabi/newpipe/fragments/detail/VideoDetailFragment.java
@@ -52,6 +52,7 @@ import com.squareup.picasso.Callback;
import org.schabi.newpipe.App;
import org.schabi.newpipe.R;
+import org.schabi.newpipe.database.stream.model.StreamEntity;
import org.schabi.newpipe.databinding.FragmentVideoDetailBinding;
import org.schabi.newpipe.download.DownloadDialog;
import org.schabi.newpipe.error.ErrorActivity;
@@ -73,8 +74,7 @@ import org.schabi.newpipe.fragments.EmptyFragment;
import org.schabi.newpipe.fragments.list.comments.CommentsFragment;
import org.schabi.newpipe.fragments.list.videos.RelatedItemsFragment;
import org.schabi.newpipe.ktx.AnimationType;
-import org.schabi.newpipe.local.dialog.PlaylistAppendDialog;
-import org.schabi.newpipe.local.dialog.PlaylistCreationDialog;
+import org.schabi.newpipe.local.dialog.PlaylistDialog;
import org.schabi.newpipe.local.history.HistoryRecordManager;
import org.schabi.newpipe.player.MainPlayer;
import org.schabi.newpipe.player.MainPlayer.PlayerType;
@@ -99,6 +99,7 @@ import org.schabi.newpipe.util.external_communication.KoreUtils;
import org.schabi.newpipe.util.external_communication.ShareUtils;
import java.util.ArrayList;
+import java.util.Collections;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
@@ -444,12 +445,11 @@ public final class VideoDetailFragment
break;
case R.id.detail_controls_playlist_append:
if (getFM() != null && currentInfo != null) {
-
- final PlaylistAppendDialog d = PlaylistAppendDialog.fromStreamInfo(currentInfo);
disposables.add(
- PlaylistAppendDialog.onPlaylistFound(getContext(),
- () -> d.show(getFM(), TAG),
- () -> PlaylistCreationDialog.newInstance(d).show(getFM(), TAG)
+ PlaylistDialog.createCorrespondingDialog(
+ getContext(),
+ Collections.singletonList(new StreamEntity(currentInfo)),
+ dialog -> dialog.show(getFM(), TAG)
)
);
}
@@ -594,6 +594,11 @@ public final class VideoDetailFragment
// Init
//////////////////////////////////////////////////////////////////////////*/
+ @Override
+ public void onViewCreated(@NonNull final View rootView, final Bundle savedInstanceState) {
+ super.onViewCreated(rootView, savedInstanceState);
+ }
+
@Override // called from onViewCreated in {@link BaseFragment#onViewCreated}
protected void initViews(final View rootView, final Bundle savedInstanceState) {
super.initViews(rootView, savedInstanceState);
@@ -604,6 +609,18 @@ public final class VideoDetailFragment
binding.detailThumbnailRootLayout.requestFocus();
+ binding.detailControlsPlayWithKodi.setVisibility(
+ KoreUtils.shouldShowPlayWithKodi(requireContext(), serviceId)
+ ? View.VISIBLE
+ : View.GONE
+ );
+ binding.detailControlsCrashThePlayer.setVisibility(
+ DEBUG && PreferenceManager.getDefaultSharedPreferences(getContext())
+ .getBoolean(getString(R.string.show_crash_the_player_key), false)
+ ? View.VISIBLE
+ : View.GONE
+ );
+
if (DeviceUtils.isTv(getContext())) {
// remove ripple effects from detail controls
final int transparent = ContextCompat.getColor(requireContext(),
@@ -638,8 +655,14 @@ public final class VideoDetailFragment
binding.detailControlsShare.setOnClickListener(this);
binding.detailControlsOpenInBrowser.setOnClickListener(this);
binding.detailControlsPlayWithKodi.setOnClickListener(this);
- binding.detailControlsPlayWithKodi.setVisibility(KoreUtils.shouldShowPlayWithKodi(
- requireContext(), serviceId) ? View.VISIBLE : View.GONE);
+ if (DEBUG) {
+ binding.detailControlsCrashThePlayer.setOnClickListener(
+ v -> VideoDetailPlayerCrasher.onCrashThePlayer(
+ this.getContext(),
+ this.player,
+ getLayoutInflater())
+ );
+ }
binding.overlayThumbnail.setOnClickListener(this);
binding.overlayThumbnail.setOnLongClickListener(this);
diff --git a/app/src/main/java/org/schabi/newpipe/fragments/detail/VideoDetailPlayerCrasher.java b/app/src/main/java/org/schabi/newpipe/fragments/detail/VideoDetailPlayerCrasher.java
new file mode 100644
index 000000000..9309a8a49
--- /dev/null
+++ b/app/src/main/java/org/schabi/newpipe/fragments/detail/VideoDetailPlayerCrasher.java
@@ -0,0 +1,159 @@
+package org.schabi.newpipe.fragments.detail;
+
+import android.content.Context;
+import android.util.Log;
+import android.view.ContextThemeWrapper;
+import android.view.LayoutInflater;
+import android.view.ViewGroup;
+import android.widget.RadioButton;
+import android.widget.RadioGroup;
+import android.widget.Toast;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+import androidx.appcompat.app.AlertDialog;
+
+import com.google.android.exoplayer2.C;
+import com.google.android.exoplayer2.ExoPlaybackException;
+
+import org.schabi.newpipe.R;
+import org.schabi.newpipe.databinding.ListRadioIconItemBinding;
+import org.schabi.newpipe.databinding.SingleChoiceDialogViewBinding;
+import org.schabi.newpipe.player.Player;
+import org.schabi.newpipe.util.ThemeHelper;
+
+import java.io.IOException;
+import java.util.Collections;
+import java.util.LinkedHashMap;
+import java.util.Map;
+import java.util.function.Supplier;
+
+/**
+ * Outsourced logic for crashing the player in the {@link VideoDetailFragment}.
+ */
+public final class VideoDetailPlayerCrasher {
+
+ // This has to be <= 23 chars on devices running Android 7 or lower (API <= 25)
+ // or it fails with an IllegalArgumentException
+ // https://stackoverflow.com/a/54744028
+ private static final String TAG = "VideoDetPlayerCrasher";
+
+ private static final Map> AVAILABLE_EXCEPTION_TYPES =
+ getExceptionTypes();
+
+ private VideoDetailPlayerCrasher() {
+ // No impls
+ }
+
+ private static Map> getExceptionTypes() {
+ final String defaultMsg = "Dummy";
+ final Map> exceptionTypes = new LinkedHashMap<>();
+ exceptionTypes.put(
+ "Source",
+ () -> ExoPlaybackException.createForSource(
+ new IOException(defaultMsg)
+ )
+ );
+ exceptionTypes.put(
+ "Renderer",
+ () -> ExoPlaybackException.createForRenderer(
+ new Exception(defaultMsg),
+ "Dummy renderer",
+ 0,
+ null,
+ C.FORMAT_HANDLED
+ )
+ );
+ exceptionTypes.put(
+ "Unexpected",
+ () -> ExoPlaybackException.createForUnexpected(
+ new RuntimeException(defaultMsg)
+ )
+ );
+ exceptionTypes.put(
+ "Remote",
+ () -> ExoPlaybackException.createForRemote(defaultMsg)
+ );
+
+ return Collections.unmodifiableMap(exceptionTypes);
+ }
+
+ private static Context getThemeWrapperContext(final Context context) {
+ return new ContextThemeWrapper(
+ context,
+ ThemeHelper.isLightThemeSelected(context)
+ ? R.style.LightTheme
+ : R.style.DarkTheme);
+ }
+
+ public static void onCrashThePlayer(
+ @NonNull final Context context,
+ @Nullable final Player player,
+ @NonNull final LayoutInflater layoutInflater
+ ) {
+ if (player == null) {
+ Log.d(TAG, "Player is not available");
+ Toast.makeText(context, "Player is not available", Toast.LENGTH_SHORT)
+ .show();
+
+ return;
+ }
+
+ // -- Build the dialog/UI --
+
+ final Context themeWrapperContext = getThemeWrapperContext(context);
+
+ final LayoutInflater inflater = LayoutInflater.from(themeWrapperContext);
+ final RadioGroup radioGroup = SingleChoiceDialogViewBinding.inflate(layoutInflater)
+ .list;
+
+ final AlertDialog alertDialog = new AlertDialog.Builder(getThemeWrapperContext(context))
+ .setTitle("Choose an exception")
+ .setView(radioGroup)
+ .setCancelable(true)
+ .setNegativeButton(R.string.cancel, null)
+ .create();
+
+ for (final Map.Entry> entry
+ : AVAILABLE_EXCEPTION_TYPES.entrySet()) {
+ final RadioButton radioButton = ListRadioIconItemBinding.inflate(inflater).getRoot();
+ radioButton.setText(entry.getKey());
+ radioButton.setChecked(false);
+ radioButton.setLayoutParams(
+ new RadioGroup.LayoutParams(
+ ViewGroup.LayoutParams.MATCH_PARENT,
+ ViewGroup.LayoutParams.WRAP_CONTENT
+ )
+ );
+ radioButton.setOnClickListener(v -> {
+ tryCrashPlayerWith(player, entry.getValue().get());
+ if (alertDialog != null) {
+ alertDialog.cancel();
+ }
+ });
+ radioGroup.addView(radioButton);
+ }
+
+ alertDialog.show();
+ }
+
+ /**
+ * Note that this method does not crash the underlying exoplayer directly (it's not possible).
+ * It simply supplies a Exception to {@link Player#onPlayerError(ExoPlaybackException)}.
+ * @param player
+ * @param exception
+ */
+ private static void tryCrashPlayerWith(
+ @NonNull final Player player,
+ @NonNull final ExoPlaybackException exception
+ ) {
+ Log.d(TAG, "Crashing the player using player.onPlayerError(ex)");
+ try {
+ player.onPlayerError(exception);
+ } catch (final Exception exPlayer) {
+ Log.e(TAG,
+ "Run into an exception while crashing the player:",
+ exPlayer);
+ }
+ }
+}
diff --git a/app/src/main/java/org/schabi/newpipe/fragments/list/BaseListFragment.java b/app/src/main/java/org/schabi/newpipe/fragments/list/BaseListFragment.java
index c30b6fc05..b9065c969 100644
--- a/app/src/main/java/org/schabi/newpipe/fragments/list/BaseListFragment.java
+++ b/app/src/main/java/org/schabi/newpipe/fragments/list/BaseListFragment.java
@@ -143,7 +143,7 @@ public abstract class BaseListFragment extends BaseStateFragment
final View focusedItem = itemsList.getFocusedChild();
final RecyclerView.ViewHolder itemHolder =
itemsList.findContainingViewHolder(focusedItem);
- return itemHolder.getAdapterPosition();
+ return itemHolder.getBindingAdapterPosition();
} catch (final NullPointerException e) {
return -1;
}
@@ -378,6 +378,13 @@ public abstract class BaseListFragment extends BaseStateFragment
if (KoreUtils.shouldShowPlayWithKodi(context, item.getServiceId())) {
entries.add(StreamDialogEntry.play_with_kodi);
}
+
+ // show "mark as watched" only when watch history is enabled
+ if (StreamDialogEntry.shouldAddMarkAsWatched(item.getStreamType(), context)) {
+ entries.add(
+ StreamDialogEntry.mark_as_watched
+ );
+ }
if (!isNullOrEmpty(item.getUploaderUrl())) {
entries.add(StreamDialogEntry.show_channel_details);
}
diff --git a/app/src/main/java/org/schabi/newpipe/fragments/list/channel/ChannelFragment.java b/app/src/main/java/org/schabi/newpipe/fragments/list/channel/ChannelFragment.java
index 1d16559ac..30e38a966 100644
--- a/app/src/main/java/org/schabi/newpipe/fragments/list/channel/ChannelFragment.java
+++ b/app/src/main/java/org/schabi/newpipe/fragments/list/channel/ChannelFragment.java
@@ -98,11 +98,9 @@ public class ChannelFragment extends BaseListInfoFragment
}
@Override
- public void setUserVisibleHint(final boolean isVisibleToUser) {
- super.setUserVisibleHint(isVisibleToUser);
- if (activity != null
- && useAsFrontPage
- && isVisibleToUser) {
+ public void onResume() {
+ super.onResume();
+ if (activity != null && useAsFrontPage) {
setTitle(currentInfo != null ? currentInfo.getName() : name);
}
}
diff --git a/app/src/main/java/org/schabi/newpipe/fragments/list/kiosk/KioskFragment.java b/app/src/main/java/org/schabi/newpipe/fragments/list/kiosk/KioskFragment.java
index f37f487bf..c25f18e8b 100644
--- a/app/src/main/java/org/schabi/newpipe/fragments/list/kiosk/KioskFragment.java
+++ b/app/src/main/java/org/schabi/newpipe/fragments/list/kiosk/KioskFragment.java
@@ -99,9 +99,12 @@ public class KioskFragment extends BaseListInfoFragment {
}
@Override
- public void setUserVisibleHint(final boolean isVisibleToUser) {
- super.setUserVisibleHint(isVisibleToUser);
- if (useAsFrontPage && isVisibleToUser && activity != null) {
+ public void onResume() {
+ super.onResume();
+ if (!Localization.getPreferredContentCountry(requireContext()).equals(contentCountry)) {
+ reloadContent();
+ }
+ if (useAsFrontPage && activity != null) {
try {
setTitle(kioskTranslatedName);
} catch (final Exception e) {
@@ -117,15 +120,6 @@ public class KioskFragment extends BaseListInfoFragment {
return inflater.inflate(R.layout.fragment_kiosk, container, false);
}
- @Override
- public void onResume() {
- super.onResume();
-
- if (!Localization.getPreferredContentCountry(requireContext()).equals(contentCountry)) {
- reloadContent();
- }
- }
-
/*//////////////////////////////////////////////////////////////////////////
// Menu
//////////////////////////////////////////////////////////////////////////*/
diff --git a/app/src/main/java/org/schabi/newpipe/fragments/list/playlist/PlaylistFragment.java b/app/src/main/java/org/schabi/newpipe/fragments/list/playlist/PlaylistFragment.java
index f3aa2e306..a8763af73 100644
--- a/app/src/main/java/org/schabi/newpipe/fragments/list/playlist/PlaylistFragment.java
+++ b/app/src/main/java/org/schabi/newpipe/fragments/list/playlist/PlaylistFragment.java
@@ -176,6 +176,12 @@ public class PlaylistFragment extends BaseListInfoFragment {
entries.add(StreamDialogEntry.play_with_kodi);
}
+ // show "mark as watched" only when watch history is enabled
+ if (StreamDialogEntry.shouldAddMarkAsWatched(item.getStreamType(), context)) {
+ entries.add(
+ StreamDialogEntry.mark_as_watched
+ );
+ }
if (!isNullOrEmpty(item.getUploaderUrl())) {
entries.add(StreamDialogEntry.show_channel_details);
}
diff --git a/app/src/main/java/org/schabi/newpipe/fragments/list/search/SearchFragment.java b/app/src/main/java/org/schabi/newpipe/fragments/list/search/SearchFragment.java
index 7de212383..d4d73f74f 100644
--- a/app/src/main/java/org/schabi/newpipe/fragments/list/search/SearchFragment.java
+++ b/app/src/main/java/org/schabi/newpipe/fragments/list/search/SearchFragment.java
@@ -1088,7 +1088,7 @@ public class SearchFragment extends BaseListFragment {
- if (hasPlaylists) {
- onSuccess.run();
- } else {
- onFailed.run();
- }
- });
- }
-
- public static PlaylistAppendDialog fromStreamInfo(final StreamInfo info) {
- final PlaylistAppendDialog dialog = new PlaylistAppendDialog();
- dialog.setInfo(Collections.singletonList(new StreamEntity(info)));
- return dialog;
- }
-
- public static PlaylistAppendDialog fromStreamInfoItems(final List items) {
- final PlaylistAppendDialog dialog = new PlaylistAppendDialog();
- final List entities = new ArrayList<>(items.size());
- for (final StreamInfoItem item : items) {
- entities.add(new StreamEntity(item));
- }
- dialog.setInfo(entities);
- return dialog;
- }
-
- public static PlaylistAppendDialog fromPlayQueueItems(final List items) {
- final PlaylistAppendDialog dialog = new PlaylistAppendDialog();
- final List entities = new ArrayList<>(items.size());
- for (final PlayQueueItem item : items) {
- entities.add(new StreamEntity(item));
- }
- dialog.setInfo(entities);
- return dialog;
+ public PlaylistAppendDialog(final List streamEntities) {
+ super(streamEntities);
}
/*//////////////////////////////////////////////////////////////////////////
@@ -104,11 +58,15 @@ public final class PlaylistAppendDialog extends PlaylistDialog {
playlistAdapter.setSelectedListener(new OnClickGesture() {
@Override
public void selected(final LocalItem selectedItem) {
- if (!(selectedItem instanceof PlaylistMetadataEntry) || getStreams() == null) {
+ if (!(selectedItem instanceof PlaylistMetadataEntry)
+ || getStreamEntities() == null) {
return;
}
- onPlaylistSelected(playlistManager, (PlaylistMetadataEntry) selectedItem,
- getStreams());
+ onPlaylistSelected(
+ playlistManager,
+ (PlaylistMetadataEntry) selectedItem,
+ getStreamEntities()
+ );
}
});
@@ -146,11 +104,17 @@ public final class PlaylistAppendDialog extends PlaylistDialog {
//////////////////////////////////////////////////////////////////////////*/
public void openCreatePlaylistDialog() {
- if (getStreams() == null || !isAdded()) {
+ if (getStreamEntities() == null || !isAdded()) {
return;
}
- PlaylistCreationDialog.newInstance(getStreams()).show(getParentFragmentManager(), TAG);
+ final PlaylistCreationDialog playlistCreationDialog =
+ new PlaylistCreationDialog(getStreamEntities());
+ // Move the dismissListener to the new dialog.
+ playlistCreationDialog.setOnDismissListener(this.getOnDismissListener());
+ this.setOnDismissListener(null);
+
+ playlistCreationDialog.show(getParentFragmentManager(), TAG);
requireDialog().dismiss();
}
@@ -165,7 +129,7 @@ public final class PlaylistAppendDialog extends PlaylistDialog {
private void onPlaylistSelected(@NonNull final LocalPlaylistManager manager,
@NonNull final PlaylistMetadataEntry playlist,
@NonNull final List streams) {
- if (getStreams() == null) {
+ if (getStreamEntities() == null) {
return;
}
diff --git a/app/src/main/java/org/schabi/newpipe/local/dialog/PlaylistCreationDialog.java b/app/src/main/java/org/schabi/newpipe/local/dialog/PlaylistCreationDialog.java
index f48c72d04..6664144cd 100644
--- a/app/src/main/java/org/schabi/newpipe/local/dialog/PlaylistCreationDialog.java
+++ b/app/src/main/java/org/schabi/newpipe/local/dialog/PlaylistCreationDialog.java
@@ -7,29 +7,22 @@ import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
-import androidx.appcompat.app.AlertDialog;
+import androidx.appcompat.app.AlertDialog.Builder;
import org.schabi.newpipe.NewPipeDatabase;
import org.schabi.newpipe.R;
import org.schabi.newpipe.database.stream.model.StreamEntity;
import org.schabi.newpipe.databinding.DialogEditTextBinding;
import org.schabi.newpipe.local.playlist.LocalPlaylistManager;
+import org.schabi.newpipe.util.ThemeHelper;
import java.util.List;
import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers;
public final class PlaylistCreationDialog extends PlaylistDialog {
- public static PlaylistCreationDialog newInstance(final List streams) {
- final PlaylistCreationDialog dialog = new PlaylistCreationDialog();
- dialog.setInfo(streams);
- return dialog;
- }
-
- public static PlaylistCreationDialog newInstance(final PlaylistAppendDialog appendDialog) {
- final PlaylistCreationDialog dialog = new PlaylistCreationDialog();
- dialog.setInfo(appendDialog.getStreams());
- return dialog;
+ public PlaylistCreationDialog(final List streamEntities) {
+ super(streamEntities);
}
/*//////////////////////////////////////////////////////////////////////////
@@ -39,16 +32,18 @@ public final class PlaylistCreationDialog extends PlaylistDialog {
@NonNull
@Override
public Dialog onCreateDialog(@Nullable final Bundle savedInstanceState) {
- if (getStreams() == null) {
+ if (getStreamEntities() == null) {
return super.onCreateDialog(savedInstanceState);
}
final DialogEditTextBinding dialogBinding
= DialogEditTextBinding.inflate(getLayoutInflater());
+ dialogBinding.getRoot().getContext().setTheme(ThemeHelper.getDialogTheme(requireContext()));
dialogBinding.dialogEditText.setHint(R.string.name);
dialogBinding.dialogEditText.setInputType(InputType.TYPE_CLASS_TEXT);
- final AlertDialog.Builder dialogBuilder = new AlertDialog.Builder(requireContext())
+ final Builder dialogBuilder = new Builder(requireContext(),
+ ThemeHelper.getDialogTheme(requireContext()))
.setTitle(R.string.create_playlist)
.setView(dialogBinding.getRoot())
.setCancelable(true)
@@ -61,11 +56,10 @@ public final class PlaylistCreationDialog extends PlaylistDialog {
R.string.playlist_creation_success,
Toast.LENGTH_SHORT);
- playlistManager.createPlaylist(name, getStreams())
+ playlistManager.createPlaylist(name, getStreamEntities())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(longs -> successToast.show());
});
-
return dialogBuilder.create();
}
}
diff --git a/app/src/main/java/org/schabi/newpipe/local/dialog/PlaylistDialog.java b/app/src/main/java/org/schabi/newpipe/local/dialog/PlaylistDialog.java
index 2c2987e95..c2d4474f8 100644
--- a/app/src/main/java/org/schabi/newpipe/local/dialog/PlaylistDialog.java
+++ b/app/src/main/java/org/schabi/newpipe/local/dialog/PlaylistDialog.java
@@ -1,6 +1,8 @@
package org.schabi.newpipe.local.dialog;
import android.app.Dialog;
+import android.content.Context;
+import android.content.DialogInterface;
import android.os.Bundle;
import android.view.Window;
@@ -8,23 +10,29 @@ import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.DialogFragment;
+import org.schabi.newpipe.NewPipeDatabase;
import org.schabi.newpipe.database.stream.model.StreamEntity;
+import org.schabi.newpipe.local.playlist.LocalPlaylistManager;
import org.schabi.newpipe.util.StateSaver;
import java.util.List;
import java.util.Queue;
+import java.util.function.Consumer;
+
+import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers;
+import io.reactivex.rxjava3.disposables.Disposable;
public abstract class PlaylistDialog extends DialogFragment implements StateSaver.WriteRead {
+
+ @Nullable
+ private DialogInterface.OnDismissListener onDismissListener = null;
+
private List streamEntities;
private org.schabi.newpipe.util.SavedState savedState;
- protected void setInfo(final List entities) {
- this.streamEntities = entities;
- }
-
- protected List getStreams() {
- return streamEntities;
+ public PlaylistDialog(final List streamEntities) {
+ this.streamEntities = streamEntities;
}
/*//////////////////////////////////////////////////////////////////////////
@@ -43,6 +51,10 @@ public abstract class PlaylistDialog extends DialogFragment implements StateSave
StateSaver.onDestroy(savedState);
}
+ public List getStreamEntities() {
+ return streamEntities;
+ }
+
@NonNull
@Override
public Dialog onCreateDialog(final Bundle savedInstanceState) {
@@ -55,6 +67,14 @@ public abstract class PlaylistDialog extends DialogFragment implements StateSave
return dialog;
}
+ @Override
+ public void onDismiss(@NonNull final DialogInterface dialog) {
+ super.onDismiss(dialog);
+ if (onDismissListener != null) {
+ onDismissListener.onDismiss(dialog);
+ }
+ }
+
/*//////////////////////////////////////////////////////////////////////////
// State Saving
//////////////////////////////////////////////////////////////////////////*/
@@ -84,4 +104,47 @@ public abstract class PlaylistDialog extends DialogFragment implements StateSave
savedState, outState, this);
}
}
+
+ /*//////////////////////////////////////////////////////////////////////////
+ // Getter + Setter
+ //////////////////////////////////////////////////////////////////////////*/
+
+ @Nullable
+ public DialogInterface.OnDismissListener getOnDismissListener() {
+ return onDismissListener;
+ }
+
+ public void setOnDismissListener(
+ @Nullable final DialogInterface.OnDismissListener onDismissListener
+ ) {
+ this.onDismissListener = onDismissListener;
+ }
+
+ /*//////////////////////////////////////////////////////////////////////////
+ // Dialog creation
+ //////////////////////////////////////////////////////////////////////////*/
+
+ /**
+ * Creates a {@link PlaylistAppendDialog} when playlists exists,
+ * otherwise a {@link PlaylistCreationDialog}.
+ *
+ * @param context context used for accessing the database
+ * @param streamEntities used for crating the dialog
+ * @param onExec execution that should occur after a dialog got created, e.g. showing it
+ * @return Disposable
+ */
+ public static Disposable createCorrespondingDialog(
+ final Context context,
+ final List streamEntities,
+ final Consumer onExec
+ ) {
+ return new LocalPlaylistManager(NewPipeDatabase.getInstance(context))
+ .hasPlaylists()
+ .observeOn(AndroidSchedulers.mainThread())
+ .subscribe(hasPlaylists ->
+ onExec.accept(hasPlaylists
+ ? new PlaylistAppendDialog(streamEntities)
+ : new PlaylistCreationDialog(streamEntities))
+ );
+ }
}
diff --git a/app/src/main/java/org/schabi/newpipe/local/feed/FeedDatabaseManager.kt b/app/src/main/java/org/schabi/newpipe/local/feed/FeedDatabaseManager.kt
index ff7c2848e..e28f2d31a 100644
--- a/app/src/main/java/org/schabi/newpipe/local/feed/FeedDatabaseManager.kt
+++ b/app/src/main/java/org/schabi/newpipe/local/feed/FeedDatabaseManager.kt
@@ -42,7 +42,7 @@ class FeedDatabaseManager(context: Context) {
fun getStreams(
groupId: Long = FeedGroupEntity.GROUP_ALL_ID,
getPlayedStreams: Boolean = true
- ): Flowable> {
+ ): Maybe> {
return when (groupId) {
FeedGroupEntity.GROUP_ALL_ID -> {
if (getPlayedStreams) feedTable.getAllStreams()
diff --git a/app/src/main/java/org/schabi/newpipe/local/feed/FeedFragment.kt b/app/src/main/java/org/schabi/newpipe/local/feed/FeedFragment.kt
index 965075bf3..5b593bcd7 100644
--- a/app/src/main/java/org/schabi/newpipe/local/feed/FeedFragment.kt
+++ b/app/src/main/java/org/schabi/newpipe/local/feed/FeedFragment.kt
@@ -21,16 +21,23 @@ package org.schabi.newpipe.local.feed
import android.annotation.SuppressLint
import android.app.Activity
+import android.content.Context
import android.content.Intent
import android.content.SharedPreferences
+import android.graphics.Typeface
+import android.graphics.drawable.Drawable
+import android.graphics.drawable.LayerDrawable
import android.os.Bundle
import android.os.Parcelable
+import android.util.Log
import android.view.LayoutInflater
import android.view.Menu
import android.view.MenuInflater
import android.view.MenuItem
import android.view.View
import android.view.ViewGroup
+import android.widget.Button
+import androidx.annotation.AttrRes
import androidx.annotation.Nullable
import androidx.appcompat.app.AlertDialog
import androidx.appcompat.content.res.AppCompatResources
@@ -40,8 +47,10 @@ import androidx.core.view.isVisible
import androidx.lifecycle.ViewModelProvider
import androidx.preference.PreferenceManager
import androidx.recyclerview.widget.GridLayoutManager
+import androidx.recyclerview.widget.RecyclerView
import com.xwray.groupie.GroupieAdapter
import com.xwray.groupie.Item
+import com.xwray.groupie.OnAsyncUpdateListener
import com.xwray.groupie.OnItemClickListener
import com.xwray.groupie.OnItemLongClickListener
import icepick.State
@@ -65,10 +74,12 @@ import org.schabi.newpipe.fragments.BaseStateFragment
import org.schabi.newpipe.info_list.InfoItemDialog
import org.schabi.newpipe.ktx.animate
import org.schabi.newpipe.ktx.animateHideRecyclerViewAllowingScrolling
+import org.schabi.newpipe.ktx.slideUp
import org.schabi.newpipe.local.feed.item.StreamItem
import org.schabi.newpipe.local.feed.service.FeedLoadService
import org.schabi.newpipe.local.subscription.SubscriptionManager
import org.schabi.newpipe.player.helper.PlayerHolder
+import org.schabi.newpipe.util.DeviceUtils
import org.schabi.newpipe.util.Localization
import org.schabi.newpipe.util.NavigationHelper
import org.schabi.newpipe.util.StreamDialogEntry
@@ -76,6 +87,7 @@ import org.schabi.newpipe.util.ThemeHelper.getGridSpanCountStreams
import org.schabi.newpipe.util.ThemeHelper.shouldUseGridLayout
import java.time.OffsetDateTime
import java.util.ArrayList
+import java.util.function.Consumer
class FeedFragment : BaseStateFragment() {
private var _feedBinding: FragmentFeedBinding? = null
@@ -97,6 +109,8 @@ class FeedFragment : BaseStateFragment() {
private var updateListViewModeOnResume = false
private var isRefreshing = false
+ private var lastNewItemsCount = 0
+
init {
setHasOptionsMenu(true)
}
@@ -126,8 +140,9 @@ class FeedFragment : BaseStateFragment() {
_feedBinding = FragmentFeedBinding.bind(rootView)
super.onViewCreated(rootView, savedInstanceState)
- val factory = FeedViewModel.Factory(requireContext(), groupId, showPlayedItems)
+ val factory = FeedViewModel.Factory(requireContext(), groupId)
viewModel = ViewModelProvider(this, factory).get(FeedViewModel::class.java)
+ showPlayedItems = viewModel.getShowPlayedItemsFromPreferences()
viewModel.stateLiveData.observe(viewLifecycleOwner, { it?.let(::handleResult) })
groupAdapter = GroupieAdapter().apply {
@@ -135,6 +150,20 @@ class FeedFragment : BaseStateFragment() {
setOnItemLongClickListener(listenerStreamItem)
}
+ feedBinding.itemsList.addOnScrollListener(object : RecyclerView.OnScrollListener() {
+ override fun onScrollStateChanged(recyclerView: RecyclerView, newState: Int) {
+ // Check if we scrolled to the top
+ if (newState == RecyclerView.SCROLL_STATE_IDLE &&
+ !recyclerView.canScrollVertically(-1)
+ ) {
+
+ if (tryGetNewItemsLoadedButton()?.isVisible == true) {
+ hideNewItemsLoaded(true)
+ }
+ }
+ }
+ })
+
feedBinding.itemsList.adapter = groupAdapter
setupListViewMode()
}
@@ -158,7 +187,7 @@ class FeedFragment : BaseStateFragment() {
}
}
- fun setupListViewMode() {
+ private fun setupListViewMode() {
// does everything needed to setup the layouts for grid or list modes
groupAdapter.spanCount = if (shouldUseGridLayout(context)) getGridSpanCountStreams(context) else 1
feedBinding.itemsList.layoutManager = GridLayoutManager(requireContext(), groupAdapter.spanCount).apply {
@@ -170,6 +199,10 @@ class FeedFragment : BaseStateFragment() {
super.initListeners()
feedBinding.refreshRootView.setOnClickListener { reloadContent() }
feedBinding.swipeRefreshLayout.setOnRefreshListener { reloadContent() }
+ feedBinding.newItemsLoadedButton.setOnClickListener {
+ hideNewItemsLoaded(true)
+ feedBinding.itemsList.scrollToPosition(0)
+ }
}
// /////////////////////////////////////////////////////////////////////////
@@ -213,6 +246,7 @@ class FeedFragment : BaseStateFragment() {
showPlayedItems = !item.isChecked
updateTogglePlayedItemsButton(item)
viewModel.togglePlayedItems(showPlayedItems)
+ viewModel.saveShowPlayedItemsToPreferences(showPlayedItems)
}
return super.onOptionsItemSelected(item)
@@ -236,6 +270,9 @@ class FeedFragment : BaseStateFragment() {
}
override fun onDestroyView() {
+ // Ensure that all animations are canceled
+ feedBinding.newItemsLoadedButton?.clearAnimation()
+
feedBinding.itemsList.adapter = null
_feedBinding = null
super.onDestroyView()
@@ -355,13 +392,7 @@ class FeedFragment : BaseStateFragment() {
}
// show "mark as watched" only when watch history is enabled
- val isWatchHistoryEnabled = PreferenceManager
- .getDefaultSharedPreferences(context)
- .getBoolean(getString(R.string.enable_watch_history_key), false)
- if (item.streamType != StreamType.AUDIO_LIVE_STREAM &&
- item.streamType != StreamType.LIVE_STREAM &&
- isWatchHistoryEnabled
- ) {
+ if (StreamDialogEntry.shouldAddMarkAsWatched(item.streamType, context)) {
entries.add(
StreamDialogEntry.mark_as_watched
)
@@ -404,7 +435,17 @@ class FeedFragment : BaseStateFragment() {
}
loadedState.items.forEach { it.itemVersion = itemVersion }
- groupAdapter.updateAsync(loadedState.items, false, null)
+ // This need to be saved in a variable as the update occurs async
+ val oldOldestSubscriptionUpdate = oldestSubscriptionUpdate
+
+ groupAdapter.updateAsync(
+ loadedState.items, false,
+ OnAsyncUpdateListener {
+ oldOldestSubscriptionUpdate?.run {
+ highlightNewItemsAfter(oldOldestSubscriptionUpdate)
+ }
+ }
+ )
listState?.run {
feedBinding.itemsList.layoutManager?.onRestoreInstanceState(listState)
@@ -464,7 +505,7 @@ class FeedFragment : BaseStateFragment() {
errors.subList(i + 1, errors.size)
)
},
- { throwable -> throwable.printStackTrace() }
+ { throwable -> Log.e(TAG, "Unable to process", throwable) }
)
return // this will be called on the remaining errors by handleFeedNotAvailable()
}
@@ -526,6 +567,125 @@ class FeedFragment : BaseStateFragment() {
)
}
+ /**
+ * Highlights all items that are after the specified time
+ */
+ private fun highlightNewItemsAfter(updateTime: OffsetDateTime) {
+ var highlightCount = 0
+
+ var doCheck = true
+
+ for (i in 0 until groupAdapter.itemCount) {
+ val item = groupAdapter.getItem(i) as StreamItem
+
+ var typeface = Typeface.DEFAULT
+ var backgroundSupplier = { ctx: Context ->
+ resolveDrawable(ctx, R.attr.selectableItemBackground)
+ }
+ if (doCheck) {
+ // If the uploadDate is null or true we should highlight the item
+ if (item.streamWithState.stream.uploadDate?.isAfter(updateTime) != false) {
+ highlightCount++
+
+ typeface = Typeface.DEFAULT_BOLD
+ backgroundSupplier = { ctx: Context ->
+ // Merge the drawables together. Otherwise we would lose the "select" effect
+ LayerDrawable(
+ arrayOf(
+ resolveDrawable(ctx, R.attr.dashed_border),
+ resolveDrawable(ctx, R.attr.selectableItemBackground)
+ )
+ )
+ }
+ } else {
+ // Decreases execution time due to the order of the items (newest always on top)
+ // Once a item is is before the updateTime we can skip all following items
+ doCheck = false
+ }
+ }
+
+ // The highlighter has to be always set
+ // When it's only set on items that are highlighted it will highlight all items
+ // due to the fact that itemRoot is getting recycled
+ item.execBindEnd = Consumer { viewBinding ->
+ val context = viewBinding.itemRoot.context
+ viewBinding.itemRoot.background = backgroundSupplier.invoke(context)
+ viewBinding.itemVideoTitleView.typeface = typeface
+ }
+ }
+
+ // Force updates all items so that the highlighting is correct
+ // If this isn't done visible items that are already highlighted will stay in a highlighted
+ // state until the user scrolls them out of the visible area which causes a update/bind-call
+ groupAdapter.notifyItemRangeChanged(
+ 0,
+ minOf(groupAdapter.itemCount, maxOf(highlightCount, lastNewItemsCount))
+ )
+
+ if (highlightCount > 0) {
+ showNewItemsLoaded()
+ }
+
+ lastNewItemsCount = highlightCount
+ }
+
+ private fun resolveDrawable(context: Context, @AttrRes attrResId: Int): Drawable? {
+ return androidx.core.content.ContextCompat.getDrawable(
+ context,
+ android.util.TypedValue().apply {
+ context.theme.resolveAttribute(
+ attrResId,
+ this,
+ true
+ )
+ }.resourceId
+ )
+ }
+
+ private fun showNewItemsLoaded() {
+ tryGetNewItemsLoadedButton()?.clearAnimation()
+ tryGetNewItemsLoadedButton()
+ ?.slideUp(
+ 250L,
+ delay = 100,
+ execOnEnd = {
+ // Disabled animations would result in immediately hiding the button
+ // after it showed up
+ if (DeviceUtils.hasAnimationsAnimatorDurationEnabled(context)) {
+ // Hide the new items-"popup" after 10s
+ hideNewItemsLoaded(true, 10000)
+ }
+ }
+ )
+ }
+
+ private fun hideNewItemsLoaded(animate: Boolean, delay: Long = 0) {
+ tryGetNewItemsLoadedButton()?.clearAnimation()
+ if (animate) {
+ tryGetNewItemsLoadedButton()?.animate(
+ false,
+ 200,
+ delay = delay,
+ execOnEnd = {
+ // Make the layout invisible so that the onScroll toTop method
+ // only does necessary work
+ tryGetNewItemsLoadedButton()?.isVisible = false
+ }
+ )
+ } else {
+ tryGetNewItemsLoadedButton()?.isVisible = false
+ }
+ }
+
+ /**
+ * The view/button can be disposed/set to null under certain circumstances.
+ * E.g. when the animation is still in progress but the view got destroyed.
+ * This method is a helper for such states and can be used in affected code blocks.
+ */
+ private fun tryGetNewItemsLoadedButton(): Button? {
+ return _feedBinding?.newItemsLoadedButton
+ }
+
// /////////////////////////////////////////////////////////////////////////
// Load Service Handling
// /////////////////////////////////////////////////////////////////////////
@@ -533,6 +693,8 @@ class FeedFragment : BaseStateFragment() {
override fun doInitialLoadLogic() {}
override fun reloadContent() {
+ hideNewItemsLoaded(false)
+
getActivity()?.startService(
Intent(requireContext(), FeedLoadService::class.java).apply {
putExtra(FeedLoadService.EXTRA_GROUP_ID, groupId)
diff --git a/app/src/main/java/org/schabi/newpipe/local/feed/FeedViewModel.kt b/app/src/main/java/org/schabi/newpipe/local/feed/FeedViewModel.kt
index 8bdf412b5..2cbf9ad05 100644
--- a/app/src/main/java/org/schabi/newpipe/local/feed/FeedViewModel.kt
+++ b/app/src/main/java/org/schabi/newpipe/local/feed/FeedViewModel.kt
@@ -1,15 +1,18 @@
package org.schabi.newpipe.local.feed
import android.content.Context
+import androidx.core.content.edit
import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
import androidx.lifecycle.ViewModelProvider
+import androidx.preference.PreferenceManager
import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers
import io.reactivex.rxjava3.core.Flowable
import io.reactivex.rxjava3.functions.Function4
import io.reactivex.rxjava3.processors.BehaviorProcessor
import io.reactivex.rxjava3.schedulers.Schedulers
+import org.schabi.newpipe.R
import org.schabi.newpipe.database.feed.model.FeedGroupEntity
import org.schabi.newpipe.database.stream.StreamWithState
import org.schabi.newpipe.local.feed.item.StreamItem
@@ -23,19 +26,16 @@ import java.time.OffsetDateTime
import java.util.concurrent.TimeUnit
class FeedViewModel(
- applicationContext: Context,
+ private val applicationContext: Context,
groupId: Long = FeedGroupEntity.GROUP_ALL_ID,
initialShowPlayedItems: Boolean = true
) : ViewModel() {
private var feedDatabaseManager: FeedDatabaseManager = FeedDatabaseManager(applicationContext)
private val toggleShowPlayedItems = BehaviorProcessor.create()
- private val streamItems = toggleShowPlayedItems
+ private val toggleShowPlayedItemsFlowable = toggleShowPlayedItems
.startWithItem(initialShowPlayedItems)
.distinctUntilChanged()
- .switchMap { showPlayedItems ->
- feedDatabaseManager.getStreams(groupId, showPlayedItems)
- }
private val mutableStateLiveData = MutableLiveData()
val stateLiveData: LiveData = mutableStateLiveData
@@ -43,17 +43,28 @@ class FeedViewModel(
private var combineDisposable = Flowable
.combineLatest(
FeedEventManager.events(),
- streamItems,
+ toggleShowPlayedItemsFlowable,
feedDatabaseManager.notLoadedCount(groupId),
feedDatabaseManager.oldestSubscriptionUpdate(groupId),
- Function4 { t1: FeedEventManager.Event, t2: List,
+ Function4 { t1: FeedEventManager.Event, t2: Boolean,
t3: Long, t4: List ->
- return@Function4 CombineResultHolder(t1, t2, t3, t4.firstOrNull())
+ return@Function4 CombineResultEventHolder(t1, t2, t3, t4.firstOrNull())
}
)
.throttleLatest(DEFAULT_THROTTLE_TIMEOUT, TimeUnit.MILLISECONDS)
.subscribeOn(Schedulers.io())
+ .observeOn(Schedulers.io())
+ .map { (event, showPlayedItems, notLoadedCount, oldestUpdate) ->
+ var streamItems = if (event is SuccessResultEvent || event is IdleEvent)
+ feedDatabaseManager
+ .getStreams(groupId, showPlayedItems)
+ .blockingGet(arrayListOf())
+ else
+ arrayListOf()
+
+ CombineResultDataHolder(event, streamItems, notLoadedCount, oldestUpdate)
+ }
.observeOn(AndroidSchedulers.mainThread())
.subscribe { (event, listFromDB, notLoadedCount, oldestUpdate) ->
mutableStateLiveData.postValue(
@@ -75,20 +86,50 @@ class FeedViewModel(
combineDisposable.dispose()
}
- private data class CombineResultHolder(val t1: FeedEventManager.Event, val t2: List, val t3: Long, val t4: OffsetDateTime?)
+ private data class CombineResultEventHolder(
+ val t1: FeedEventManager.Event,
+ val t2: Boolean,
+ val t3: Long,
+ val t4: OffsetDateTime?
+ )
+
+ private data class CombineResultDataHolder(
+ val t1: FeedEventManager.Event,
+ val t2: List,
+ val t3: Long,
+ val t4: OffsetDateTime?
+ )
fun togglePlayedItems(showPlayedItems: Boolean) {
toggleShowPlayedItems.onNext(showPlayedItems)
}
+ fun saveShowPlayedItemsToPreferences(showPlayedItems: Boolean) =
+ PreferenceManager.getDefaultSharedPreferences(applicationContext).edit {
+ this.putBoolean(applicationContext.getString(R.string.feed_show_played_items_key), showPlayedItems)
+ this.apply()
+ }
+
+ fun getShowPlayedItemsFromPreferences() = getShowPlayedItemsFromPreferences(applicationContext)
+
+ companion object {
+ private fun getShowPlayedItemsFromPreferences(context: Context) =
+ PreferenceManager.getDefaultSharedPreferences(context)
+ .getBoolean(context.getString(R.string.feed_show_played_items_key), true)
+ }
+
class Factory(
private val context: Context,
- private val groupId: Long = FeedGroupEntity.GROUP_ALL_ID,
- private val showPlayedItems: Boolean
+ private val groupId: Long = FeedGroupEntity.GROUP_ALL_ID
) : ViewModelProvider.Factory {
@Suppress("UNCHECKED_CAST")
override fun create(modelClass: Class): T {
- return FeedViewModel(context.applicationContext, groupId, showPlayedItems) as T
+ return FeedViewModel(
+ context.applicationContext,
+ groupId,
+ // Read initial value from preferences
+ getShowPlayedItemsFromPreferences(context.applicationContext)
+ ) as T
}
}
}
diff --git a/app/src/main/java/org/schabi/newpipe/local/feed/item/StreamItem.kt b/app/src/main/java/org/schabi/newpipe/local/feed/item/StreamItem.kt
index 0d2caf126..217e3f3e3 100644
--- a/app/src/main/java/org/schabi/newpipe/local/feed/item/StreamItem.kt
+++ b/app/src/main/java/org/schabi/newpipe/local/feed/item/StreamItem.kt
@@ -19,6 +19,7 @@ import org.schabi.newpipe.util.Localization
import org.schabi.newpipe.util.PicassoHelper
import org.schabi.newpipe.util.StreamTypeUtil
import java.util.concurrent.TimeUnit
+import java.util.function.Consumer
data class StreamItem(
val streamWithState: StreamWithState,
@@ -31,6 +32,12 @@ data class StreamItem(
private val stream: StreamEntity = streamWithState.stream
private val stateProgressTime: Long? = streamWithState.stateProgressMillis
+ /**
+ * Will be executed at the end of the [StreamItem.bind] (with (ListStreamItemBinding,Int)).
+ * Can be used e.g. for highlighting a item.
+ */
+ var execBindEnd: Consumer? = null
+
override fun getId(): Long = stream.uid
enum class ItemVersion { NORMAL, MINI, GRID }
@@ -97,6 +104,8 @@ data class StreamItem(
viewBinding.itemAdditionalDetails.text =
getStreamInfoDetailLine(viewBinding.itemAdditionalDetails.context)
}
+
+ execBindEnd?.accept(viewBinding)
}
override fun isLongClickable() = when (stream.streamType) {
diff --git a/app/src/main/java/org/schabi/newpipe/local/history/HistoryRecordManager.java b/app/src/main/java/org/schabi/newpipe/local/history/HistoryRecordManager.java
index 823e56d9e..d94088cd0 100644
--- a/app/src/main/java/org/schabi/newpipe/local/history/HistoryRecordManager.java
+++ b/app/src/main/java/org/schabi/newpipe/local/history/HistoryRecordManager.java
@@ -120,19 +120,11 @@ public class HistoryRecordManager {
}
// Update the stream progress to the full duration of the video
- final List states = streamStateTable.getState(streamId)
- .blockingFirst();
- if (!states.isEmpty()) {
- final StreamStateEntity entity = states.get(0);
- entity.setProgressMillis(duration * 1000);
- streamStateTable.update(entity);
- } else {
- final StreamStateEntity entity = new StreamStateEntity(
- streamId,
- duration * 1000
- );
- streamStateTable.insert(entity);
- }
+ final StreamStateEntity entity = new StreamStateEntity(
+ streamId,
+ duration * 1000
+ );
+ streamStateTable.upsert(entity);
// Add a history entry
final StreamHistoryEntity latestEntry = streamHistoryTable.getLatestEntry(streamId);
@@ -334,9 +326,9 @@ public class HistoryRecordManager {
.getState(entities.get(0).getUid()).blockingFirst();
if (states.isEmpty()) {
result.add(null);
- continue;
+ } else {
+ result.add(states.get(0));
}
- result.add(states.get(0));
}
return result;
}).subscribeOn(Schedulers.io());
@@ -362,9 +354,9 @@ public class HistoryRecordManager {
.blockingFirst();
if (states.isEmpty()) {
result.add(null);
- continue;
+ } else {
+ result.add(states.get(0));
}
- result.add(states.get(0));
}
return result;
}).subscribeOn(Schedulers.io());
diff --git a/app/src/main/java/org/schabi/newpipe/local/history/StatisticsPlaylistFragment.java b/app/src/main/java/org/schabi/newpipe/local/history/StatisticsPlaylistFragment.java
index 9632b47f7..43a5fcf3c 100644
--- a/app/src/main/java/org/schabi/newpipe/local/history/StatisticsPlaylistFragment.java
+++ b/app/src/main/java/org/schabi/newpipe/local/history/StatisticsPlaylistFragment.java
@@ -101,9 +101,9 @@ public class StatisticsPlaylistFragment
}
@Override
- public void setUserVisibleHint(final boolean isVisibleToUser) {
- super.setUserVisibleHint(isVisibleToUser);
- if (activity != null && isVisibleToUser) {
+ public void onResume() {
+ super.onResume();
+ if (activity != null) {
setTitle(activity.getString(R.string.title_activity_history));
}
}
@@ -366,6 +366,16 @@ public class StatisticsPlaylistFragment
if (KoreUtils.shouldShowPlayWithKodi(context, infoItem.getServiceId())) {
entries.add(StreamDialogEntry.play_with_kodi);
}
+
+ // show "mark as watched" only when watch history is enabled
+ if (StreamDialogEntry.shouldAddMarkAsWatched(
+ item.getStreamEntity().getStreamType(),
+ context
+ )) {
+ entries.add(
+ StreamDialogEntry.mark_as_watched
+ );
+ }
entries.add(StreamDialogEntry.show_channel_details);
StreamDialogEntry.setEnabledEntries(entries);
diff --git a/app/src/main/java/org/schabi/newpipe/local/playlist/LocalPlaylistFragment.java b/app/src/main/java/org/schabi/newpipe/local/playlist/LocalPlaylistFragment.java
index 21da9e571..87d913b3b 100644
--- a/app/src/main/java/org/schabi/newpipe/local/playlist/LocalPlaylistFragment.java
+++ b/app/src/main/java/org/schabi/newpipe/local/playlist/LocalPlaylistFragment.java
@@ -709,8 +709,8 @@ public class LocalPlaylistFragment extends BaseLocalListFragment playlist) {
- final PlaylistAppendDialog d = PlaylistAppendDialog.fromPlayQueueItems(playlist);
-
- PlaylistAppendDialog.onPlaylistFound(getApplicationContext(),
- () -> d.show(getSupportFragmentManager(), TAG),
- () -> PlaylistCreationDialog.newInstance(d).show(getSupportFragmentManager(), TAG));
+ private void openPlaylistAppendDialog(final List playQueueItems) {
+ PlaylistDialog.createCorrespondingDialog(
+ getApplicationContext(),
+ playQueueItems.stream().map(StreamEntity::new).collect(Collectors.toList()),
+ dialog -> dialog.show(getSupportFragmentManager(), TAG)
+ );
}
////////////////////////////////////////////////////////////////////////////
diff --git a/app/src/main/java/org/schabi/newpipe/player/Player.java b/app/src/main/java/org/schabi/newpipe/player/Player.java
index 22e66e793..2d8c1a830 100644
--- a/app/src/main/java/org/schabi/newpipe/player/Player.java
+++ b/app/src/main/java/org/schabi/newpipe/player/Player.java
@@ -1,12 +1,13 @@
package org.schabi.newpipe.player;
-import static com.google.android.exoplayer2.Player.DISCONTINUITY_REASON_AD_INSERTION;
+import static com.google.android.exoplayer2.Player.DISCONTINUITY_REASON_AUTO_TRANSITION;
import static com.google.android.exoplayer2.Player.DISCONTINUITY_REASON_INTERNAL;
-import static com.google.android.exoplayer2.Player.DISCONTINUITY_REASON_PERIOD_TRANSITION;
+import static com.google.android.exoplayer2.Player.DISCONTINUITY_REASON_REMOVE;
import static com.google.android.exoplayer2.Player.DISCONTINUITY_REASON_SEEK;
import static com.google.android.exoplayer2.Player.DISCONTINUITY_REASON_SEEK_ADJUSTMENT;
+import static com.google.android.exoplayer2.Player.DISCONTINUITY_REASON_SKIP;
import static com.google.android.exoplayer2.Player.DiscontinuityReason;
-import static com.google.android.exoplayer2.Player.EventListener;
+import static com.google.android.exoplayer2.Player.Listener;
import static com.google.android.exoplayer2.Player.REPEAT_MODE_ALL;
import static com.google.android.exoplayer2.Player.REPEAT_MODE_OFF;
import static com.google.android.exoplayer2.Player.REPEAT_MODE_ONE;
@@ -96,7 +97,6 @@ import android.widget.ProgressBar;
import android.widget.RelativeLayout;
import android.widget.SeekBar;
import android.widget.TextView;
-import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
@@ -116,6 +116,7 @@ import com.google.android.exoplayer2.C;
import com.google.android.exoplayer2.DefaultRenderersFactory;
import com.google.android.exoplayer2.ExoPlaybackException;
import com.google.android.exoplayer2.PlaybackParameters;
+import com.google.android.exoplayer2.Player.PositionInfo;
import com.google.android.exoplayer2.RenderersFactory;
import com.google.android.exoplayer2.SimpleExoPlayer;
import com.google.android.exoplayer2.Timeline;
@@ -123,13 +124,14 @@ import com.google.android.exoplayer2.source.BehindLiveWindowException;
import com.google.android.exoplayer2.source.MediaSource;
import com.google.android.exoplayer2.source.TrackGroup;
import com.google.android.exoplayer2.source.TrackGroupArray;
-import com.google.android.exoplayer2.text.CaptionStyleCompat;
+import com.google.android.exoplayer2.text.Cue;
import com.google.android.exoplayer2.trackselection.TrackSelectionArray;
import com.google.android.exoplayer2.ui.AspectRatioFrameLayout;
+import com.google.android.exoplayer2.ui.CaptionStyleCompat;
import com.google.android.exoplayer2.ui.SubtitleView;
import com.google.android.exoplayer2.upstream.DefaultBandwidthMeter;
import com.google.android.exoplayer2.util.Util;
-import com.google.android.exoplayer2.video.VideoListener;
+import com.google.android.exoplayer2.video.VideoSize;
import com.google.android.material.floatingactionbutton.FloatingActionButton;
import com.squareup.picasso.Picasso;
import com.squareup.picasso.Target;
@@ -163,6 +165,7 @@ import org.schabi.newpipe.player.playback.MediaSourceManager;
import org.schabi.newpipe.player.playback.PlaybackListener;
import org.schabi.newpipe.player.playback.PlayerMediaSession;
import org.schabi.newpipe.player.playback.SurfaceHolderCallback;
+import org.schabi.newpipe.player.playererror.PlayerErrorHandler;
import org.schabi.newpipe.player.playqueue.PlayQueue;
import org.schabi.newpipe.player.playqueue.PlayQueueAdapter;
import org.schabi.newpipe.player.playqueue.PlayQueueItem;
@@ -174,12 +177,12 @@ import org.schabi.newpipe.player.resolver.MediaSourceTag;
import org.schabi.newpipe.player.resolver.VideoPlaybackResolver;
import org.schabi.newpipe.player.seekbarpreview.SeekbarPreviewThumbnailHelper;
import org.schabi.newpipe.player.seekbarpreview.SeekbarPreviewThumbnailHolder;
-import org.schabi.newpipe.util.StreamTypeUtil;
import org.schabi.newpipe.util.DeviceUtils;
import org.schabi.newpipe.util.ListHelper;
import org.schabi.newpipe.util.NavigationHelper;
import org.schabi.newpipe.util.PicassoHelper;
import org.schabi.newpipe.util.SerializedCache;
+import org.schabi.newpipe.util.StreamTypeUtil;
import org.schabi.newpipe.util.external_communication.KoreUtils;
import org.schabi.newpipe.util.external_communication.ShareUtils;
import org.schabi.newpipe.views.ExpandableSurfaceView;
@@ -197,9 +200,8 @@ import io.reactivex.rxjava3.disposables.Disposable;
import io.reactivex.rxjava3.disposables.SerialDisposable;
public final class Player implements
- EventListener,
PlaybackListener,
- VideoListener,
+ Listener,
SeekBar.OnSeekBarChangeListener,
View.OnClickListener,
PopupMenu.OnMenuItemClickListener,
@@ -266,7 +268,7 @@ public final class Player implements
@Nullable private MediaSourceTag currentMetadata;
@Nullable private Bitmap currentThumbnail;
- @Nullable private Toast errorToast;
+ @NonNull private PlayerErrorHandler playerErrorHandler;
/*//////////////////////////////////////////////////////////////////////////
// Player
@@ -411,6 +413,8 @@ public final class Player implements
videoResolver = new VideoPlaybackResolver(context, dataSource, getQualityResolver());
audioResolver = new AudioPlaybackResolver(context, dataSource);
+ playerErrorHandler = new PlayerErrorHandler(context);
+
windowManager = ContextCompat.getSystemService(context, WindowManager.class);
}
@@ -501,10 +505,6 @@ public final class Player implements
// Setup video view
setupVideoSurface();
- simpleExoPlayer.addVideoListener(this);
-
- // Setup subtitle view
- simpleExoPlayer.addTextOutput(binding.subtitleView);
// enable media tunneling
if (DEBUG && PreferenceManager.getDefaultSharedPreferences(context)
@@ -513,7 +513,7 @@ public final class Player implements
+ "media tunneling disabled in debug preferences");
} else if (DeviceUtils.shouldSupportMediaTunneling()) {
trackSelector.setParameters(trackSelector.buildUponParameters()
- .setTunnelingAudioSessionId(C.generateAudioSessionIdV21(context)));
+ .setTunnelingEnabled(true));
} else if (DEBUG) {
Log.d(TAG, "[" + Util.DEVICE_DEBUG_INFO + "] does not support media tunneling");
}
@@ -695,7 +695,7 @@ public final class Player implements
},
error -> {
if (DEBUG) {
- error.printStackTrace();
+ Log.w(TAG, "Failed to start playback", error);
}
// In case any error we can start playback without history
initPlayback(newQueue, repeatMode, playbackSpeed, playbackPitch,
@@ -774,6 +774,8 @@ public final class Player implements
destroyPlayer();
initPlayer(playOnReady);
setRepeatMode(repeatMode);
+ // #6825 - Ensure that the shuffle-button is in the correct state on the UI
+ setShuffleButton(binding.shuffleButton, simpleExoPlayer.getShuffleModeEnabled());
setPlaybackParameters(playbackSpeed, playbackPitch, playbackSkipSilence);
playQueue = queue;
@@ -807,7 +809,6 @@ public final class Player implements
if (!exoPlayerIsNull()) {
simpleExoPlayer.removeListener(this);
- simpleExoPlayer.removeVideoListener(this);
simpleExoPlayer.stop();
simpleExoPlayer.release();
}
@@ -858,10 +859,10 @@ public final class Player implements
final int queuePos = playQueue.getIndex();
final long windowPos = simpleExoPlayer.getCurrentPosition();
+ final long duration = simpleExoPlayer.getDuration();
- if (windowPos > 0 && windowPos <= simpleExoPlayer.getDuration()) {
- setRecovery(queuePos, windowPos);
- }
+ // No checks due to https://github.com/TeamNewPipe/NewPipe/pull/7195#issuecomment-962624380
+ setRecovery(queuePos, Math.max(0, Math.min(windowPos, duration)));
}
private void setRecovery(final int queuePos, final long windowPos) {
@@ -896,7 +897,7 @@ public final class Player implements
public void smoothStopPlayer() {
// Pausing would make transition from one stream to a new stream not smooth, so only stop
- simpleExoPlayer.stop(false);
+ simpleExoPlayer.stop();
}
//endregion
@@ -2435,7 +2436,9 @@ public final class Player implements
}
@Override
- public void onPositionDiscontinuity(@DiscontinuityReason final int discontinuityReason) {
+ public void onPositionDiscontinuity(
+ final PositionInfo oldPosition, final PositionInfo newPosition,
+ @DiscontinuityReason final int discontinuityReason) {
if (DEBUG) {
Log.d(TAG, "ExoPlayer - onPositionDiscontinuity() called with "
+ "discontinuityReason = [" + discontinuityReason + "]");
@@ -2447,7 +2450,8 @@ public final class Player implements
// Refresh the playback if there is a transition to the next video
final int newWindowIndex = simpleExoPlayer.getCurrentWindowIndex();
switch (discontinuityReason) {
- case DISCONTINUITY_REASON_PERIOD_TRANSITION:
+ case DISCONTINUITY_REASON_AUTO_TRANSITION:
+ case DISCONTINUITY_REASON_REMOVE:
// When player is in single repeat mode and a period transition occurs,
// we need to register a view count here since no metadata has changed
if (getRepeatMode() == REPEAT_MODE_ONE && newWindowIndex == playQueue.getIndex()) {
@@ -2468,7 +2472,7 @@ public final class Player implements
playQueue.setIndex(newWindowIndex);
}
break;
- case DISCONTINUITY_REASON_AD_INSERTION:
+ case DISCONTINUITY_REASON_SKIP:
break; // only makes Android Studio linter happy, as there are no ads
}
@@ -2480,6 +2484,11 @@ public final class Player implements
//TODO check if this causes black screen when switching to fullscreen
animate(binding.surfaceForeground, false, DEFAULT_CONTROLS_DURATION);
}
+
+ @Override
+ public void onCues(final List cues) {
+ binding.subtitleView.onCues(cues);
+ }
//endregion
@@ -2501,34 +2510,37 @@ public final class Player implements
*
*
* @see #processSourceError(IOException)
- * @see com.google.android.exoplayer2.Player.EventListener#onPlayerError(ExoPlaybackException)
+ * @see com.google.android.exoplayer2.Player.Listener#onPlayerError(ExoPlaybackException)
*/
@Override
public void onPlayerError(@NonNull final ExoPlaybackException error) {
- if (DEBUG) {
- Log.d(TAG, "ExoPlayer - onPlayerError() called with: " + "error = [" + error + "]");
- }
- if (errorToast != null) {
- errorToast.cancel();
- errorToast = null;
- }
+ Log.e(TAG, "ExoPlayer - onPlayerError() called with:", error);
saveStreamProgressState();
switch (error.type) {
case ExoPlaybackException.TYPE_SOURCE:
processSourceError(error.getSourceException());
- showStreamError(error);
+ playerErrorHandler.showPlayerError(
+ error,
+ currentMetadata.getMetadata(),
+ R.string.player_stream_failure);
break;
case ExoPlaybackException.TYPE_UNEXPECTED:
- showRecoverableError(error);
+ playerErrorHandler.showPlayerError(
+ error,
+ currentMetadata.getMetadata(),
+ R.string.player_recoverable_failure);
setRecovery();
reloadPlayQueueManager();
break;
case ExoPlaybackException.TYPE_REMOTE:
case ExoPlaybackException.TYPE_RENDERER:
default:
- showUnrecoverableError(error);
+ playerErrorHandler.showPlayerError(
+ error,
+ currentMetadata.getMetadata(),
+ R.string.player_unrecoverable_failure);
onPlaybackShutdown();
break;
}
@@ -2550,37 +2562,6 @@ public final class Player implements
playQueue.error();
}
}
-
- private void showStreamError(final Exception exception) {
- exception.printStackTrace();
-
- if (errorToast == null) {
- errorToast = Toast
- .makeText(context, R.string.player_stream_failure, Toast.LENGTH_SHORT);
- errorToast.show();
- }
- }
-
- private void showRecoverableError(final Exception exception) {
- exception.printStackTrace();
-
- if (errorToast == null) {
- errorToast = Toast
- .makeText(context, R.string.player_recoverable_failure, Toast.LENGTH_SHORT);
- errorToast.show();
- }
- }
-
- private void showUnrecoverableError(final Exception exception) {
- exception.printStackTrace();
-
- if (errorToast != null) {
- errorToast.cancel();
- }
- errorToast = Toast
- .makeText(context, R.string.player_unrecoverable_failure, Toast.LENGTH_SHORT);
- errorToast.show();
- }
//endregion
@@ -3865,19 +3846,17 @@ public final class Player implements
}
@Override // exoplayer listener
- public void onVideoSizeChanged(final int width, final int height,
- final int unappliedRotationDegrees,
- final float pixelWidthHeightRatio) {
+ public void onVideoSizeChanged(final VideoSize videoSize) {
if (DEBUG) {
Log.d(TAG, "onVideoSizeChanged() called with: "
- + "width / height = [" + width + " / " + height
- + " = " + (((float) width) / height) + "], "
- + "unappliedRotationDegrees = [" + unappliedRotationDegrees + "], "
- + "pixelWidthHeightRatio = [" + pixelWidthHeightRatio + "]");
+ + "width / height = [" + videoSize.width + " / " + videoSize.height
+ + " = " + (((float) videoSize.width) / videoSize.height) + "], "
+ + "unappliedRotationDegrees = [" + videoSize.unappliedRotationDegrees + "], "
+ + "pixelWidthHeightRatio = [" + videoSize.pixelWidthHeightRatio + "]");
}
- binding.surfaceView.setAspectRatio(((float) width) / height);
- isVerticalVideo = width < height;
+ binding.surfaceView.setAspectRatio(((float) videoSize.width) / videoSize.height);
+ isVerticalVideo = videoSize.width < videoSize.height;
if (globalScreenOrientationLocked(context)
&& isFullscreen
@@ -4182,8 +4161,7 @@ public final class Player implements
} catch (@NonNull final IndexOutOfBoundsException e) {
// Why would this even happen =(... but lets log it anyway, better safe than sorry
if (DEBUG) {
- Log.d(TAG, "player.isCurrentWindowDynamic() failed: " + e.getMessage());
- e.printStackTrace();
+ Log.d(TAG, "player.isCurrentWindowDynamic() failed: ", e);
}
return false;
}
diff --git a/app/src/main/java/org/schabi/newpipe/player/event/PlayerGestureListener.java b/app/src/main/java/org/schabi/newpipe/player/event/PlayerGestureListener.java
index 998324c9c..e55c596b8 100644
--- a/app/src/main/java/org/schabi/newpipe/player/event/PlayerGestureListener.java
+++ b/app/src/main/java/org/schabi/newpipe/player/event/PlayerGestureListener.java
@@ -69,26 +69,18 @@ public class PlayerGestureListener
if (DEBUG) {
Log.d(TAG, "onSingleTap called with playerType = [" + player.getPlayerType() + "]");
}
- if (playerType == MainPlayer.PlayerType.POPUP) {
- if (player.isControlsVisible()) {
- player.hideControls(100, 100);
- } else {
- player.getPlayPauseButton().requestFocus();
- player.showControlsThenHide();
- }
+ if (player.isControlsVisible()) {
+ player.hideControls(150, 0);
+ return;
+ }
+ // -- Controls are not visible --
- } else /* playerType == MainPlayer.PlayerType.VIDEO */ {
-
- if (player.isControlsVisible()) {
- player.hideControls(150, 0);
- } else {
- if (player.getCurrentState() == Player.STATE_COMPLETED) {
- player.showControls(0);
- } else {
- player.showControlsThenHide();
- }
- }
+ // When player is completed show controls and don't hide them later
+ if (player.getCurrentState() == Player.STATE_COMPLETED) {
+ player.showControls(0);
+ } else {
+ player.showControlsThenHide();
}
}
@@ -103,6 +95,8 @@ public class PlayerGestureListener
+ player.getPlayerType() + "], portion = [" + portion + "]");
}
if (playerType == MainPlayer.PlayerType.VIDEO) {
+
+ // -- Brightness and Volume control --
final boolean isBrightnessGestureEnabled =
PlayerHelper.isBrightnessGestureEnabled(service);
final boolean isVolumeGestureEnabled = PlayerHelper.isVolumeGestureEnabled(service);
@@ -121,15 +115,14 @@ public class PlayerGestureListener
}
} else /* MainPlayer.PlayerType.POPUP */ {
+
+ // -- Determine if the ClosingOverlayView (red X) has to be shown or hidden --
final View closingOverlayView = player.getClosingOverlayView();
- if (player.isInsideClosingRadius(movingEvent)) {
- if (closingOverlayView.getVisibility() == View.GONE) {
- animate(closingOverlayView, true, 200);
- }
- } else {
- if (closingOverlayView.getVisibility() == View.VISIBLE) {
- animate(closingOverlayView, false, 200);
- }
+ final boolean showClosingOverlayView = player.isInsideClosingRadius(movingEvent);
+ // Check if an view is in expected state and if not animate it into the correct state
+ final int expectedVisibility = showClosingOverlayView ? View.VISIBLE : View.GONE;
+ if (closingOverlayView.getVisibility() != expectedVisibility) {
+ animate(closingOverlayView, showClosingOverlayView, 200);
}
}
}
@@ -210,11 +203,12 @@ public class PlayerGestureListener
Log.d(TAG, "onScrollEnd called with playerType = ["
+ player.getPlayerType() + "]");
}
- if (playerType == MainPlayer.PlayerType.VIDEO) {
- if (DEBUG) {
- Log.d(TAG, "onScrollEnd() called");
- }
+ if (player.isControlsVisible() && player.getCurrentState() == STATE_PLAYING) {
+ player.hideControls(DEFAULT_CONTROLS_DURATION, DEFAULT_CONTROLS_HIDE_TIME);
+ }
+
+ if (playerType == MainPlayer.PlayerType.VIDEO) {
if (player.getVolumeRelativeLayout().getVisibility() == View.VISIBLE) {
animate(player.getVolumeRelativeLayout(), false, 200, SCALE_AND_ALPHA,
200);
@@ -223,15 +217,7 @@ public class PlayerGestureListener
animate(player.getBrightnessRelativeLayout(), false, 200, SCALE_AND_ALPHA,
200);
}
-
- if (player.isControlsVisible() && player.getCurrentState() == STATE_PLAYING) {
- player.hideControls(DEFAULT_CONTROLS_DURATION, DEFAULT_CONTROLS_HIDE_TIME);
- }
- } else {
- if (player.isControlsVisible() && player.getCurrentState() == STATE_PLAYING) {
- player.hideControls(DEFAULT_CONTROLS_DURATION, DEFAULT_CONTROLS_HIDE_TIME);
- }
-
+ } else /* Popup-Player */ {
if (player.isInsideClosingRadius(event)) {
player.closePopup();
} else if (!player.isPopupClosing()) {
diff --git a/app/src/main/java/org/schabi/newpipe/player/helper/AudioReactor.java b/app/src/main/java/org/schabi/newpipe/player/helper/AudioReactor.java
index 2e2fda86c..b36f9f234 100644
--- a/app/src/main/java/org/schabi/newpipe/player/helper/AudioReactor.java
+++ b/app/src/main/java/org/schabi/newpipe/player/helper/AudioReactor.java
@@ -16,7 +16,6 @@ import androidx.media.AudioManagerCompat;
import com.google.android.exoplayer2.SimpleExoPlayer;
import com.google.android.exoplayer2.analytics.AnalyticsListener;
-import com.google.android.exoplayer2.decoder.DecoderCounters;
public class AudioReactor implements AudioManager.OnAudioFocusChangeListener, AnalyticsListener {
@@ -150,15 +149,9 @@ public class AudioReactor implements AudioManager.OnAudioFocusChangeListener, An
//////////////////////////////////////////////////////////////////////////*/
@Override
- public void onAudioSessionId(final EventTime eventTime, final int audioSessionId) {
+ public void onAudioSessionIdChanged(final EventTime eventTime, final int audioSessionId) {
notifyAudioSessionUpdate(true, audioSessionId);
}
-
- @Override
- public void onAudioDisabled(final EventTime eventTime, final DecoderCounters counters) {
- notifyAudioSessionUpdate(false, player.getAudioSessionId());
- }
-
private void notifyAudioSessionUpdate(final boolean active, final int audioSessionId) {
if (!PlayerHelper.isUsingDSP()) {
return;
diff --git a/app/src/main/java/org/schabi/newpipe/player/helper/LoadController.java b/app/src/main/java/org/schabi/newpipe/player/helper/LoadController.java
index 71cfcc818..ec0e4e4a7 100644
--- a/app/src/main/java/org/schabi/newpipe/player/helper/LoadController.java
+++ b/app/src/main/java/org/schabi/newpipe/player/helper/LoadController.java
@@ -1,81 +1,28 @@
package org.schabi.newpipe.player.helper;
import com.google.android.exoplayer2.DefaultLoadControl;
-import com.google.android.exoplayer2.LoadControl;
-import com.google.android.exoplayer2.Renderer;
-import com.google.android.exoplayer2.source.TrackGroupArray;
-import com.google.android.exoplayer2.trackselection.TrackSelectionArray;
-import com.google.android.exoplayer2.upstream.Allocator;
-public class LoadController implements LoadControl {
+public class LoadController extends DefaultLoadControl {
public static final String TAG = "LoadController";
-
- private final long initialPlaybackBufferUs;
- private final LoadControl internalLoadControl;
private boolean preloadingEnabled = true;
- /*//////////////////////////////////////////////////////////////////////////
- // Default Load Control
- //////////////////////////////////////////////////////////////////////////*/
-
- public LoadController() {
- this(PlayerHelper.getPlaybackStartBufferMs());
- }
-
- private LoadController(final int initialPlaybackBufferMs) {
- this.initialPlaybackBufferUs = initialPlaybackBufferMs * 1000;
-
- final DefaultLoadControl.Builder builder = new DefaultLoadControl.Builder();
- builder.setBufferDurationsMs(
- DefaultLoadControl.DEFAULT_MIN_BUFFER_MS,
- DefaultLoadControl.DEFAULT_MAX_BUFFER_MS,
- initialPlaybackBufferMs,
- DefaultLoadControl.DEFAULT_BUFFER_FOR_PLAYBACK_AFTER_REBUFFER_MS);
- internalLoadControl = builder.build();
- }
-
- /*//////////////////////////////////////////////////////////////////////////
- // Custom behaviours
- //////////////////////////////////////////////////////////////////////////*/
-
@Override
public void onPrepared() {
preloadingEnabled = true;
- internalLoadControl.onPrepared();
- }
-
- @Override
- public void onTracksSelected(final Renderer[] renderers, final TrackGroupArray trackGroups,
- final TrackSelectionArray trackSelections) {
- internalLoadControl.onTracksSelected(renderers, trackGroups, trackSelections);
+ super.onPrepared();
}
@Override
public void onStopped() {
preloadingEnabled = true;
- internalLoadControl.onStopped();
+ super.onStopped();
}
@Override
public void onReleased() {
preloadingEnabled = true;
- internalLoadControl.onReleased();
- }
-
- @Override
- public Allocator getAllocator() {
- return internalLoadControl.getAllocator();
- }
-
- @Override
- public long getBackBufferDurationUs() {
- return internalLoadControl.getBackBufferDurationUs();
- }
-
- @Override
- public boolean retainBackBufferFromKeyframe() {
- return internalLoadControl.retainBackBufferFromKeyframe();
+ super.onReleased();
}
@Override
@@ -85,20 +32,10 @@ public class LoadController implements LoadControl {
if (!preloadingEnabled) {
return false;
}
- return internalLoadControl.shouldContinueLoading(
+ return super.shouldContinueLoading(
playbackPositionUs, bufferedDurationUs, playbackSpeed);
}
- @Override
- public boolean shouldStartPlayback(final long bufferedDurationUs, final float playbackSpeed,
- final boolean rebuffering) {
- final boolean isInitialPlaybackBufferFilled
- = bufferedDurationUs >= this.initialPlaybackBufferUs * playbackSpeed;
- final boolean isInternalStartingPlayback = internalLoadControl
- .shouldStartPlayback(bufferedDurationUs, playbackSpeed, rebuffering);
- return isInitialPlaybackBufferFilled || isInternalStartingPlayback;
- }
-
public void disablePreloadingOfCurrentTrack() {
preloadingEnabled = false;
}
diff --git a/app/src/main/java/org/schabi/newpipe/player/helper/MediaSessionManager.java b/app/src/main/java/org/schabi/newpipe/player/helper/MediaSessionManager.java
index ef0d84029..8d344c877 100644
--- a/app/src/main/java/org/schabi/newpipe/player/helper/MediaSessionManager.java
+++ b/app/src/main/java/org/schabi/newpipe/player/helper/MediaSessionManager.java
@@ -179,9 +179,7 @@ public class MediaSessionManager {
// If we got an album art check if the current set AlbumArt is null
if (optAlbumArt.isPresent() && getMetadataAlbumArt() == null) {
if (DEBUG) {
- if (getMetadataAlbumArt() == null) {
- Log.d(TAG, "N_getMetadataAlbumArt: thumb == null");
- }
+ Log.d(TAG, "N_getMetadataAlbumArt: thumb == null");
}
return true;
}
@@ -191,16 +189,19 @@ public class MediaSessionManager {
}
+ @Nullable
private Bitmap getMetadataAlbumArt() {
return mediaSession.getController().getMetadata()
.getBitmap(MediaMetadataCompat.METADATA_KEY_ALBUM_ART);
}
+ @Nullable
private String getMetadataTitle() {
return mediaSession.getController().getMetadata()
.getString(MediaMetadataCompat.METADATA_KEY_TITLE);
}
+ @Nullable
private String getMetadataArtist() {
return mediaSession.getController().getMetadata()
.getString(MediaMetadataCompat.METADATA_KEY_ARTIST);
diff --git a/app/src/main/java/org/schabi/newpipe/player/helper/PlaybackParameterDialog.java b/app/src/main/java/org/schabi/newpipe/player/helper/PlaybackParameterDialog.java
index bbe281921..5139ef9cd 100644
--- a/app/src/main/java/org/schabi/newpipe/player/helper/PlaybackParameterDialog.java
+++ b/app/src/main/java/org/schabi/newpipe/player/helper/PlaybackParameterDialog.java
@@ -1,5 +1,8 @@
package org.schabi.newpipe.player.helper;
+import static org.schabi.newpipe.player.Player.DEBUG;
+import static org.schabi.newpipe.util.Localization.assureCorrectAppLanguage;
+
import android.app.Dialog;
import android.content.Context;
import android.os.Bundle;
@@ -18,9 +21,6 @@ import androidx.preference.PreferenceManager;
import org.schabi.newpipe.R;
import org.schabi.newpipe.util.SliderStrategy;
-import static org.schabi.newpipe.player.Player.DEBUG;
-import static org.schabi.newpipe.util.Localization.assureCorrectAppLanguage;
-
public class PlaybackParameterDialog extends DialogFragment {
// Minimum allowable range in ExoPlayer
private static final double MINIMUM_PLAYBACK_VALUE = 0.10f;
@@ -157,7 +157,6 @@ public class PlaybackParameterDialog extends DialogFragment {
setupControlViews(view);
final AlertDialog.Builder dialogBuilder = new AlertDialog.Builder(requireActivity())
- .setTitle(R.string.playback_speed_control)
.setView(view)
.setCancelable(true)
.setNegativeButton(R.string.cancel, (dialogInterface, i) ->
diff --git a/app/src/main/java/org/schabi/newpipe/player/helper/PlayerDataSource.java b/app/src/main/java/org/schabi/newpipe/player/helper/PlayerDataSource.java
index 5fea4761b..b7584151d 100644
--- a/app/src/main/java/org/schabi/newpipe/player/helper/PlayerDataSource.java
+++ b/app/src/main/java/org/schabi/newpipe/player/helper/PlayerDataSource.java
@@ -1,14 +1,18 @@
package org.schabi.newpipe.player.helper;
import android.content.Context;
+import android.os.Build;
import androidx.annotation.NonNull;
+import com.google.android.exoplayer2.source.MediaParserExtractorAdapter;
import com.google.android.exoplayer2.source.ProgressiveMediaSource;
import com.google.android.exoplayer2.source.SingleSampleMediaSource;
+import com.google.android.exoplayer2.source.chunk.MediaParserChunkExtractor;
import com.google.android.exoplayer2.source.dash.DashMediaSource;
import com.google.android.exoplayer2.source.dash.DefaultDashChunkSource;
import com.google.android.exoplayer2.source.hls.HlsMediaSource;
+import com.google.android.exoplayer2.source.hls.MediaParserHlsMediaChunkExtractor;
import com.google.android.exoplayer2.source.smoothstreaming.DefaultSsChunkSource;
import com.google.android.exoplayer2.source.smoothstreaming.SsMediaSource;
import com.google.android.exoplayer2.upstream.DataSource;
@@ -19,7 +23,7 @@ import com.google.android.exoplayer2.upstream.TransferListener;
public class PlayerDataSource {
private static final int MANIFEST_MINIMUM_RETRY = 5;
private static final int EXTRACTOR_MINIMUM_RETRY = Integer.MAX_VALUE;
- private static final int LIVE_STREAM_EDGE_GAP_MILLIS = 10000;
+ public static final int LIVE_STREAM_EDGE_GAP_MILLIS = 10000;
private final DataSource.Factory cacheDataSourceFactory;
private final DataSource.Factory cachelessDataSourceFactory;
@@ -32,51 +36,83 @@ public class PlayerDataSource {
}
public SsMediaSource.Factory getLiveSsMediaSourceFactory() {
- return new SsMediaSource.Factory(new DefaultSsChunkSource.Factory(
- cachelessDataSourceFactory), cachelessDataSourceFactory)
+ return new SsMediaSource.Factory(
+ new DefaultSsChunkSource.Factory(cachelessDataSourceFactory),
+ cachelessDataSourceFactory
+ )
.setLoadErrorHandlingPolicy(
new DefaultLoadErrorHandlingPolicy(MANIFEST_MINIMUM_RETRY))
.setLivePresentationDelayMs(LIVE_STREAM_EDGE_GAP_MILLIS);
}
public HlsMediaSource.Factory getLiveHlsMediaSourceFactory() {
- return new HlsMediaSource.Factory(cachelessDataSourceFactory)
- .setAllowChunklessPreparation(true)
+ final HlsMediaSource.Factory factory =
+ new HlsMediaSource.Factory(cachelessDataSourceFactory)
+ .setAllowChunklessPreparation(true)
+ .setLoadErrorHandlingPolicy(
+ new DefaultLoadErrorHandlingPolicy(MANIFEST_MINIMUM_RETRY));
+
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
+ factory.setExtractorFactory(MediaParserHlsMediaChunkExtractor.FACTORY);
+ }
+
+ return factory;
+ }
+
+ public DashMediaSource.Factory getLiveDashMediaSourceFactory() {
+ return new DashMediaSource.Factory(
+ getDefaultDashChunkSourceFactory(cachelessDataSourceFactory),
+ cachelessDataSourceFactory
+ )
.setLoadErrorHandlingPolicy(
new DefaultLoadErrorHandlingPolicy(MANIFEST_MINIMUM_RETRY));
}
- public DashMediaSource.Factory getLiveDashMediaSourceFactory() {
- return new DashMediaSource.Factory(new DefaultDashChunkSource.Factory(
- cachelessDataSourceFactory), cachelessDataSourceFactory)
- .setLoadErrorHandlingPolicy(
- new DefaultLoadErrorHandlingPolicy(MANIFEST_MINIMUM_RETRY))
- .setLivePresentationDelayMs(LIVE_STREAM_EDGE_GAP_MILLIS, true);
- }
+ private DefaultDashChunkSource.Factory getDefaultDashChunkSourceFactory(
+ final DataSource.Factory dataSourceFactory
+ ) {
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
+ return new DefaultDashChunkSource.Factory(
+ MediaParserChunkExtractor.FACTORY,
+ dataSourceFactory,
+ 1
+ );
+ }
- public SsMediaSource.Factory getSsMediaSourceFactory() {
- return new SsMediaSource.Factory(new DefaultSsChunkSource.Factory(
- cacheDataSourceFactory), cacheDataSourceFactory);
+ return new DefaultDashChunkSource.Factory(dataSourceFactory);
}
public HlsMediaSource.Factory getHlsMediaSourceFactory() {
- return new HlsMediaSource.Factory(cacheDataSourceFactory);
+ final HlsMediaSource.Factory factory = new HlsMediaSource.Factory(cacheDataSourceFactory);
+
+ if (Build.VERSION.SDK_INT < Build.VERSION_CODES.R) {
+ return factory;
+ }
+
+ // *** >= Android 11 / R / API 30 ***
+ return factory.setExtractorFactory(MediaParserHlsMediaChunkExtractor.FACTORY);
}
public DashMediaSource.Factory getDashMediaSourceFactory() {
- return new DashMediaSource.Factory(new DefaultDashChunkSource.Factory(
- cacheDataSourceFactory), cacheDataSourceFactory);
+ return new DashMediaSource.Factory(
+ getDefaultDashChunkSourceFactory(cacheDataSourceFactory),
+ cacheDataSourceFactory
+ );
}
public ProgressiveMediaSource.Factory getExtractorMediaSourceFactory() {
- return new ProgressiveMediaSource.Factory(cacheDataSourceFactory)
- .setLoadErrorHandlingPolicy(
- new DefaultLoadErrorHandlingPolicy(EXTRACTOR_MINIMUM_RETRY));
- }
+ final ProgressiveMediaSource.Factory factory;
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
+ factory = new ProgressiveMediaSource.Factory(
+ cacheDataSourceFactory,
+ MediaParserExtractorAdapter.FACTORY
+ );
+ } else {
+ factory = new ProgressiveMediaSource.Factory(cacheDataSourceFactory);
+ }
- public ProgressiveMediaSource.Factory getExtractorMediaSourceFactory(
- @NonNull final String key) {
- return getExtractorMediaSourceFactory().setCustomCacheKey(key);
+ return factory.setLoadErrorHandlingPolicy(
+ new DefaultLoadErrorHandlingPolicy(EXTRACTOR_MINIMUM_RETRY));
}
public SingleSampleMediaSource.Factory getSampleMediaSourceFactory() {
diff --git a/app/src/main/java/org/schabi/newpipe/player/helper/PlayerHelper.java b/app/src/main/java/org/schabi/newpipe/player/helper/PlayerHelper.java
index 828833a8d..c51b6d5dd 100644
--- a/app/src/main/java/org/schabi/newpipe/player/helper/PlayerHelper.java
+++ b/app/src/main/java/org/schabi/newpipe/player/helper/PlayerHelper.java
@@ -1,5 +1,18 @@
package org.schabi.newpipe.player.helper;
+import static com.google.android.exoplayer2.Player.REPEAT_MODE_ALL;
+import static com.google.android.exoplayer2.Player.REPEAT_MODE_OFF;
+import static com.google.android.exoplayer2.Player.REPEAT_MODE_ONE;
+import static org.schabi.newpipe.player.Player.IDLE_WINDOW_FLAGS;
+import static org.schabi.newpipe.player.Player.PLAYER_TYPE;
+import static org.schabi.newpipe.player.helper.PlayerHelper.AutoplayType.AUTOPLAY_TYPE_ALWAYS;
+import static org.schabi.newpipe.player.helper.PlayerHelper.AutoplayType.AUTOPLAY_TYPE_NEVER;
+import static org.schabi.newpipe.player.helper.PlayerHelper.AutoplayType.AUTOPLAY_TYPE_WIFI;
+import static org.schabi.newpipe.player.helper.PlayerHelper.MinimizeMode.MINIMIZE_ON_EXIT_MODE_BACKGROUND;
+import static org.schabi.newpipe.player.helper.PlayerHelper.MinimizeMode.MINIMIZE_ON_EXIT_MODE_NONE;
+import static org.schabi.newpipe.player.helper.PlayerHelper.MinimizeMode.MINIMIZE_ON_EXIT_MODE_POPUP;
+import static java.lang.annotation.RetentionPolicy.SOURCE;
+
import android.annotation.SuppressLint;
import android.content.Context;
import android.content.Intent;
@@ -21,11 +34,11 @@ import androidx.preference.PreferenceManager;
import com.google.android.exoplayer2.PlaybackParameters;
import com.google.android.exoplayer2.Player.RepeatMode;
import com.google.android.exoplayer2.SeekParameters;
-import com.google.android.exoplayer2.text.CaptionStyleCompat;
import com.google.android.exoplayer2.trackselection.AdaptiveTrackSelection;
-import com.google.android.exoplayer2.trackselection.TrackSelection;
+import com.google.android.exoplayer2.trackselection.ExoTrackSelection;
import com.google.android.exoplayer2.ui.AspectRatioFrameLayout;
import com.google.android.exoplayer2.ui.AspectRatioFrameLayout.ResizeMode;
+import com.google.android.exoplayer2.ui.CaptionStyleCompat;
import com.google.android.exoplayer2.util.MimeTypes;
import org.schabi.newpipe.R;
@@ -57,19 +70,6 @@ import java.util.Objects;
import java.util.Set;
import java.util.concurrent.TimeUnit;
-import static com.google.android.exoplayer2.Player.REPEAT_MODE_ALL;
-import static com.google.android.exoplayer2.Player.REPEAT_MODE_OFF;
-import static com.google.android.exoplayer2.Player.REPEAT_MODE_ONE;
-import static java.lang.annotation.RetentionPolicy.SOURCE;
-import static org.schabi.newpipe.player.Player.IDLE_WINDOW_FLAGS;
-import static org.schabi.newpipe.player.Player.PLAYER_TYPE;
-import static org.schabi.newpipe.player.helper.PlayerHelper.AutoplayType.AUTOPLAY_TYPE_ALWAYS;
-import static org.schabi.newpipe.player.helper.PlayerHelper.AutoplayType.AUTOPLAY_TYPE_NEVER;
-import static org.schabi.newpipe.player.helper.PlayerHelper.AutoplayType.AUTOPLAY_TYPE_WIFI;
-import static org.schabi.newpipe.player.helper.PlayerHelper.MinimizeMode.MINIMIZE_ON_EXIT_MODE_BACKGROUND;
-import static org.schabi.newpipe.player.helper.PlayerHelper.MinimizeMode.MINIMIZE_ON_EXIT_MODE_NONE;
-import static org.schabi.newpipe.player.helper.PlayerHelper.MinimizeMode.MINIMIZE_ON_EXIT_MODE_POPUP;
-
public final class PlayerHelper {
private static final StringBuilder STRING_BUILDER = new StringBuilder();
private static final Formatter STRING_FORMATTER
@@ -305,14 +305,7 @@ public final class PlayerHelper {
return 2 * 1024 * 1024L; // ExoPlayer CacheDataSink.MIN_RECOMMENDED_FRAGMENT_SIZE
}
- /**
- * @return the number of milliseconds the player buffers for before starting playback
- */
- public static int getPlaybackStartBufferMs() {
- return 500;
- }
-
- public static TrackSelection.Factory getQualitySelector() {
+ public static ExoTrackSelection.Factory getQualitySelector() {
return new AdaptiveTrackSelection.Factory(
1000,
AdaptiveTrackSelection.DEFAULT_MAX_DURATION_FOR_QUALITY_DECREASE_MS,
diff --git a/app/src/main/java/org/schabi/newpipe/player/playback/CustomTrackSelector.java b/app/src/main/java/org/schabi/newpipe/player/playback/CustomTrackSelector.java
index d70707fdb..389be7062 100644
--- a/app/src/main/java/org/schabi/newpipe/player/playback/CustomTrackSelector.java
+++ b/app/src/main/java/org/schabi/newpipe/player/playback/CustomTrackSelector.java
@@ -13,7 +13,7 @@ import com.google.android.exoplayer2.RendererCapabilities.Capabilities;
import com.google.android.exoplayer2.source.TrackGroup;
import com.google.android.exoplayer2.source.TrackGroupArray;
import com.google.android.exoplayer2.trackselection.DefaultTrackSelector;
-import com.google.android.exoplayer2.trackselection.TrackSelection;
+import com.google.android.exoplayer2.trackselection.ExoTrackSelection;
import com.google.android.exoplayer2.util.Assertions;
/**
@@ -28,7 +28,7 @@ public class CustomTrackSelector extends DefaultTrackSelector {
private String preferredTextLanguage;
public CustomTrackSelector(final Context context,
- final TrackSelection.Factory adaptiveTrackSelectionFactory) {
+ final ExoTrackSelection.Factory adaptiveTrackSelectionFactory) {
super(context, adaptiveTrackSelectionFactory);
}
@@ -50,7 +50,7 @@ public class CustomTrackSelector extends DefaultTrackSelector {
@Override
@Nullable
- protected Pair selectTextTrack(
+ protected Pair selectTextTrack(
final TrackGroupArray groups,
@NonNull final int[][] formatSupport,
@NonNull final Parameters params,
@@ -86,7 +86,7 @@ public class CustomTrackSelector extends DefaultTrackSelector {
}
}
return selectedGroup == null ? null
- : Pair.create(new TrackSelection.Definition(selectedGroup, selectedTrackIndex),
+ : Pair.create(new ExoTrackSelection.Definition(selectedGroup, selectedTrackIndex),
Assertions.checkNotNull(selectedTrackScore));
}
}
diff --git a/app/src/main/java/org/schabi/newpipe/player/playererror/PlayerErrorHandler.java b/app/src/main/java/org/schabi/newpipe/player/playererror/PlayerErrorHandler.java
new file mode 100644
index 000000000..626200ae1
--- /dev/null
+++ b/app/src/main/java/org/schabi/newpipe/player/playererror/PlayerErrorHandler.java
@@ -0,0 +1,89 @@
+package org.schabi.newpipe.player.playererror;
+
+import android.content.Context;
+import android.util.Log;
+import android.widget.Toast;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+import androidx.annotation.StringRes;
+import androidx.preference.PreferenceManager;
+
+import com.google.android.exoplayer2.ExoPlaybackException;
+
+import org.schabi.newpipe.R;
+import org.schabi.newpipe.error.EnsureExceptionSerializable;
+import org.schabi.newpipe.error.ErrorActivity;
+import org.schabi.newpipe.error.ErrorInfo;
+import org.schabi.newpipe.error.UserAction;
+import org.schabi.newpipe.extractor.Info;
+
+/**
+ * Handles (exoplayer)errors that occur in the player.
+ */
+public class PlayerErrorHandler {
+ // This has to be <= 23 chars on devices running Android 7 or lower (API <= 25)
+ // or it fails with an IllegalArgumentException
+ // https://stackoverflow.com/a/54744028
+ private static final String TAG = "PlayerErrorHandler";
+
+ @Nullable
+ private Toast errorToast;
+
+ @NonNull
+ private final Context context;
+
+ public PlayerErrorHandler(@NonNull final Context context) {
+ this.context = context;
+ }
+
+ public void showPlayerError(
+ @NonNull final ExoPlaybackException exception,
+ @NonNull final Info info,
+ @StringRes final int textResId
+ ) {
+ // Hide existing toast message
+ if (errorToast != null) {
+ Log.d(TAG, "Trying to cancel previous player error error toast");
+ errorToast.cancel();
+ errorToast = null;
+ }
+
+ if (shouldReportError()) {
+ try {
+ reportError(exception, info);
+ // When a report pops up we need no toast
+ return;
+ } catch (final Exception ex) {
+ Log.w(TAG, "Unable to report error:", ex);
+ // This will show the toast as fallback
+ }
+ }
+
+ Log.d(TAG, "Showing player error toast");
+ errorToast = Toast.makeText(context, textResId, Toast.LENGTH_SHORT);
+ errorToast.show();
+ }
+
+ private void reportError(@NonNull final ExoPlaybackException exception,
+ @NonNull final Info info) {
+ ErrorActivity.reportError(
+ context,
+ new ErrorInfo(
+ EnsureExceptionSerializable.ensureSerializable(exception),
+ UserAction.PLAY_STREAM,
+ "Player error[type=" + exception.type + "] occurred while playing: "
+ + info.getUrl(),
+ info
+ )
+ );
+ }
+
+ private boolean shouldReportError() {
+ return PreferenceManager
+ .getDefaultSharedPreferences(context)
+ .getBoolean(
+ context.getString(R.string.report_player_errors_key),
+ false);
+ }
+}
diff --git a/app/src/main/java/org/schabi/newpipe/player/playqueue/PlayQueue.java b/app/src/main/java/org/schabi/newpipe/player/playqueue/PlayQueue.java
index 014c13339..f2259b120 100644
--- a/app/src/main/java/org/schabi/newpipe/player/playqueue/PlayQueue.java
+++ b/app/src/main/java/org/schabi/newpipe/player/playqueue/PlayQueue.java
@@ -436,14 +436,16 @@ public abstract class PlayQueue implements Serializable {
* top, so shuffling a size-2 list does nothing)
*/
public synchronized void shuffle() {
- // Can't shuffle an list that's empty or only has one element
- if (size() <= 2) {
- return;
- }
// Create a backup if it doesn't already exist
+ // Note: The backup-list has to be created at all cost (even when size <= 2).
+ // Otherwise it's not possible to enter shuffle-mode!
if (backup == null) {
backup = new ArrayList<>(streams);
}
+ // Can't shuffle a list that's empty or only has one element
+ if (size() <= 2) {
+ return;
+ }
final int originalIndex = getIndex();
final PlayQueueItem currentItem = getItem();
diff --git a/app/src/main/java/org/schabi/newpipe/player/playqueue/PlayQueueItemTouchCallback.java b/app/src/main/java/org/schabi/newpipe/player/playqueue/PlayQueueItemTouchCallback.java
index 5fee43659..b283e105e 100644
--- a/app/src/main/java/org/schabi/newpipe/player/playqueue/PlayQueueItemTouchCallback.java
+++ b/app/src/main/java/org/schabi/newpipe/player/playqueue/PlayQueueItemTouchCallback.java
@@ -51,6 +51,6 @@ public abstract class PlayQueueItemTouchCallback extends ItemTouchHelper.SimpleC
@Override
public void onSwiped(final RecyclerView.ViewHolder viewHolder, final int swipeDir) {
- onSwiped(viewHolder.getAdapterPosition());
+ onSwiped(viewHolder.getBindingAdapterPosition());
}
}
diff --git a/app/src/main/java/org/schabi/newpipe/player/resolver/PlaybackResolver.java b/app/src/main/java/org/schabi/newpipe/player/resolver/PlaybackResolver.java
index 81e629c2f..cfe9dbb62 100644
--- a/app/src/main/java/org/schabi/newpipe/player/resolver/PlaybackResolver.java
+++ b/app/src/main/java/org/schabi/newpipe/player/resolver/PlaybackResolver.java
@@ -9,6 +9,7 @@ import androidx.annotation.Nullable;
import com.google.android.exoplayer2.C;
import com.google.android.exoplayer2.MediaItem;
import com.google.android.exoplayer2.source.MediaSource;
+import com.google.android.exoplayer2.source.MediaSourceFactory;
import com.google.android.exoplayer2.util.Util;
import org.schabi.newpipe.extractor.stream.StreamInfo;
@@ -41,20 +42,28 @@ public interface PlaybackResolver extends Resolver {
@NonNull final String sourceUrl,
@C.ContentType final int type,
@NonNull final MediaSourceTag metadata) {
- final Uri uri = Uri.parse(sourceUrl);
+ final MediaSourceFactory factory;
switch (type) {
case C.TYPE_SS:
- return dataSource.getLiveSsMediaSourceFactory().setTag(metadata)
- .createMediaSource(MediaItem.fromUri(uri));
+ factory = dataSource.getLiveSsMediaSourceFactory();
+ break;
case C.TYPE_DASH:
- return dataSource.getLiveDashMediaSourceFactory().setTag(metadata)
- .createMediaSource(MediaItem.fromUri(uri));
+ factory = dataSource.getLiveDashMediaSourceFactory();
+ break;
case C.TYPE_HLS:
- return dataSource.getLiveHlsMediaSourceFactory().setTag(metadata)
- .createMediaSource(MediaItem.fromUri(uri));
+ factory = dataSource.getLiveHlsMediaSourceFactory();
+ break;
default:
throw new IllegalStateException("Unsupported type: " + type);
}
+
+ return factory.createMediaSource(
+ new MediaItem.Builder()
+ .setTag(metadata)
+ .setUri(Uri.parse(sourceUrl))
+ .setLiveTargetOffsetMs(PlayerDataSource.LIVE_STREAM_EDGE_GAP_MILLIS)
+ .build()
+ );
}
@NonNull
@@ -67,21 +76,30 @@ public interface PlaybackResolver extends Resolver {
@C.ContentType final int type = TextUtils.isEmpty(overrideExtension)
? Util.inferContentType(uri) : Util.inferContentType("." + overrideExtension);
+ final MediaSourceFactory factory;
switch (type) {
case C.TYPE_SS:
- return dataSource.getLiveSsMediaSourceFactory().setTag(metadata)
- .createMediaSource(MediaItem.fromUri(uri));
+ factory = dataSource.getLiveSsMediaSourceFactory();
+ break;
case C.TYPE_DASH:
- return dataSource.getDashMediaSourceFactory().setTag(metadata)
- .createMediaSource(MediaItem.fromUri(uri));
+ factory = dataSource.getDashMediaSourceFactory();
+ break;
case C.TYPE_HLS:
- return dataSource.getHlsMediaSourceFactory().setTag(metadata)
- .createMediaSource(MediaItem.fromUri(uri));
+ factory = dataSource.getHlsMediaSourceFactory();
+ break;
case C.TYPE_OTHER:
- return dataSource.getExtractorMediaSourceFactory(cacheKey).setTag(metadata)
- .createMediaSource(MediaItem.fromUri(uri));
+ factory = dataSource.getExtractorMediaSourceFactory();
+ break;
default:
throw new IllegalStateException("Unsupported type: " + type);
}
+
+ return factory.createMediaSource(
+ new MediaItem.Builder()
+ .setTag(metadata)
+ .setUri(uri)
+ .setCustomCacheKey(cacheKey)
+ .build()
+ );
}
}
diff --git a/app/src/main/java/org/schabi/newpipe/settings/ContentSettingsManager.kt b/app/src/main/java/org/schabi/newpipe/settings/ContentSettingsManager.kt
index 6bc63a56a..3ac275695 100644
--- a/app/src/main/java/org/schabi/newpipe/settings/ContentSettingsManager.kt
+++ b/app/src/main/java/org/schabi/newpipe/settings/ContentSettingsManager.kt
@@ -1,6 +1,7 @@
package org.schabi.newpipe.settings
import android.content.SharedPreferences
+import android.util.Log
import org.schabi.newpipe.streams.io.SharpOutputStream
import org.schabi.newpipe.streams.io.StoredFileHelper
import org.schabi.newpipe.util.ZipHelper
@@ -13,6 +14,9 @@ import java.io.ObjectOutputStream
import java.util.zip.ZipOutputStream
class ContentSettingsManager(private val fileLocator: NewPipeFileLocator) {
+ companion object {
+ const val TAG = "ContentSetManager"
+ }
/**
* Exports given [SharedPreferences] to the file in given outputPath.
@@ -31,7 +35,7 @@ class ContentSettingsManager(private val fileLocator: NewPipeFileLocator) {
output.flush()
}
} catch (e: IOException) {
- e.printStackTrace()
+ Log.e(TAG, "Unable to exportDatabase", e)
}
ZipHelper.addFileToZip(outZip, fileLocator.settings.path, "newpipe.settings")
@@ -101,9 +105,9 @@ class ContentSettingsManager(private val fileLocator: NewPipeFileLocator) {
preferenceEditor.commit()
}
} catch (e: IOException) {
- e.printStackTrace()
+ Log.e(TAG, "Unable to loadSharedPreferences", e)
} catch (e: ClassNotFoundException) {
- e.printStackTrace()
+ Log.e(TAG, "Unable to loadSharedPreferences", e)
}
}
}
diff --git a/app/src/main/java/org/schabi/newpipe/settings/MainSettingsFragment.java b/app/src/main/java/org/schabi/newpipe/settings/MainSettingsFragment.java
index 2f65af4d6..12599b828 100644
--- a/app/src/main/java/org/schabi/newpipe/settings/MainSettingsFragment.java
+++ b/app/src/main/java/org/schabi/newpipe/settings/MainSettingsFragment.java
@@ -16,8 +16,9 @@ public class MainSettingsFragment extends BasePreferenceFragment {
public void onCreatePreferences(final Bundle savedInstanceState, final String rootKey) {
addPreferencesFromResource(R.xml.main_settings);
- if (!CheckForNewAppVersion.isGithubApk(App.getApp())) {
- final Preference update = findPreference(getString(R.string.update_pref_screen_key));
+ if (!CheckForNewAppVersion.isReleaseApk(App.getApp())) {
+ final Preference update
+ = findPreference(getString(R.string.update_pref_screen_key));
getPreferenceScreen().removePreference(update);
defaultPreferences.edit().putBoolean(getString(R.string.update_app_key), false).apply();
diff --git a/app/src/main/java/org/schabi/newpipe/settings/PeertubeInstanceListFragment.java b/app/src/main/java/org/schabi/newpipe/settings/PeertubeInstanceListFragment.java
index 5f388efb7..dfc053a62 100644
--- a/app/src/main/java/org/schabi/newpipe/settings/PeertubeInstanceListFragment.java
+++ b/app/src/main/java/org/schabi/newpipe/settings/PeertubeInstanceListFragment.java
@@ -303,8 +303,8 @@ public class PeertubeInstanceListFragment extends Fragment {
return false;
}
- final int sourceIndex = source.getAdapterPosition();
- final int targetIndex = target.getAdapterPosition();
+ final int sourceIndex = source.getBindingAdapterPosition();
+ final int targetIndex = target.getBindingAdapterPosition();
instanceListAdapter.swapItems(sourceIndex, targetIndex);
return true;
}
@@ -322,7 +322,7 @@ public class PeertubeInstanceListFragment extends Fragment {
@Override
public void onSwiped(@NonNull final RecyclerView.ViewHolder viewHolder,
final int swipeDir) {
- final int position = viewHolder.getAdapterPosition();
+ final int position = viewHolder.getBindingAdapterPosition();
// do not allow swiping the selected instance
if (instanceList.get(position).getUrl().equals(selectedInstance.getUrl())) {
instanceListAdapter.notifyItemChanged(position);
diff --git a/app/src/main/java/org/schabi/newpipe/settings/UpdateSettingsFragment.java b/app/src/main/java/org/schabi/newpipe/settings/UpdateSettingsFragment.java
index d2f56b487..bc183d08a 100644
--- a/app/src/main/java/org/schabi/newpipe/settings/UpdateSettingsFragment.java
+++ b/app/src/main/java/org/schabi/newpipe/settings/UpdateSettingsFragment.java
@@ -1,34 +1,48 @@
package org.schabi.newpipe.settings;
+import static org.schabi.newpipe.CheckForNewAppVersion.startNewVersionCheckService;
+
import android.os.Bundle;
+import android.widget.Toast;
import androidx.preference.Preference;
import org.schabi.newpipe.R;
-import static org.schabi.newpipe.CheckForNewAppVersion.startNewVersionCheckService;
-
public class UpdateSettingsFragment extends BasePreferenceFragment {
private final Preference.OnPreferenceChangeListener updatePreferenceChange
= (preference, checkForUpdates) -> {
defaultPreferences.edit()
.putBoolean(getString(R.string.update_app_key), (boolean) checkForUpdates).apply();
- if ((boolean) checkForUpdates) {
- // Search for updates immediately when update checks are enabled.
- // Reset the expire time. This is necessary to check for an update immediately.
- defaultPreferences.edit()
- .putLong(getString(R.string.update_expiry_key), 0).apply();
- startNewVersionCheckService();
- }
+ if ((boolean) checkForUpdates) {
+ checkNewVersionNow();
+ }
return true;
};
+ private final Preference.OnPreferenceClickListener manualUpdateClick
+ = preference -> {
+ Toast.makeText(getContext(), R.string.checking_updates_toast, Toast.LENGTH_SHORT).show();
+ checkNewVersionNow();
+ return true;
+ };
+
+ private void checkNewVersionNow() {
+ // Search for updates immediately when update checks are enabled.
+ // Reset the expire time. This is necessary to check for an update immediately.
+ defaultPreferences.edit()
+ .putLong(getString(R.string.update_expiry_key), 0).apply();
+ startNewVersionCheckService();
+ }
+
@Override
public void onCreatePreferences(final Bundle savedInstanceState, final String rootKey) {
addPreferencesFromResource(R.xml.update_settings);
- final String updateToggleKey = getString(R.string.update_app_key);
- findPreference(updateToggleKey).setOnPreferenceChangeListener(updatePreferenceChange);
+ findPreference(getString(R.string.update_app_key))
+ .setOnPreferenceChangeListener(updatePreferenceChange);
+ findPreference(getString(R.string.manual_update_key))
+ .setOnPreferenceClickListener(manualUpdateClick);
}
}
diff --git a/app/src/main/java/org/schabi/newpipe/settings/tabs/ChooseTabsFragment.java b/app/src/main/java/org/schabi/newpipe/settings/tabs/ChooseTabsFragment.java
index 6e50765ba..c9eb42fca 100644
--- a/app/src/main/java/org/schabi/newpipe/settings/tabs/ChooseTabsFragment.java
+++ b/app/src/main/java/org/schabi/newpipe/settings/tabs/ChooseTabsFragment.java
@@ -299,8 +299,8 @@ public class ChooseTabsFragment extends Fragment {
return false;
}
- final int sourceIndex = source.getAdapterPosition();
- final int targetIndex = target.getAdapterPosition();
+ final int sourceIndex = source.getBindingAdapterPosition();
+ final int targetIndex = target.getBindingAdapterPosition();
selectedTabsAdapter.swapItems(sourceIndex, targetIndex);
return true;
}
@@ -318,7 +318,7 @@ public class ChooseTabsFragment extends Fragment {
@Override
public void onSwiped(@NonNull final RecyclerView.ViewHolder viewHolder,
final int swipeDir) {
- final int position = viewHolder.getAdapterPosition();
+ final int position = viewHolder.getBindingAdapterPosition();
tabList.remove(position);
selectedTabsAdapter.notifyItemRemoved(position);
diff --git a/app/src/main/java/org/schabi/newpipe/util/DeviceUtils.java b/app/src/main/java/org/schabi/newpipe/util/DeviceUtils.java
index bdf5e8ce4..bbe9a7edb 100644
--- a/app/src/main/java/org/schabi/newpipe/util/DeviceUtils.java
+++ b/app/src/main/java/org/schabi/newpipe/util/DeviceUtils.java
@@ -6,6 +6,7 @@ import android.content.pm.PackageManager;
import android.content.res.Configuration;
import android.os.BatteryManager;
import android.os.Build;
+import android.provider.Settings;
import android.util.TypedValue;
import android.view.KeyEvent;
@@ -144,4 +145,11 @@ public final class DeviceUtils {
public static boolean isInMultiWindow(final AppCompatActivity activity) {
return Build.VERSION.SDK_INT >= Build.VERSION_CODES.N && activity.isInMultiWindowMode();
}
+
+ public static boolean hasAnimationsAnimatorDurationEnabled(final Context context) {
+ return Settings.System.getFloat(
+ context.getContentResolver(),
+ Settings.Global.ANIMATOR_DURATION_SCALE,
+ 1F) != 0F;
+ }
}
diff --git a/app/src/main/java/org/schabi/newpipe/util/NavigationHelper.java b/app/src/main/java/org/schabi/newpipe/util/NavigationHelper.java
index cb796a7a6..c01e051b0 100644
--- a/app/src/main/java/org/schabi/newpipe/util/NavigationHelper.java
+++ b/app/src/main/java/org/schabi/newpipe/util/NavigationHelper.java
@@ -157,7 +157,9 @@ public final class NavigationHelper {
return;
}
- Toast.makeText(context, R.string.popup_playing_toast, Toast.LENGTH_SHORT).show();
+ if (PlayerHolder.getInstance().getType() != PlayerType.POPUP) {
+ Toast.makeText(context, R.string.popup_playing_toast, Toast.LENGTH_SHORT).show();
+ }
final Intent intent = getPlayerIntent(context, MainPlayer.class, queue, resumePlayback);
intent.putExtra(Player.PLAYER_TYPE, MainPlayer.PlayerType.POPUP.ordinal());
ContextCompat.startForegroundService(context, intent);
@@ -166,8 +168,10 @@ public final class NavigationHelper {
public static void playOnBackgroundPlayer(final Context context,
final PlayQueue queue,
final boolean resumePlayback) {
- Toast.makeText(context, R.string.background_player_playing_toast, Toast.LENGTH_SHORT)
- .show();
+ if (PlayerHolder.getInstance().getType() != MainPlayer.PlayerType.AUDIO) {
+ Toast.makeText(context, R.string.background_player_playing_toast, Toast.LENGTH_SHORT)
+ .show();
+ }
final Intent intent = getPlayerIntent(context, MainPlayer.class, queue, resumePlayback);
intent.putExtra(Player.PLAYER_TYPE, MainPlayer.PlayerType.AUDIO.ordinal());
ContextCompat.startForegroundService(context, intent);
@@ -502,6 +506,27 @@ public final class NavigationHelper {
context.startActivity(intent);
}
+ /**
+ * Opens {@link ChannelFragment}.
+ * Use this instead of {@link #openChannelFragment(FragmentManager, int, String, String)}
+ * when no fragments are used / no FragmentManager is available.
+ * @param context
+ * @param serviceId
+ * @param url
+ * @param title
+ */
+ public static void openChannelFragmentUsingIntent(final Context context,
+ final int serviceId,
+ final String url,
+ @NonNull final String title) {
+ final Intent intent = getOpenIntent(context, url, serviceId,
+ StreamingService.LinkType.CHANNEL);
+ intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+ intent.putExtra(Constants.KEY_TITLE, title);
+
+ context.startActivity(intent);
+ }
+
public static void openMainActivity(final Context context) {
final Intent mIntent = new Intent(context, MainActivity.class);
mIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
diff --git a/app/src/main/java/org/schabi/newpipe/util/NewPipeTextViewHelper.java b/app/src/main/java/org/schabi/newpipe/util/NewPipeTextViewHelper.java
new file mode 100644
index 000000000..cf1a9a03a
--- /dev/null
+++ b/app/src/main/java/org/schabi/newpipe/util/NewPipeTextViewHelper.java
@@ -0,0 +1,61 @@
+package org.schabi.newpipe.util;
+
+import android.content.Context;
+import android.text.Selection;
+import android.text.Spannable;
+import android.widget.TextView;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+
+import org.schabi.newpipe.util.external_communication.ShareUtils;
+import org.schabi.newpipe.views.NewPipeEditText;
+import org.schabi.newpipe.views.NewPipeTextView;
+
+public final class NewPipeTextViewHelper {
+ private NewPipeTextViewHelper() {
+ }
+
+ /**
+ * Share the selected text of {@link NewPipeTextView NewPipeTextViews} and
+ * {@link NewPipeEditText NewPipeEditTexts} with
+ * {@link ShareUtils#shareText(Context, String, String)}.
+ *
+ *
+ * This allows EMUI users to get the Android share sheet instead of the EMUI share sheet when
+ * using the {@code Share} command of the popup menu which appears when selecting text.
+ *
+ *
+ * @param textView the {@link TextView} on which sharing the selected text. It should be a
+ * {@link NewPipeTextView} or a {@link NewPipeEditText} (even if
+ * {@link TextView standard TextViews} are supported).
+ */
+ public static void shareSelectedTextWithShareUtils(@NonNull final TextView textView) {
+ final CharSequence textViewText = textView.getText();
+ shareSelectedTextIfNotNullAndNotEmpty(textView, getSelectedText(textView, textViewText));
+ if (textViewText instanceof Spannable) {
+ Selection.setSelection((Spannable) textViewText, textView.getSelectionEnd());
+ }
+ }
+
+ @Nullable
+ private static CharSequence getSelectedText(@NonNull final TextView textView,
+ @Nullable final CharSequence text) {
+ if (!textView.hasSelection() || text == null) {
+ return null;
+ }
+
+ final int start = textView.getSelectionStart();
+ final int end = textView.getSelectionEnd();
+ return String.valueOf(start > end ? text.subSequence(end, start)
+ : text.subSequence(start, end));
+ }
+
+ private static void shareSelectedTextIfNotNullAndNotEmpty(
+ @NonNull final TextView textView,
+ @Nullable final CharSequence selectedText) {
+ if (selectedText != null && selectedText.length() != 0) {
+ ShareUtils.shareText(textView.getContext(), "", selectedText.toString());
+ }
+ }
+}
diff --git a/app/src/main/java/org/schabi/newpipe/util/StreamDialogEntry.java b/app/src/main/java/org/schabi/newpipe/util/StreamDialogEntry.java
index ec51cc370..0ffbe4137 100644
--- a/app/src/main/java/org/schabi/newpipe/util/StreamDialogEntry.java
+++ b/app/src/main/java/org/schabi/newpipe/util/StreamDialogEntry.java
@@ -5,12 +5,15 @@ import android.net.Uri;
import android.widget.Toast;
import androidx.fragment.app.Fragment;
+import androidx.preference.PreferenceManager;
import org.schabi.newpipe.NewPipeDatabase;
import org.schabi.newpipe.R;
+import org.schabi.newpipe.database.stream.model.StreamEntity;
import org.schabi.newpipe.extractor.stream.StreamInfoItem;
+import org.schabi.newpipe.extractor.stream.StreamType;
import org.schabi.newpipe.local.dialog.PlaylistAppendDialog;
-import org.schabi.newpipe.local.dialog.PlaylistCreationDialog;
+import org.schabi.newpipe.local.dialog.PlaylistDialog;
import org.schabi.newpipe.local.history.HistoryRecordManager;
import org.schabi.newpipe.player.playqueue.SinglePlayQueue;
import org.schabi.newpipe.util.external_communication.KoreUtils;
@@ -81,14 +84,16 @@ public enum StreamDialogEntry {
delete(R.string.delete, (fragment, item) -> {
}), // has to be set manually
- append_playlist(R.string.append_playlist, (fragment, item) -> {
- final PlaylistAppendDialog d = PlaylistAppendDialog
- .fromStreamInfoItems(Collections.singletonList(item));
-
- PlaylistAppendDialog.onPlaylistFound(fragment.getContext(),
- () -> d.show(fragment.getParentFragmentManager(), "StreamDialogEntry@append_playlist"),
- () -> PlaylistCreationDialog.newInstance(d)
- .show(fragment.getParentFragmentManager(), "StreamDialogEntry@create_playlist")
+ append_playlist(R.string.add_to_playlist, (fragment, item) -> {
+ PlaylistDialog.createCorrespondingDialog(
+ fragment.getContext(),
+ Collections.singletonList(new StreamEntity(item)),
+ dialog -> dialog.show(
+ fragment.getParentFragmentManager(),
+ "StreamDialogEntry@"
+ + (dialog instanceof PlaylistAppendDialog ? "append" : "create")
+ + "_playlist"
+ )
);
}),
@@ -191,6 +196,16 @@ public enum StreamDialogEntry {
void onClick(Fragment fragment, StreamInfoItem infoItem);
}
+ public static boolean shouldAddMarkAsWatched(final StreamType streamType,
+ final Context context) {
+ final boolean isWatchHistoryEnabled = PreferenceManager
+ .getDefaultSharedPreferences(context)
+ .getBoolean(context.getString(R.string.enable_watch_history_key), false);
+ return streamType != StreamType.AUDIO_LIVE_STREAM
+ && streamType != StreamType.LIVE_STREAM
+ && isWatchHistoryEnabled;
+ }
+
/////////////////////////////////////////////
// private method to open channel fragment //
/////////////////////////////////////////////
diff --git a/app/src/main/java/org/schabi/newpipe/util/TLSSocketFactoryCompat.java b/app/src/main/java/org/schabi/newpipe/util/TLSSocketFactoryCompat.java
index 8cf5a4cdf..05e69408a 100644
--- a/app/src/main/java/org/schabi/newpipe/util/TLSSocketFactoryCompat.java
+++ b/app/src/main/java/org/schabi/newpipe/util/TLSSocketFactoryCompat.java
@@ -10,9 +10,8 @@ import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSocket;
import javax.net.ssl.SSLSocketFactory;
-import javax.net.ssl.TrustManager;
-import static org.schabi.newpipe.MainActivity.DEBUG;
+import android.util.Log;
/**
@@ -21,6 +20,7 @@ import static org.schabi.newpipe.MainActivity.DEBUG;
*/
public class TLSSocketFactoryCompat extends SSLSocketFactory {
+ private static final String TAG = "TLSSocketFactoryCom";
private static TLSSocketFactoryCompat instance = null;
@@ -32,14 +32,6 @@ public class TLSSocketFactoryCompat extends SSLSocketFactory {
internalSSLSocketFactory = context.getSocketFactory();
}
-
- public TLSSocketFactoryCompat(final TrustManager[] tm)
- throws KeyManagementException, NoSuchAlgorithmException {
- final SSLContext context = SSLContext.getInstance("TLS");
- context.init(null, tm, new java.security.SecureRandom());
- internalSSLSocketFactory = context.getSocketFactory();
- }
-
public static TLSSocketFactoryCompat getInstance()
throws NoSuchAlgorithmException, KeyManagementException {
if (instance != null) {
@@ -53,9 +45,7 @@ public class TLSSocketFactoryCompat extends SSLSocketFactory {
try {
HttpsURLConnection.setDefaultSSLSocketFactory(getInstance());
} catch (NoSuchAlgorithmException | KeyManagementException e) {
- if (DEBUG) {
- e.printStackTrace();
- }
+ Log.e(TAG, "Unable to setAsDefault", e);
}
}
diff --git a/app/src/main/java/org/schabi/newpipe/views/NewPipeEditText.java b/app/src/main/java/org/schabi/newpipe/views/NewPipeEditText.java
new file mode 100644
index 000000000..2adc28d0e
--- /dev/null
+++ b/app/src/main/java/org/schabi/newpipe/views/NewPipeEditText.java
@@ -0,0 +1,45 @@
+package org.schabi.newpipe.views;
+
+import android.content.Context;
+import android.util.AttributeSet;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+import androidx.appcompat.widget.AppCompatEditText;
+
+import org.schabi.newpipe.util.NewPipeTextViewHelper;
+import org.schabi.newpipe.util.external_communication.ShareUtils;
+
+/**
+ * An {@link AppCompatEditText} which uses {@link ShareUtils#shareText(Context, String, String)}
+ * when sharing selected text by using the {@code Share} command of the floating actions.
+ *
+ * This allows NewPipe to show Android share sheet instead of EMUI share sheet when sharing text
+ * from {@link AppCompatEditText} on EMUI devices.
+ *
+ */
+public class NewPipeEditText extends AppCompatEditText {
+
+ public NewPipeEditText(@NonNull final Context context) {
+ super(context);
+ }
+
+ public NewPipeEditText(@NonNull final Context context, @Nullable final AttributeSet attrs) {
+ super(context, attrs);
+ }
+
+ public NewPipeEditText(@NonNull final Context context,
+ @Nullable final AttributeSet attrs,
+ final int defStyleAttr) {
+ super(context, attrs, defStyleAttr);
+ }
+
+ @Override
+ public boolean onTextContextMenuItem(final int id) {
+ if (id == android.R.id.shareText) {
+ NewPipeTextViewHelper.shareSelectedTextWithShareUtils(this);
+ return true;
+ }
+ return super.onTextContextMenuItem(id);
+ }
+}
diff --git a/app/src/main/java/org/schabi/newpipe/views/NewPipeTextView.java b/app/src/main/java/org/schabi/newpipe/views/NewPipeTextView.java
new file mode 100644
index 000000000..8fdac32db
--- /dev/null
+++ b/app/src/main/java/org/schabi/newpipe/views/NewPipeTextView.java
@@ -0,0 +1,45 @@
+package org.schabi.newpipe.views;
+
+import android.content.Context;
+import android.util.AttributeSet;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+import androidx.appcompat.widget.AppCompatTextView;
+
+import org.schabi.newpipe.util.NewPipeTextViewHelper;
+import org.schabi.newpipe.util.external_communication.ShareUtils;
+
+/**
+ * An {@link AppCompatTextView} which uses {@link ShareUtils#shareText(Context, String, String)}
+ * when sharing selected text by using the {@code Share} command of the floating actions.
+ *
+ * This allows NewPipe to show Android share sheet instead of EMUI share sheet when sharing text
+ * from {@link AppCompatTextView} on EMUI devices.
+ *
+ */
+public class NewPipeTextView extends AppCompatTextView {
+
+ public NewPipeTextView(@NonNull final Context context) {
+ super(context);
+ }
+
+ public NewPipeTextView(@NonNull final Context context, @Nullable final AttributeSet attrs) {
+ super(context, attrs);
+ }
+
+ public NewPipeTextView(@NonNull final Context context,
+ @Nullable final AttributeSet attrs,
+ final int defStyleAttr) {
+ super(context, attrs, defStyleAttr);
+ }
+
+ @Override
+ public boolean onTextContextMenuItem(final int id) {
+ if (id == android.R.id.shareText) {
+ NewPipeTextViewHelper.shareSelectedTextWithShareUtils(this);
+ return true;
+ }
+ return super.onTextContextMenuItem(id);
+ }
+}
diff --git a/app/src/main/res/layout-land/activity_player_queue_control.xml b/app/src/main/res/layout-land/activity_player_queue_control.xml
index 4b79d92f6..c2359552e 100644
--- a/app/src/main/res/layout-land/activity_player_queue_control.xml
+++ b/app/src/main/res/layout-land/activity_player_queue_control.xml
@@ -60,7 +60,7 @@
android:padding="8dp"
tools:ignore="RtlHardcoded,RtlSymmetry">
-
-
-
-
-
-
-
-
-
-
+ tools:visibility="gone" />
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
@@ -82,7 +82,7 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+ android:paddingStart="6dp"
+ android:paddingTop="4dp"
+ android:paddingEnd="6dp">
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+ android:orientation="vertical">
-
+
+
+
+
diff --git a/app/src/main/res/layout/dialog_playlists.xml b/app/src/main/res/layout/dialog_playlists.xml
index b64a9241c..99c46e552 100644
--- a/app/src/main/res/layout/dialog_playlists.xml
+++ b/app/src/main/res/layout/dialog_playlists.xml
@@ -23,7 +23,7 @@
app:srcCompat="@drawable/ic_playlist_add"
tools:ignore="ContentDescription,RtlHardcoded" />
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
@@ -85,14 +85,14 @@
android:layout_gravity="end"
android:text="@string/give_back" />
-
-
@@ -105,14 +105,14 @@
android:layout_gravity="end"
android:text="@string/open_in_browser" />
-
-
diff --git a/app/src/main/res/layout/fragment_channel.xml b/app/src/main/res/layout/fragment_channel.xml
index 873f3c884..9e2257539 100644
--- a/app/src/main/res/layout/fragment_channel.xml
+++ b/app/src/main/res/layout/fragment_channel.xml
@@ -30,7 +30,7 @@
android:visibility="gone"
tools:visibility="visible">
-
-
-
-
-
-
-
-
-
-
-
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+ tools:visibility="gone" />
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
-
-
-
-
-
-
-
-
-
-
-
- -->
-
-
-
- -->
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+ tools:listitem="@layout/select_channel_item" />
-
-
-
+ tools:listitem="@layout/select_kiosk_item" />
diff --git a/app/src/main/res/layout/select_kiosk_item.xml b/app/src/main/res/layout/select_kiosk_item.xml
index 6cd04ae34..680767bba 100644
--- a/app/src/main/res/layout/select_kiosk_item.xml
+++ b/app/src/main/res/layout/select_kiosk_item.xml
@@ -22,7 +22,7 @@
app:tint="@color/contrastColor"
tools:ignore="RtlHardcoded" />
-
-
-
-
diff --git a/app/src/main/res/layout/settings_category_header_title.xml b/app/src/main/res/layout/settings_category_header_title.xml
index 679b9048c..c7d6920b0 100644
--- a/app/src/main/res/layout/settings_category_header_title.xml
+++ b/app/src/main/res/layout/settings_category_header_title.xml
@@ -1,5 +1,5 @@
-
-
-
-
-
-
-
-
-
-
diff --git a/app/src/main/res/menu/menu_play_queue_item.xml b/app/src/main/res/menu/menu_play_queue_item.xml
index ebb361be9..b23f8008f 100644
--- a/app/src/main/res/menu/menu_play_queue_item.xml
+++ b/app/src/main/res/menu/menu_play_queue_item.xml
@@ -9,7 +9,10 @@
android:title="@string/play_queue_stream_detail" />
+ android:title="@string/add_to_playlist" />
+
diff --git a/app/src/main/res/values-ar/strings.xml b/app/src/main/res/values-ar/strings.xml
index f90a82c44..0034cf2dc 100644
--- a/app/src/main/res/values-ar/strings.xml
+++ b/app/src/main/res/values-ar/strings.xml
@@ -47,7 +47,7 @@
خطأ
تعذر تحليل الموقع
تعذر فك تشفير توقيع رابط الفيديو
- اضغط على عدسة المكبرة للبدء.
+ اضغط على العدسة المكبرة للبدء.
اشتراك
مشترك
الاشتراكات
@@ -235,7 +235,7 @@
إنشاء قائمة تشغيل جديدة
إعادة تسمية
التسمية
- إضافة إلى قائمة التشغيل
+ إضافة إلى قائمة التشغيل
هل تريد حذف قائمة التشغيل هذه؟
تم إنشاء قائمة التشغيل
تمت إضافتها إلى قائمة التشغيل
@@ -262,7 +262,7 @@
عملية التصدير جارية …
إستيراد ملف
معرفك, soundcloud.com/هويتك
- عند إيقاف تحميل أي صور مصغرة، وتوفير البيانات واستخدام الذاكرة. تعمل التغييرات على محو ذاكرة التخزين المؤقت للصورة الموجودة على الذاكرة أو على القرص
+ قم بإيقاف تشغيله لمنع تحميل الصور المصغرة وحفظ البيانات واستخدام الذاكرة. تمسح التغييرات كلاً من ذاكرة التخزين المؤقت للصورة الموجودة في الذاكرة والموجودة على القرص
امسح البيانات الوصفيّة المخزّنة مؤقّتًا
إزالة جميع بيانات صفحات الويب المخزنة مؤقّتًا
تم محو ذاكرة التخزين المؤقتّة للبيانات الوصفيّة
@@ -597,7 +597,7 @@
خلط
كرّر
يمكنك تحديد ثلاثة إجراءات كحد أقصى لإظهارها في الإشعار المضغوط!
- قم بتحرير كل اشعار أدناه من خلال النقر عليه. حدد ما يصل إلى ثلاثة منها لتظهر في الإشعار المضغوط باستخدام مربعات الاختيار الموجودة على اليمين
+ قم بتحرير كل إشعار أدناه من خلال النقر عليه. حدد ما يصل إلى ثلاثة منها لتظهر في الإشعار المضغوط باستخدام مربعات الاختيار الموجودة على اليمين
زر الإجراء الخامس
زر الإجراء الرابع
زر الإجراء الثالث
@@ -717,4 +717,14 @@
بدء تشغيل المشغل الرئيسي في وضع ملء الشاشة
وضع التالي على قائمة الانتظار
تم وضع التالي على قائمة الانتظار
+ جاري المعالجة ... قد يستغرق لحظة
+ التحقق من وجود تحديثات
+ التحقق يدويا من وجود إصدارات جديدة
+ جاري التحقق من وجود تحديثات…
+ عناصر تغذية جديدة
+ الإبلاغ عن أخطاء المشغل
+ إظهار خيار تعطل عند استخدام المشغل
+ إظهار \"تعطل المشغل\"
+ تحطيم المشغل
+ رفع تقرير لأخطاء المشغل بالتفصيل الكامل بدلا من إظهار رسالة اشعار قصيرة الأجل (مفيدة لتشخيص المشاكل)
\ No newline at end of file
diff --git a/app/src/main/res/values-az/strings.xml b/app/src/main/res/values-az/strings.xml
index a5775792a..faad933a7 100644
--- a/app/src/main/res/values-az/strings.xml
+++ b/app/src/main/res/values-az/strings.xml
@@ -1,6 +1,6 @@
- Başlamaq üçün \"Axtarış\" bölməsinə toxunun
+ Başlamaq üçün \"Axtarış\" bölməsinə toxunun.
%1$s tarixində yayımlanıb
Axın pleyeri tapılmadı. \"VLC\" yüklənilsin\?
Axın pleyeri tapılmadı (baxmaq üçün \"VLC\"ni yükləyə bilərsiniz).
@@ -59,7 +59,7 @@
İzləmə tarixçəsi
Axtarış sorğularını lokal olaraq saxlayın
Axtarış tarixçəsi
- Axtarış edərkən təklifləri göstər
+ Axtarış edərkən göstəriləcək təklifləri seçin
Axtarış təklifləri
Pleyerin parlaqlığını idarə etmək üçün jestlərdən istifadə edin
Parlaqlığın jestlə idarə edilməsi
@@ -77,7 +77,7 @@
Bir pleyerdən digərinə keçmək növbənizi dəyişdirə bilər
Növbəni təmizləmədən öncə təsdiq üçün soruş
Qeyri-dəqiq axtarış (videonu irəli/geri çəkmə) istifadə edin
- Qeyri-dəqiq axtarış pleyerə azaldılmış həssaslıqla mövqeləri daha sürətlə axtarmağa imkan verir. 5, 15 və ya 25 saniyəlik axtarış bununla işləmir.
+ Qeyri-dəqiq axtarış oynadıcıya azaldılmış həssaslıqla mövqeləri daha sürətlə axtarmağa imkan verir. 5, 15 və ya 25 saniyəlik axtarış bununla işləmir
Cəld irəli/geri çəkmə müddəti
Heç nə
Buferizasiya olunur
@@ -99,7 +99,7 @@
Kanallar
%s tərəfindən
\"Youtube\"un \"Məhdudiyyətli Rejimi\"ni aktivləşdir
- Yaş limiti olduğuna görə (məs. 18+) böyük ehtimal uşaqlar üçün uyğun olmayan məzmunu göstər.
+ Yaş limiti olduğuna görə (məs. 18+) böyük ehtimal uşaqlar üçün uyğun olmayan məzmunu göstər
Yaş məhdudiyyətli məzmunu göstər
Məzmun
Ani pəncərədə oxudulur
@@ -119,7 +119,7 @@
\"Əlavə etmək üçün basılı tutun\" məsləhətini göstər
\"Növbəti\" və \"Bənzər\" videoları göstər
Tarixçəni, abunəlikləri və oxutma siyahılarını ixrac et
- Cari tarixçənizi və abunəliklərinizi ləğv edər
+ "Cari tarixçə, abunəliklər, pleylistlər və (istəyə görə) ayarlarınızın üzərinə yazır"
reCAPTCHA çərəzləri təmizləndi
reCAPTCHA çərəzlərini təmizlə
Məlumat bazasını ixrac et
@@ -268,4 +268,30 @@
Video təsvirini və əlavə bilgiləri gizlətmək üçün söndürün
Təsviri göstər
Bildirişləri rənglə
+ Belə qovluq yoxdur
+ Əsas oynadıcını (pleyeri) tam ekranda başlat
+ Xarici oynadıcılar bu cür linkləri dəstəkləmir
+ Yerli axtarış təklifləri
+ Video
+ Əlaqəli videolar
+ İzlənmiş kimi işarələ
+ Aşağıdakılardan biri ilə aç
+ Gecə Mövzusu
+ Ani açılan pəncərə (popup) xüsusiyyətlərini xatırla
+ Ani açılan pəncərənin son ölçüsü və mövqeyini xatırla
+ Video yayımı tapılmadı
+ Şərhlər
+ Təsvir
+
+ Nəticə yoxdur
+ İlkin ayarları qaytar
+ Fayl köçürüldü və ya silindi
+ Oynadıcı xətası düzəldilir
+ Bərpa oluna bilməyən oynadıcı xətası baş verdi
+ Oldu
+ Bu video yaş məhdudiyyətlidir.
+\n\"YouTube\"un yeni yaş məhdudiyyətli videolar siyasətinə görə \"NewPipe\" bu cür videoların yayımını əldə edə bilmir, beləliklə, videonu oynatmaq mümkün deyil.
+ Səs yayımı tapılmadı
+ Başqa proqramların üzərində göstərmə icazəsi ver
+ İlkin ayarları qaytarmaq istəyirsiniz\?
\ No newline at end of file
diff --git a/app/src/main/res/values-b+ast/strings.xml b/app/src/main/res/values-b+ast/strings.xml
index 213ef6f48..19ed896f0 100644
--- a/app/src/main/res/values-b+ast/strings.xml
+++ b/app/src/main/res/values-b+ast/strings.xml
@@ -132,7 +132,7 @@
Escartar
Llista de reproducción nueva
Nome
- Amestar a una llista de reproducción
+ Amestar a una llista de reproducción
¿Desanicair esta llista de reproducción\?
Ensin sotítulos
Axustar
diff --git a/app/src/main/res/values-b+uz+Latn/strings.xml b/app/src/main/res/values-b+uz+Latn/strings.xml
index 16f28dc09..4d4602daa 100644
--- a/app/src/main/res/values-b+uz+Latn/strings.xml
+++ b/app/src/main/res/values-b+uz+Latn/strings.xml
@@ -534,7 +534,7 @@
Pleylist eskizi sifatida o\'rnating
Unmute rejimi
Mute rejimi
- Playlist qo\'shish
+ Playlist qo\'shish
Nomi
Nomni o\'zgartirish
Yangi Playlist
diff --git a/app/src/main/res/values-b+zh+HANS+CN/strings.xml b/app/src/main/res/values-b+zh+HANS+CN/strings.xml
index 9670c318d..4e9511d8c 100644
--- a/app/src/main/res/values-b+zh+HANS+CN/strings.xml
+++ b/app/src/main/res/values-b+zh+HANS+CN/strings.xml
@@ -1,6 +1,6 @@
- 点击放大镜开始使用。
+ 点击放大镜图标即可开始使用。
发布于 %1$s
在浏览器中打开
在悬浮窗中打开
@@ -33,7 +33,7 @@
- %s 个视频
- 禁用
+ 停用
后台播放
显示搜索建议
订阅
@@ -62,7 +62,7 @@
网格
NewPipe 可更新!
服务器不接受多线程下载, 使用 @string/msg_threads = 1 重试
- 自动恢复上次播放
+ 自动播放
清空数据
播放历史已删除
喜欢
@@ -115,7 +115,7 @@
等待中
已暂停
已加入队列
- 加入队列
+ 排队
操作已被系统拒绝
下载失败
没有评论
@@ -211,7 +211,7 @@
时下流行
前 50
最新与热门
- 显示“长按添加”说明
+ 显示“长按加入播放队列”提示
在视频详情页中,长按后台播放或悬浮窗播放按钮时显示提示
无法播放此串流
发生无法处理的播放器错误
@@ -259,7 +259,7 @@
新建播放列表
重命名
名称
- 添加至播放列表
+ 添加至播放列表
设为播放列表封面
收藏播放列表
删除收藏
@@ -385,7 +385,7 @@
停止
最大重试次数
取消下载前的最多重试次数
- 切换到移动流量网络后中断播放
+ 切换到按流量计费的网络后中断下载
切换至移动数据时可能有用,虽然部分下载无法被暂停
事件
会议大会
@@ -490,7 +490,7 @@
可用时使用专用 feed 获取
仅在某些服务中可用,通常速度更快,但返回的视频数量可能有限,而且信息通常不完整(如无视频时长、类型,无直播状态)
启用快速模式
- 禁用快速模式
+ 停用快速模式
您是否觉得 feed 加载太慢?如果是这样,请尝试启用快速加载(可在设置中修改,也可使用下面的按钮修改)
\n
\nNewPipe 提供两种 feed 加载策略:
@@ -534,7 +534,7 @@
显示结果:%s
从不
仅在 Wi-Fi 下
- 视频开始播放后,自动定位到上次播放时的位置 — %s
+ 自动开始播放 — %s
播放队列
无法识别此 URL。是否用其他应用打开\?
自动加入播放队列
@@ -579,7 +579,7 @@
相关视频
评论
显示视频描述和其他信息
- 用…打开
+ 打开方式
设备上没有应用可以打开
让应用崩溃
此内容仅对已付费的用户可用,因此 NewPipe 无法流式传输或下载该内容。
@@ -598,9 +598,9 @@
选择你最喜欢的夜间主题 — %s
夜间主题
显示频道详情
- 如果遇到黑屏或视频播放卡顿的情况,请禁用媒体隧道
- 禁用媒体隧道
- 关闭简介中的文本选择功能
+ 如果遇到黑屏或视频播放卡顿的情况,请停用媒体隧道
+ 停用媒体隧道
+ 停用简介中的文本选择功能
内部
私享
未分类
@@ -611,10 +611,10 @@
语言
年龄限制
私有性
- 发行许可
+ 许可
标签
类别
- 开启简介中的文本选择功能
+ 启用简介中的文本选择功能
你现在可以选择简介中的文本,注意,在选择模式下,页面可能会闪烁,链接可能无法点击。
打开网站
%s 提供这个原因:
@@ -633,7 +633,7 @@
显示已观看的项目
关闭
开启
- 评论功能已禁用
+ 评论功能已停用
进度条缩略图预览
不显示
低品质(较小)
@@ -652,9 +652,19 @@
- 完成了 %s 个下载
- 滑动项目以删除它们
+ 滑动即可删除项目
若自动旋转被锁定,不在以小窗播放器形式中播放视频,而直接切换到全屏模式。仍可以通过退出全屏以切换至小窗播放器
以全屏启动主播放器
- 已将下个视频加入队列
- 将下一个视频加入队列
+ 已添加为下一个播放
+ 下一个播放
+ 处理中…可能需要一些时间
+ 手动检查新版本
+ 检查更新中…
+ 检查更新
+ 新订阅源条目
+ 完整报告播放器错误,而不是弹出一个临时Toast(对诊断应用很有用)
+ 显示\"使播放器崩溃\"
+ 在使用播放器时显示一个崩溃选项
+ 使播放器崩溃
+ 报告播放器错误
\ No newline at end of file
diff --git a/app/src/main/res/values-be/strings.xml b/app/src/main/res/values-be/strings.xml
index 46eedac34..4b185b301 100644
--- a/app/src/main/res/values-be/strings.xml
+++ b/app/src/main/res/values-be/strings.xml
@@ -274,7 +274,7 @@
Стварыць плэйліст
Перайменаваць
Імя
- Дадаць у плэйліст
+ Дадаць у плэйліст
На мініяцюру плэйліста
Дадаць плэйліст у закладкі
Выдаліць закладку
diff --git a/app/src/main/res/values-bg/strings.xml b/app/src/main/res/values-bg/strings.xml
index f1edfa124..065a8fbce 100644
--- a/app/src/main/res/values-bg/strings.xml
+++ b/app/src/main/res/values-bg/strings.xml
@@ -97,7 +97,7 @@
Съжаляваме, това не би трябвало да се случва.
Докладвай за грешката чрез имейл
Съжаляваме, възникнаха някои грешки.
- ДОКЛАД
+ Доклад
Инфо:
Какво се случи:
Вашият коментар (на английски):
@@ -151,7 +151,7 @@
Отметнати плейлисти
Добавяне към
Използвай бързо, но неточно превъртане
- Неточното превъртане позволява на плейъра да превърта кадри по-бързо, с намалена прецизност
+ По-бързо превъртане с по-ниска прецизност. Превъртане с по 5, 15 или 25 секунди няма да работи с тази опция
Зареждай миниатюри
Кеш-паметта с изображения е изтрита
Изтрий кешираните метаданни
@@ -173,7 +173,7 @@
Експортиране на историята, абонаментите и плейлистите
Изтрий историята с изгледани
Изтрий цялата история с изгледани\?
- Историята с изгледани е изтрита.
+ Историята с изгледани е изтрита
Изтрий историята на търсенията
Изтрива историята с въвежданите за търсене ключови думи
Изтрий цялата история на търсенията\?
@@ -197,7 +197,7 @@
Съдействайте
За всичко, което се сетите: превод, промени по дизайна, изчистване на кода или много сериозни промени по кода – помощта е винаги добре дошла. Колкото повече развитие, толкова по-добре!
Направете дарение
- NewPipe се разработва от доброволци, които отделят от своето време, за да ви доставят най-доброто преживяване. Дайте от себе си в замяна, за да помогнете на разработчиците да направят NewPipe още по-добро приложение, докато се наслаждават на едно кафе от вас.
+ NewPipe се разработва от доброволци, които отделят от своето време, за да предоставят най-доброто потребителско изживяване. Включете се в разработката като почерпите разработчиците с една чашка кафе, които да изпият, докато правят NewPipe още по-добро приложение.
Дари
Уебсайт
Посетете сайта на NewPipe за повече информация и новини.
@@ -207,8 +207,8 @@
Прочетете нашата политика за поверителност
Лицензът на NewPipe
Липсва стрийм плейър (можете да изтеглите VLC, за да пуснете стрийма).
- Изключете, за да спрете зареждането на всички миниатюри, спестявайки трафик и памет. При промяна на тази настройка, текущата кеш-памет на изображенията ще бъде изтрита.
- Показвай подсказка, когато е избран фонов режим или режим в прозорец на страницата с детайли на съответния клип
+ Изключете, за да спрете зареждането на всички миниатюри, спестявайки трафик и памет. При промяна на тази настройка, текущата кеш-памет на изображенията ще бъде изтрита
+ Показвай подсказка при избор на фоновия режим или режим в прозорец от екрана за „Детайли“ към видео
Изтрива историята на възпроизвежданите стриймове и позицията на възпроизвеждането
Не са намерени видео стриймове
Не са намерени аудио стриймове
@@ -267,7 +267,7 @@
Нов Плейлист
Преименувай
Име
- Добави Към Плейлист
+ Добави Към Плейлист
Задай като миниатюра на плейлиста
Миниатюрата на плейлиста е сменена
Премахни отметката
@@ -281,7 +281,7 @@
Увеличи
Авто-генерирани
Надписи
- Модифицирай мащаба на текста и фона на надписите. Изисква рестарт на приложението, за да се приложат промените.
+ Модифицирай текстовия мащаб на надписите и стила на техния фон. За промените се изисква рестарт на приложението
Следенето за пропускане на памет може да направи приложението нестабилно
Докладвай за извънредни грешки
Импортирай
@@ -293,11 +293,17 @@
Предишно експортиране
Неуспешно импортиране на абонатите
Неуспешно експортиране на абонатите
- Импортирайте YouTube абонаментите, чрез изтегляне на нужния файл:
+ Импортирайте вашите YouTube абонаменти чрез Google takeout:
\n
-\n1. Посетете тази връзка: %1$s
+\n1. Посетете следната връзка: %1$s
\n2. Влезте в акаунта си, когато това се изиска
-\n3. Изтеглянето трябва да започне (това е експортирания файл)
+\n3. За продукти изберете „Премахване на избора от всички“
+\n4. Превъртете до YouTube и YouTube Music и отбележете тази опция
+\n5. Изберете „Включени са всички данни“, след това „Премахване на избора от всички“. Отбележете само „абонаменти“ и изберете OK
+\n6. Изберете „Следваща стъпка“, след това „Създаване на експортиране“
+\n5. Изберете бутона „Изтегляне“ след като той се появи
+\n6. Изберете ВНЕСИ ФАЙЛ по-долу и посочете изтегления ZIP-файл
+\n7. [В случай, че внасянето се провали] Разархивирайте .csv файла (обичайно в подпапка \"YouTube and YouTube Music/subscriptions/subscriptions.csv\"), изберете ВНЕСИ ФАЙЛ по-долу и посочете разархивирания CSV-файл
Импортирайте SoundCloud профил чрез въвеждане на хипервръзката към него или чрез вашия ID:
\n
\n1. Включете „десктоп режим“ в браузър (сайтът е недостъпен за мобилни устройства)
@@ -333,9 +339,9 @@
Откачи (може да предизвика промени)
Отписване
Контрол на звука с жестове
- Променяйте звука на плейъра с жестове
+ Използвай жестове за контрол на звука
Контрол на яркостта с жестове
- Променяйте яркостта на плейъра с жестове
+ Използвай жестове за контрол на яркостта
Файлът е изтрит
Събития
Показвай коментари
@@ -343,7 +349,7 @@
Автоматично пускане
Избери раздел
Промени
- Продължи възпроизвеждане
+ Възобнови възпроизвеждането
Изтрии данни
Показване на резултати за: %s
Няма коментари
@@ -367,4 +373,187 @@
Повторение
Отваряне с
Миниатюра 1:1
+ Висококачествени (големи)
+ Автоматично възпроизвеждане — %s
+ Никога
+ Завършено
+ прекъснат
+ Това видео е с възрастови ограничения.
+\nПоради новите политики на YouTube за видеа с възрастови ограничения, NewPipe не може да достъпи нито един от видеопотоците на това видео и не може да го възпроизведе.
+ Не показвай
+ Местни предложения за търсене
+ Моля проверете дали има създадена дискусия за срив като този. Постъпилите дубликати са в ущърб на така ценното време за разработка.
+ Показване на метаданни
+ Мрежа
+ Списък
+ Четвърто действие
+ Стъпка на превъртане
+ Маркирай като гледан
+ Второ действие
+ Първо действие
+ Трето действие
+ Пето действие
+ Изберете до три действия за компактното известие!
+ Потвърждение за изтриване на опашката
+ Автоматично
+ Изключете за скриване на описанията под видеата и допълнителната информация
+ Само при Wi-Fi
+ Вид на списъка
+ Възстанови последната позиция
+ Нова версия на NewPipe е налична!
+ Миниатюри на лентата за превъртане
+ Нискокачествени (малки)
+ Докоснете за изтегляне
+ на опашка
+ Актуализации
+ Презаписване
+ Файл с това име вече съществува
+ Покажи грешка
+ Неуспешна връзка със сървъра
+ Неуспешно намиране на сървър
+ Неуспешно установяване на сигурна връзка
+ неуспешно презаписване на файла
+ Прекъсни изтеглянията
+
+ - Изтрито %1$s изтегляне
+ - Изтрити бяха %1$s изтегляния
+
+ Сървърът не приема мулти-нишкови изтегляния, прави се нов опит с @string/msg_threads = 1
+ Неуспешно възстановяване на това изтегляне
+ Радио
+ Не са заредени: %d
+
+ - %d избран
+ - %d избрани
+
+ Изберете абонаменти
+ Съдържанието не е налично във Вашата държава.
+ Няма подходящо инсталирано приложение за отваряне на файла
+ Поддръжка
+ Сървър
+ Публичен
+ Миниатюра линк
+ Език на интерфейса
+ Спри звука
+ пост-обработката
+
+ - Изтеглянето завърши
+ - %s изтегляния са готови
+
+ Създай уникално име
+ Изтрий изтеглените файлове
+ Няма избрани абонаменти
+ Страница на плейлиста
+ Глави
+ Лиценз
+ %s посочва следната причина:
+ Маркери
+ Достъпност
+ Език
+ Вътрешен
+ Включен
+ Изключен
+ Отвори уеб-страницата
+ Отбелязан със сърце от автора
+ Конференции
+ Най-харесвани
+ Готово
+ Коментари
+ Езикът ще се смени след рестартиране на приложението
+ Скрит
+ Частен
+ Предложения от сървъра
+ Добави инстанция
+ Видеа
+ Доклад в GitHub
+ Копиране във форматиран вид
+ ∞ клипове
+ 100+ видеа
+ възстановяване
+ От %s
+ Известие за нова версия
+ Описание
+ Превключване на услуги, текущо избран:
+ Калкулиране на хеш
+ Няма отметнати плейлисти
+ Изберете инстанция
+ Коментарите са изключени
+ Кои раздели се показват на началната страница
+ Няма свободно място на устройството
+ Помощ
+
+ - %d секунда
+ - %d секунди
+
+ Премахни изгледаните
+ Неуспешно зареждане на коментарите
+ Възрастова граница
+ Прекъсване
+ Максимален брой опити преди отменяне на изтеглянето
+ Създай
+ Искате ли да изтриете тази група\?
+ Това съдържание не се поддържа от NewPipe.
+\n
+\nЕвентуално може да бъде поддържано в бъдещи версии.
+ Обработка… Ще отнеме момент
+ Поради ограничения в ExoPlayer, стъпката за превъртане е зададена на %d секунди
+ Видата, които са били изгледани преди и след добавянето към плейлиста ще бъдат премахнати.
+\nСигурни ли сте\? Това не може да бъде отменено!
+ „Storage Access Framework“ позволява изтегляния във външна SD-карта
+ Започни изтеглянията
+ Затвори
+ Изтрий историята на изтеглянията
+ Файлът не може да бъде създаден
+ Изтеглен файл с това име вече съществува
+ Изтеглянето се провали
+ Възстанови първоначалните настройки
+ Позиции в списъци
+ Изтеглянето във външна SD-карта не е възможно. Нулиране на местоположението на папката за изтегляне\?
+ Пусни звука
+ Песни
+ Изпълнители
+ Албуми
+ Известие
+ Скорошни
+ Категория
+ Изтеглянето започна
+ Действието отказано от системата
+ Изберете любимите си PeerTube инстанции
+ Поддържат се само HTTPS хипервръзки
+
+ - %d минута
+ - %d минути
+
+
+ - %d час
+ - %d часа
+
+
+ - %d ден
+ - %d дни
+
+ Създадено от %s
+ Съдържанието е достъпно само за хора, които са си платили, затова не може да бъде гледано или изтеглено с NewPipe.
+ Това видео е достъпно за абонати на YouTube Music Premium, затова не може да бъде гледано или изтеглено с NewPipe.
+ Премахни изгледаните видеа\?
+ Да, както и само частично изгледаните видеа
+ Брой на абонати не е наличен
+ Инстанцията вече съществува
+ Файлът е преместен или изтрит
+ Известие за нова версия на NewPipe
+ PeerTube инстанции
+ Има насрочено изтегляне с това име
+ Вече има активно изтегляне с това име
+ Искате да изтриете историята на изтеглянията или всички изтеглени файлове\?
+ Полезно при превключване към мобилни данни, въпреки че някои изтегляния не поддържат възобновяване и ще започнат отначало
+ Срив на приложението
+ Цветът на известието да се избира според главния цвят в миниатюрата на видеото (може да не работи на всички устройства)
+ Използване на ограничения режим на YouTube
+ YouTube предлага „ограничен режим“, чрез който можете да филтрирате потенциално съдържание за възрастни
+ Това видео е с възрастова граница.
+\n
+\nВключете „%1$s“ в настройките ако искате да го пуснете.
+ Показвай цветни Picasso-панделки в горната част на изображенията като индикатор за техния произход (червен – от мрежата, син – от диска и червен – от паметта)
+ Автоматична (тази на устройството)
+ Мащабиране на миниатюрата в известието от 16:9 към 1:1 формат (възможни са изкривявания)
\ No newline at end of file
diff --git a/app/src/main/res/values-bn-rBD/strings.xml b/app/src/main/res/values-bn-rBD/strings.xml
index 6198b926e..d561d52e8 100644
--- a/app/src/main/res/values-bn-rBD/strings.xml
+++ b/app/src/main/res/values-bn-rBD/strings.xml
@@ -188,7 +188,7 @@
বুকমার্ক মুছুন
আন মিউট
মিউট
- প্লে লিস্ট এ যুক্ত করুন
+ প্লে লিস্ট এ যুক্ত করুন
নাম
নতুন প্লে লিস্ট
সবসময় জিজ্ঞেস করুন
diff --git a/app/src/main/res/values-bn-rIN/strings.xml b/app/src/main/res/values-bn-rIN/strings.xml
index 79ce1caaa..831364013 100644
--- a/app/src/main/res/values-bn-rIN/strings.xml
+++ b/app/src/main/res/values-bn-rIN/strings.xml
@@ -167,7 +167,7 @@
প্লে লিস্ট ডিলিট করতে চান\?
আন মিউট
মিউট
- প্লে লিস্ট এ যুক্ত করুন
+ প্লে লিস্ট এ যুক্ত করুন
সবসময় জিজ্ঞেস করুন
ভিডিও প্লেয়ার
ড্রয়ার বন্ধ করুন
diff --git a/app/src/main/res/values-bn/strings.xml b/app/src/main/res/values-bn/strings.xml
index a2f9dec31..83ffd9c64 100644
--- a/app/src/main/res/values-bn/strings.xml
+++ b/app/src/main/res/values-bn/strings.xml
@@ -37,7 +37,7 @@
বুকমার্ক মুছুন
আন মিউট
মিউট
- প্লে লিস্ট এ যুক্ত করুন
+ প্লে লিস্ট এ যুক্ত করুন
নাম
নাম পাল্টাও
নতুন প্লে লিস্ট
@@ -580,4 +580,9 @@
ট্যাবলেট অবস্থা
বন্ধ
চালু
+
+ - ডাউনলোড সমাপ্ত
+ - %sটি ডাউনলোড সমাপ্ত
+
+ দেখা হয়েছে চিহ্নিত করো
\ No newline at end of file
diff --git a/app/src/main/res/values-ca/strings.xml b/app/src/main/res/values-ca/strings.xml
index cbd725c77..353ef532c 100644
--- a/app/src/main/res/values-ca/strings.xml
+++ b/app/src/main/res/values-ca/strings.xml
@@ -86,7 +86,7 @@
Crea una llista de reproducció
Canvia el nom
Nom
- Afegeix a una llista de reproducció
+ Afegeix a una llista de reproducció
Importa
Importa des de
Exporta a
@@ -649,4 +649,8 @@
Suggeriments de cerca local
Tema fosc
Marca com a vist
+ Processant... Pot trigar un moment
+ Inicia el reproductor principal en pantalla completa
+ Llisqueu els elements per eliminar-los
+ Si la rotació automàtica està bloquejada, no inicieu vídeos al mini reproductor, sinó que aneu directament al mode de pantalla completa. Podeu accedir igualment al mini reproductor sortint de pantalla completa
\ No newline at end of file
diff --git a/app/src/main/res/values-ckb/strings.xml b/app/src/main/res/values-ckb/strings.xml
index b04048c5f..e524f9f7d 100644
--- a/app/src/main/res/values-ckb/strings.xml
+++ b/app/src/main/res/values-ckb/strings.xml
@@ -403,7 +403,7 @@
ناوفایل
دانان لەسەر وێنۆچکەی خشتەلێدان
دەربارەی نیوپایپ
- زیادکردن بۆ خشتەلێدان
+ زیادکردن بۆ خشتەلێدان
(نەزانراو)
زمانی بهرنامه
پەڕەی کیۆسک
@@ -631,8 +631,8 @@
\'Storage Access Framework\' پشتگیری نهكراوه لهسهر وهشانهكانی ئهندرۆید كیتكات و نزمتر
كڕاشی بهرنامهكه
پیشاندانی دزهكردنی بیرگه
- لهنۆبهتكرا
- لهنۆبهت
+ لهنۆبهت دانرا
+ لهنۆبهت دانان
پیشاندانی وردهكارییهكانی كهناڵ
چارهسهر كردن
هێشتا فۆڵدهری دابهزاندن دانهنراوه، ئێستا فۆڵدهری بنهڕهتی دابهزاندن ههڵبژێره
@@ -666,4 +666,7 @@
لادانی بابەتەکان بە سواندنیان
لە حاڵەتێکدا کە لاربوونەوە ناکارا کرابوو ، ئەوا لەجیاتی لێدانی ڤیدیۆکان لە لێدەرێکی بچووکدا ، ڕاستەوخۆ ڤیدیۆکان لە دۆخی پڕ بە ڕوونمادا لێبدرێن. دەتوانیت بە دەرچوونت لەسەر ڤیدیۆکە بەردەوام بیت لەسەر لێدەرێکی بچووک
دەستپێکردنی لێدەری سەرەکی لە ڕوونماپڕ
+ لە نۆبەت دانان بۆ دواتر
+ لە نۆبەت دانرا بۆ دواتر
+ جێبەجێ دەکرێت... ڕەنگە ساتێک بخایەنێت
\ No newline at end of file
diff --git a/app/src/main/res/values-cs/strings.xml b/app/src/main/res/values-cs/strings.xml
index 1791c1794..e62de53bb 100644
--- a/app/src/main/res/values-cs/strings.xml
+++ b/app/src/main/res/values-cs/strings.xml
@@ -234,7 +234,7 @@
Nový playlist
Přejmenovat
Jméno
- Přidat do playlistu
+ Přidat do playlistu
Nastavit jako miniaturu playlistu
Přidat playlist do záložek
Smazat záložku
@@ -681,4 +681,5 @@
Přidat do fronty (další)
Tažením položky odstraníte
Spustit hlavní přehrávač na celé obrazovce
+ Zpracovávám... může trvat moment
\ No newline at end of file
diff --git a/app/src/main/res/values-da/strings.xml b/app/src/main/res/values-da/strings.xml
index 158ec44ec..d59c35edb 100644
--- a/app/src/main/res/values-da/strings.xml
+++ b/app/src/main/res/values-da/strings.xml
@@ -270,7 +270,7 @@
Ny spilleliste
Omdøb
Navn
- Føj til spilleliste
+ Føj til spilleliste
Slet denne spilleliste\?
Spilleliste oprettet
Ingen undertekster
diff --git a/app/src/main/res/values-de/strings.xml b/app/src/main/res/values-de/strings.xml
index ca4d3e4d9..feb7e85c3 100644
--- a/app/src/main/res/values-de/strings.xml
+++ b/app/src/main/res/values-de/strings.xml
@@ -184,7 +184,7 @@
Tipp anzeigen, wenn der Hintergrundwiedergabe- oder Pop-up-Knopf „Details:“ im Video gedrückt wird
Neu und Heiß
Halten, um zur Wiedergabeliste hinzuzufügen
- „Zum Anhängen gedrückt halten“ Tipp anzeigen
+ „Halten zum Einreihen“ Tipp anzeigen
[Unbekannt]
Wiedergabe im Hintergrund starten
Wiedergabe in einem Pop-up starten
@@ -228,7 +228,7 @@
Immer fragen
Neue Wiedergabeliste
Umbenennen
- Zur Wiedergabeliste hinzufügen
+ Zur Wiedergabeliste hinzufügen
Als Vorschaubild der Wiedergabeliste festlegen
Lesezeichen entfernen
Diese Wiedergabeliste löschen?
@@ -290,7 +290,7 @@
\n4. Klicke auf „Nächster Schritt“ und dann auf „Export erstellen“
\n5. Klicke auf die Schaltfläche „Download“, nachdem sie erscheint
\n6. Klicke unten auf \"Datei importieren\" und wähle die heruntergeladene Zip-Datei aus
-\n7. [Wenn der Zip-Import fehlschlägt] Entpacke die csv-Datei (normalerweise unter „YouTube und YouTube Music/subscriptions/subscriptions.json“), klicke auf \"Datei importieren\" und wähle die extrahierte csv-Datei aus
+\n7. [Wenn der Zip-Import fehlschlägt] Entpacke die CSV-Datei (normalerweise unter „YouTube und YouTube Music/Abos/Abos.csv“), klicke auf \"Datei importieren\" und wähle die extrahierte CSV-Datei aus
Importiere ein SoundCloud-Profil, indem die URL oder deine ID eingegeben wird:
\n
\n1. Aktiviere den Desktop-Modus in einem Web-Browser (die Seite ist für mobile Geräte nicht verfügbar)
@@ -545,7 +545,7 @@
Wiedergabelisten-Seite
Bisher keine Lesezeichen für Wiedergabelisten
Wiedergabeliste auswählen
- Bitte überprüfen Sie, ob es schon Fragen zu diesem Thema gibt. Doppelt erstellte Tickets kosten uns Zeit, die wir nutzen könnten, um diesen Fehler zu beheben.
+ Bitte prüfe, ob nicht bereits ein Thema existiert, das deinen Absturz behandelt. Doppelt erstellte Tickets kosten uns Zeit, die wir nutzen könnten, um diesen Fehler zu beheben.
Zeige Ergebnisse für: %s
Wiedergabe automatisch starten — %s
Nur über WLAN
@@ -566,7 +566,7 @@
Wiederholen
Nichts
Warteschlange abspielen
- Automatische Warteschlange
+ Auto-Einreihung
Der Wechsel von einem Player zu einem anderen kann deine Warteschlange überschreiben
Überschreiben der Warteschlange bestätigen
Die aktive Player-Warteschlange wird ersetzt
@@ -669,4 +669,14 @@
Hauptplayer im Vollbildmodus starten
Als Nächstes eingereiht
Als Nächstes in Wiedergabe einreihen
+ Verarbeitung… Kann einen Moment dauern
+ Nach Aktualisierungen suchen
+ Suche nach Aktualisierungen…
+ Manuelle Prüfung auf neue Versionen
+ Neue Feed-Elemente
+ \"Absturz des Players\" anzeigen
+ Absturz des Players
+ Meldet Playerfehler mit allen Details, anstatt eine kurzlebige Popupmeldung anzuzeigen (nützlich für die Diagnose von Problemen)
+ Zeigt eine Absturzoption an, wenn der Player verwendet wird
+ Playerfehler melden
\ No newline at end of file
diff --git a/app/src/main/res/values-el/strings.xml b/app/src/main/res/values-el/strings.xml
index 3d4343195..bff4dea91 100644
--- a/app/src/main/res/values-el/strings.xml
+++ b/app/src/main/res/values-el/strings.xml
@@ -106,7 +106,7 @@
Κρατήστε ιστορικό των αναπαραχθέντων βίντεο
Ανάκτηση αναπαραγωγής
Συνέχιση της αναπαραγωγής έπειτα από διακοπές (π.χ. κλήσεις)
- Εμφάνιση επεξήγησης του «Πιέστε παρατεταμένα για προσθήκη»
+ Εμφάνιση επεξήγησης του «Πιέστε παρατεταμένα για προσθήκη στην ουρά»
Εμφάνιση υπόδειξης όταν πατηθεί το κουμπί παρασκηνίου ή αναδυόμενου παραθύρου στη σελίδα λεπτομερειών του βίντεο
Προεπιλεγμένη χώρα περιεχομένου
Αναπαραγωγός
@@ -252,7 +252,7 @@
Αφαίρεση
Λεπτομέρειες
Ρυθμίσεις ήχου
- Πιέστε παρατεταμένα για να προστεθεί στην ουρά
+ Πιέστε παρατεταμένα για προσθήκη στην ουρά
Εκκίνηση αναπαραγωγής στο παρασκήνιο
Εκκίνηση αναπαραγωγής σε ένα αναδυόμενο παράθυρο
Άνοιγμα συρταριού
@@ -270,7 +270,7 @@
Νέα λίστα αναπαραγωγής
Μετονομασία
Όνομα
- Προσθήκη σε λίστα αναπαραγωγής
+ Προσθήκη σε λίστα αναπαραγωγής
Ορισμός ως μικρογραφία λίστας αναπαραγωγής
Προσθήκη σελιδοδείκτη στη λίστα
Διαγραφή σελιδοδείκτη
@@ -304,7 +304,7 @@
\n4. Πατήστε «Επόμενο βήμα» και μετά «Δημιουργία εξαγωγής».
\n5. Πατήστε «Λήψη» όταν εμφανιστεί.
\n6. Πατήστε το ΕΙΣΑΓΩΓΗ ΑΡΧΕΙΟΥ και επιλέξτε το ληφθέν αρχείο zip.
-\n7. Αν η εισαγωγή από το zip αποτύχει, εξάγετε το αρχείο .csv (συνήθως βρίσκεται στο \"YouTube και YouTube Music/subscriptions/subscriptions.csv\"), πατήστε το ΕΙΣΑΓΩΓΗ ΑΡΧΕΙΟΥ και επιλέξτε το ληφθέν αρχείο csv.
+\n7. Αν η εισαγωγή από το zip αποτύχει, εξάγετε το αρχείο .csv (συνήθως βρίσκεται στο \"YouTube και YouTube Music/subscriptions/subscriptions.csv\"), πατήστε το ΕΙΣΑΓΩΓΗ ΑΡΧΕΙΟΥ και επιλέξτε το ληφθέν αρχείο csv
Για να εισάγετε τον λογαριασμό SoundCloud σας, πληκτρολογήστε τον σύνδεσμο ή το ID σας:
\n
\n1. Ενεργοποιήστε τη λειτουργία «Desktop mode» στον φυλλομετρητή σας (καθώς η ιστοσελίδα δεν είναι διαθέσιμη για κινητά)
@@ -487,7 +487,7 @@
Λειτουργία περιορισμένης πρόσβασης του YouTube
Ειδοποίηση
Δεν ήταν δυνατή η αναγνώριση της διεύθυνσης URL. Άνοιγμα με άλλη εφαρμογή;
- Αυτόματη ουρά
+ Αυτόματη προσθήκη στην ουρά
Η ουρά του ενεργού αναπαραγωγού θα αντικατασταθεί
Η εναλλαγή από έναν αναπαραγωγό σε άλλον, μπορεί να αντικαταστήσει την ουρά σας
Ζητήστε επιβεβαίωση πριν από την εκκαθάριση μιας ουράς
@@ -665,8 +665,18 @@
- %s λήψεις ολοκληρώθηκαν
Απομάκρυνση αντικειμένων με σύρσιμο
- Εκκίνηση των βίντεο σε πλήρη οθόνη και όχι σε αναδυόμενο παράθυρο, αν η αυτόματη περιστροφή της οθόνης είναι ανενεργή. Μπορείτε να ενεργοποιήσετε το αναδυόμενο παράθυρο βγαίνοντας από την πλήρη οθόνη.
+ Εκκίνηση των βίντεο σε πλήρη οθόνη και όχι σε αναδυόμενο παράθυρο, αν η αυτόματη περιστροφή της οθόνης είναι ανενεργή. Μπορείτε να ενεργοποιήσετε το αναδυόμενο παράθυρο βγαίνοντας από την πλήρη οθόνη
Εκκίνηση κύριου αναπαραγωγού σε πλήρη οθόνη
Προστέθηκε το επόμενο στην ουρά
Προσθήκη επόμενου στην ουρά
+ Επεξεργασία... Μπορεί να πάρει λίγο χρόνο
+ Έλεγχος αναβάθμισης…
+ Χειροκίνητος έλεγχος για νέα έκδοση
+ Έλεγχος αναβάθμισης
+ Νέα αντικείμενα τροφοδοσίας
+ Εμφάνιση «κατάρρευσης αναπαραγωγέα»
+ Εμφανίζει μια επιλογή κατάρρευσης κατά τη χρήση του αναπαραγωγέα
+ Αναφορά σφαλμάτων αναπαραγωγέα
+ Αναφορά σφαλμάτων αναπαραγωγέα με λεπτομέρειες αντί για ένα σύντομο μήνυμα (χρήσιμο για διάγνωση προβλημάτων)
+ Κατάρρευση αναπαραγωγέα
\ No newline at end of file
diff --git a/app/src/main/res/values-eo/strings.xml b/app/src/main/res/values-eo/strings.xml
index 50cdf09b3..bdf1aa6c2 100644
--- a/app/src/main/res/values-eo/strings.xml
+++ b/app/src/main/res/values-eo/strings.xml
@@ -18,8 +18,8 @@
Sono
Defaŭlta sondosierformo
Etoso
- Malluma
- Luma
+ Malhela
+ Hela
Nigra
Elŝuti
Ligilo ne subtenita
@@ -34,7 +34,7 @@
Malŝatoj
Neniu elsendlflua ludilo trovita. Ĉu instali la aplikaĵon VLC\?
Ĉu instali la mankan aplikaĵon Kore\?
- Montri la sekvan filmeton kaj similajn filmetojn
+ Montri \'Sekvajn\' kaj \'Similajn\' videojn
Ĉiuj bildetoj ne ŝargeblas
La subskribo de la ligilo de la filmeto ne malĉifreblas
La retejo ne analizeblas
@@ -42,7 +42,7 @@
Ludi filmeton, daŭro:
Bildeto de la alŝutinto
Elŝutujo por filmetoj
- Elŝutujo por muziko
+ Elŝutujo por aŭdio
Montri opcion por ludi filmeton per la aplikaĵo Kodi
Elŝutitaj filmetoj estas konservitaj tie
Dosierujo por konservi elŝutitajn muzikojn
@@ -76,11 +76,11 @@
Defaŭlta rezolucio de la ŝprucfenestra ludilo
Montri pli altajn rezoluciojn
Nur kelkaj aparatoj povas ludi 2K / 4K filmetojn
- Defaŭlta fomato de filmeto
- Memoru ŝprucfenestran grandecon kaj pozicion
- Memoru lastan grandecon kaj pozicion de ŝprucfenestro
- Uzi rapide, ne precizan serĉon
- Ne preciza serĉo permesas al la ludanto serĉi poziciojn pli rapide kun malalta precizeco. Serĉi por 5, 15 kaj 25 sekundoj ne funckios kun tio opcio
+ Defaŭlta filmetdosierformo
+ Memori ecojn de ŝprucfenestro
+ Memori lastan grandon kaj pozicion de ŝprucfenestro
+ Uzi rapidan malekzaktan serĉon
+ Malekzakta serĉo permesas ke, la ludilo serĉi poziciojn pli rapide sed kun malpli ekzakto. Serĉi por 5, 15 aŭ 25 sekundoj ne funckias kun ĉi tio opcio
Ŝarĝi bildetojn
Ne povis konstrui la dosierujon de elŝuto
Enhavo limigita al aĝo
@@ -153,7 +153,7 @@
Nova ludlisto
Alinomi
Nomo
- Aldoni al la ludlisto
+ Aldoni al la ludlisto
Meti kiel bildeto de ludlisto
Legosigno Ludlisto
Forviŝi Legosignon
@@ -162,7 +162,7 @@
Ludlistita
Bildeto de ludlisto ŝanĝiĝita.
Malcimigi
- Auto-vico sekva fluo
+ Memenvici sekvan fluon
Daŭrigi finanta (malripetanta) atendovico aldonante rilata enhavo
Dosiero
Tia dosierujo ne ekzistas
@@ -183,11 +183,11 @@
\n2. Iru tien: %1$s
\n3. Ensalutu kiam oni petas vin
\n4. Kopiu la ligilon de profilo ke oni kondikis vin.
- Malŝaltu por malebligi ŝarĝajn bildetojn, konservi datumojn kaj uzadon de memoro. Ŝanĝoj forviŝas ambaŭ en-memoro kaj sur-disko bildo kaŝmemoro
- Bildoj en kaŝmemoro forviŝitaj
- Forviŝi la metadatumojn kaŝitajn
- Forviŝi ĉiojn retpaĝojn kaŝitajn
- Metadatumoj kaŝitaj forviŝitaj
+ Malŝaltu por malebligi ŝarĝajn bildetojn por konservi datumuzadon kaj memoruzadon. Ŝanĝoj vakigi ambaŭ en memoran kaj en diskan bildkaŝmemoron
+ Bildokaŝmemoro vakigis
+ Vakigi kaŝmemorigitajn metadatumojn
+ Vakigi tutajn kaŝmemorigitajn retpaĝajn datumojn
+ Kaŝmemorojn de metadatumojn vakigis
Neniuj torentoj haveblaj por elŝuti
Neniu apo instalita por ludi ĉi tiun dosieron
Forviŝi vidohistorion
@@ -224,7 +224,7 @@
Eventoj
Konferencoj
Montri komentojn
- Malŝati por malvidigi komentojn
+ Malŝatu por kaŝi komentojn
Aŭtoludo
Ne povis ŝarĝi komentojn
Fermi
@@ -433,7 +433,7 @@
- %s aŭskultantoj
La lingvo ŝanĝos kiam la apo restartos
- Rapida antaŭen / posten serĉan daŭron
+ Daŭro de rapidpluiga/revolva serĉo
Instancoj de PeerTube
Elekti viajn preferitajn instancojn de PeerTube
Trovu la instancojn ke vi ŝatas ĉe %s
@@ -515,7 +515,7 @@
\n
\nŜalti \"%1$s\" en la agordoj, se vi volas vidi ĝin.
Sciigo
- Malhela etoso
+ Nokta etoso
farbi sciigon
Alŝuto
Skali bildeton ĝis 1:1 proportio
@@ -543,4 +543,17 @@
Priskribo
Komentoj
Montri priskribon
+ Skali la bildeto de la video en la sciigo inter 16:9 kaj 1:1 propocio (povas kaŭzi distordo)
+ Montri metadatumojn
+ Marki spektita
+ Malŝatu por kaŝi metadatumujojn kio havas aldonajn informojn pri la elsendfluisto, enhavo de la fluo, aŭ serĉpto
+ Malŝaltu por kaŝi la videan priskribon kaj aldonan informon
+ Peti por konfirmo antaŭ vakigado atendvico
+ Via atendvico povas anstataŭigi se vi ŝanĝi al malsama ludilo
+ La aktiva ludila atendvico anstataŭigos
+ Kvina agobutono
+ Unua agobutono
+ Dua agobutono
+ Tria agobutono
+ Kvara agobutono
\ No newline at end of file
diff --git a/app/src/main/res/values-es/strings.xml b/app/src/main/res/values-es/strings.xml
index 1e0d406a1..ffdf60d7e 100644
--- a/app/src/main/res/values-es/strings.xml
+++ b/app/src/main/res/values-es/strings.xml
@@ -183,7 +183,7 @@
[Desconocido]
Comenzar a reproducir en segundo plano
Reproducir en modo emergente
- Mostrar la sugerencia \"Mantener pulsado para añadir a la cola\"
+ Mostrar sugerencia de \"Mantener pulsado para añadir a la cola\"
Nuevo y lo mejor
Mantener pulsado para añadir a la cola
Donar
@@ -231,7 +231,7 @@
Lista de reproducción nueva
Cambiar nombre
Nombre
- Añadir a la lista de reproducción
+ Añadir a la lista de reproducción
Definir como miniatura de lista de reproducción
Marcar lista de reproducción
Quitar marcador
@@ -250,7 +250,7 @@
Forzar informe de excepciones no entregables de RX fuera del fragmento o del ciclo de actividad después del descarte
Usar búsqueda rápida e inexacta
La búsqueda inexacta permite al reproductor buscar posiciones más rápido con menor precisión. Buscar de a 5, 15 o 25 segundos no funciona
- Poner en cola vídeo relacionado siguiente
+ Poner en cola automáticamente la siguiente transmisión
Continuar reproducción sin repetir al añadir de forma automática un vídeo relacionado con el último visto
Archivo
Archivo movido o borrado
@@ -553,7 +553,7 @@
Reproducir cola
Notificación
No se pudo reconocer la URL. ¿Abrir con otra aplicación\?
- Poner en cola
+ Poner en cola automáticamente
Cambiar de un reproductor a otro puede reemplazar la cola de reproducción
La cola de reproducción activa será reemplazada
Pedir confirmación antes de vaciar una cola
@@ -672,4 +672,14 @@
Iniciar reproductor principal en pantalla completa
Añadido el siguiente vídeo a la cola
Añadir el siguiente vídeo a la cola
+ Procesando… Podría tomar un momento
+ Buscar actualizaciones
+ Buscar nuevas versiones manualmente
+ Buscando actualizaciones…
+ Nuevos elementos en el muro
+ Cerrar abruptamente el reproductor
+ Informar de errores del reproductor
+ Muestra una opción de cierre abrupto al usar el reproductor
+ Informar de errores del reproductor con detalle en lugar de mostrar un mensaje emergente efímero (útil para diagnosticar problemas)
+ Mostrar \"Cerrar abruptamente el reproductor\"
\ No newline at end of file
diff --git a/app/src/main/res/values-et/strings.xml b/app/src/main/res/values-et/strings.xml
index 1321806f5..ecf5faa6e 100644
--- a/app/src/main/res/values-et/strings.xml
+++ b/app/src/main/res/values-et/strings.xml
@@ -256,7 +256,7 @@
Uus esitusloend
Nimeta ümber
Nimi
- Lisa esitusloendisse
+ Lisa esitusloendisse
Määra esitusloendi pisipildiks
Lisa esitusloend järjehoidjaks
Eemalda järjehoidja
@@ -669,4 +669,9 @@
Käivita meediamängija täisekraanivaates
Lisasin esitamiseks järgmisena
Lisa esitamiseks järgmisena
+ Töötlen andmeid… Võib kuluda mõni hetk
+ Kontrollin uuendusi…
+ Kontrolli uuendusi
+ Kontrolli uuendusi käsitsi
+ Uued andmevoo kirjed
\ No newline at end of file
diff --git a/app/src/main/res/values-eu/strings.xml b/app/src/main/res/values-eu/strings.xml
index 9ca4bfae6..5b8161bf2 100644
--- a/app/src/main/res/values-eu/strings.xml
+++ b/app/src/main/res/values-eu/strings.xml
@@ -259,7 +259,7 @@
Erreprodukzio-zerrenda berria
Aldatu izena
Izena
- Gehitu erreprodukzio-zerrendara
+ Gehitu erreprodukzio-zerrendara
Ezarri erreprodukzio-zerrendaren iruditxo gisa
Gogoko erreprodukzio-zerrenda
Kendu gogokoa
diff --git a/app/src/main/res/values-fa/strings.xml b/app/src/main/res/values-fa/strings.xml
index e66825b96..027f593d2 100644
--- a/app/src/main/res/values-fa/strings.xml
+++ b/app/src/main/res/values-fa/strings.xml
@@ -22,7 +22,7 @@
پوشه بارگیری صداها را انتخاب کنید
وضوح پیشگزیده
پخش با کودی
- کارهٔ کوره (Kore) پیدا نشد. نصب شود؟
+ کارهٔ کُره (Kore) پیدا نشد. نصب شود؟
نمایش گزینهٔ «پخش با کودی»
نمایش گزینهای برای پخش ویدیو با مرکز رسانهٔ کودی
صدا
@@ -94,15 +94,15 @@
پس زمینه
افزودن به
نمایش کیفیت بالاتر
- تنها برخی دستگاهها توانایی پخش ویدئوهای 2K و 4K را دارند
- قالب ویدئوی پیشفرض
+ تنها برخی دستگاهها توانایی پخش ویدیوهای 2K و 4K را دارند
+ قالب ویدیویی پیشگزیده
سیاه
- دریافت تصویر بندانگشتی
+ بار کردن بندانگشتیها
قرار دادن خودکار جریان بعدی در صف
پیشنهادهای جستجو
گزینش پیشنهادها برای نمایش هنگام جستوجو
تاریخچه جستجو
- نگهداشتن آمار ویدئوهای دیدهشده
+ نگهداشتن رد ویدیوهای دیده
کشور محتوای پیشفرض
پخشکننده
رفتار
@@ -123,7 +123,7 @@
صادرکردن
تاریخچه، اشتراکها، سیاهههای پخش و (به صورت اختیاری) تنظیماتتان را بازنویسی خواهند کرد
برونریزی پیشینه، اشتراکها، سیاهههای پخش و تنظیمات
- پاککردن تاریخچه ویدئوهای دیدهشده
+ پاکسازی تاریخچهٔ دیدن
وارد کردن
وارد کردن از
صادر کردن به
@@ -144,7 +144,7 @@
تمام تاریخچه جستجو پاک شود؟
پیشینهٔ جستجو حذف شد
ناتوانی در پخش این جریان
- هیچ جریان ویدئویی پیدا نشد
+ هیچ جریان ویدیویی پیدا نشد
هیچ جریان صدایی پیدا نشد
چنین پوشهای وجود ندارد
چنین منبع محتوا/پروندهای وجود ندارد
@@ -164,7 +164,7 @@
- %s بازدید
- %s بازدید
- بدون ویدئو
+ بدون ویدیو
- %s ویدیو
- %s ویدیو
@@ -204,12 +204,12 @@
هنز کانال مشترکشدهای وجود ندارد
یک کیوسک را انتخاب کنید
محبوب
- ۵۰ ویدئوی برتر
+ ۵۰ برتر
جدید و داغ
حذف
جزئیات
تنظیمات صدا
- پخشکننده ویدئو
+ پخشکنندهٔ ویدیو
پخشکننده پسزمینه
همیشه بپرس
در حال دریافت اطلاعات…
@@ -217,7 +217,7 @@
فهرست پخش جدید
تغییر نام
نام
- افزودن به سیاههٔ پخش
+ افزودن به سیاههٔ پخش
تنظیم برای تصویر سیاههٔ پخش
این فهرست پخش پاک شود؟
فهرست پخش ایجاد شد
@@ -417,8 +417,8 @@
کوچک کردن پخش کننده به پس زمینه
آیدی شما، soundcloud.com/yourid
عملکرد هنگام تغییر به برنامه دیگر از پخشکننده اصلی فیلم — %s
- آهنگها
- ویدئوها
+ قطعهها
+ ویدیوها
این نمونه قبلا وجود دارد
تنها نشانیهای دارای http پشتیبانی میشوند
ناتوانی در اعتبارسنجی نشانی نمونه
@@ -484,8 +484,8 @@
کیوسک پیشفرض
انجام شد
وقتی انجام شد، «Done» یا «انجام شد» را بفشارید
- بینهایت ویدئو
- بیش از ۱۰۰ ویدئو
+ ∞ ویدیو
+ بیش از ۱۰۰ ویدیو
- %s شنونده
- %s شنونده
@@ -501,7 +501,7 @@
راهنما
هنرمندان
آلبومها
- موسیقیها
+ آوازها
روشن کردن «حالت محدود» یوتوب
نمایش نتایج برای: %s
گزارش روی گیتهاب
@@ -509,7 +509,7 @@
انتخاب یک فهرست پخش
نشانکهای فهرست پخش هنوز موجود نیستند
از گزارش قالببندیشده را رونوشت بگیرید
- تولید شده به صورت خودکار (بارگذارکننده ای یافت نشد)
+ خودکار ایجاد شده (بارگذاری پیدا نشد)
گروههای کانال
انتخاب اشتراکها
اشتراکی انتخاب نشده است
@@ -669,4 +669,14 @@
آغاز پخشکنندهٔ اصلی در تمامصفحه
بعدی در صف گذاشته شد
در صف گذاشتن بعدی
+ در حال پردازش… ممکن است کمی طول بکشد
+ بررسی بهروز رسانیها
+ بررسی دستی برای نگارشهای جدید
+ بررسی کردن بهروز رسانیها…
+ موارد خوراک جدید
+ فروپاشی پخشکننده
+ گزارش خطاهای پخش کننده
+ نمایش یک گزینهٔ فروپاشی هنگام استفاده از پخش کننده
+ گزارش خطاهای پخش کننده با جزییات کامل به جای نشان دادن پیامی با عمر کوتاه (مناسب برای تشخیص مشکلات)
+ نمایش «فروپاشی پخش کننده»
\ No newline at end of file
diff --git a/app/src/main/res/values-fi/strings.xml b/app/src/main/res/values-fi/strings.xml
index 25ae94dd5..713cdb38d 100644
--- a/app/src/main/res/values-fi/strings.xml
+++ b/app/src/main/res/values-fi/strings.xml
@@ -1,6 +1,6 @@
- Napauta suurennuslasia aloittaaksesi.
+ Aloita napauttamalla suurennuslasia.
Julkaistu %1$s
Ei löytynyt suoratoistosoitinta. Asennetaanko VLC\?
Asenna
@@ -194,10 +194,10 @@
Suoratoistosoitinta ei löytynyt (voit asentaa VLC:n toistaaksesi).
Lataa suoratoistotiedosto
Näytä lisätietoja
- Soittolistakirjanmerkit
+ Kirjanmerkit
Lisää soittolistaan
Käytä nopeampaa epätarkkaa pikakelausta
- Epätarkka kelaus mahdollistaa videon kelauksen nopeammin huonommalla tarkkuudella. Kelaaminen 5, 15 tai 25 sekunnin erissä ei toimi tämän kanssa
+ Epätarkka kelaus mahdollistaa videon kelauksen nopeammin huonommalla tarkkuudella. Kelaaminen 5, 15 tai 25 sekunnin hyppäyksin ei toimi tämän kanssa
Lataa esikatselukuvat
Poista käytöstä estääksesi esikatselukuvien lataus. Tämä säästää dataa ja vähentää muistin käyttöä. Asetuksen muuttaminen poistaa muistissa ja levyllä olevan kuvavälimuistin
Kuvavälimuisti tyhjennetty
@@ -271,7 +271,7 @@
Uusi soittolista
Uudelleennimeä
Nimi
- Lisää soittolistaan
+ Lisää soittolistaan
Aseta soittolistan kuvakkeeksi
Tallenna soittolista kirjanmerkkeihin
Poista kirjanmerkki
@@ -304,8 +304,9 @@
\n2. Kirjaudu sisään pyydettäessä
\n3. Klikkaa \"Kaikki Youtube-data valittuna\", sitten \"Poista kaikki valinnat\", sitten ainoastaan \"tilaukset\" ja klikkaa \"OK\"
\n4. Klikkaa \"Seuraava vaihe\" ja \"Luo vienti\"
-\n5. Klikkaa \"Lataa\" tämän ilmestyessä
-\n6. Ladatusta zip-tiedostosta pura .json-tiedosto (yleensä sijainnissa \"Youtube ja Youtube Musiikki/tilaukset/tilaukset.json\") ja tuo se tänne.
+\n5. Klikkaa \"Lataa\"-painiketta tämän ilmestyessä
+\n6. Klikkaa TUO TIEDOSTO alhaalta ja valitse ladattu tiedosto
+\n7. [Jos zip-tiedoston tuonti epäonnistuu] Pura .csv-tiedosto (yleensä sijainnissa \"Youtube ja Youtube Musiikki/tilaukset/tilaukset.csv\") ja klikkaa TUO TIEDOSTO alhaalta ja valitse purettu csv-tiedosto
Tuo SoundCloud-profiili kirjoittamalla joko osoite tai ID:si:
\n
\n1. Laita päälle työpöytämoodi selaimessasi (tai käytä tietokonetta, tämä sivu ei toimi mobiilisivuna)
@@ -655,4 +656,21 @@
Näytä kuvailmaisimet
Etähakuehdotukset
Paikalliset hakuehdotukset
+ Lisää seuraavaksi
+ Seuraavaksi jonossa
+
+ - Lataus valmis
+ - %s latausta valmiina
+
+ Käynnistä pääsoitin koko näytössä
+ Pyyhkäise kohteita poistaaksesi ne
+ Älä käynnistä videoita minisoittimessa, vaan siirry suoraan koko näytön tilaan, jos automaattinen kierto on lukittu. Voit silti käyttää minisoitinta poistumalla koko näytön tilasta
+
+ - Poistettu %1$s lataus
+ - Poistettu %1$s latausta
+
+ Käsitellään… Voi kestää hetken
+ Tarkista päivitykset
+ Tarkista manuaalisesti onko uusia versioita saatavilla
+ Tarkistetaan päivityksiä…
\ No newline at end of file
diff --git a/app/src/main/res/values-fr/strings.xml b/app/src/main/res/values-fr/strings.xml
index f4226497a..44d43ce83 100644
--- a/app/src/main/res/values-fr/strings.xml
+++ b/app/src/main/res/values-fr/strings.xml
@@ -230,7 +230,7 @@
Nouvelle liste de lecture
Renommer
Nom
- Ajouter à la liste de lecture
+ Ajouter à la liste de lecture
Définir comme miniature de la liste de lecture
Enregister la liste de lecture
Supprimer le signet
@@ -671,4 +671,14 @@
Lancer le lecteur principal en plein écran
Mettre en file d’attente la suivante
Placé comme suivant dans liste de lecture
+ Traitement en cours… Veuillez patienter
+ Vérifier manuellement de nouvelles versions
+ Vérification des mises à jour…
+ Vérifier les mises à jours
+ Nouveaux éléments du flux
+ Reporter les erreurs du lecteur en détail au lieu de montrer un bref message éphémère (utile pour diagnostiquer les problèmes)
+ Reporter des erreurs du lecteur
+ Couper le lecteur
+ Montrer \"Couper le lecteur\"
+ Montrer une option couper lors de l\'utilisation du lecteur
\ No newline at end of file
diff --git a/app/src/main/res/values-gl/strings.xml b/app/src/main/res/values-gl/strings.xml
index 185fdda9a..a8c9f0419 100644
--- a/app/src/main/res/values-gl/strings.xml
+++ b/app/src/main/res/values-gl/strings.xml
@@ -1,6 +1,6 @@
- Toque en \"Buscar\" para comezar
+ Prema na lupa para comezar.
Publicado o día %1$s
Non foi encontrado ningún reprodutor. Quere instalar o VLC\?
Non foi encontrado ningún reprodutor (pode instalar o VLC para o reproducir).
@@ -270,7 +270,7 @@
Nova lista de reprodución
Renomear
Nome
- Engadir á lista de reprodución
+ Engadir á lista de reprodución
Estabelecer como miniatura da lista de reprodución
Gardar a lista de reprodución nos marcadores
Eliminar o marcador
diff --git a/app/src/main/res/values-he/strings.xml b/app/src/main/res/values-he/strings.xml
index 6bc06eb3e..fe2911168 100644
--- a/app/src/main/res/values-he/strings.xml
+++ b/app/src/main/res/values-he/strings.xml
@@ -240,7 +240,7 @@
רשימת נגינה חדשה
שינוי שם
שם
- הוספה לרשימת נגינה
+ הוספה לרשימת נגינה
הוספת רשימת נגינה לסימניות
הסרת סימנייה
למחוק רשימת נגינה זו\?
@@ -693,4 +693,14 @@
הפעלת הנגן הראשי במסך מלא
נוסף כהבא בתור
הוספה כהבא בתור
+ מתבצע עיבוד… נא להמתין רגע קט
+ איתור עדכונים
+ מתבצע איתור עדכונים…
+ לנסות לאתר גרסאות חדשות ידנית
+ פריטים חדשים בהזנה
+ להקריס את הנגן
+ הצגת „להקריס את הנגן”
+ דיווח על שגיאות בנגן
+ מדווח על שגיאות בנגן בפירוט מלא במקום להציג הודעה שקופצת למסך לזמן קצר (יעיל לניתוח תקלות)
+ הצגת אפשרות קריסה בעת שימוש בנגן
\ No newline at end of file
diff --git a/app/src/main/res/values-hi/strings.xml b/app/src/main/res/values-hi/strings.xml
index 6402fc638..0e30cf4dd 100644
--- a/app/src/main/res/values-hi/strings.xml
+++ b/app/src/main/res/values-hi/strings.xml
@@ -230,7 +230,7 @@
नई प्लेलिस्ट
नाम बदलें
नाम
- प्लेलिस्ट में जोड़ें
+ प्लेलिस्ट में जोड़ें
प्लेलिस्ट थंबनेल के रूप में सेट करें
प्लेलिस्ट बुकमार्क करें
बुकमार्क हटायें
@@ -555,4 +555,8 @@
उदाहरण जोड़ें
%s . पर अपनी पसंद के उदाहरण ढूँढ़ें
अपने पसंदीदा PeerTube उदाहरण चुनें
+ मुख्य प्लेयर को पूर्ण स्क्रीन में शुरू करें
+ मिनी प्लेयर में वीडियो शुरू न करें, लेकिन ऑटो रोटेशन लॉक होने पर सीधे फुल स्क्रीन मोड पर जाएं। आप अब भी फ़ुलस्क्रीन से बाहर निकलकर मिनी प्लेयर तक पहुंच सकते हैं।
+ टिप्पणियाँ करना बंद है
+ देखा हुआ चिह्नित करें
\ No newline at end of file
diff --git a/app/src/main/res/values-hr/strings.xml b/app/src/main/res/values-hr/strings.xml
index 88e79451e..3f72baa92 100644
--- a/app/src/main/res/values-hr/strings.xml
+++ b/app/src/main/res/values-hr/strings.xml
@@ -36,7 +36,7 @@
Prikaži više rezolucije
Samo neki uređaji podržavaju reprodukciju 2K/4K videozapisa
Reproduciraj s Kodijem
- Kore aplikacija nije pronađena. Želite li ju instalirati?
+ Instalirati nedostajući Kore program\?
Prikaži opciju \"Reproduciraj putem Kodija\"
Prikaži opciju za reproduciranje videozapisa putem Kodija
Zvuk
@@ -82,14 +82,14 @@
Nije moguće dohvatiti stranicu
Sadržaj nije dostupan
Nije moguće postaviti izbornik za preuzimanje
- Aplikacija/UI se srušio
- Oprostite, ovo se nije trebalo dogoditi.
+ Program/korisničko sučelje su preknuli raditi
+ Oprosti, ovo se nije trebalo dogoditi.
Prijavi pogrešku putem e-maila
Žao nam je, došlo je do neke greške.
Prijavi
Informacije:
Što se dogodilo:
- Što:\\nZahtjev:\\nJezik sadržaja:\\nZemlja sadržaja:\\nJezik aplikacije:\\nUsluga:\\nGMT vrijeme:\\nPaket:\\nVerzija:\\nVerzija OS-a:
+ Što:\\nZahtjev:\\nJezik sadržaja:\\nZemlja sadržaja:\\nJezik programa:\\nUsluga:\\nGMT vrijeme:\\nPaket:\\nVerzija:\\nVerzija OS-a:
Vaš komentar (na engleskom):
Detalji:
Sličica pregleda videozapisa
@@ -131,7 +131,7 @@
© %1$s od %2$s pod %3$s
O aplikaciji
Licence
- Besplatna i mala YouTube aplikacija za Android.
+ Slobodan i mali YouTube program za Android.
Pogledaj na GitHubu
Licenca za NewPipe
Ako imate ideja za prijevod, promjene u dizajnu, čišćenje koda ili neke veće promjene u kodu, pomoć je uvijek dobro došla. Što više radimo, to bolji postajemo!
@@ -167,10 +167,10 @@
Reproduciraj sve
Nije moguće reproducirati ovaj stream
- Dogodila se neoporavljiva pogreška reproduktora
- Oporavljanje od pogreške reproduktora
+ Dogodila se neoporavljiva greška reproduktora
+ Oporavljanje od greške reproduktora
Prikaži savjet za držanje
- Prikažite savjet kada je pritisnut gumb za pozadinsku ili skočnu reprodukciju na stranici detalja videozapisa
+ Prikaži savjet kad se pritisne gumb za pozadinsku ili skočni prozor u detaljima videa:
Želite li izbrisati ovu stavku iz povijesti pretraživanja?
Sadržaj
Prazna stranica
@@ -193,16 +193,16 @@
Reproduciraj u skočnom prozoru
Otvori ladicu
Zatvori ladicu
- Video reprodukcija
- Pozadinska reprodukcija
- Skočna reprodukcija
+ Video reproduktor
+ Pozadinski reproduktor
+ Skočni reproduktor
Uvjek pitaj
- Dohvaćam informacije…
- Odabrani sadržaj se učitava
+ Dohvaćanje podataka …
+ Učitava se odabrani sadržaj
Nova playlista
Preimenuj
Ime
- Dodaj u playlistu
+ Dodaj u playlistu
Postavi kao minijaturu playliste
Zabilježi playlistu
Ukloni zabilješku
@@ -215,7 +215,7 @@
Ispuniti
Povećaj
Auto generirano
- Monitoring curenja memorije može uzrokovati greške u radu aplikacije prilikom odlaganje gomile
+ Praćenje curenja memorije može uzrokovati greške u radu programa prilikom odlaganje gomile
Izvijesti o krajevima životnog ciklusa
Prikaži informacije
Zabilježeni popisi
@@ -252,7 +252,7 @@
Odbaci
Preimenuj
1 stavka izbrisana.
- Nijedna aplikacija nije instalirana za reprodukciju te datoteke
+ Nijedan program nije instaliran za reprodukciju ove datoteke
Vrati
Posjetite web stranicu NewPipe za više informacija i vijesti.
NewPipeova pravila o privatnosti
@@ -274,14 +274,15 @@
Prethodni izvoz
Nije bilo moguće uvesti pretplate
Nije bilo moguće izvesti pretplate
- Uvezite pretplate na YouTubu pomoću Google Takeouta:
+ Uvezi pretplate na YouTubu pomoću Google Takeouta:
\n
-\n1. Idite na ovaj URL: %1$s
-\n2. Prijavite se
-\n3. Kliknite \"Uključeni svi podaci\", zatim \"Poništi odabir svih\", a zatim odaberite samo \"pretplate\" i kliknite \"U redu\"
-\n4. Kliknite na \"Nastavi\", a zatim \"Stvori izvoz\"
-\n5. Kliknite na \"Preuzmi\"
-\n6. Preuzmite zip datoteku i izvucite json datoteku (pod \"YouTube and YouTube Music/subscriptions/subscriptions.json\") pa uvezite je ovdje.
+\n1. Idi na ovaj URL: %1$s
+\n2. Prijavi se
+\n3. Pritisni „Uključeni svi podaci”, zatim „Poništi odabir svih”, a zatim odaberi samo „pretplate” i pritisni „U redu”
+\n4. Pritisni na „Nastavi”, a zatim „Stvori izvoz”
+\n5. Pritisni na „Preuzmi”
+\n6. Dolje pritisni na UVEZI DATOEKU i odaberi zip datoteku za peuzimanje
+\n7. [Ako uvoz zip datoteke ne uspije] Izdvoji .csv datoteku (pod \"YouTube and YouTube Music/subscriptions/subscriptions.json\"). Dolje pritisni UVEZI DATOTEKU i odaberi izdvojenu csv datoteku
vašID, soundcloud.com/vašID
Uzmite u obzir da ova operacija može uzrokovat veliku potrošnju prometa.
\n
@@ -308,11 +309,11 @@
Briše povijest ključnih riječi pretraživanja
Vanjska pohrana nije dostupna
Ažuriranja
- Prikažite obavijest kada je dostupna nova verzija aplikacije
+ Prikaži obavijest i zatraži aktualiziranje programa kad je dostupna nova verzija
Popis
Popločeno
Dostupna je nova verzija za NewPipe!
- Dodirnite za preuzimanje
+ Dodirni za preuzimanje
Preuzimanje nije uspjelo
Prikaži pogrešku
Isključi za sprječavanje učitavanja sličica, čime se štede podatci i memorija. Promjena postavke čisti predmemoriju u radnoj memoriji i u pohrani
@@ -326,9 +327,9 @@
Koristi gesture za kontrolu svjetline
Zadana zemlja sadržaja
Otkrivanje grešaka
- Obavijest o ažuriranju aplikacije
+ Obavijest o novoj verziji programa
Preuzimanje na vanjsku SD karticu nije moguće. Ponovo postaviti lokaciju mape za preuzimanje\?
- Vanjski playeri ne podržavaju ove vrste veza
+ Vanjski reproduktori ne podržavaju ove vrste veza
Nije pronađen nijedan videozapis
Nije pronađen nijedan audio zapis
Nema takve datoteke/izvora sadržaja
@@ -344,7 +345,7 @@
Preferirana \'otvori\' akcija
Zadana radnja pri otvaranju sadržaja — %s
Titlovi
- Izmijeni skalu podnaslova i pozadinske stilove reproduktora. Potrebno je ponovno pokretanje aplikacije kako bi stupilo na snagu
+ Promijeni veličinu podnaslova reproduktora i pozadinske stilove reproduktora. Za stupanje na snagu, program se mora ponovo pokrenuti
Prisilno izvješćivanje o greškama Rx-a koje se ne mogu isporučiti izvan \'fragmenta\' ili životnog ciklusa aktivnosti nakon odlaganja
Uvezite SoundCloud profil tako da upišete URL ili svoj ID:
\n
@@ -355,10 +356,10 @@
brzina
Visina tona
Odspoji (može prouzročiti izobličenje)
- Smanji prilikom mijenjanje aplikacije
- Radnja prilikom prebacivanja na drugu aplikaciju iz glavnog videoplayera – %s
- Smanji na pozadinski player
- Smanji na skočni player
+ Sklopi prilikom mijenjanje programa
+ Radnja prilikom prebacivanja na drugi program iz glavnog video reproduktora – %s
+ Smanji na pozadinski reproduktor
+ Smanji na skočni reproduktor
Način prikaza popisa
Automatski
Gotovo
@@ -393,9 +394,9 @@
Nema komentara
Komentare nije moguće učitati
Zatvori
- NewPipe je copyleft libre software: možete ga koristiti, proučavati i poboljšavati po volji. Konkretno, možete ga redistribuirati i / ili modificirati pod uvjetima GNU opće javne licence koju je objavila Free Software Foundation, bilo verzije 3 Licence, ili (po vašem izboru) bilo koje kasnije verzije.
- Projekt NewPipe ozbiljno shvaća vašu privatnost. Stoga aplikacija ne prikuplja nikakve podatke bez vašeg pristanka.
-\nNewPipe pravila o privatnosti detaljno objašnjavaju koji se podaci šalju i pohranjuju kada šaljete izvješće o padu aplikacije.
+ NewPipe je copyleft libre software: Može se koristiti, proučavati i poboljšavati po volji. Konkretno, može se redistribuirati i / ili modificirati pod uvjetima GNU opće javne licence koju je objavila Free Software Foundation, bilo licence verzije 3, ili (po vlastitom izboru) bilo koje kasnije verzije.
+ Projekt NewPipe ozbiljno shvaća tvou privatnost. Stoga program ne prikuplja nikakve podatke bez tvog pristanka.
+\nNewPipe pravila o privatnosti detaljno objašnjavaju koji se podaci šalju i spremaju kad šalješ izvještaje o prekidu rada programa.
Kako bismo se uskladili s Europskom općom uredbom o zaštiti podataka (GDPR), upozoravamo vas na politiku privatnosti tvrtke NewPipe. Pažljivo ga pročitajte.
\nZa slanje izvješća o pogreškama potrebno je prihvatiti politiku privatnosti.
Nastavi reprodukciju
@@ -416,7 +417,7 @@
Izbrisati sve pozicije reprodukcije\?
Nitko ne gleda
Nitko ne sluša
- Jezik će se promjeniti nakon ponovnog pokretanja aplikacije
+ Jezik će se promijeniti nakon ponovnog pokretanja programa
Zadani Kiosk
Podržani su samo HTTP URL-ovi
Lokalno
@@ -424,8 +425,8 @@
Autogenerirano (prenositelj nedefiniran)
Očisti povijest preuzimanja
Izbriši preuzete datoteke
- Dajte dopuštenje za prikazivanje na vrhu
- Jezik aplikacije
+ Dopusti prikaz iznad drugih programa
+ Jezik programa
Zadani sustav
Videozapisi
Isključi
@@ -483,7 +484,7 @@
Gumb druge radnje
Gumb prve radnje
Prikazuju se rezultati za: %s
- Nije moguće prepoznati URL. Želite li otvoriti u drugoj aplikaciji\?
+ Nije moguće prepoznati URL. Želiš li otvoriti s drugim programom\?
Smanjiti omjer minijatura na 1:1
Učitavanje u predmemoriju
Istovremeno se pokreće jedno preuzimanje
@@ -491,8 +492,8 @@
Dodaj u popis izvođenja
Popis izvođenja
Automatski popis izvođenja
- Popis izvođenja aktivnog playera će se zamijeniti
- Prebacivanje s jednog playera na drugi može zamijeniti popisa izvođenja
+ Popis izvođenja aktivnog reproduktora će se zamijeniti
+ Prebacivanje s jednog reproduktora na drugi može zamijeniti popisa izvođenja
Pitaj prije pražnjenja popisa izvođenja
- %s slušatelj
@@ -593,7 +594,7 @@
Isključi za skrivanje polja metapodataka s dodatnim podacima o autoru streama, sadržaju streama ili zahtjevu za pretraživanje
Prikaži metapodatke
Slični videozapisi
- Nijedna aplikacija na vašem uređaju ne može to otvoriti
+ Nijedan program na tvom uređaju ovo ne može otvoriti
Poglavlja videozapisa
Opis
Komentari
@@ -617,7 +618,7 @@
Riješi
Noćna tema
Prikaži detalje kanala
- Iskljuci medija tuneling ako dobivate crni ekran kada gledate video
+ Isključi tuneliranje medija ako doživiš crni ekran ili isprekidanu reprodukciju videa
Iskljuci medija tuneling
Isklj.
Uklj.
@@ -659,4 +660,29 @@
Privatnost
Sada možeš odabrati tekst u opisu. Napomena: stranica će možda treperiti i možda nećeš moći kliknuti poveznice u načinu rada za odabir teksta.
%s daje ovaj razlog:
+ Obrada... Pričekajte trenutak
+ Pogreška pri prikazu detalja kanala
+ Učitavanje detalja o kanalu…
+ Povucite stavke da biste ih uklonili
+ Prikazati indikatore slike
+
+ - Dovršeno %s preuzimanje
+ - Dovršena %s preuzimanja
+ - Dovršeno %s preuzimanja
+
+ Pokreni glavni reproduktor u cjeloekranskom prikazu
+ Reproduciraj sljedeće
+ U redu čekanja
+ Prikažite Picassove vrpce u boji na slikama koje označavaju njihov izvor: crvena za mrežu, plava za disk i zelena za memoriju
+
+ - Izbrisano %1$s preuzimanje
+ - Izbrisana %1$s preuzimanja
+ - Izbrisano %1$s preuzimanja
+
+ Prijedlozi daljinjske pretrage
+ Ručno traži nove verzije
+ Traženje novih verzija …
+ Prijedlozi lokalne pretrage
+ Traži nove verzije
+ Nemoj pokretati videa u mini reproduktoru, već se izravno pokreni cjeloekranski prikaz, ako je automatsko okretanje zaključano. Mini reproduktoru i dalje možeš pristupiti izlaskom iz cjeloekranskog prikaza
\ No newline at end of file
diff --git a/app/src/main/res/values-hu/strings.xml b/app/src/main/res/values-hu/strings.xml
index ca1913403..e5c9c1bb3 100644
--- a/app/src/main/res/values-hu/strings.xml
+++ b/app/src/main/res/values-hu/strings.xml
@@ -28,7 +28,7 @@
Válaszd ki a hangfájlok letöltési helyét
Hálózati hiba
Lejátszás háttérben
- Videó és audio
+ Videó és hang
Megjelenés
Tartalom preferált nyelve
\'Következő\' és \'Hasonló\' videók mutatása
@@ -40,7 +40,7 @@
Tetszik
Nem tetszik
Előnézeti kép
- Vidó lejátszása, időtartam:
+ Videó lejátszása, hossz:
Fetöltő profilképe
Tartalom
Korhatáros tartalom megjelenítése
@@ -78,7 +78,7 @@
Katt a részletekért
Kérlek várj…
Vágólapra másolva
- Kérlek adj meg egy letöltés könyvtárat a beállításokban
+ Kérlek, válassz egy létező könyvtárat a letöltésekhez
Csatornáról leiratkozva
Nem sikerült megváltoztatni a feliratkozást
Nem sikerült frissíteni a feliratkozást
@@ -191,7 +191,8 @@
Létrehozás
Átnevezés
- Ez az engedély szükséges a felugró ablakban történő megnyitáshoz
+ Ez az engedély szükséges
+\na felugró ablakban történő megnyitáshoz
1 elem törölve.
reCAPTCHA rejtvény
reCAPTCHA rejtvény igényelve
@@ -254,7 +255,7 @@
Új lejátszási lista
Átnevezés
Név
- Lejátszási listához adás
+ Lejátszási listához adás
Beállítás lejátszási lista indexképeként
Könyvjelző törlése
Törlődjön ez a lejátszási lista\?
@@ -314,7 +315,7 @@
Válassz fület
Kommentek mutatása
Kapcsold ki a kommentek elrejtéséhez
- Tartalmak alapértelmezett országa
+ Alapértelmezett ország tartalom
Folytatás főnézetben
Figyelmen kívül hagy
Lejátszási lista könyvjelzők közé
diff --git a/app/src/main/res/values-in/strings.xml b/app/src/main/res/values-in/strings.xml
index 82c867f86..b420c56d1 100644
--- a/app/src/main/res/values-in/strings.xml
+++ b/app/src/main/res/values-in/strings.xml
@@ -200,9 +200,9 @@
Konten halaman utama
Halaman Kosong
Halaman Kiosk
- Halaman Kanal
- Pilih kanal
- Belum ada langganan kanal
+ Halaman Channel
+ Pilih channel
+ Belum ada langganan channel
Pilih kiosk
Diekspor
Diimpor
@@ -229,7 +229,7 @@
Daftar Putar Baru
Ubah Nama
Nama
- Tambah ke daftar putar
+ Tambah ke daftar putar
Atur sebagai thumbnail daftar putar
Markah Daftar Putar
Hapus Markah
@@ -290,7 +290,7 @@
\n3. Klik \"Semua data disertakan\", lalu \"Batalkan semua pilihan\", lalu hanya pilih \"langganan\" dan klik \"OKE\"
\n4. Klik \"Langkah berikutnya\" dan kemudian \"Buat ekspor\"
\n5. Klik tombol \"Unduh\" dan
-\n6. Dari unduhan zip takeout ekstrak berkas .json (biasanya di bawah \"YouTube and YouTube Music/subscriptions/subscriptions.json\") dan impor di sini.
+\n6. Dari unduhan zip takeout ekstrak berkas .json (biasanya di bawah \"YouTube and YouTube Music/subscriptions/subscriptions.json\") dan impor di sini
Impor profil SoundCloud dengan mengetik URL atau ID Anda:
\n
\n1. Aktifkan \"mode desktop\" di peramban web (situs tidak tersedia untuk perangkat seluler)
@@ -305,7 +305,7 @@
Tempo
Nada
Batalkan tautan (dapat menyebabkan distorsi)
- Kanal
+ Channel
Daftar Putar
Trek
Pengguna
@@ -467,7 +467,7 @@
- %d hari
- Grup kanal
+ Grup channel
Terakhir diperbarui: %s
Tidak dimuat: %d
Memuat langganan…
@@ -522,7 +522,7 @@
Aktifkan \"Mode Terbatas\" YouTube
Oleh %s
Dibuat oleh %s
- Thumbnail avatar kanal
+ Thumbnail avatar channel
Harap periksa apakah masalah yang sama sudah ada atau belum. Ketika laporan Anda ternyata sudah ada, Anda membuat kami menghabiskan waktu yang seharusnya bisa kami gunakan untuk meningkatkan aplikasi menjadi lebih baik.
Laporkan di GitHub
Salin laporan dengan format
@@ -596,7 +596,7 @@
Selesaikan
Tema malam
Pengunduhan dimulai
- Tampilkan rincian channel
+ Tampilkan detail channel
Nonaktifkan terowongan media (tunnel) jiaka anda mengalami sebuah layar hitam atau kerusakan dalam memutar video
Nonaktifkan terowongan media (tunnel)
Internal
@@ -621,7 +621,7 @@
Mode langganan cepat tidak menyediakan lebih banyak info tentang ini.
Akun kreator telah dinonaktifkan.
\nNewPipe tidak akan bisa memuat langganan ini lagi.
-\nApakah Anda ingin berhenti berlangganan kanal ini\?
+\nApakah Anda ingin berhenti berlangganan channel ini\?
Tidak bisa memuat langganan untuk \'%s\'.
Galat memuat langganan
Mulai Android 10, hanya \'Storage Access Framework\' yang didukung
@@ -650,4 +650,20 @@
- Menghapus %1$s unduhan
+ tambahkan ke selanjutnya
+ telah ditambahkan ke selanjutnya
+ Tampilkan Ribon bewarna Picasso di atas gambar yang mengindikasikan asalnya: merah untuk jaringan, biru untuk disk dan hijau untuk memori
+ Jangan memulai memutar video di mini player, tapi nyalakan langsung di mode layar penuh, jika rotasi otomatis terkunci. Anda tetap dapat mengakses mini player dengan keluar dari layar penuh
+ Memuat Detail Channel…
+ Galat Menampilkan Detail Channel
+ Memproses… Mungkin butuh waktu sebentar
+ Periksa Pembaruan
+ Periksa manual untuk versi baru
+ Memeriksa pembaruan…
+ Item feed baru
+ Tampilkan \"hentikan pemain video\"
+ Menampilkan opsi penghentian ketika menggunakan pemain video
+ Melaporkan kesalahan pemain video dalam detail yang penuh daripada menampilkan pesan toast yang muncul sebentar (berguna untuk memeriksa masalah)
+ Laporkan kesalahan pemain video
+ Hentikan pemain video
\ No newline at end of file
diff --git a/app/src/main/res/values-it/strings.xml b/app/src/main/res/values-it/strings.xml
index af9d529d3..fc55ba69d 100644
--- a/app/src/main/res/values-it/strings.xml
+++ b/app/src/main/res/values-it/strings.xml
@@ -231,7 +231,7 @@
Nuova playlist
Rinomina
Nome
- Aggiungi alla playlist
+ Aggiungi alla playlist
Imposta come copertina della playlist
Salva playlist
Rimuovi playlist
@@ -669,4 +669,14 @@
Avvia il lettore principale a schermo intero
Aggiunto alla coda come prossimo
Accoda come prossimo
+ Elaborazione... Potrebbe volerci un attimo
+ Controlla aggiornamenti
+ Verifica manualmente la presenza di nuove versioni
+ Controllo aggiornamenti…
+ Nuovi elementi feed
+ Segnala errori del lettore multimediale
+ Quando il lettore multimediale è in uso, mostra un\'opzione per farlo crashare
+ Invece di mostrare un messaggio popup di breve durata, gli errori del lettore multimediale saranno visualizzati in modo dettagliato (utile per diagnosticare i problemi)
+ Mostra \"Fai crashare il lettore\"
+ Fai crashare il lettore
\ 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 769a31b52..6cedc2566 100644
--- a/app/src/main/res/values-ja/strings.xml
+++ b/app/src/main/res/values-ja/strings.xml
@@ -221,7 +221,7 @@
新規プレイリスト
変更
プレイリスト名
- プレイリストに追加
+ プレイリストに追加
プレイリストのサムネイルに設定
プレイリストをブックマーク
ブックマークを削除
@@ -654,4 +654,15 @@
ピカソは、画像の上に、画像の出所を識別する色彩記章を表示します: 赤はネットワーク、青はディスク、緑はメモリ
画像に標識を表示
+ 処理中… 少し時間がかかるかもしれません
+ 新しいバージョンを手動で確認します
+ アップデートを確認中…
+ アップデートを確認
+ 次をキューに追加
+ 次をキューに追加しました
+ クリエイターの心をこめて
+ プレーヤーのエラーを、短時間のトーストメッセージではなく、詳細に報告する(問題の診断に役立ちます)
+ プレイヤーのエラーを報告
+ \"プレイヤーがクラッシュ\"を表示
+ プレイヤーがクラッシュ
\ No newline at end of file
diff --git a/app/src/main/res/values-kab/strings.xml b/app/src/main/res/values-kab/strings.xml
index 5f5cc33a4..b3679ce82 100644
--- a/app/src/main/res/values-kab/strings.xml
+++ b/app/src/main/res/values-kab/strings.xml
@@ -63,7 +63,7 @@
Tidyanin
Ulac iwenniten
Isem
- Isedγiten
+ Ileqman
Yettraǧu
Iɣewwaren n umeslaw
Sermed imesli
@@ -138,11 +138,14 @@
Snifel isem
Tividyutin
Ldi deg uminig
- Yeffeɣ-d deg %1$s
+ Teffeɣ-d deg %1$s
Senned ɣef «Nadi» akken ad tebduḍ
Ula d yiwet n tmeẓriwt
- %s n tmeẓriwt
- %s n tmeẓriyin
+ Taggayt
+ Tabaḍnit
+ Turagt
\ No newline at end of file
diff --git a/app/src/main/res/values-kmr/strings.xml b/app/src/main/res/values-kmr/strings.xml
index 3fa5f2f45..d7ac85dd1 100644
--- a/app/src/main/res/values-kmr/strings.xml
+++ b/app/src/main/res/values-kmr/strings.xml
@@ -498,7 +498,7 @@
Wekî Thumbnailê Lîsteya Lîsteyê saz bikin
Bê deng kirin
Bêdeng
- Li lîsteyê zêde bike
+ Li lîsteyê zêde bike
Nav
Navlêkirin
Lîstinê ya nû
diff --git a/app/src/main/res/values-ko/strings.xml b/app/src/main/res/values-ko/strings.xml
index aaf02a5dd..880c45aee 100644
--- a/app/src/main/res/values-ko/strings.xml
+++ b/app/src/main/res/values-ko/strings.xml
@@ -230,7 +230,7 @@
새로운 재생목록
이름 바꾸기
이름
- 재생목록에 추가
+ 재생목록에 추가
재생목록 썸네일로 설정
재생목록 북마크하기
북마크 제거하기
diff --git a/app/src/main/res/values-ku/strings.xml b/app/src/main/res/values-ku/strings.xml
index 2cdd31d3b..be2a8086f 100644
--- a/app/src/main/res/values-ku/strings.xml
+++ b/app/src/main/res/values-ku/strings.xml
@@ -212,7 +212,7 @@
لیستەلێدانی نوێ
ناولێنانەوە
ناو
- زیادکردن بۆ لیستەلێدان
+ زیادکردن بۆ لیستەلێدان
دانان لەسەر وێنۆچکەی لیستەلێدان
لیستەلێدانی نیشانەکراو
لادانی نیشانەکراو
diff --git a/app/src/main/res/values-lt/strings.xml b/app/src/main/res/values-lt/strings.xml
index dae17e3ff..2b84f6a01 100644
--- a/app/src/main/res/values-lt/strings.xml
+++ b/app/src/main/res/values-lt/strings.xml
@@ -235,7 +235,7 @@
Naujas grojaraštį
Pervadinti
Pavadinimas
- Pridėti į grojaraštį
+ Pridėti į grojaraštį
Nustatyti kaip grojaraščio miniatiūrą
Pridėti grojaraštį į žymes
Pašalinti žymes
@@ -681,4 +681,9 @@
Paleisti pagrindinį grotuvą viso ekrano režimu
Sekantis pridėtas į eilę
Įtraukti į eilę sekantį
+ Apdorojama… tai gali užtrukti
+ Tikrinti ar yra atnaujinimų
+ Tikrinti ar yra atnaujinimų rankiniu būdu
+ Tikrinti ar yra atnaujinimų…
+ Nauji sklaidos kanalo elementai
\ No newline at end of file
diff --git a/app/src/main/res/values-lv/strings.xml b/app/src/main/res/values-lv/strings.xml
index 01167c426..5e337648c 100644
--- a/app/src/main/res/values-lv/strings.xml
+++ b/app/src/main/res/values-lv/strings.xml
@@ -5,7 +5,7 @@
Atskaņošanas saraksts radīts
Dzēst atskaņošanas sarakstu\?
Iestatīt, kā atskaņošanas saraksta attēlu
- Pievienot atskaņošanas sarakstam
+ Pievienot atskaņošanas sarakstam
Vārds
Pārsaukt
Jauns Atskaņošanas Saraksts
@@ -201,15 +201,15 @@
Ārējā krātuve nepieejama
Kļūda
Palīdzība
- Meklēšanas vēsture izdzēsta.
+ Meklēšanas vēsture izdzēsta
Izdzēsy visu meklēšanas vēsturi\?
Izdzēš meklēto vārdu vēsturi
Izdzēst skatīšanās vēsturi
- Atskaņošanas pozīcikas izdzēstas.
+ Atskaņošanas pozīcikas izdzēstas
Izdzēst visas atskaņošanas pozīcijas\?
Izdzēš visas atskaņošanas pozīcijas
Izdzēst atskaņošanas pozīcijas
- Skatīšanās vēsture izdzēsta.
+ Skatīšanās vēsture izdzēsta
Izdzēst visu skatīšanās vēsturi\?
Izdzēš atskaņoto videoklipu un atskaņošanas pozīciju vēsturi
Notīrīt skatīšanās vēsturi
@@ -278,7 +278,7 @@
Atrodiet instances, kas jums patīk ar %s
Izvēlaties jūsu mīļāko PeerTube instanci
PeerTube instances
- Valoda nomainīsies, kad aplikāciju restartēs.
+ Valoda nomainīsies, kad aplikāciju restartēs
Neviena lietotne jūsu ierīcē nevar šo atvērt
Nodaļas
Jaunākie
@@ -304,7 +304,7 @@
\nTātad izvēle sakrīt ar vēlamo: ātrums vai precīza informācija.
Izslēgt ātro režīmu
Ieslēgt ātro režīmu
- Pieejams dažos pakalpojumos, tas parasti ir daudz ātrāk, taču var atgriezt ierobežotu daudzumu informācijas un bieži arī nepilnīgu informāciju (piemēram, nav video ilguma, vienuma veida, nav tiešraides statusa).
+ Pieejams dažos pakalpojumos, tas parasti ir daudz ātrāk, taču var atgriezt ierobežotu daudzumu informācijas un bieži arī nepilnīgu informāciju (piemēram, nav video ilguma, vienuma veida, nav tiešraides statusa)
Iegūt no īpašās plūsmas, kad tas ir pieejams
Vienmēr atjauniniet
Laiks pēc pēdējās atjaunināšanas, pirms abonements tiek uzskatīts par novecojušu — %s
@@ -356,10 +356,10 @@
System default
Lietotnes valoda
Izvēlieties instanci
- Izmantojiet KPS
- “Krātuves Piekļuves Sistēma” ļauj lejupielādēt ārējā SD kartē.
-\nAr dažām ierīcēm nestrādā
- Jums tiks jautāts, kur saglabāt katru lejupielādi
+ Izmantot sistēmas mapes izvēlni
+ “Krātuves Piekļuves Sistēma” ļauj lejupielādēt ārējā SD kartē
+ Jums tiks jautāts, kur saglabāt katru lejupielādi.
+\nIeslēdziet sistēmas mapes izvēlni, ja vēlaties lejupielādēt uz ārējo SD karti
Jautājiet, kur lejupielādēt
Pauzēt lejupielādes
Sākt lejupielādes
@@ -426,14 +426,15 @@
\n2. Ierakstaties, kad tiek prasīts
\n3. Noklikšķiniet uz \"Visi dati iekļauti\", pēc tam uz \"Atcelt visu atlasi\", pēc tam atlasiet tikai \"Abonementi\" un noklikšķiniet uz \"Labi\"
\n4. Noklikšķiniet uz \"Nākamais solis\" un pēc tam uz \"Izveidot eksportu\"
-\n5. Pēc tam, kad tā parādās, noklikšķiniet uz pogas \"Lejupielādēt\" un
-\n6. No lejupielādētā izņemšanas zip izvelciet .json failu (parasti sadaļā “YouTube un YouTube mūzika / abonementi / abonementi.json”) un importējiet to šeit.
+\n5. Pēc tam, kad tā parādās, noklikšķiniet uz pogas \"Lejupielādēt\"
+\n6. Noklikšķiniet \"Importēt failu\" apakšā un izvēlaties lejupielādēto zip failu
+\n7. [Ja zip faila imports neizdodas] No lejupielādētā izņemšanas zip izvelciet .csv failu (parasti sadaļā “YouTube un YouTube mūzika / abonementi / abonementi.csv\"), noklikšķiniet uz \"Importēt failu\" apakšā un izvēlaties iegūto csv failu
Noklusējuma darbība, kad atver saturu — %s
Pakalpojumu oriģinālteksti būs redzami video vienumos
Pēc izdzēšanas, piespiedu kārtā ziņot par nepiegādātiem Rx izņēmumiem, ārpus fragmenta vai darbības dzīves cikla
Ziņot par ārpus-dzīves-cikla kļūdu
Atmiņas noplūdes uzraudzība var izraisīt lietotnes nereaģēšanu, kad tiek nottīrītas vairs nevajadzīgas lietas no atmiņas
- Mainīt atskaņotāja subtitru teksta mērogu un fona stilus. Nepieciešama lietotnes restartēšana, lai tā stātos spēkā.
+ Mainīt atskaņotāja subtitru teksta mērogu un fona stilus. Nepieciešama lietotnes restartēšana, lai tā stātos spēkā
Automātiski ģenerēts (neviens augšupielādētājs nav atrasts)
Ielikts atskaņošanas sarakstā
Noņemt Grāmatzīmi
@@ -506,7 +507,7 @@
Skatīšanās vēsture
Glabāt meklēšanas vēsturi uz telefona
Meklēšanas vēsture
- Meklējot, rādīt ieteikumus
+ Izvēlaties, kādus ieteikumus rādīt, rakstot meklēšanas joslā
Meklēšanas ieteikumi
Velkot ar pirkstu, mainiet video atskaņošanas spilgtumu
Spilgtuma kontrole, atskaņojot video
@@ -519,20 +520,20 @@
Izdzēst visus kešatmiņā glabātos mājaslapu datus
Notīrīt kešatmiņas metadatus
Attēlu kešatmiņa notīrīta
- Izslēdziet, lai paslēptu informācijas zīmes ar papildus ziņām par video autoru, video saturu vai meklēšanas rezultātu.
+ Izslēdziet, lai paslēptu informācijas zīmes ar papildus ziņām par video autoru, video saturu vai meklēšanas rezultātu
Rādīt papildus informāciju
Izslēdziet, ja nevēlaties redzēt video aprakstus un papildus informāciju
Rādīt video aprakstu
Rādīt \'Nākošos\' un \'Līdzīgos\' videoklipus
Izslēdziet, ja vēlaties neredzēt komentārus
Rādīt komentārus
- Izslēdziet, ja vēlaties nelādēt video attēlus, ietaupot datus un atmiņu. Opcija notīra kešatmiņu, izdzēšot visus saglabātos video attēlus.
+ Izslēdziet, ja vēlaties nelādēt video attēlus, ietaupot datus un atmiņu. Opcija notīra kešatmiņu, izdzēšot visus saglabātos video attēlus
Ielādēt video attēlus
Tagadējā atskaņošanas rinda tiks aizvietota
Mainoties vienam video uz citu, iespējams notīrīsies jūsu atskaņošanas rinda
Prasīt apstiprinājumu, pirms notīrīt atskaņošanas rindu
Uz priekšu/ uz atpakaļu, meklētāja ilgums
- Neprecīzs meklētājs atļauj video atskaņotājam atrast pozīciju atrāk, bet ar zemāku precizitāti. Meklēšana 5, 15 vai 25 sekundes uz priekšu vai atpakaļ, nestrādā ar šo opciju.
+ Neprecīzs meklētājs atļauj video atskaņotājam atrast pozīciju atrāk, bet ar zemāku precizitāti. Meklēšana 5, 15 vai 25 sekundes uz priekšu vai atpakaļ, nestrādā ar šo opciju
Izmantot ātru, neprecīzu meklētāju
Melna
Tumša
@@ -557,7 +558,7 @@
Sajaukt
Atkārtot
Jūs varat izvēlēties tikai 3 darbības, kuras rādīs kompaktajā notifikācijā!
- Rediģējiet katru notifikācijas darbību pieskaroties tai. Izvēlaties trīs darbības, kuras rādīs kompaktā notifikācijā, izmantojot rūtiņas labajā pusē.
+ Rediģējiet katru notifikācijas darbību pieskaroties tai. Izvēlaties trīs darbības, kuras rādīs kompaktā notifikācijā, izmantojot rūtiņas labajā pusē
Piektā darbības poga
Ceturtā darbības poga
Trešā darbības poga
@@ -631,4 +632,57 @@
Nerādīt
Konts ir pārtraukts
Komentāri ir atspējoti
+ Ielikt rindā nākošo
+ Ielikts rindā nākošais
+ Sākt video atskaņotāju pilnekrāna režīmā
+ Nesākt video atskaņošanu samazinātā režīmā, bet pilnekrāna režīmā, ja automātiskā rotācija ir izslēgta
+ Izslēgt multivides tuneļošanu
+ Izslēdziet multivides tuneļošanu, ja jums video atskaņošanas laikā parādās melns ekrāns vai aizķeršanās
+ Rādīt krāsainas lentes virs attēliem, norādot to avotu: sarkana - tīkls, zila - disks, zaļa - atmiņa
+ “Krātuves Piekļuves Sistēma” ir neatbalstīta uz Android KitKat un zemākām versijām
+ Ieslēgt teksta atlasīšanu video aprakstā
+ Nav izvēlēts noklusējuma lejupielādes mape, izvēlaties to tagad
+ Pārvelciet objektus, lai tos noņemtu
+ Rādīt noskatītos video
+ Lokālie meklēšanas ieteikumi
+ Rādīt attēlu indikatorus
+ Augstas kvalitātes (lielāks)
+ Pārbaudīt atjauninājumus
+ Manuāli pārbaudīt, vai ir atjauninājumi
+ Video atskaņošanas joslas sīktēla priekšskatījums
+ Pārbauda, vai ir atjauninājumi…
+ Sākot ar Android 10, tikai“Krātuves Piekļuves Sistēma” ir atbalstīta
+ Nevarēja ielādēt straumi priekš \'%s\'.
+ Kļūda lādējot plūsmu
+ Autora konts tika slēgts.
+\nNewPipe turpmāk nevarēs ielādēt šo plūsmu.
+\nVai vēlaties atteikties no šī kanāla abonēšanas\?
+ Ātrās straumes režīms nesniedz vairāk informācijas par šo.
+ %s dod šādu pamatojumu:
+ Izslēgt teksta atlasīšanu video aprakstā
+ Iekšeji
+ Autors piekrīt
+ Atvērt mājaslapu
+ Tabletes režīms
+ Kļūda rādot kanāla informāciju
+ Ielādē kanāla informāciju…
+ Zemas kvalitātes (mazāks)
+ Privātums
+ Sarakstā neiekļauts
+ Video attēla URL
+ Uzņēmums
+ Attālinātie meklēšanas ieteikumi
+ Atzīmēt kā skatītu
+ Apstrādā... Var aizņemt kādu laiku
+
+ - Izdzēsa %1$s lejupielāžu
+ - Izdzēsa %1$s lejupielādi
+ - Izdzēsa %1$s lejupielādes
+
+
+ - Lejupielāžu pabeigtas
+ - Lejupielāde pabeigta
+ - Lejupielādes pabeigtas
+
+ Tagad varat atlasīt tekstu video aprakstā.
\ No newline at end of file
diff --git a/app/src/main/res/values-mk/strings.xml b/app/src/main/res/values-mk/strings.xml
index c0e16def2..d925e2970 100644
--- a/app/src/main/res/values-mk/strings.xml
+++ b/app/src/main/res/values-mk/strings.xml
@@ -248,7 +248,7 @@
Создај нова плејлиста
Прекрсти плејлиста
Име
- Додај во плејлиста
+ Додај во плејлиста
Постави како икона на плејлистата
Обележи ја плејлистата
Избриши ја белешката
diff --git a/app/src/main/res/values-ml/strings.xml b/app/src/main/res/values-ml/strings.xml
index 20372cbb9..a536ccd4d 100644
--- a/app/src/main/res/values-ml/strings.xml
+++ b/app/src/main/res/values-ml/strings.xml
@@ -54,7 +54,7 @@
പ്ലേലിസ്റ്റ് ലഘുചിത്രമായി സജ്ജമാക്കുക
അൺമ്യൂട്ട്
മ്യൂട്ട്
- പ്ലേലിസ്റ്റിലേക്ക് ചേർക്കുക
+ പ്ലേലിസ്റ്റിലേക്ക് ചേർക്കുക
പേര്
പേര് മാറ്റുക
പുതിയ പ്ലേലിസ്റ്റ്
@@ -655,4 +655,7 @@
റിമോട്ട് സെർച്ച് നിർദ്ദേശങ്ങൾ
ലോക്കൽ സെർച്ച് നിർദേശങ്ങൾ
കണ്ടതാണെന്ന് അടയാളപ്പെടുത്തുക
+ തുടങ്ങുന്ന പ്രേധാന പേജ് മുഴുവന് സ്ക്രീനില് കാണിക്കുക
+ ഐറ്റം കളയണം എന്നുണ്ടെല് സ്വൈപ്പ് ചൈയ്യുക
+ മിനി പ്ലേയര് -ല് വീഡിയോ -ക്കള് ഒരിക്കലും സ്റ്റാര്ട്ട് ചൈയ്യരുത് , പക്ഷേ നേരെ ഫുള് സ്ക്രീന് മോഡിലെക് മാറും .ഓട്ടോ റൊട്ടേഷന് ലോക്ക് ചെയിത്തിട്ടുണ്ടെങ്കില് നിലവിലെ ഫുള് സ്ക്രീന് നില് നിന്നും മിനി പ്ലായേറിലെക് മാറാന് ആകും
\ No newline at end of file
diff --git a/app/src/main/res/values-ms/strings.xml b/app/src/main/res/values-ms/strings.xml
index ddf04c1e2..76aef646f 100644
--- a/app/src/main/res/values-ms/strings.xml
+++ b/app/src/main/res/values-ms/strings.xml
@@ -284,7 +284,7 @@
Senarai Main Baru
Namakan semula
Nama
- Tambah ke Senarai Main
+ Tambah ke Senarai Main
Tetapkan sebagai Thumbnail Senarai Main
Menanda senarai main
Hapuskan Penanda Halaman
diff --git a/app/src/main/res/values-nb-rNO/strings.xml b/app/src/main/res/values-nb-rNO/strings.xml
index b7c370900..b0ed47b71 100644
--- a/app/src/main/res/values-nb-rNO/strings.xml
+++ b/app/src/main/res/values-nb-rNO/strings.xml
@@ -231,7 +231,7 @@
Ny spilleliste
Gi nytt navn
Navn
- Legg til i spilleliste
+ Legg til i spilleliste
Sett som miniatyrbilde for spilleliste
Bokmerk spilleliste
Fjern bokmerke
@@ -665,4 +665,15 @@
Vis bildeindikatorer
Dra elementer for å fjerne dem
Start hovedspiller i fullskjerm
+ Spill etterpå
+ Spill etterpå
+ Se etter oppdateringer
+ Behandler … Kan ta sin tid
+ Krasj avspilleren
+ Rapporter avspillerfeil
+ Sirlig rapportering av feil, istedenfor å kun vise et lite oppsprett en stund (nyttig i avlusningsøyemed)
+ Vis «Krasj spilleren»
+ Se etter nye versjoner manuelt
+ Nye informasjonskanalelementer
+ Ser etter oppdateringer …
\ No newline at end of file
diff --git a/app/src/main/res/values-ne/strings.xml b/app/src/main/res/values-ne/strings.xml
index f26e8a051..71c9e107f 100644
--- a/app/src/main/res/values-ne/strings.xml
+++ b/app/src/main/res/values-ne/strings.xml
@@ -292,7 +292,7 @@
नया प्लेलिस्ट
पुनः नामकरण
नाम
- प्लेसूचीमा थप्नुहोस
+ प्लेसूचीमा थप्नुहोस
प्लेलिस्ट थम्बनेल रूपमा सेट
बुकमार्क प्लेलिस्ट
बुकमार्क हटाउ
diff --git a/app/src/main/res/values-nl-rBE/strings.xml b/app/src/main/res/values-nl-rBE/strings.xml
index 5190e814e..56b53d814 100644
--- a/app/src/main/res/values-nl-rBE/strings.xml
+++ b/app/src/main/res/values-nl-rBE/strings.xml
@@ -54,9 +54,9 @@
Onthoud grootte en positie van pop-up
Onthoud laatste grootte en positie van pop-up
Snel, minder exact spoelen gebruiken
- Minder exact spoelen laat de speler sneller posities zoeken met verminderde precisie. 5, 15 en 25 seconden werken niet.
+ Minder exact spoelen laat de speler sneller posities zoeken met verminderde precisie. 5, 15 en 25 seconden werken niet
Miniatuurvoorbeelden laden
- Schakel dit uit voor het laden van miniatuurvoorbeelden te verhinderen; dit bespaart mobiele gegevens en geheugen. Het wijzigen van deze instelling wist het geheugen en de afbeeldingscache.
+ Schakel dit uit voor het laden van miniatuurvoorbeelden te verhinderen; dit bespaart mobiele gegevens en geheugen. Het wijzigen van deze instelling wist het geheugen en de afbeeldingscache
Afbeeldingscache gewist
Gecachete metagegevens wissen
Alle gecachete webpagina-gegevens wissen
@@ -64,7 +64,7 @@
Volgende stream automatisch in wachtrij plaatsen
Automatisch een gerelateerde stream toekennen bij het afspelen van de laatste stream in een niet-herhalende afspeelwachtlijst
Zoeksuggesties
- Toon suggesties bij zoeken
+ Kies de suggesties die getoond worden bij het zoeken
Zoekgeschiedenis
Sla zoekopdrachten lokaal op
Geschiedenis bekijken
@@ -252,7 +252,7 @@
Nieuwe afspeellijst
Hernoemen
Naam
- Toevoegen aan afspeellijst
+ Toevoegen aan afspeellijst
Instellen als miniatuur voor afspeellijst
Afspeellijst toevoegen aan bladwijzers
Bladwijzer verwijderen
@@ -266,7 +266,7 @@
Inzoomen
Automatisch gegenereerd
Bijschriften
- Bijschrift grootte en achtergrond stijlen wijzigen. Vereist herstart van de app.
+ Bijschrift grootte en achtergrond stijlen wijzigen. Vereist herstart van de app
Het monitoren van geheugenlekken kan ervoor zorgen dat de app niet goed meer reageert
Out-of-lifecycle-fouten melden
Forceer het melden van niet-bezorgbare Rx-uitzonderingen buiten fragment of activiteitscyclus
@@ -286,7 +286,8 @@
\n3. Klik op \"Alle YouTube-gegevens inbegrepen\", dan op \"Selectie van alle items ongedaan maken\", dan selecteer alleen \"abonnementen\" en klik op \"OK\"
\n4. Klik op \"Volgende stap\", dan op \"Export maken\"
\n5. Klik op de knop \"Downloaden\" nadat deze verschijnt
-\n6. Uit de Takeout zipfile, pak de .json uit (gebruikelijk in de folder \"YouTube en YouTube Music/abonnementen/abonnementen.json\") en importeer deze hier.
+\n6. Klik op IMPORTEER BESTAND hieronder en selecteer het gedownloade zip-bestand
+\n7. [Als de zip import faalt] Pak het .csv bestand uit (gebruikelijk in de folder \"YouTube en YouTube Music/abonnementen/abonnementen.csv), klik op IMPORTEER BESTAND hieronder en selecteer het uitgepakt csv bestand
Importeer een SoundCloud-profiel door de URL of het ID ervan in te voeren:
\n
\n1. Kies een webbrowser en schakel bureaubladmodus in (de website is niet beschikbaar voor mobiele apparaten)
@@ -304,11 +305,11 @@
Wissen afspeel geschiedenis
Verwijdert de geschiedenis van bekeken video\'s en afspeelposities
Alle afspeel geschiedenis verwijderen\?
- Afspeel geschiedenis verwijderd.
+ Afspeel geschiedenis verwijderd
Zoekgeschiedenis wissen
Verwijdert de gebruikte zoektermen
De hele zoekgeschiedenis verwijderen\?
- Zoekgeschiedenis verwijderd.
+ Zoekgeschiedenis verwijderd
1 item verwijderd.
NewPipe is vrije software: u kan het gebruiken, bestuderen, delen en verbeteren zoveel u maar wil. U kan het opnieuw uitgeven en/of aanpassen volgens de voorwaarden van de GNU General Public License, gepubliceerd door de Free Software Foundation, versie 3 van de licentie, of (indien gewenst) om het even welke latere versie.
Wilt u ook de instellingen importeren\?
@@ -496,7 +497,7 @@
Meest leuk gevonden
Recent toegevoegd
Lokaal
- De taal zal veranderen zodra de app opnieuw is opgestart.
+ De taal zal veranderen zodra de app opnieuw is opgestart
Geen afspeellijst bladwijzers
Selecteer een afspeellijst
Standaard kiosk
@@ -521,7 +522,7 @@
Geef toestemming voor weergave over andere apps
Stream bestand downloaden
Hulp
- Afspeelposities verwijderd.
+ Afspeelposities verwijderd
Alle afspeelposities verwijderen\?
Verwijdert alle geschiedenis van afspeelposities
Verwijder geschiedenis afspeelposities
@@ -563,7 +564,7 @@
Shuffle
Herhaal
Je kan maximaal drie acties selecteren om te tonen in de compacte notificatie!
- Pas elke notificatie actie hieronder aan door er op te tikken. Selecteer tot drie acties die getoond worden in de compacte notificatie door gebruik te maken van de selectie vakjes aan de rechterkant.
+ Pas elke notificatie actie hieronder aan door er op te tikken. Selecteer tot drie acties die getoond worden in de compacte notificatie door gebruik te maken van de selectie vakjes aan de rechterkant
Vijfde actie knop
Vierde actie knop
Derde actie knop
@@ -580,7 +581,7 @@
Hash aan het berekenen
Meldingen van vooruitgang video hashing
Video Hash Melding
- Zet uit om metadata pop-ups te verbergen met extra informatie over de stream auteur, stream inhoud of een zoekaanvraag.
+ Zet uit om metadata pop-ups te verbergen met extra informatie over de stream auteur, stream inhoud of een zoekaanvraag
Toon metadata
Media vertunneling uitschakelen
Toon kanaal details
@@ -609,4 +610,19 @@
Deze inhoud is niet toegankelijk in uw land.
Geen app beschikbaar om dit te openen
Hoofdstukken
+ Volgende in de wachtrij
+ Volgende in de wachtrij
+ Hoge kwaliteit (groter)
+ Lage kwaliteit (kleiner)
+ Start hoofdspeler in volledig scherm
+ Veeg items om ze te verwijderen
+ Zoekbalk miniatuurvoorbeeld
+ Markeer als bekeken
+ Lokale zoeksuggesties
+ Suggesties voor zoeken op afstand
+ Start geen video\'s in de minispeler, maar schakel direct over naar volledig scherm-modus, als de auto rotatie is vergrendeld. U kunt de minispeler nog steeds openen door het volledige scherm te verlaten
+ Geen download map ingesteld, kies nu de standaard download map
+ Niet tonen
+ Reacties zijn uitgeschakeld
+ Toon afbeeldingsindicatoren
\ No newline at end of file
diff --git a/app/src/main/res/values-nl/strings.xml b/app/src/main/res/values-nl/strings.xml
index f33e5d9cd..9fef6b795 100644
--- a/app/src/main/res/values-nl/strings.xml
+++ b/app/src/main/res/values-nl/strings.xml
@@ -231,7 +231,7 @@
Nieuwe afspeellijst
Naam wijzigen
Naam
- Toevoegen aan afspeellijst
+ Toevoegen aan afspeellijst
Instellen als miniatuur voor afspeellijst
Afspeellijst toevoegen aan bladwijzers
Bladwijzer verwijderen
@@ -564,7 +564,7 @@
Eerste actieknop
Schaal de miniatuurafbeelding van de video die getoond wordt in de notificatie van verhouding 16:9 naar 1:1 (dit kan vervorming creëren)
Schaal de miniatuurafbeelding tot verhouding 1:1
- Auto-wachtrij
+ Automatisch in de wachtrij plaatsen
Toon memory leaks
In de wachtrij geplaatst
In de wachtrij plaatsen
@@ -669,4 +669,14 @@
Veeg items om ze te verwijderen
Start geen video\'s in de minispeler, maar ga direct naar de volledige schermmodus, als automatisch draaien is vergrendeld. Je hebt nog steeds toegang tot de minispeler door de volledige schermmodus af te sluiten
Start hoofdspeler als volledig scherm
+ Rapporteer fouten van de speler in volledig detail in plaats van een kortstondige toastmelding te tonen (handig voor het diagnosticeren van problemen)
+ Verwerken... Dit kan even duren
+ Crash de speler
+ Rapporteer fouten van de speler
+ Toon \"crash de speler\"
+ Toon een crash overzicht bij gebruik van de speler
+ Controleer handmatig op nieuwe versies
+ Controleer op updates
+ Bezig met controleren op updates…
+ Nieuwe feed items
\ No newline at end of file
diff --git a/app/src/main/res/values-pa/strings.xml b/app/src/main/res/values-pa/strings.xml
index 75f40b725..219440faa 100644
--- a/app/src/main/res/values-pa/strings.xml
+++ b/app/src/main/res/values-pa/strings.xml
@@ -1,6 +1,6 @@
- ਸ਼ੁਰੂ ਕਰਨ ਲਈ ਸਰਚ ਦਬਾਓ
+ ਸ਼ੁਰੂ ਕਰਨ ਲਈ ਵੱਡਦਰਸ਼ੀ ਕੱਚ ਨੂੰ ਦਬਾਓ
%1$s ਨੂੰ ਜਾਰੀ ਕੀਤੀ ਗਈ
ਕੋਈ ਸਟ੍ਰੀਮ ਪਲੇਅਰ ਨਹੀਂ ਮਿਲਿਆ। ਤੁਸੀਂ ਵੀਐੱਲਸੀ ਸਥਾਪਤ ਕਰਨਾ ਚਾਹੋਗੇ\?
ਸਟ੍ਰੀਮ ਪਲੇਅਰ ਨਹੀਂ ਮਿਲਿਆ (ਤੁਸੀਂ ਵੀਐੱਲਸੀ ਸਥਾਪਤ ਕਰਕੇ ਇਸਨੂੰ ਚਲਾ ਸਕਦੇ ਹੋ)।
@@ -259,7 +259,7 @@
ਨਵੀਂ ਪਲੇ-ਲਿਸਟ
ਨਾਮ ਬਦਲੋ
ਨਾਮ
- ਪਲੇ-ਸੂਚੀ ਵਿੱਚ ਸ਼ਾਮਲ ਕਰੋ
+ ਪਲੇ-ਸੂਚੀ ਵਿੱਚ ਸ਼ਾਮਲ ਕਰੋ
ਬਤੌਰ ਪਲੇ-ਸੂਚੀ ਥਮਨੇਲ ਸੈੱਟ ਕਰੋ
ਬੁੱਕਮਾਰਕ ਪਲੇ-ਲਿਸਟ
ਬੁੱਕਮਾਰਕ ਹਟਾਓ
diff --git a/app/src/main/res/values-pl/strings.xml b/app/src/main/res/values-pl/strings.xml
index 0de5abcf0..7a776d862 100644
--- a/app/src/main/res/values-pl/strings.xml
+++ b/app/src/main/res/values-pl/strings.xml
@@ -45,11 +45,11 @@
Raport o błędach
Błąd
Błąd sieci
- Nie można załadować wszystkich miniatur
+ Nie udało się załadować wszystkich miniatur
Nie udało się odszyfrować sygnatury URL wideo
- Nie można przetworzyć strony internetowej
+ Nie udało się przetworzyć strony internetowej
Zawartość niedostępna
- Nie można ustawić menu pobierania
+ Nie udało się utworzyć menu pobierania
Przepraszamy, to nie powinno mieć miejsca.
Zgłoś błąd przez e-mail
Niestety, coś poszło nie tak.
@@ -150,10 +150,10 @@
Pokaż wskazówkę po naciśnięciu tła lub wyskakującego przycisku „Szczegóły” w odtwarzaczu
Odtwórz wszystkie
[Nieznane]
- Nie można odtworzyć strumienia
+ Nie udało się odtworzyć tego strumienia
Wystąpił nieodwracalny błąd odtwarzacza
Odzyskiwanie po błędzie odtwarzacza
- Nic tu nie ma. Słychać świerszcze
+ Nic tu nie ma. Słychać tylko świerszcze.
Brak subskrybentów
- %s subskrybent
@@ -238,7 +238,7 @@
Nowa playlista
Zmień nazwę
Nazwa
- Dodaj do playlisty
+ Dodaj do playlisty
Ustaw jako miniaturę playlisty
Dodaj do ulubionych
Usuń z ulubionych
@@ -252,8 +252,8 @@
Powiększ
Wygenerowane automatycznie
Monitorowanie wycieków pamięci może powodować niestabilność aplikacji podczas zrzutu pamięci
- Zgłoś błędy spoza cyklu życia
- Wymuś raportowanie niedostarczonych wyjątków Rx poza cyklem życia fragmentu lub aktywności
+ Zgłaszaj błędy spoza cyklu życia
+ Wymuś raportowanie niedostarczonych wyjątków Rx poza cyklem życia fragmentu lub aktywności po usunięciu
Używaj szybkiego, niedokładnego przewijania
Niedokładne przewijanie umożliwia szybsze przewijanie ze zmniejszoną dokładnością. Przewijanie o 5, 15 lub 25 sekund nie działa w tym przypadku
Wczytuj miniatury
@@ -353,7 +353,7 @@
Powiadomienia o nowej wersji NewPipe
Pamięć zewnętrzna niedostępna
Pobieranie na kartę SD nie jest możliwe. Zresetować lokalizację folderu zapisywania\?
- Nie można odczytać zapisanych kart, więc będą używane domyślne
+ Nie udało się odczytać zapisanych kart, więc będą używane domyślne
Przywróć domyślne
Czy chcesz przywrócić ustawienia domyślne\?
Liczba subskrybentów jest niedostępna
@@ -381,7 +381,7 @@
Nie można utworzyć pliku
Nie można utworzyć folderu docelowego
Nie udało się nawiązać bezpiecznego połączenia
- Nie można znaleźć serwera
+ Nie udało się znaleźć serwera
Nie można połączyć się z serwerem
Serwer nie wysyła danych
Serwer nie akceptuje pobierania wielowątkowego, spróbuj ponownie za pomocą @string/msg_threads = 1
@@ -399,7 +399,7 @@
Wyłącz, aby ukryć komentarze
Automatyczne odtwarzanie
Brak komentarzy
- Nie można załadować komentarzy
+ Nie udało się załadować komentarzy
Zamknij
Wznawiaj odtwarzanie
Przywracaj odtwarzanie od ostatniej pozycji
@@ -544,7 +544,7 @@
Usunąć obejrzane wideo\?
Usuń obejrzane
Oryginalne teksty z usług będą widoczne w strumieniowanych pozycjach
- Pokaż oryginalny czas
+ Pokazuj oryginalny czas na pozycjach
Włącz tryb ograniczonego dostępu YouTube\'a
Przez %s
Utworzony przez %s
@@ -667,8 +667,8 @@
Oznacz jako obejrzane
Ładowanie szczegółów kanału…
Błąd podczas wyświetlania szczegółów kanału
- Pokaż kolorowe wstążki Picasso nad obrazami wskazujące ich źródło: czerwone dla sieci, niebieskie dla dysku i zielone dla pamięci
- Pokaż wskaźniki obrazu
+ Pokazuj kolorowe wstążki Picasso nad obrazami wskazujące ich źródło: czerwone dla sieci, niebieskie dla dysku i zielone dla pamięci
+ Pokazuj wskaźniki obrazu
Zdalne podpowiedzi wyszukiwania
Lokalne podpowiedzi wyszukiwania
@@ -688,4 +688,14 @@
Uruchamiaj główny odtwarzacz w trybie pełnoekranowym
Dodano do kolejki (następny)
Dodaj do kolejki (następny)
+ Przetwarzanie… Może to chwilę potrwać
+ Sprawdzanie aktualizacji…
+ Ręcznie sprawdź dostępność nowych wersji
+ Sprawdź dostępność aktualizacji
+ Nowe pozycje kanału
+ Zgłaszaj błędy odtwarzacza
+ Pokazuje opcję psucia podczas korzystania z odtwarzacza
+ Zepsuj odtwarzacz
+ Pokazuj „zepsuj odtwarzacz”
+ Zgłasza szczegółowo błędy odtwarzacza zamiast pokazywać krótkotrwałą wiadomość toast (przydatne do diagnozowania problemów)
\ No newline at end of file
diff --git a/app/src/main/res/values-pt-rBR/strings.xml b/app/src/main/res/values-pt-rBR/strings.xml
index 1f53db3ce..434993d2b 100644
--- a/app/src/main/res/values-pt-rBR/strings.xml
+++ b/app/src/main/res/values-pt-rBR/strings.xml
@@ -1,7 +1,7 @@
Áudio
- Não foi possível decodificar assinatura do URL do vídeo
+ Não foi possível decodificar assinatura da URL do vídeo
Seu comentário (em inglês):
O que ocorreu:
Informação:
@@ -11,8 +11,8 @@
Checksum
Conteúdo
Conteúdo indisponível
- As miniaturas não puderam ser carregadas
- Noturno
+ Não foi possível carregar todas as miniaturas
+ Escuro
Formato de áudio padrão
Resolução padrão
Excluir
@@ -28,13 +28,13 @@
OK
Erro
Instalar
- Diurno
+ Claro
Erro
Copiado para a área de transferência
Nome do arquivo
Toque para detalhes
- NewPipe baixando
- Aguarde…
+ O NewPipe está baixando
+ Por favor, espere…
Erro de rede
Abrir no navegador
Pausar
@@ -69,25 +69,25 @@
Escolha a pasta de download para arquivos de vídeo
Vídeos baixados são salvos aqui
Pasta para vídeos baixados
- Instalar faltando o aplicativo Kore\?
+ Instalar o aplicativo Kore\?
Miniatura de visualização do vídeo
Toque na lupa para começar.
Threads
- Defina uma pasta de download depois nas configurações
+ Por favor, defina uma pasta de download depois nas configurações
Sem player de vídeo. Instalar VLC\?
O site não pôde ser analisado
Áudio
Reproduzir com Kodi
Pesquisar
- Mostra opção para ver vídeo via Kodi
+ Mostra uma opção para ver vídeo pelo media center do Kodi
Usar player de áudio externo
Usar player de vídeo externo
- Mostrar \"Reproduzir com Kodi\"
+ Mostrar opção \"Reproduzir com Kodi\"
Ocorrido:\\nPedido:\\nIdioma do conteúdo:\\nPaís do conteúdo:\\nIdioma do app:\\nServiço:\\nHora GMT:\\nPacote:\\nVersão:\\nVersão do Sistema Operacional:
Abrir no modo popup
Resolução padrão do popup
- Mostrar resoluções maiores
- Poucos dispositivos suportam vídeos em 2K/4K
+ Mostrar resoluções mais altas
+ Apenas alguns dispositivos suportam vídeos em 2K/4K
Formato de vídeo padrão
Reproduzindo em modo popup
Tudo
@@ -110,17 +110,17 @@
Licenças de Terceiros
Sobre
Licenças
- App leve e livre de transmissão no Android.
+ Stream leve e livre no Android.
Ver no GitHub
Licença do NewPipe
- Se você tem ideias de; tradução, mudança de design, limpeza de código ou grandes mudanças de código—ajuda é sempre bem-vinda. Quanto mais se faz, melhor fica!
+ Se você tem ideias de: tradução, mudança no design, limpeza de código ou grandes mudanças de código — ajuda é sempre bem-vinda. Quanto mais se faz, melhor fica!
Ler licença
Colaborar
© %1$s %2$s protegido pela licença %3$s
- Sobre NewPipe
+ Sobre o NewPipe
Baixar
Caracteres permitidos em nome de arquivos
- Caracteres inválidos são substituídos por este valor
+ Os caracteres inválidos são substituídos por este valor
Caractere de substituição
Letras e dígitos
Caracteres especiais
@@ -136,11 +136,11 @@
Histórico de pesquisa
Armazena histórico de pesquisa localmente
Histórico de vídeo
- Armazena histórico de vídeos
+ Armazena histórico de vídeos assistidos
Histórico
Histórico
Notificações do NewPipe
- Notificações para players popup e segundo plano do NewPipe
+ Notificações para players popup e em segundo plano do NewPipe
Comportamento
Histórico e cache
Desfazer
@@ -162,7 +162,7 @@
Player
Nada aqui além de grilos
- Excluir este item do histórico de busca\?
+ Deseja excluir este item do histórico de busca\?
Conteúdo da página inicial
Página em branco
Página do Quiosque
@@ -176,7 +176,7 @@
Mostrar dica \"Segure para pôr na fila\"
Mostra dica ao tocar no botão segundo plano ou popup em \"Detalhes:\" do vídeo
Reproduzir tudo
- Este vídeo não pôde ser reproduzido
+ Este stream não pôde ser reproduzido
Ocorreu um erro irrecuperável no player
Recuperando do erro do player
Remover
@@ -187,10 +187,10 @@
Reproduzir em segundo plano
Reproduzir em um popup
Doar
- NewPipe é desenvolvido por voluntários que usam seu tempo livre para trazer a melhor experiência para você. Retribua para ajudar os desenvolvedores a tornarem o NewPipe ainda melhor enquanto desfrutam uma xícara de café.
+ O NewPipe é desenvolvido por voluntários que usam seu tempo livre para trazer a você a melhor experiência de usuário. Retribua e ajude os desenvolvedores a tornarem o NewPipe ainda melhor enquanto eles desfrutam de uma xícara de café.
Retribuir
Site oficial
- Visite o site NewPipe para mais informações e novidades.
+ Visite o site do NewPipe para mais informações e novidades.
Sem player de vídeo (você pode instalar o VLC).
País padrão do conteúdo
Sempre
@@ -199,8 +199,8 @@
Mudar para popup
Mudar para principal
Players externos não suportam estes tipos de links
- Sem transmissões de vídeo
- Sem transmissões de áudio
+ Nenhum stream de vídeo encontrado
+ Nenhum stream de áudio encontrado
Player de vídeo
Player em segundo plano
Player popup
@@ -209,10 +209,10 @@
Importar base de dados
Exportar base de dados
Substitui seu histórico atual, inscrições, playlists e (opcionalmente) configurações
- Exporte histórico, inscrições, playlists e configurações
+ Exporta histórico, inscrições, playlists e configurações
Exportado
Importado
- Não há nenhum arquivo ZIP válido
+ Nenhum arquivo ZIP válido
Aviso: Não foi possível importar todos os arquivos.
Isso irá sobrescrever suas configurações atuais.
Baixar arquivo
@@ -226,35 +226,35 @@
Último reproduzido
Mais reproduzido
Sempre perguntar
- Nova playlist
+ Nova Playlist
Renomear
Nome
- Adicionar à Playlist
- Definir Como Capa da Playlist
+ Adicionar à playlist
+ Definir como miniatura da playlist
Favoritar playlist
- Desfavoritar
+ Remover dos favoritos
Excluir esta playlist\?
Playlist criada
Adicionado à playlist
- Capa da playlist alterada.
+ Miniatura da playlist alterada.
Sem legendas
Ajustar
Preencher
Zoom
Gerado automaticamente
- A monitoração de vazamento de memória pode tornar o app instável
- Reportar erros fora do ciclo de vida
- Força relatório de exceções Rx não entregues fora do ciclo de vida do fragmento ou atividade após o descarte
+ O monitoramento de vazamento de memória pode tornar o app instável durante o heap dumping
+ Reportar erros de out-of-lifecycle
+ Forçar entrega de relatórios de erros Rx fora de um fragmento ou atividade de lifecycle após o descarte
Usar busca de posição rápida (inexata)
- Busca inexata permite que o reprodutor ache posições mais rápido, reduzindo a precisão. Não funciona para voltar ou avançar 5, 15 ou 25 segundos
+ A busca inexata permite que o player ache posições mais rápido com a precisão reduzida. Não funciona para voltar ou avançar 5, 15 ou 25 segundos
Pôr próximo vídeo na fila automaticamente
- Continua fila (sem loop) anexando vídeos similares
+ Continua a reprodução da fila (sem repetição) adicionando mais vídeos similares
Arquivo
Pasta não existe
Arquivo/fonte do conteúdo não existe
O arquivo não existe ou não há permissão para leitura ou escrita
- O nome do arquivo não pode estar vazio
- Um erro ocorreu: %1$s
+ O nome do arquivo não pode ficar vazio
+ Ocorreu um erro: %1$s
Importar
Importar de
Exportar para
@@ -267,64 +267,64 @@
Importe inscrições do YouTube pelo Google takeout:
\n
\n1. Acesse este link: %1$s
-\n2. Logue quando solicitado
+\n2. Faça login quando solicitado
\n3. Clique em \"Todos os dados incluídos\", em seguida, em \"Desmarque todos\", em seguida, selecione apenas \"assinaturas\" e clique em \"OK\"
-\n4. Clique em \"Próximo passo\" e, em seguida, em \"Criar exportação\"
+\n4. Clique em \"Próximo passo\" e em seguida, em \"Criar exportação\"
\n5. Clique no botão \"Baixar\" quando ele aparecer
\n6. Clique em Importar Arquivo abaixo e selecione o arquivo zip baixado
\n7. Caso a importação do arquivo zip falhe: Extraia o arquivo .csv (normalmente em \"YouTube e YouTube Music/subscriptions/subscriptions.csv\", clique em Importar Arquivo abaixo e selecione o arquivo cvs extraído
Importe um perfil do SoundCloud digitando o URL ou seu ID:
\n
-\n1. Ative o \"modo desktop\" no navegador (o site está indisponível em celulares)
+\n1. Ative o \"modo desktop\" no navegador (o site não está disponível em aparelhos celulares)
\n2. Acesse este URL: %1$s
-\n3. Logue quando solicitado
-\n4. Copie o URL do perfil redirecionado.
+\n3. Faça login quando solicitado
+\n4. Copie o URL do perfil que voçê foi redirecionado.
seuID, soundcloud.com/seuid
- Tenha em mente que esta operação poderá usar bastante a conexão com a internet.
+ Tenha em mente que esta operação poderá consumir muitos dados.
\n
-\nVocê deseja continuar?
+\nVocê deseja continuar\?
Carregar miniaturas
Cache de imagens limpo
- Limpar metadados em cache
- Exclui todos os dados em cache de páginas
+ Limpar cache de metadados
+ Remove todos os dados de páginas em cache
Cache de metadados limpo
Controles de velocidade de reprodução
Ritmo
- Desative para não carregar miniaturas e economizar em uso de dados e memória. A alteração limpa todo o cache de imagens
+ Desative para não carregar miniaturas e economizar no uso de dados e memória. A alteração limpa todo o cache de imagens em memória e em disco
Altura
Desvincular (pode causar distorção)
Ação de \'abrir\' preferida
Ação padrão ao abrir conteúdo — %s
- Nenhum vídeo disponível para baixar
+ Nenhum stream disponível para baixar
Abrir gaveta
Fechar gaveta
Legendas
- Mudar tamanho da legenda e estilos de fundo. Requer reiniciar o app para ter efeito
- Sem app instalado para reproduzir este arquivo
+ Mudar tamanho da legenda e estilos de plano de fundo. Requer reiniciar o app para ter efeito
+ Nenhum app instalado para reproduzir este arquivo
Excluir histórico de vídeo
Exclui o histórico de vídeos e as posições de reprodução
Excluir todo o histórico de vídeo\?
- Histórico de vídeo limpo
+ Histórico de vídeos excluído
Excluir histórico de pesquisa
Exclui o histórico de pesquisas feitas
Excluir todo o histórico de pesquisa\?
Histórico de busca limpo
1 item excluído.
- NewPipe é um software livre copyleft: Pode usar, estudar, compartilhar e melhorar o app. Especificamente você pode redistribuir e/ou modificá-lo sob os termos da Licença Pública Geral GNU, publicada pela Fundação de Software Livre, versão 3 da Licença, ou (a seu critério) qualquer versão posterior.
+ NewPipe é um copyleft de software livre: Você pode usar, estudar, compartilhar e melhorar a seu gosto. Especificamente você pode redistribuir e/ou modificá-lo sob os termos da GNU General Public License como publicado pela Fundação de Software Livre, na versão 3 da Licença, ou (a seu critério) qualquer versão posterior.
Você também quer importar as configurações?
Política de privacidade do NewPipe
- O projeto NewPipe leva sua privacidade muito a sério. Por isso, o app não coleta dado algum sem sua permissão.
-\nA política de privacidade do NewPipe explica em detalhes os dados enviados e salvos ao enviar um relatório de erro.
+ O projeto NewPipe leva sua privacidade muito a sério. Por isso, o app não coleta nenhum dado sem seu consentimento.
+\nA política de privacidade do NewPipe explica em detalhes quais dados são envidados e salvos quando você manda um relatório de erro.
Ler a política de privacidade
- A fim de cumprir com o Regulamento Geral sobre a Proteção de Dados da UE (RGPD), chamamos sua atenção para a política de privacidade do NewPipe. Por favor, leia com atenção.
-\nDeve aceitá-la para nos enviar relatório de erro.
+ A fim de cumprir com o Regulamento Geral sobre a Proteção de Dados da UE (RGPD), chamamos sua atenção para a política de privacidade do NewPipe. Por favor, leia com atenção.
+\nVocê deve aceitá-la para nos enviar o relatório de erros.
Aceitar
Recusar
Ilimitado
- Limitar resolução em dados móveis
- Minimizar ao mudar app
- Ação ao mudar app no player principal — %s
- Nenhuma
+ Limitar a resolução quando estiver usando dados móveis
+ Minimizar ao trocar entre apps
+ Ação ao mudar para outro app a partir do player de vídeo principal — %s
+ Nenhum
Minimizar para segundo plano
Minimizar para player popup
Avanço rápido durante silêncio
@@ -340,7 +340,7 @@
Use gestos para mudar volume do player
Gesto para brilho
Use gestos para mudar brilho do player
- Depuração
+ Debug
Atualizações
Eventos
Arquivo excluído
@@ -356,46 +356,46 @@
Conferências
Atualizações
Notificar quando uma nova versão do app estiver disponível
- Modo de exibição da lista
+ Modo de exibição em lista
Lista
Grade
Automático
- Atualização do NewPipe está disponível!
+ Atualização do NewPipe disponível!
Toque para baixar
Finalizado
pausado
- Na fila
+ na fila
pós-processamento
Fila
Ação negada pelo sistema
- Erro ao baixar
+ O download falhou
Gerar nome único
Sobrescrever
Um arquivo baixado com esse nome já existe
- Existe um download em progresso com este nome
+ Já existe um download em progresso com este nome
Mostrar erro
O arquivo não pode ser criado
A pasta de destino não pode ser criada
Uma conexão segura não pôde ser estabelecida
O servidor não pôde ser encontrado
- Não foi possível conectar ao servidor
+ Não foi possível se conectar ao servidor
O servidor não envia dados
- O servidor não aceita downloads em multi-thread, tente com @string/msg_threads = 1
+ O servidor não aceita downloads em multi-thread, tente de novo com @string/msg_threads = 1
Não encontrado
- Falha no pós processamento
+ Falha no pós-processamento
Parar
- Tentativas Máximas
+ Número máximo de tentativas
Número máximo de tentativas antes de cancelar o download
- Pausar quando trocar para dados móveis
+ Interromper quando estiver usando dados móveis
Útil ao mudar para dados móveis, mas alguns downloads podem não ser suspensos
Pendente
Mostrar comentários
Desative para ocultar comentários
- Reprodução Automática
+ Reprodução automática
Sem comentários
Não foi possível carregar os comentários
Fechar
- Retomar reprodução
+ Continuar reprodução
Restaura última posição da reprodução
Posições em listas
Mostra indicadores de posição de reprodução em listas
@@ -403,24 +403,24 @@
Posições de reprodução limpas
Arquivo movido ou excluído
Já existe um arquivo com este nome
- O arquivo não pôde ser sobrescrito
- Existe um download pendente com este nome
- NewPipe foi fechado enquanto manipulava o arquivo
+ O arquivo não pode ser sobrescrito
+ Já existe um download pendente com este nome
+ O NewPipe foi fechado enquanto manipulava o arquivo
Sem espaço disponível
- Progresso perdido pois o arquivo foi excluído
+ O progresso foi perdido pois o arquivo foi excluído
Tempo limite de conexão
Excluir todo o histórico de downloads ou excluir todos os arquivos baixados\?
- Limitar fila de download
+ Limitar fila de downloads
Um download será feito ao mesmo tempo
Iniciar downloads
Pausar downloads
Perguntar onde salvar o arquivo
- Será questionado onde salvar cada download.
-\nAtive o seletor de pasta do sistema (SAF) se você quiser fazer o download para um cartão SD externo
- Usar selecionador de pasta do sistema (SAF)
- O \'Storage Access Framework\' permite baixar para um cartão SD externo
+ Você será questionado onde salvar cada download.
+\nAtive o seletor de pasta do sistema (SAF) se você quiser baixar em um cartão SD externo
+ Usar o seletor de pastas do sistema (SAF)
+ O \'Storage Access Framework\' permite baixar em um cartão SD externo
Excluir posição das reproduções
- Exclui toda as posições de reprodução
+ Exclui todas as posições de reprodução
Excluir todas as posições de reprodução\?
Alternar serviço, selecionados:
Quiosque Padrão
@@ -434,36 +434,36 @@
- %s ouvinte
- %s ouvintes
- O idioma atualizará ao reiniciar o app
- Duração do retrocesso/avanço rápido
- Instâncias PeerTube
- Escolha suas instâncias PeerTube favoritas
+ O idioma será alterado após reiniciar o app
+ Duração do salto para avançar/retroceder
+ Instâncias do PeerTube
+ Escolha suas instâncias do PeerTube favoritas
Procure instâncias que gosta em %s
Adicionar instância
Insira o link da instância
Erro ao validar a instância
Apenas links HTTPS são suportados
- Instância já existe
+ A instância já existe
Local
Recentes
Mais curtidos
- Autogerado (sem uploader encontrado)
+ Gerado automaticamente (nenhum uploader encontrado)
recuperando
O download não pôde ser recuperado
Escolha uma instância
Limpar histórico de downloads
Excluir arquivos baixados
- Permitir exibição sobre outros apps
+ Dar permissão para mostrar por cima de outros apps
Idioma do app
Padrão do sistema
- Toque em \"Feito\" ao resolver
- Feito
+ Toque em \"Pronto\" ao resolver
+ Pronto
Vídeos
- %d segundo
- %d segundos
- Devido aos limites do ExoPlayer a duração do avanço foi definida para %d segundos
+ Devido a limitações do ExoPlayer, a duração do avanço foi definida para %d segundos
Desativar som
Ativar som
Ajuda
@@ -485,7 +485,7 @@
Carregando feed…
Processando feed…
Selecionar inscrições
- Sem inscrições selecionadas
+ Nenhuma inscrição selecionada
- %d selecionada
- %d selecionadas
@@ -494,27 +494,27 @@
Excluir este grupo\?
Novo
Feed
- Limiar de atualização do feed
- Período para que uma inscrição seja considerada desatualizada — %s
- Atualizar sempre
- Buscar do feed dedicado, se disponível
- Disponível em alguns serviços, é mais rápido,mas pode devolver informações limitadas ou incompletas (ex. sem duração, tipo de item, ou status ativo)
+ Limite de atualização do feed
+ Tempo após a última atualização antes que uma inscrição seja considerada desatualizada — %s
+ Sempre atualizar
+ Buscar do feed dedicado quando disponível
+ Disponível em alguns serviços, geralmente é muito mais rápido mas pode retornar um número limitado de itens e geralmente informações incompletas (por exemplo sem duração, tipo de item, sem status em tempo real)
Ativar modo rápido
Desativar modo rápido
- Acha o carregamento do feed lento\? Se sim, tente ativar o modo rápido (pode mudar nas configurações ou tocando no botão abaixo).
-\n
-\nNewPipe oferece duas estratégias para carregar o feed:
-\n• Obter todo o canal inscrito, lento mas completo.
-\n• Usar um endpoint de serviço dedicado, rápido mas geralmente incompleto.
-\n
-\nA diferença entre os dois é que o rápido geralmente falta alguma informação como a duração ou tipo do item (não pode distinguir entre vídeo normal e ao vivo) e pode mostrar menos itens.
-\n
-\nYouTube é um exemplo de serviço que oferece o modo rápido com seu feed RSS.
-\n
-\nAssim, a escolha se resume ao que prefere: Velocidade ou informação precisa.
- NewPipe ainda não suporta esse conteúdo.
+ Acha o carregamento do feed muito lento\? Se sim, tente ativar o modo de carregamento rápido (você pode mudar em configurações ou tocando no botão abaixo).
\n
-\nO suporte pode aparecer em uma versão futura.
+\nO NewPipe oferece duas estratégias para carregar o feed:
+\n• Buscar todo o conteúdo do canal inscrito, que é lento mas completo.
+\n• Usar um endpoint de serviço dedicado, que é rápido mas geralmente incompleto.
+\n
+\nA diferença entre os dois é que o rápido geralmente falta alguma informação, como a duração ou tipo do item (não consegue distinguir entre as lives e os vídeos normais) e pode retornar menos itens.
+\n
+\nO YouTube é um exemplo de serviço que oferece o modo rápido com seu feed RSS.
+\n
+\nAssim, a escolha se resume ao que você prefere: rapidez ou informação precisa.
+ O NewPipe ainda não suporta esse conteúdo.
+\n
+\nEsperamos que terá suporte em uma versão futura.
∞ vídeos
+100 vídeos
Artistas
@@ -524,8 +524,8 @@
\n
\nAtive \"%1$s\" nas configurações se quiser vê-lo.
Sim, e vídeos parcialmente vistos
- Vídeos vistos antes e depois de adicionar à playlists serão removidos.
-\nTem certeza\? Isto não pode ser desfeito!
+ Os vídeos que foram vistos antes e depois de terem sidos adicionados à playlist serão removidos.
+\nTem certeza\? Esta ação não pode ser desfeita!
Remover vídeos vistos\?
Remover vistos
Textos originais dos serviços serão visíveis nos itens de transmissão
@@ -533,13 +533,13 @@
Ativar o \"Modo Restrito\" do YouTube
Por %s
Criado por %s
- Capa do avatar do canal
+ Miniatura do avatar do canal
Mostrar apenas inscrições não agrupadas
Mostrando resultados para: %s
- Ainda não há favoritos de playlists
- Página da playlist
+ Ainda não há playlists favoritas
+ Página de playlist
Selecione uma playlist
- Verifique se já existe um assunto discutindo essa falha. Criar duplicatas tirará um tempo que poderíamos gastar corrigindo o bug real.
+ Por favor verifique se uma issue discutindo este problema já existe. Ao criar tickets duplicados, você tira de nós um tempo no qual poderíamos estar usando para corrigir um bug real.
Reporte no GitHub
Copiar relatório formatado
Nunca
@@ -550,21 +550,21 @@
Pôr na fila automaticamente
A fila do player ativo será substituída
Mudar de um player para outro pode substituir sua fila
- Solicitar confirmação antes de limpar uma fila
+ Pedir confirmação antes de limpar uma fila
Aleatório
Carregando
Notificação
Nada
Repetir
- Selecione no máximo três botões para a notificação compacta!
- Edite os botões de ação da notificação compacta aqui. Selecione até três deles usando as caixas de seleção à direita e toque neles para configurá-los
+ Você pode selecionar até no máximo três botões para mostrar na notificação compacta!
+ Edite os botões de ação de notificação abaixo tocando em cada um. Selecione até três deles para serem mostrados na notificação compacta usando as caixas de seleção à direita
Quinto botão de ação
Quarto botão de ação
Terceiro botão de ação
Segundo botão de ação
Primeiro botão de ação
- Dimensione a miniatura do vídeo mostrada na notificação da proporção 16:9 para 1:1 (pode apresentar distorções)
- Dimensione a miniatura para a proporção de 1:1
+ Dimensionar a miniatura do vídeo mostrada na notificação da proporção 16:9 para 1:1 (pode apresentar distorções)
+ Dimensionar a miniatura para a proporção de 1:1
Mostrar vazamentos de memória
Na fila
Pôr na fila
@@ -572,20 +572,20 @@
Apagar cookies de reCAPTCHA
Os cookies de reCAPTCHA foram apagados
O YouTube oferece um \"Modo Restrito\" que oculta conteúdo potencialmente adulto
- Mostrar conteúdo possivelmente inadequado para crianças que tem um limite de idade (como +18)
- Permite que o Android personalize a cor da notificação de acordo com a cor principal da miniatura (nem todos os dispositivos suportam)
+ Mostra conteúdo possivelmente inadequado para crianças pois tem restrição de idade (como +18)
+ Permite que o Android personalize a cor da notificação de acordo com a cor principal da miniatura (isso não está disponível em todos os dispositivos)
Colorir notificação
- Usar miniatura para o plano de fundo da tela de bloqueio e as notificações
+ Usar miniatura para o plano de fundo da tela de bloqueio e notificações
Mostrar miniatura
Calculando hash
Notificações para o progresso do hash do vídeo
Notificação de Hash do Vídeo
- Desative para ocultar as caixas de informações meta com informações adicionais sobre o criador, conteúdo do stream ou uma solicitação de pesquisa
- Mostrar informação meta
+ Desative para ocultar as caixas de informações de metadados com informações adicionais sobre o criador, conteúdo do stream ou uma solicitação de pesquisa
+ Mostrar informação de metadados
Recentes
Capítulos
Descrição
- Transmissões relacionadas
+ Ítens relacionados
Comentários
Desative para ocultar a descrição do vídeo e informações adicionais
Mostrar descrição
@@ -593,12 +593,12 @@
Nenhum aplicativo em seu dispositivo pode abrir isso
O aplicativo parou
Este conteúdo está disponível apenas para usuários que pagaram, portanto não pode ser transmitido ou baixado pelo NewPipe.
- Este vídeo está disponível apenas para assinantes do YouTube Music Premium, portanto, não pode ser transmitido ou baixado por NewPipe.
+ Este vídeo está disponível apenas para assinantes do YouTube Music Premium, portanto não pode ser transmitido ou baixado por NewPipe.
Este conteúdo é privado, portanto não pode ser transmitido ou baixado pelo NewPipe.
- Esta é uma faixa do SoundCloud Go +, pelo menos no seu país, portanto não pode ser transmitida ou baixada pelo NewPipe.
+ Esta é uma faixa do SoundCloud Go+, pelo menos no seu país, portanto não pode ser transmitida ou baixada pelo NewPipe.
Este conteúdo não está disponível em seu país.
Este vídeo tem restrição de idade.
-\nDevido às novas políticas do YouTube sobre vídeos com restrição de idade, NewPipe não pode acessar nenhum vídeo do stream e, portanto, não pode reproduzi-lo.
+\nDevido às novas políticas do YouTube sobre vídeos com restrição de idade, o NewPipe não pode acessar nenhuma de suas streams de vídeo e assim ele não pode ser exibido.
Rádio
Destaque
Resolvido
@@ -608,8 +608,8 @@
Automático (tema do dispositivo)
Tema Noturno
Mostrar detalhes do canal
- Desative o túnel de mídia se você tiver uma tela preta ou a reprodução do vídeo estiver engasgando
- Desativar túnel de mídia
+ Desative o tunelamento de mídia se aparecer uma tela preta ou se tiver engasgos durante a reprodução do vídeo
+ Desativar tunelamento de mídia
Interno
Privado
Não Listado
@@ -625,19 +625,19 @@
Categoria
Desativar seleção de texto na descrição
Ativar seleção de texto na descrição
- Agora você pode selecionar o texto dentro da descrição. Observe que a página pode piscar e os links podem não ser clicáveis no modo de seleção.
+ Agora você pode selecionar o texto dentro da descrição. Note que a página pode piscar e os links podem não ser clicáveis no modo de seleção.
Abrir site
%s fornece este motivo:
Conta encerrada
O modo feed rápido não fornece mais informações sobre isso.
A conta do autor foi encerrada.
\nNewPipe não poderá carregar este feed no futuro.
-\nQuer cancelar a inscrição neste canal\?
+\nDeseja cancelar a inscrição neste canal\?
Não foi possível carregar o feed para \'%s\'.
- Erro ao carregar feed
- A partir do Android 10, apenas o \'Storage Access Framework\' é compatível
+ Erro ao carregar o feed
+ O \'Storage Access Framework\' é compatível apenas com versões a partir do Android 10
O \'Storage Access Framework\' não é compatível com Android KitKat e versões anteriores
- Você será questionado sobre onde salvar cada download
+ Você será questionado onde salvar cada download
Nenhuma pasta de download definida ainda, escolha a pasta de download padrão agora
Desligado
Ligado
@@ -650,7 +650,7 @@
Comentários estão desabilitados
Marcar como visto
Curtido pelo criador
- Exibir fitas coloridas de picasso no topo das imagens indicando sua fonte: vermelho para rede, azul para disco e verde para memória
+ Exibir fitas coloridas de Picasso no topo das imagens indicando sua fonte: vermelho para rede, azul para disco e verde para memória
Carregando detalhes do canal…
Erro ao exibir detalhes do canal
@@ -658,15 +658,25 @@
- %1$s downloads apagados
- - Download finalizado
- - %s downloads finalizados
+ - Download concluído
+ - %s downloads concluídos
Exibir indicadores com imagem
Adicionado na próxima posição da fila
Adicionar a próxima posição da fila
Deslize items para remove-los
- Não iniciar o reprodutor pequeno, mas sim iniciar no modo tela cheia, caso rotação automática estiver bloqueada. Você pode ainda acessar o reprodutor pequeno saindo do modo tela cheia
- Iniciar o reprodutor principal em tela cheia
+ Não inicia os vídeos no player reduzido, mas muda direto para o modo de tela cheia, se a rotação automatica estiver travada. Você ainda consegue acessar o player reduzido saindo da tela cheia
+ Iniciar o player principal em tela cheia
Sugestões de busca remotas
Sugestões de busca locais
+ Processando… Pode demorar um pouco
+ Procurar por atualizações
+ Procurar manualmente por novas versões
+ Procurando por atualizações…
+ Travar o player
+ Reporta os erros do player em detalhes completos, em vez de mostrar uma mensagem de notificação de curta duração (útil para diagnosticar problemas)
+ Mostrar \"travar o player\"
+ Reportar erros do player
+ Mostra uma opção de travamento ao usar o player
+ Novos itens do feed
\ No newline at end of file
diff --git a/app/src/main/res/values-pt-rPT/strings.xml b/app/src/main/res/values-pt-rPT/strings.xml
index ad4bb5061..446c79486 100644
--- a/app/src/main/res/values-pt-rPT/strings.xml
+++ b/app/src/main/res/values-pt-rPT/strings.xml
@@ -351,7 +351,7 @@
- %d hora
- %d horas
- Colocar vídeo seguinte na fila
+ Enfileirar o próximo stream automaticamente
Defina as suas instâncias favoritas PeerTube
Exportar histórico, subscrições, listas de reprodução e definições
Melhor resolução
@@ -468,7 +468,7 @@
Selecionar subscrições
Adicionado à lista de reprodução
Formato padrão de vídeo
- Mostrar dica \"Toque longo para colocar na fila\"
+ Mostrar dica \"Toque longo para enfileirar\"
Escolha uma instância
Limpar todos os dados da página web
Fechar menu
@@ -504,7 +504,7 @@
Utilizar pesquisa rápida
Está prestes a substituir a configuração atual.
Mudar para popup
- Adicionar à lista de reprodução
+ Adicionar à lista de reprodução
Reproduzir no modo poppup
Acha que a fonte demora muito tempo a carregar\? Se sim, tente ativar o carregamento rápido (pode alterar a opção nas definições ou no botão abaixo).
\n
@@ -547,7 +547,7 @@
Reproduzir fila
Notificação
URL não reconhecido. Abrir com outra aplicação\?
- Colocar na fila automaticamente
+ Enfileiramento automático
A fila do reprodutor ativo será substituída
Mudar de um reprodutor para outro pode substituir a sua fila
Pedir confirmação antes de limpar uma fila
@@ -642,12 +642,12 @@
Erro ao carregar o feed
A partir do Android 10, apenas o \'Storage Access Framework\' é compatível
\'Storage Access Framework\' não é compatível com Android KitKat e versões anteriores
- Sempre que transferir um ficheiro, terá que indicar o local para o guardar
+ Sempre que descarregar um ficheiro, terá que indicar o local para o guardar
Não mostrar
Baixa qualidade (menor)
Alta qualidade (maior)
Pré-visualização da miniatura da barra de pesquisa
- Ainda sem pasta de descarregas definida, escolha agora a pasta de descarregas padrão
+ Ainda não foi definida uma pasta de descarregamento, escolha agora a pasta de descarregamento padrão
Comentários estão desativados
Marcar como visto
A carregar detalhes do canal…
@@ -669,4 +669,14 @@
Iniciar reprodutor principal em ecrã completo
Enfileirado o próximo
Enfileirar o próximo
+ A processar… Pode demorar um momento
+ Procurar atualizações
+ Verificar manualmente se existe uma nova versão
+ A procurar atualizações…
+ Novos itens
+ Travar o reprodutor
+ Relata os erros do reprodutor com todos os detalhes em vez de mostrar uma mensagem de notificação por pouco tempo (útil para diagnosticar problemas)
+ Relatar erros do reprodutor
+ Mostrar \"travar o reprodutor\"
+ Mostra uma opção de travamento ao usar o reprodutor
\ No newline at end of file
diff --git a/app/src/main/res/values-pt/strings.xml b/app/src/main/res/values-pt/strings.xml
index 7b8cd4cdc..9e36e1928 100644
--- a/app/src/main/res/values-pt/strings.xml
+++ b/app/src/main/res/values-pt/strings.xml
@@ -1,7 +1,7 @@
Publicado em %1$s
- Não tem um reprodutor de vídeo. Instalar VLC\?
+ Não tem um reprodutor de vídeo. Instalar o VLC\?
Instalar
Cancelar
Abrir no navegador
@@ -198,7 +198,7 @@
Criar
Mudar nome
Doar
- Não foi encontrado um reprodutor (pode instalar VLC para reproduzir).
+ Não foi encontrado um reprodutor (pode instalar o VLC para reproduzir).
Descarregar ficheiro de vídeo
Adicionar a
Utilizar pesquisa rápida
@@ -242,7 +242,7 @@
A carregar o conteúdo solicitado
Nova lista de reprodução
Mudar nome
- Adicionar à lista de reprodução
+ Adicionar à lista de reprodução
Guardar lista de reprodução como favorita
Remover marcador
Eliminar esta lista de reprodução\?
@@ -282,7 +282,7 @@
Ritmo
Limpar histórico de visualizações
Continuar (sem repetição) a fila de reprodução anexando um vídeo relacionado
- Mostrar dica \"Toque longo para colocar na fila\"
+ Mostrar dica \"Toque longo para enfileirar\"
Mostrar dica ao premir em segundo plano ou no botão \"Detalhes:\" da janela popup
Canais
Listas de reprodução
@@ -303,7 +303,7 @@
O projeto NewPipe leva a sua privacidade muito a sério. Por isso, não recolhe nenhum dado sem o seu consentimento.
\nA polícia de privacidade do NewPipe explica, em detalhe, os tipos de dados enviados sempre que submete um relatório de erro.
Ver política de privacidade
- Colocar vídeo seguinte na fila
+ Enfileirar o próximo stream automaticamente
NewPipe é um software livre \"copyleft\": pode utilizar, estudar, partilhar e melhorar a aplicação. Especificamente, pode redistribuir e/ou modificar a aplicação nos termos da GNU General Public License, conforme publicada pela Free Software Foundation, tanto a versão 3 da licença ou (por opção) qualquer versão posterior.
Também deseja importar as definições\?
Toque longo para colocar na fila
@@ -554,7 +554,7 @@
A carregar
A fila do reprodutor ativo será substituída
URL não reconhecido. Abrir com outra aplicação\?
- Colocar na fila automaticamente
+ Enfileiramento automático
Baralhar
Notificação
Apenas em Wi-Fi
@@ -610,8 +610,8 @@
Mostrar detalhes do canal
Desative esta opção se estiverem a ocorrer erros de ecrã escuro ou paragens durante a reprodução
Desativar túnel multimédia
- Sempre que transferir um ficheiro, terá que indicar o local para o guardar
- Ainda sem pasta de descarregas definida, escolha agora a pasta de descarregas padrão
+ Sempre que descarregar um ficheiro, terá que indicar o local para o guardar
+ Ainda não foi definida uma pasta de descarregamento, escolha agora a pasta de descarregamento padrão
%s fornece este motivo:
Conta encerrada
Mostrar itens vistos
@@ -622,7 +622,7 @@
Não foi possível carregar o feed para \'%s\'.
Erro ao carregar o feed
A partir do Android 10, apenas o \'Storage Access Framework\' é compatível
- \'Storage Access Framework\' não é compatível com Android KitKat e versões anteriores
+ A \'Framework de acesso ao armazenamento\' não está disponível no Android KitKat e anteriores
Pré-visualização da miniatura da barra de pesquisa
Marcar como visto
Desligado
@@ -669,4 +669,14 @@
Iniciar reprodutor principal em ecrã completo
Enfileirado o próximo
Enfileirar o próximo
+ A processar… Pode demorar um momento
+ Procurar atualizações
+ Verificar manualmente se existe uma nova versão
+ A procurar atualizações…
+ Novos itens
+ Travar o reprodutor
+ Relata os erros do reprodutor com todos os detalhes em vez de mostrar uma mensagem de notificação por pouco tempo (útil para diagnosticar problemas)
+ Relatar erros do reprodutor
+ Mostrar \"travar o reprodutor\"
+ Mostra uma opção de travamento ao usar o reprodutor
\ No newline at end of file
diff --git a/app/src/main/res/values-ro/strings.xml b/app/src/main/res/values-ro/strings.xml
index c1a8e784f..83f2a2a78 100644
--- a/app/src/main/res/values-ro/strings.xml
+++ b/app/src/main/res/values-ro/strings.xml
@@ -94,7 +94,7 @@
Da
Dezactivat
Aplicația/UI s-a oprit
- Ce:\\nSolicitare:\\nLimba conținutului:\\nȚara conținutului:\\nLimba aplicației:\\nServiciu:\\nOra GMT:\\nPachet:\\nVersiune: \\nVersiune OS:
+ Ce:\\nSolicitare:\\nLimba conținutului:\\nȚara conținutului:\\nLimba aplicației:\\nServiciu:\\nOra GMT:\\nPachet:\\nVersiune: \\nVersiune SO:
k
mil.
mld.
@@ -266,7 +266,7 @@
Ștergeți întregul istoric al vizionărilor\?
1 element șters.
Playlist nou
- Adăugați la playlist
+ Adăugați la playlist
Importare
Importați din
Exportați în
@@ -371,7 +371,7 @@
Faceți ca Android să personalizeze culoarea notificării în funcție de culoarea principală din miniatură (rețineți că aceasta nu este disponibilă pe toate dispozitivele)
Colorează notificarea
Nimic
- Buffering
+ Tamponare
Redare aleatorie
Repetaţi
Puteți selecta cel mult trei acțiuni pentru afișare în notificarea compactă!
@@ -681,4 +681,5 @@
Afișați panglici colorate de Picasso deasupra imaginilor, indicând sursa acestora: roșu pentru rețea, albastru pentru disc și verde pentru memorie
Afișați indicatorii de imagine
Dezactivați tunelarea media dacă întâmpinați un ecran negru sau blocaje la redarea video
+ Procesarea.. Poate dura un moment
\ No newline at end of file
diff --git a/app/src/main/res/values-ru/strings.xml b/app/src/main/res/values-ru/strings.xml
index f895cea27..4710777f9 100644
--- a/app/src/main/res/values-ru/strings.xml
+++ b/app/src/main/res/values-ru/strings.xml
@@ -113,9 +113,9 @@
Сторонние лицензии
О приложении
Прочитать лицензию
- Свободное и легковесное потоковое воспроизведение для Android.
+ Свободный и легковесный потоковый плеер для Android.
Открыть на GitHub
- Приветствуется всё — идеи, перевод, изменения дизайна, чистка кода или огромные изменения в коде. Чем больше сделано, тем лучше!
+ Приветствуется всё — идеи, перевод, редизайн, чистка кода или огромные изменения в коде. Чем больше сделано, тем лучше!
© %1$s • %2$s • %3$s
Помощь проекту
Подписаться
@@ -251,7 +251,7 @@
Новый плейлист
Переименовать
Имя
- В плейлист
+ В плейлист
На миниатюру плейлиста
Сохранить плейлист
Удалить плейлист
@@ -324,7 +324,7 @@
Хотите импортировать настройки?
Конфиденциальность
Проект NewPipe очень серьёзно относится к вашей конфиденциальности. Приложение не собирает никаких данных без вашего согласия.
-\nПолитика конфиденциальности NewPipe подробно объясняет, какие данные обрабатываются и хранятся при отправке отчёта о сбоях.
+\nПолитика конфиденциальности подробно объясняет, какие данные обрабатываются и хранятся при отправке отчёта о сбоях.
Прочитать политику
В соответствии с Общим регламентом по защите данных ЕС (GDPR), обращаем ваше внимание на политику конфиденциальности NewPipe. Пожалуйста, внимательно ознакомьтесь с ней.
\nВам необходимо принять её условия, чтобы отправить нам отчёт об ошибке.
@@ -548,7 +548,7 @@
Миниатюра значка канала
Только несгруппированные
Плейлистов ещё нет
- Проверьте, не зарегистрирована ли уже проблема по вашей ошибке. Дубликаты впустую тратят наше время, отвлекая от реальных задач.
+ Проверьте, не открыта ли уже проблема по этой ошибке. Дубликаты впустую тратят наше время, отвлекая от реальных задач.
Результаты для: %s
Страница плейлиста
Выберите плейлист
@@ -680,9 +680,19 @@
- %s загрузок завершено
- %s загрузок завершено
- Удалять элементы смахиванием
+ Удаление элементов — смахиванием
Запускать видео во весь экран, если отключён автоповорот. Мини-плеер доступен при выходе из полноэкранного режима
Начинать просмотр в полноэкранном режиме
Добавлено следующим
Добавить следующим
+ Обработка… Подождите немного
+ Проверить обновления вручную
+ Проверить обновления
+ Проверка обновлений…
+ Новое на канале
+ Отчёт об ошибках плеера
+ Подробные отчёты об ошибках плеера вместо коротких всплывающих сообщений (полезно при диагностике проблем)
+ Показать \"Вызвать сбой плеера\"
+ Показать функцию вызова сбоя при работе плеера
+ Вызвать сбой плеера
\ No newline at end of file
diff --git a/app/src/main/res/values-sc/strings.xml b/app/src/main/res/values-sc/strings.xml
index 95ba064a5..daecc4f6c 100644
--- a/app/src/main/res/values-sc/strings.xml
+++ b/app/src/main/res/values-sc/strings.xml
@@ -39,7 +39,7 @@
Imposta che a miniadura de s\'iscalita
Allughe su sonu
Pone a sa muda
- Annanghe a s\'iscalita
+ Annanghe a s\'iscalita
Nùmene
Càmbia de nùmene
Iscalita noa
@@ -669,4 +669,8 @@
Allughe su letore printzipale a ischermu intreu
Postu in lista comente imbeniente
Pone in lista comente imbeniente
+ Protzessende… Bi diat pòdere chèrrere unu pagu de tempus
+ Chirca agiornamentos
+ Verìfica in manera manuale pro versiones noas
+ Controllende sos agiornamentos…
\ No newline at end of file
diff --git a/app/src/main/res/values-sk/strings.xml b/app/src/main/res/values-sk/strings.xml
index 82655d4ad..4d0f904ba 100644
--- a/app/src/main/res/values-sk/strings.xml
+++ b/app/src/main/res/values-sk/strings.xml
@@ -234,7 +234,7 @@
Nový zoznam skladieb
Premenovať
Názov
- Pridať do zoznamu skladieb
+ Pridať do zoznamu skladieb
Nastaviť ako miniatúru zoznamu skladieb
Záložka zoznamu skladieb
Odstrániť Záložku
@@ -290,7 +290,7 @@
\n4. Kliknite na \"Ďaľší krok\" a potom na \"Vytvoriť export\"
\n5. Po chvíli sa objaví tlačidlo s nápisom \"Stiahnuť\"
\n6. Kliknite na IMPORT ZO SÚBORU a zvoľte stiahnutý zip súbor
-\n7. Ak import zip súbory zlyhá. Stiahnutý súbor otvorte a extraktujte .csv súbor (nachádza sa v \"/Takeout/YouTube a YouTube Music/odbery/\"). Tento súbor importujte do NewPipe.
+\n7. Ak import zip súbory zlyhá. Stiahnutý súbor otvorte a extraktujte .csv súbor (nachádza sa v \"/Takeout/YouTube a YouTube Music/odbery/\"), tento súbor importujte do NewPipe
Importovať SoundCloud profil zadaním URL adresy alebo vášho ID:
\n
\n1. Prepnite režim na \"desktop\" (web nie je dostupný pre mobilné zariadenia)
@@ -421,7 +421,7 @@
Pri každom sťahovaní súboru sa bude vyžadovať zadanie cieľového adresára.
\nAk chcete súbory sťahovať na externú SD kartu povoľte možnosť výberu adresára (SAF)
Použite výber adresára (SAF)
- \'Storage Access Framework\' umožňuje sťahovanie na externú SD kartu.
+ \"Storage Access Framework\" umožňuje sťahovanie na externú SD kartu
Odstrániť pozície prehrávania
Odstráni všetky pozície prehrávania
Odstrániť všetky pozície prehrávania\?
@@ -648,7 +648,7 @@
\'Storage Access Framework\' je podporovaný len od Androidu 10 a vyššie
\'Storage Access Framework\' nie je podporovaný v systéme Android KitKat a ani v starších verziách
Pri každom sťahovaní sa zobrazí výzva kam uložiť súbor
- Nie je nastavený adresár na sťahovanie. Nastavte ho teraz.
+ Nie je nastavený adresár na sťahovanie, nastavte ho teraz
Označiť ako pozorované
Načítavanie podrobností o kanáli…
Chyba pri zobrazení podrobností kanála
@@ -679,4 +679,11 @@
Hlavný prehrávač na celej obrazovke
Návrhy vzdialeného vyhľadávania
Miestne návrhy vyhľadávania
+ Pridať do zoznamu
+ Ďaľší v poradí
+ Spracovávanie... môže to chvíľku trvať
+ Skontrolovať aktualizácie
+ Ručne skontrolovať nové verzie
+ Kontrolujú sa aktualizácie…
+ Nové položky informačného kanála
\ No newline at end of file
diff --git a/app/src/main/res/values-sl/strings.xml b/app/src/main/res/values-sl/strings.xml
index c6be5581b..dbfef543d 100644
--- a/app/src/main/res/values-sl/strings.xml
+++ b/app/src/main/res/values-sl/strings.xml
@@ -247,7 +247,7 @@
Napolni
Seznam predvajanja je bil ustvarjen
Izbrišem seznam predvajanja\?
- Dodaj v seznam predvajanja
+ Dodaj v seznam predvajanja
Preimenuj
Nov seznam predvajanja
Nalaganje zahtevano vsebino
diff --git a/app/src/main/res/values-so/strings.xml b/app/src/main/res/values-so/strings.xml
index 5455d728b..bf9e7a768 100644
--- a/app/src/main/res/values-so/strings.xml
+++ b/app/src/main/res/values-so/strings.xml
@@ -115,7 +115,7 @@
Calaamadso Xulka
Ku fadhiisi galka xulka
Ka hadalsii
- Ku dar xul
+ Ku dar xul
Magaca ka baddal
Xul Cusub
Soo kicinaya shayga la codsaday
diff --git a/app/src/main/res/values-sq/strings.xml b/app/src/main/res/values-sq/strings.xml
index f9d2e8cfd..10ab40e69 100644
--- a/app/src/main/res/values-sq/strings.xml
+++ b/app/src/main/res/values-sq/strings.xml
@@ -183,7 +183,7 @@
Vendose si pamjen statike të listës së luajtjes
Me zë
Pa zë
- Shto në listën e luajtjes
+ Shto në listën e luajtjes
Emri
Riemërto
Listë Luajtje e Re
diff --git a/app/src/main/res/values-sr/strings.xml b/app/src/main/res/values-sr/strings.xml
index 628f2a100..66258db25 100644
--- a/app/src/main/res/values-sr/strings.xml
+++ b/app/src/main/res/values-sr/strings.xml
@@ -194,7 +194,7 @@
Увек
Само једном
[непознато]
- Прикажи поруку „задржи ради стављања у ред”
+ Прикажи поруку „задржи ради заказивања”
Донација
ЊуПајп развијају волонтери у своје слободно време како би вам пружили најбоље искуство. Узвратите им како би наставили са побољшавањем ЊуПајпа док уживају уз шољицу кафе.
Узврати
@@ -350,7 +350,7 @@
Постави као сличицу листе
Упали звук
Утишај
- Додај на листу
+ Додај на листу
Назив
Преименуј
Нова листа
@@ -507,9 +507,9 @@
Контрола осветљености потезом
Користите потезе за контролу јачине звука плејера
Контрола јачине звука потезом
- Аутоматски ред
+ Самостално заказивање
Наставите да завршавате (не понављајући) ред репродукције додавањем повезаног стрима
- Аутоматски стави у ред следећи ток
+ Самостално закажи следећи ток
Кеш метаподатака обрисан
Искључите за сакривање поља мета-података са додатним информацијама о творцу тока, садржају или захтеву за претрагу
Прикажи мета-податке
@@ -652,4 +652,15 @@
укљ
Режим таблета
Прикажи пуштано
+ Закажи следеће
+ Заказано је следеће
+ Местни предлози претраге
+ Удаљени предлози претраге
+ Означи као одгледано
+ Разговори су онемогућени
+ Обрађујем… Може потрајати пар тренутака
+ Приказуј указиваче слике
+ Не покрећи видео у малом прозору, већ пређи одмах у пун приказ заслона, уколико је обртање приказа закључано. И даље можете приступити малом приказу извођача изласком из пуног приказа
+ Пријави грешке програма извођача видеа
+ Покрени пуни главни приказ извођача
\ No newline at end of file
diff --git a/app/src/main/res/values-sv/strings.xml b/app/src/main/res/values-sv/strings.xml
index 8eb761329..d36248f55 100644
--- a/app/src/main/res/values-sv/strings.xml
+++ b/app/src/main/res/values-sv/strings.xml
@@ -91,7 +91,7 @@
Håll koll på videor som du tittat på
Återuppta uppspelning
Fortsätt uppspelning efter avbrott (t.ex. telefonsamtal)
- Visa \"Håll för att lägga till\"-tips
+ Visa \"Håll för att placera i kön\"-tips
Visa tips när bakgrunds- eller popup-knappen trycks på sidan för videodetaljer
Spelare
Beteende
@@ -115,9 +115,9 @@
Video
Ljud
Försök igen
- T.
+ t
mn
- Mrd.
+ md
Inga prenumeranter
- %s prenumerant
@@ -271,7 +271,7 @@
Ny spellista
Byt namn
Namn
- Lägg till i spellista
+ Lägg till i spellista
Använd som spellistans miniatyrbild
Bokmärk spellistan
Ta bort bokmärke
@@ -333,7 +333,7 @@
Minimera vid växling av applikationen
Åtgärd när du växlar till andra applikationer från huvudvideospelare — %s
Ingen
- Minimera till Bakgrunds-spelare
+ Minimera till bakgrunds-spelare
Minimera till popup-spelare
Sluta prenumerera
Välj flik
@@ -347,10 +347,10 @@
Aviseringar för nya NewPipe-versioner
Extern lagring otillgänglig
Fel vid läsning av sparade flikar, använder standardflikar
- Återställ till standardvärden
+ Återställ standardvärden
Vill du återställa till standard\?
Antalet prenumeranter är otillgängligt
- Vilka flikar som visas på huvudsidan
+ Vilka flikar visas på huvudsidan
Uppdateringar
Visa avisering för att uppdatera appen när en ny version finns tillgänglig
Listvy
@@ -368,7 +368,7 @@
Hämtningen misslyckades
Generera unikt namn
Skriv över
- Det finns en pågående hämtning med det här namnet
+ Det finns en pågående hämtning med det namnet
Visa fel
Kunde inte fastställa en säker anslutning
Kunde inte hitta servern
@@ -389,14 +389,14 @@
Positioner i listor
Spela automatiskt
Rensa data
- Snabbspola framåt/-bakåt sökvaraktighet
+ Spola framåt/bakåt sökvaraktighet
Visa indikatorer för uppspelningsposition i listor
Ta bort uppspelningspositioner
PeerTube-instanser
Välj dina favoritpeertube-instanser
Hitta de instanser du gillar på %s
Lägg till instans
- Ange i instans-URL
+ Ange instansens URL
Det gick inte att validera instansen
Endast HTTPS-URL:er stöds
Instansen finns redan
@@ -410,7 +410,7 @@
Artister
Album
Låtar
- Denna video har en åldersgräns.
+ Denna video är åldersbegränsad.
\n
\nOm du vill visa den aktiverar du \"%1$s\" i inställningarna.
Inga kommentarer
@@ -435,7 +435,7 @@
Det finns en pågående hämtning med det här namnet
kan inte skriva över filen
Det finns redan en hämtad fil med det här namnet
- En fil med det här namnet finns redan
+ En fil med det namnet finns redan
återställer
Väntande
Originaltexter från tjänster kommer att synas i streamobjekt
@@ -467,8 +467,8 @@
Ingen prenumeration vald
Välj prenumerationer
- Bearbetar flöde …
- Läser in flödet…
+ Bearbetar flöde…
+ Läser in flöde…
Inte inläst: %d
Flödet senast uppdaterat: %s
Kanalgrupper
@@ -490,8 +490,8 @@
På grund av ExoPlayer-begränsningar sattes söktiden till %d sekunder
Ja, och delvis tittade videor
- Videor som har tittats före och efter att de har lagts till i spellistan kommer att tas bort.
-\nÄr du säker\? Detta kan inte göras ogjort!
+ Videor som har spelats före och efter att de har lagts till i spellistan kommer att tas bort.
+\nÄr du säker\? Detta kan inte ångras!
Ta bort tittade videor\?
Ta bort tittade
Systems standard
@@ -501,7 +501,7 @@
Använd systemmappväljaren (SAF)
Du kommer att bli tillfrågad var du vill spara varje hämtning.
\nAktivera systemmappväljaren (SAF) om du vill hämta till ett externt SD-kort
- Fråga vart du ska hämta
+ Fråga var filen ska sparas
Pausa hämtningar
Starta hämtningar
En hämtning körs samtidigt
@@ -514,7 +514,7 @@
Rensa hämtningshistorik
Kan inte återställa den här hämtningen
Anslutnings avbrott
- Framsteg förlorat, För att filen blev borttagen
+ Framsteg förlorat, för att filen blev borttagen
Inget utrymme kvar på enhet
NewPipe stängdes under arbete med en fil
Vänligen kontrollera om en felrapport som tar upp din krasch redan finns. Att skapa ärenden när en felrapport redan finns, tar av den tid som vi annars kunde ha ägnat åt att fixa den faktiska buggen.
@@ -524,7 +524,7 @@
Välj en spellista
Av %s
Skapad av %s
- Ingen spellista bokmärkt än
+ Ingen spellista har bokmärkts än
Visa endast prenumerationer som inte grupperats
Skala tumnagel till 1:1-förhållande
Endast över Wi-Fi
@@ -546,7 +546,7 @@
Första händelseknapp
Detta innehåll stöds ännu inte av NewPipe.
\n
-\nDet kommer förhoppningsvis inkluderas i en framtida version.
+\nDetta kommer förhoppningsvis ändras i en kommande version.
Spellistesida
Aldrig
Ingenting
@@ -661,4 +661,22 @@
- Nedladdning slutförd
- %s nedladdningar slutförda
+ Köa nästa
+ Köade nästa
+ Starta huvudspelaren i helskärmsläge
+ Bearbetar… Kan ta en stund
+ Senaste
+ Svep objekt för att ta bort dem
+ Förslag via fjärrsökning
+ Starta inte videor i minispelaren, utan byt till helskärmsläge direkt, om auto-rotation är låst. Du kan fortfarande komma åt minispelaren genom att gå ut ur helskärmsläge
+ Visa Picasso färgade band ovanpå bilderna som anger deras källa: rött för nätverk, blått för disk och grönt för minne
+ Sök efter uppdateringar
+ Kolla manuellt efter nya versioner
+ Söker efter uppdateringar…
+ Nya flödes objekt
+ Visa \"krascha spelaren\"
+ Rapportera spelarfel
+ Krascha spelaren
+ Visar ett kraschalternativ vid användning av spelaren
+ Rapporterar spelarfel i detalj i stället för att visa ett kortvarigt popup-meddelande (användbart för att diagnostisera problem)
\ No newline at end of file
diff --git a/app/src/main/res/values-ta/strings.xml b/app/src/main/res/values-ta/strings.xml
index 223f4b6bc..d1ae9ee8a 100644
--- a/app/src/main/res/values-ta/strings.xml
+++ b/app/src/main/res/values-ta/strings.xml
@@ -1,8 +1,8 @@
- தொடங்க \"தேடல்\" ஐ தட்டவும்
+ ஆரம்பிக்க பூதக்கண்ணாடியைத் தட்டு.
%1$s அன்று வெளியிடப்பட்டது
- நிகழ்பட ஓட்டி கண்டறியப்படவில்லை. VLC நிறுவ வேண்டுமா\?
+ நிகழ்பட ஓட்டி கண்டறியப்படவில்லை. VLC நிறுவவா\?
நிறுவு
ரத்துசெய்
உலாவியில் திற
@@ -14,7 +14,7 @@
நிகழ்பட ஓட்டி கண்டறியப்படவில்லை (தாங்கள் VLC-ஐ பயன்படுத்தலாம்).
திரைமேல் நிலையில் காட்டவும்
நிகழ்பட கோப்பை பதிவிறக்கு
- நீங்கள் கூறியது: %1$s\?
+ \"%1$s\" என்றீர்களா\?
வேறு நிகழ்பட ஓட்டியை பயன்படுத்தவும்
வேறு ஒலி இயக்கியை பயன்படுத்தவும்
குழுசேர்
@@ -33,13 +33,13 @@
பதிவிறக்கப்பட்ட காணொலிகள் இங்கு சேமிக்கப்படும்
காணொலியின் தரவிறக்கக் கோப்புறையை தேர்வு செய்க
ஒலி பதிவிறக்க கோப்புறை
- தரவிறக்கப்பட்ட ஒலி இங்கே சேமிக்கப்பட்டுள்ளது
+ தரவிறக்கப்பட்ட ஒலி கோப்புகள் இங்கே சேமிக்கப்பட்டுள்ளது
ஒலி கோப்புகளுக்கான பதிவிறக்கப் பாதையை தேர்வு செய்க
முதல் பிரிதிறன்
முதல் திரைமேல் நிலை பிரிதிறன்
மேம்பட்ட பிரிதிறன்களைக் காண்பி
Kodi கொண்டு இயக்கு
- Kore செயலி காணவில்லை. நிறுவலாமா\?
+ காணாத Kore செயலியை நிறுவவா\?
\"Kodi கொண்டு இயக்கு\" இடப்பை காண்பி
ஒலி
முதல் ஒலி வடிவம்
@@ -94,10 +94,10 @@
ஒலி
மீண்டும் முயற்சி
சில பிரிதிறன்களில் ஒலி நீக்கப்படும்
- சில சாதனங்கள் மட்டுமெ 2k/4k காணொளிகலை இயக்கும்
+ சில சாதனங்கள் மட்டுமே 2k/4k காணொளிகளை இயக்கமுடியும்
காணொளிகலை Kodi media center கொண்டு இயக்கும் இடப்பை காண்பி
வேகமான பொருத்தமற்ற தேடலை பயன்படுத்து
- தேடும்போது பரிந்துரைகளை கான்பி
+ தேடும்போது காட்டுவதற்கான பரிந்துரைகளைத் தெரிவுசெய்
தொலைபேசி அழைப்பு போன்ற குறுக்கீடுகளுக்கு பிறகு தொடரவும்
\'அடுத்து\' மற்றும் \'ஒப்பான\' காணொளிகலை காண்பி
தேடப்பட்ட வாக்கியத்தை அமைவிடத்தில் சேமிக்கவும்
@@ -160,9 +160,9 @@
காணொளிக் கோப்புகள்
பக்கத்தை தேர்வு செய்
சத்தக் கட்டுப்பாடு செய்கை
- Player-ன் சத்தத்தைக் கட்டுப்படுத்த செய்கையை பயன்படுத்து
+ இயக்கிச் சத்தத்தைக் கட்டுப்படுத்த சைகையைப் பயன்படுத்து
வெளிச்ச கட்டுப்பாடு செய்கை
- Player-ன் வெளிச்சத்தைக் கட்டுப்படுத்த செய்கையை பயன்படுத்து
+ இயக்கி ஒளிர்வைக் கட்டுப்படுத்த சைகையைப் பயன்படுத்து
புதுப்பித்தல்கள்
கோப்பு அழிக்கப்பட்டது
செயலி புதுப்பித்தல் அறிவிப்பு
@@ -171,7 +171,7 @@
பின்தொடர்பவர்கள் எண்ணிக்கை இல்லை
நிகழ்வுகள்
கருத்துக்களை காண்பி
- கருத்துக்களை காண்பிப்பதை நிறுத்துதலை செயலிழக்கசெய்
+ கருத்துக்களை மறைக்க அணை
தானாக ஓட்டு
திரையிடலை தொடங்கு
பட்டியலில் இடங்கள்
@@ -194,16 +194,16 @@
விளக்கத்தைக் காட்டு
செயலிலுள்ள இயக்கி வரிசை மாற்றப்படும்
ஒரு இயக்கி விட்டு மறு இயக்கி மாறுதல் உங்கள் வரிசையை மாற்றக்கூடும்
- துல்லியமற்ற நாடல் குறைந்த துல்லியத்துடன் விரைவாக நாட இயக்கியை அனுமதிக்கிறது. 5, 15 அ 25 விநாடிகள் நாடுவது இதனுடன் செயல்படா.
- இரவு தீம்
- சிறுபடத்தில் உள்ள முக்கிய வண்ணத்திற்கு ஏற்ப அறிவிப்பின் நிறத்தை Androidஐ தனிப்பயனாக்கச் செய் (இது எல்லா சாதனங்களிலும் கிடைக்காது என்பதை குறித்துக்கொள்)
+ துல்லியமற்ற நாடல் குறைந்த துல்லியத்துடன் விரைவாக நாட இயக்கியை அனுமதிக்கிறது. 5, 15 அ 25 நொடிகள் நாடுவது இதனுடன் செயல்படாது
+ இருள் தோற்றம்
+ சிறுபடத்திலுள்ள முதன்மை நிறத்திற்கேற்ப அறிவிப்பின் நிறத்தை Androidஐ தனிப்பயனாக்கச் செய் (இது எல்லா சாதனங்களிலும் கிடைக்காதென்பதை குறித்துக்கொள்)
அறிவிப்பை வண்ணமயமாக்கு
ஏதுமில்லை
இடையகப்படுத்துகிறது
கலக்கு
மீண்டும்
சுருக்க அறிவிப்பில் காட்ட அதிகபட்சம் மூன்று செயல்களை நீங்கள் தேர்ந்தெடுக்கலாம்!
- கீழே உள்ள ஒவ்வொரு அறிவிப்பு செயலையும் தட்டுவதன் மூலம் திருத்தவும். வலதுபுறத்தில் உள்ள தேர்வுப்பெட்டிகளைப் பயன்படுத்தி சுருக்க அறிவிப்பில் காண்பிக்க அவற்றில் மூன்று வரை தேர்ந்தெடுக்கவும்.
+ கீழுள்ள ஒவ்வோரறிவிப்பு செயலையும் தட்டுவதன் மூலம் திருத்துக. வலதுபுறத்திலுள்ள தேர்வுப்பெட்டிகளைப் பயன்படுத்தி சுருக்க அறிவிப்பில் காண்பிக்க அவற்றில் மூன்று வரை தேர்ந்தெடு
ஐந்தாம் செயல் பொத்தான்
நான்காம் செயல் பொத்தான்
மூன்றாம் செயல் பொத்தான்
@@ -220,4 +220,12 @@
குறைந்த தரம்
மொபைல் தரவைப் பயன்படுத்தும் போது வீடியோ தரத்தைக் கட்டுப்படுத்துங்கள்
வரம்பற்ற
+ கிடைக்கவில்லை
+ பார்த்ததாக குறிக்கவும்
+ சரி
+ அனைத்து சிறு படங்களையும் காட்ட முடியவில்லை
+ வலைத்தளத்தை பயன்படுத்த முடியவில்லை
+ தொலைதேடல் பரிந்துரைகள்
+ தானாக-சாரை
+ கடைசியாக மீட்பொலித்த இருப்பிடத்தை மீட்டெடு
\ No newline at end of file
diff --git a/app/src/main/res/values-te/strings.xml b/app/src/main/res/values-te/strings.xml
index f86ca288c..5c93dec4b 100644
--- a/app/src/main/res/values-te/strings.xml
+++ b/app/src/main/res/values-te/strings.xml
@@ -1,25 +1,25 @@
- ప్రారంభించడానికి శోధనను క్లిక్
- %1$s ప్రచురించబడింది
+ మొదలుపెట్టుటకు బూతద్దము గురుతుని తట్టండి.
+ %1$sన ప్రచురించబడింది
ఇన్స్టాల్
రద్దు చేయి
బ్రౌజర్ లో తెరవండి
- షేర్ చేయండి
+ షేర్
డౌన్లోడ్
వెతుకు
- సెట్టింగ్లు
- అంటే నువ్వు అనేది: %1$s\?
- తో పంచు
- బాహ్యట ఆడియో ప్లేయర్ని ఉపయోగించండి
+ అమరికలు
+ మీ ఉద్దేశ్యం \"%1$s\"\?
+ పంచుకో
+ బాహ్య ఆడియో ప్లేయర్ని ఉపయోగించండి
సభ్యత్వం
సబ్ స్క్రైబ్
- అన్ సబ్స్క్రైబ్ చెసిరు
+ ఛానెల్ సభ్యత్వం తీసివేయబడినది
సబ్ స్క్రైబ్ సాధ్యం కాలేదు
సబ్ స్క్రైబ్ నవీకరించలేరు
సభ్యత్వం
కొత్తది ఏమిటి
- వెనకవైపు
+ వెనుకగా
పాపప్
వీడియో డౌన్లోడ్ మార్గం
డౌన్లోడ్ చేసిన వీడియోలను నిల్వ చేయడానికి మార్గం
@@ -28,26 +28,26 @@
ఆడియో కోసం డౌన్లోడ్ మార్గాన్ని నమోదు చేయండి
ఆడియో ఫైల్లకు డౌన్లోడ్ మార్గాన్ని ఇవ్వండి
కోడితో ప్లే చేయండి
- కోరే అనువర్తనం కనుగొనబడలేదు. దీన్ని ఇన్స్టాల్ చేయండి
+ కోరే ఆప్ కనుగొనబడలేదు. దీన్ని ఇన్స్టాల్ చెయ్యాలా\?
కోరే అనువర్తనం కనుగొనబడలేదు. దీన్ని ఇన్స్టాల్ చేయండి
ఆడియో
డిఫాల్ట్ ఆడియో ఫార్మాట్
థీమ్
ప్రకాశం
- చరిత్ర
- డౌన్లోడ్
- తదుపరి వీడియో మరియు ఇలాంటి వీడియో
+ చరిత్రను చూడండి
+ డౌన్లోడ్
+ \'తదుపరి\' మరియు \'ఇలాంటి\' వీడియోలను చూపించు
చిట్కాను అనుబంధించడానికి హోల్డ్ను చూపు
Url మద్దతు లేదు
డిఫాల్ట్ భాష
ప్లేయర్
ప్రవర్తన
వీడియో & ఆడియో
- చరిత్ర
+ చరిత్ర మరియు కాష్
స్వరూపం
వెనకవైపులో ఆడుతున్నారు
పాపప్ రీతిలో ప్లే చేస్తోంది
- కంటెంట్
+ విషయము
డౌన్ లోడ్ల
డౌన్ లోడ్
లోపం నివేదిక
@@ -62,17 +62,17 @@
కంటెంట్ అందుబాటులో లేదు
డౌన్లోడ్ మెనుని సెటప్ చేయడం సాధ్యపడలేదు
ఈ స్ట్రీమ్ని ప్లే చేయడం విఫలమైంది
- ఆటగాడు లోపం నుండి పునరుద్ధరించడం
+ ప్లేయర్ లోపం నుండి పునరుద్ధరించబడుతున్నది
క్షమించాలి, అది జరగకూడదు
- ఇ-మెయిల్ ద్వారా నివేదన లోపం
- క్షమించండి, కొన్ని లోపాలు సంభవించాయి
+ ఇ-మెయిల్ ద్వారా లోపాన్ని నివేదించుము
+ క్షమించండి, ఏదో తప్పు జరిగింది.
నివేదిక
- సమాచారం
- ఏం జరిగింది
- మీ వ్యాఖ్య(ఆంగ్లం లో)
- వివరాలు
+ సమాచారం:
+ ఏం జరిగింది:
+ మీ వ్యాఖ్య(ఆంగ్లం లో):
+ వివరములు:
వీడియో ప్రివ్యూ సూక్ష్మచిత్రం
- Video preview thumbnail
+ వీడియోని ప్లే చేయండి, వ్యవధి:
ఇష్టాలు
మంది ఇష్టపడలేదు
ఫలితాలు లేవు
@@ -82,10 +82,10 @@
కె
ఎం
బి
- చందాదారులు లేరు
+ సభ్యులు లేరు
- - %s సబ్స్క్రయిబ్
- - %s సబ్స్క్రయిబలు
+ - %s సభ్యుడు
+ - %s సభ్యులు
వీక్షణలు లేవు
@@ -98,7 +98,7 @@
- %s వీడియోలు
ప్రారంభం
- ఆపు
+ విరామం
తొలగించు
అలాగే
ఫైలుపేరు
@@ -112,7 +112,7 @@
డౌన్లోడ్
ఫైల్ పేర్లలో అనుమతించిన అక్షరాలు
చెల్లని అక్షరాలు ఈ విలువతో భర్తీ చేయబడతాయి
- ప్రత్యామ్నాయం పాత్ర
+ ప్రత్యామ్నాయ అక్షరం
లెటర్స్ మరియు అంకెలు
న్యూపిప్ గురించి
మూడవ పార్టీ లైసెన్స్
@@ -120,9 +120,9 @@
లైసెన్సుల
GitHub పై చూడండి
న్యూపెయిప్స్ లైసెన్స్
- మీరు ఆలోచనలు ఉన్నాయా లేదో; అనువాదం, డిజైన్ మార్పులు, కోడ్ క్లీనింగ్ లేదా రియల్ భారీ కోడ్ మార్పులు-సహాయం ఎల్లప్పుడూ స్వాగతం. మరింత అది గెట్స్ మంచి జరుగుతుంది
+ మీకు ఆలోచనలు ఉన్నాయా; అనువాదం, డిజైన్ మార్పులు, కోడ్ శుభ్రపరచడం లేదా నిజమైన భారీ కోడ్ మార్పులు-సహాయం ఎల్లప్పుడూ స్వాగతం. ఎంత ఎక్కువ చేస్తే అంత మంచిది!
లైసెన్స్ చదువు
- కాంట్రిబ్యూషన్
+ సహకరించటానికి
చరిత్ర
చరిత్ర
మీరు ఈ అంశాన్ని శోధన చరిత్ర నుండి తొలగించాలనుకుంటున్నారా?
@@ -138,11 +138,100 @@
వివరాలు
ఆడియో సెట్టింగ్లు
ఎన్క్యూలో పట్టుకోండి
- మీదగార వీడియో కి కావాల్సిన ప్లేయర్ లేదు. VLC ప్లేయర్ ఇన్స్టాల్ చేసుకుంటారా\?
- మీదగార వీడియో కి కావాల్సిన ప్లేయర్ లేదు (మీరు VLC ఇసన్తాల్ చేసుకోండి )
- "పాపప్ మోడ్ లో తెరవండి"
+ మీదగ్గర వీడియోకి కావాల్సిన ప్లేయర్ లేదు. VLC ప్లేయర్ని ఇన్స్టాల్ చేసుకుంటారా\?
+ మీదగ్గర వీడియోకి కావాల్సిన ప్లేయర్ లేదు (మీరు VLCని ఇన్స్టాల్ చేసుకోండి ).
+ పాపప్ మోడ్లో తెరవండి
డిఫాల్ట్ పాపప్ స్పష్టత
- ప్రసార ఫైల్ను డౌన్లోడ్ చేయండి
+ ప్రసార ఫైలుని డౌన్లోడ్ చేయండి
బాహ్య వీడియో ప్లేయర్ని ఉపయోగించండి
- కొన్ని రెసొల్యూషన్స్ లో ఆడియో తీసేస్తుంది
+ కొన్ని స్పష్టతల్లో ఆడియోను తొలగిస్తుంది
+ పూర్తి స్క్రీన్లో ప్రధాన ప్లేయర్ని ప్రారంభించండి
+ డీబగ్ చేయండి
+ ఏమిలేదు
+ నోటిఫికేషన్లో చూపబడిన వీడియో థంబ్నెయిల్ను 16:9 నుండి 1:1 కారక నిష్పత్తికి స్కేల్ చేయండి (వక్రీకరణలను ప్రవేశపెట్టవచ్చు)
+ పునరావృతం చేయండి
+ వీడియో \"వివరాలు:\"లో బ్యాక్గ్రౌండ్ లేదా పాప్అప్ బటన్ను నొక్కినప్పుడు చిట్కాను చూపు
+ URLని గుర్తించడం సాధ్యపడలేదు. మరొక యాప్తో తెరవాలా\?
+ నోటిఫికేషన్ను రంగులమయం చేయండి
+ స్థానిక శోధన సూచనలు
+ రిమోట్ శోధన సూచనలు
+ ఆటోప్లే
+ అంతరాయాలు (ఉదా. ఫోన్కాల్స్) తర్వాత ప్లే చేయడం కొనసాగించండి
+ మెటా సమాచారాన్ని చూపు
+ కోడి మీడియా సెంటర్ ద్వారా వీడియోను ప్లే చేయడానికి ఎంపికను ప్రదర్శించండి
+ కొన్ని పరికరాలు మాత్రమే 2K/4K వీడియోలను ప్లే చేయగలవు
+ వీక్షించినట్లు గుర్తుపెట్టుము
+ దీనితో తెరువుము
+ దీని కోసం ఫలితాలను చూపుతోంది: %s
+ డిఫాల్ట్ స్పష్టత
+ అధిక స్పష్టతను చూపుము
+ నలుపు
+ పాప్అప్ లక్షణాలను గుర్తుంచుకో
+ సూక్ష్మచిత్రాలను లోడ్ చేయండి
+ వ్యాఖ్యలను చూపించు
+ వ్యాఖ్యలను దాచడాన్ని ఆఫ్ చేయండి
+ %sలో మీకు నచ్చిన సందర్భాలను కనుగొనండి
+ పీర్ట్యూబ్ ఉదాహరణలు
+ మూడవ చర్య బటన్
+ థంబ్నెయిల్లను లోడ్ చేయడం, డేటాను సేవ్ చేయడం మరియు మెమరీ వినియోగాన్ని నిరోధించడానికి ఆఫ్ చేయండి. మార్పులు ఇన్-మెమరీ మరియు ఆన్-డిస్క్ ఇమేజ్ కాష్ రెండింటినీ క్లియర్ చేస్తాయి
+ ఖచ్చితమైన శోధన తగ్గిన ఖచ్చితత్వంతో వేగంగా స్థానాలను పొందేందుకు ఆటగాడిని అనుమతిస్తుంది. 5, 15 లేదా 25 సెకన్ల పాటు కోరడం దీనితో పని చేయదు
+ వేగవంతమైన ఖచ్చితమైన శోధనను ఉపయోగించండి
+ జోడించండి
+ బుక్మార్క్ చేయబడిన వినోదజాబితాలు
+ ట్యాబ్ని ఎంచుకోండి
+ సభ్యత్వాన్ని తొలగించుము
+ సమాచారాన్ని చూపుము
+ సూక్ష్మచిత్రాన్ని 1:1 కారక నిష్పత్తికి స్కేల్ చేయండి
+ ఒక ప్లేయర్ నుండి మరొక ప్లేయర్కు మారడం వలన మీ క్యూను భర్తీ చేయవచ్చు
+ సంబంధిత స్ట్రీమ్ను జోడించడం ద్వారా (పునరావృతం కాని) ప్లేబ్యాక్ క్యూను ముగించడాన్ని కొనసాగించండి
+ దిగువన ఉన్న ప్రతి నోటిఫికేషన్ చర్యను దానిపై నొక్కడం ద్వారా సవరించండి. కుడివైపు ఉన్న చెక్బాక్స్లను ఉపయోగించడం ద్వారా కాంపాక్ట్ నోటిఫికేషన్లో చూపబడే వాటిలో మూడు వరకు ఎంచుకోండి
+ పాప్అప్ చివరి పరిమాణం మరియు స్థానాన్ని గుర్తుంచుకోండి
+ వీడియో వివరణ మరియు అదనపు సమాచారాన్ని దాచడాన్ని ఆఫ్ చేయండి
+ స్ట్రీమ్ సృష్టికర్త, స్ట్రీమ్ కంటెంట్ లేదా శోధన అభ్యర్థన గురించి అదనపు సమాచారంతో మెటా సమాచార పెట్టెలను దాచడానికి ఆఫ్ చేయండి
+ ప్లేయర్ ప్రకాశాన్ని నియంత్రించడానికి సంజ్ఞలను ఉపయోగించండి
+ శోధిస్తున్నప్పుడు చూపాల్సిన సూచనలను ఎంచుకోండి
+ చివరి ప్లేబ్యాక్ స్థానాన్ని పునరుద్ధరించండి
+ మీకు ఇష్టమైన పీర్ట్యూబ్ సందర్భాలను ఎంచుకోండి
+ వీక్షించిన వీడియోలను ట్రాక్ చేయండి
+ మినీ ప్లేయర్లో వీడియోలను ప్రారంభించవద్దు, ఆటో రొటేషన్ లాక్ చేయబడితే, నేరుగా పూర్తి స్క్రీన్ మోడ్కి మారండి. మీరు పూర్తి స్క్రీన్ నుండి నిష్క్రమించడం ద్వారా ఇప్పటికీ మినీ ప్లేయర్ని యాక్సెస్ చేయవచ్చు
+ సందర్భాన్ని జోడించండి
+ నవీకరణలు
+ HTTPS URLలకు మాత్రమే మద్దతు ఉంది
+ రెండవ చర్య బటన్
+ నాల్గవ చర్య బటన్
+ స్వల్పకాలిక టోస్ట్ సందేశాన్ని చూపించే బదులు పూర్తి వివరాలతో ప్లేయర్ లోపాలను నివేదిస్తుంది (సమస్యలను నిర్ధారించడానికి ఉపయోగపడుతుంది)
+ ప్లేయర్ క్రాష్ చేయండి
+ ప్లేయర్ లోపాలను నివేదించండి
+ మొదటి చర్య బటన్
+ ఐదవ చర్య బటన్
+ మీరు కాంపాక్ట్ నోటిఫికేషన్లో చూపడానికి గరిష్టంగా మూడు చర్యలను ఎంచుకోవచ్చు!
+ షఫుల్ చేయండి
+ బఫరింగ్
+ డిఫాల్ట్ వీడియో ఫార్మాట్
+ రాత్రి థీమ్
+ చీకటి
+ ఫాస్ట్-ఫార్వర్డ్/-రివైండ్ సీక్ వ్యవధి
+ క్యూను క్లియర్ చేయడానికి ముందు నిర్ధారణ కోసం అడగండి
+ క్రియాశీల ప్లేయర్ క్యూ భర్తీ చేయబడుతుంది
+ వివరణను చూపు
+ చిత్రం కాష్ తుడిచివేయబడింది
+ కాష్ చేయబడిన మెటాడేటాను తుడిచివేయండి
+ కాష్ చేసిన వెబ్పేజీ డేటా మొత్తాన్ని తీసివేయండి
+ మెటాడేటా కాష్ తుడిచివేయబడింది
+ వాల్యూమ్ సంజ్ఞ నియంత్రణ
+ ప్లేయర్ వాల్యూమ్ను నియంత్రించడానికి సంజ్ఞలను ఉపయోగించండి
+ ప్రకాశం సంజ్ఞ నియంత్రణ
+ సూచనలను శోధించండి
+ శోధన చరిత్ర
+ శోధన ప్రశ్నలను స్థానికంగా నిల్వ చేయండి
+ ప్లేబ్యాక్ పునఃప్రారంభించండి
+ జాబితాలలో స్థానాలు
+ జాబితాలలో ప్లేబ్యాక్ స్థాన సూచికలను చూపు
+ డేటాను క్లియర్ చేయండి
+ ప్లే చేయడం కొనసాగించండి
+ డిఫాల్ట్ కంటెంట్ దేశం
+ ఉదాహరణ URLని నమోదు చేయండి
+ ఉదాహరణను ధృవీకరించడం సాధ్యపడలేదు
+ ఉదాహరణ ఇప్పటికే ఉంది
+ నోటిఫికేషన్
\ No newline at end of file
diff --git a/app/src/main/res/values-th/strings.xml b/app/src/main/res/values-th/strings.xml
index 22123e517..01946c321 100644
--- a/app/src/main/res/values-th/strings.xml
+++ b/app/src/main/res/values-th/strings.xml
@@ -270,7 +270,7 @@
เพลย์ลิสต์ใหม่
เปลี่ยนชื่อ
ชื่อ
- เพิ่มในเพลย์ลิสต์
+ เพิ่มในเพลย์ลิสต์
ตั้งเป็นรูปขนาดย่อของเพลย์ลิสต์
เก็บเพลย์ลิสต์
เอาที่คั่นหน้าออก
diff --git a/app/src/main/res/values-tr/strings.xml b/app/src/main/res/values-tr/strings.xml
index f802302ab..3712b2355 100644
--- a/app/src/main/res/values-tr/strings.xml
+++ b/app/src/main/res/values-tr/strings.xml
@@ -227,7 +227,7 @@
Yeni Oynatma Listesi
Yeniden adlandır
Ad
- Oynatma listesine ekle
+ Oynatma listesine ekle
Oynatma listesi küçük resmi olarak ayarla
Oynatma listesini yer imlerine ekle
Yer imini kaldır
@@ -669,4 +669,9 @@
Ana oynatıcıyı tam ekranda başlat
Sonrakini sıraya ekle
Sonraki sıraya eklendi
+ İşleniyor… Biraz zaman alabilir
+ Güncellemeleri denetle
+ Yeni sürümleri el ile denetleyin
+ Güncellemeler denetleniyor…
+ Yeni akış ögeleri
\ No newline at end of file
diff --git a/app/src/main/res/values-uk/strings.xml b/app/src/main/res/values-uk/strings.xml
index eae9079c0..ebb0bccb1 100644
--- a/app/src/main/res/values-uk/strings.xml
+++ b/app/src/main/res/values-uk/strings.xml
@@ -19,7 +19,7 @@
Шлях до теки зі завантаженими відео
Тека для завантаження аудіо
Завантажені аудіофайли зберігаються тут
- Типова роздільна здатність
+ Типова роздільність
Програти в Kodi
Встановити відсутній застосунок Kore\?
Показати опцію «Відтворити у Kodi»
@@ -96,11 +96,11 @@
Новинки
На тлі
У вікні
- Типова роздільна здатність вікна
+ Типова роздільність вікна
Не всі пристрої можуть відтворювати 2K/4K-відео
- Показувати вищі роздільні здатності
+ Показувати вищі роздільності
Типовий формат відео
- Памʼятати розмір і позицію вікна
+ Памʼятати властивості вікна
Памʼятати останній розмір і позицію вікна
Пошукові пропозиції
Виберіть які пропозиції показувати під час пошуку
@@ -115,14 +115,14 @@
Історія переглядів
Відновлювати відтворення
Продовжувати відтворення після переривань (напр. телефонних дзвінків)
- Показати пораду «Утримуй, щоб додати»
+ Показувати підказку «Утримуйте, щоб додати в чергу»
Типова країна вмісту
Програвач
Поведінка
Історія та кеш
Відтворення у віконному режимі
Очистити
- Найкраща роздільна здатність
+ Найкраща роздільність
Скасувати
Відтворити все
Завжди
@@ -130,7 +130,7 @@
Сповіщення NewPipe
Сповіщення для програвачів NewPipe на тлі й у вікні
[Невідомо]
- Перемкнути на тло
+ Перейти у фоновий режим
Перемкнути у вікно
Перемкнути на головну
Імпортувати базу даних
@@ -165,7 +165,7 @@
Подробиці
Налаштування аудіо
Відеопрогравач
- Тловий програвач
+ Тильний програвач
Віконний програвач
Отримання інформації…
Завантаження запитаного контенту
@@ -173,7 +173,7 @@
Показати інформацію
Закладки відтворення
Додати до
- Показати підказку при натисканні на фон або на спливну кнопку «Деталі:» у відео
+ Показати підказку при натисканні на тло або на спливну кнопку «Деталі:» у відео
Сталася невиправна помилка програвача
Зовнішні програвачі не підтримують такі види посилань
Що:\\nЗапит:\\nМова вмісту:\\nКраїна вмісту:\\nМова застосунку:\\nСлужба:\\nЧас GMT:\\nПакунок:\\nВерсія:\\nВерсія ОС:
@@ -240,7 +240,7 @@
Нова добірка
Перейменувати
Назва
- Додати в добірку
+ Додати в добірку
Призначити ескізом добірки
Додати добірку до закладок
Видалити закладку
@@ -258,7 +258,7 @@
Примусове звітування про неможливість доставлення Rx-винятків, які відбуваються за межами фрагменту або діяльності життєвого циклу після усунення
Викор. швидкий неточний пошук
Неточний пошук дозволяє програвачеві рухатися позиціями швидше, проте з меншою точністю
- Автододавання в чергу наступного запису
+ Автододавання в чергу наступної трансляції
Продовжити при завершені (не повторюваної) черги, додавши повʼязаний запис
Файл
Такої теки не існує
@@ -330,7 +330,7 @@
Прийняти
Відхилити
Без обмежень
- Обмежити розд. зд. при використ. мобільних даних
+ Обмежити роздільність під час мобільних даних
Пропускати тихі проміжки
Крок
Скинути
@@ -583,7 +583,7 @@
Коментарі
Сповіщення
Не розпізнано URL. Відкрити через іншу програму\?
- Самододавання в чергу
+ Автоматична черга
Показувати метадані
Показувати описи
Нічна тема
@@ -684,4 +684,14 @@
Запустити основний програвач у повноекранному режимі
Заплановано наступним
Запланувати наступним
+ Обробка… Трохи заждіть
+ Перевірити наявність оновлень
+ Перевірка нових версій вручну
+ Перевірка оновлень…
+ Нові записи стрічки
+ Показати «збій програвача»
+ Показує параметр збою під час використання програвача
+ Повідомити про помилки програвача
+ Збій програвача
+ Повне повідомлення про помилки програвача замість, короткого звіту (корисно для діагностики проблем)
\ No newline at end of file
diff --git a/app/src/main/res/values-ur/strings.xml b/app/src/main/res/values-ur/strings.xml
index 0454fc293..1f427504b 100644
--- a/app/src/main/res/values-ur/strings.xml
+++ b/app/src/main/res/values-ur/strings.xml
@@ -248,7 +248,7 @@
نئی پلے لسٹ
نام تبدیل کریں
نام
- پلے لسٹ میں شامل
+ پلے لسٹ میں شامل
بطور پلے لسٹ انگشتی طے کریں
پلے لسٹ کو نشان زد کریں
نشان زد حدف کریں
diff --git a/app/src/main/res/values-vi/strings.xml b/app/src/main/res/values-vi/strings.xml
index 83aea33c0..341562a62 100644
--- a/app/src/main/res/values-vi/strings.xml
+++ b/app/src/main/res/values-vi/strings.xml
@@ -267,7 +267,7 @@
Tạo playlist mới
Đổi tên playlist
Tên
- Thêm vào danh sách phát
+ Thêm vào danh sách phát
Đặt làm hình thu nhỏ của danh sách phát
Đánh dấu playlist này
Xóa dấu trang
@@ -300,7 +300,7 @@
\n2. Đăng nhập khi được yêu cầu
\n3. Nhấn chọn \"Bao gồm tất cả dữ liệu trên YouTube\", sau đó nhấn \"Bỏ chọn tất cả\", sau đó chỉ chọn mục \"đăng kí\" rồi nhấn OK
\n4. Nhấn nút \"Bước tiếp theo\" rồi nhấn \"Tạo tệp xuất\"
-\n5. Nhấn nút \"Tải xuống\" khi nó hiện
+\n5. Nhấn nút \"Tải xuống\" khi nó xuất hiện
\n6. Từ file zip mới tải về, trích xuất file .json ra (thường nằm ở đường dẫn \"YouTube và YouTube Music/đăng kí/subscriptions.json\") rồi nhập vào đây.
Nhập hồ sơ SoundCloud bằng cách nhập URL hoặc ID của bạn:
\n
@@ -656,4 +656,5 @@
Khởi động trình phát chính ở toàn màn hình
Đã cho mục tiếp vào hàng đợi
Cho mục tiếp vào hàng đợi
+ Đang thực hiện...Có thể mất một lúc
\ No newline at end of file
diff --git a/app/src/main/res/values-zh-rCN/strings.xml b/app/src/main/res/values-zh-rCN/strings.xml
index e5180c51e..f6318df0b 100644
--- a/app/src/main/res/values-zh-rCN/strings.xml
+++ b/app/src/main/res/values-zh-rCN/strings.xml
@@ -259,7 +259,7 @@
新建播放列表
重 命名
名称
- 添加到播放列表
+ 添加到播放列表
设为播放列表缩略图
收藏播放列表
删除收藏
diff --git a/app/src/main/res/values-zh-rHK/strings.xml b/app/src/main/res/values-zh-rHK/strings.xml
index 63ca8f827..f69a42dbd 100644
--- a/app/src/main/res/values-zh-rHK/strings.xml
+++ b/app/src/main/res/values-zh-rHK/strings.xml
@@ -132,4 +132,116 @@
使用粗略快查
添加到
選擇標籤
+ 第一粒動作掣
+ 第二粒動作掣
+ 第三粒動作掣
+ 第四粒動作掣
+ 隨機播放
+ 緩衝緊
+ 空白
+ 用手勢去控制播放器光暗
+ 本機搜尋建議
+ 遠端搜尋建議
+ 喺本機儲存搵過嘅查詢
+ 睇過嘅紀錄
+ 恢復播放
+ 返返最後播放到去嗰個位
+ 播放清單有排位
+ 縮圖放到去 1:1 長寬比
+ 顯示喺通知嘅影片縮圖由 16:9 放到去 1:1 長寬比 (話唔定會鬆郁矇)
+ 通知色彩化
+ 等 Android 根據縮圖嘅主色自訂通知嘅顏色 (注意:唔係部部機都用得)
+ 夜色
+ 跳前/跳後嘅快轉長短
+ 關閉去隱藏影片描述同附加資訊
+ 剔低睇過
+ 開啟方式
+ 搵呢挺嘢:%s
+ 第五粒動作掣
+ 撳一下下面每粒掣去更改各個通知動作。用右手邊嘅格仔剔選最多三個,擺喺精簡通知度顯示
+ 精簡通知最多淨係擺到三個動作!
+ 循環播放
+ 載入縮圖
+ 顯示留言
+ 關閉去隱藏留言
+ 搜尋紀錄
+ 喺播放清單顯示位置編號
+ 抹除資料
+ 顯示描述
+ 抹除咗影像快取
+ 移除所有網頁嘅快取資料
+ 音量手勢控制
+ 用手勢去控制播放器音量
+ 光暗手勢控制
+ 關閉去避免載入縮圖,慳返啲數據同埋用少啲 RAM。更改會抹走記憶體以及磁碟機上面嘅影像快取
+ 粗糙快轉允許播放器比較籠統噉快轉去其他位置。快轉 5、15 或 25 秒就太精緻,粗做唔到
+ 播放器
+ 內容預設國家
+ 演出者
+ 專輯
+ 淨係支援 HTTPS 嘅 URL
+ 除錯
+ 通知
+ 復原
+ 刪除咗個檔案
+ 幾時都係
+ 一次咁多
+ 檔案
+ NewPipe 通知
+ App 更新通知
+ NewPipe 新版本通知
+ 抹走 reCAPTCHA Cookie
+ 頻道
+ 影片
+ 使用者
+ 事件
+ 歌曲
+ 抹走當您完成 reCAPTCHA 嘅時候 NewPipe 儲存嘅 Cookie
+ 轉返主版面
+ 收埋喺背景
+ 撈起去浮面
+ 匯入資料庫
+ 主播放器用全螢幕開啟
+ 如果自動旋轉鎖定,開啟影片嘅時候唔用袖珍播放器就直接飛去全螢幕模式。您仍可結束全螢幕返返去袖珍播放器
+ 個 URL 識別唔到。會唔會用另一個 app 開?
+ YouTube 提供嘅「嚴格篩選模式」可以過濾潛在嘅成人內容
+ 有年齡限制 (例如 18+) 故可能兒童不宜嘅內容都照顯示
+ 呢部影片有年齡限制。
+\n
+\n如果您想睇,請喺設定度開啟「%1$s」。
+ 呢部影片有年齡限制。
+\n鑑於 YouTube 就年齡限制影片嘅新政策,NewPipe 存取唔到條片嘅任何影像串流,所以播放唔到。
+ [未知]
+ 匯出資料庫
+ 抹走咗 reCAPTCHA Cookie
+ 恢復播放
+ 打斷 (例如有電話) 完之後繼續播放
+ 記低睇過嘅影片
+ 自動播放
+ 更新
+ 說明
+ 開啟 YouTube 嘅「嚴格篩選模式」
+ 冇串流下載得到
+ 畀權限去喺其他 app 上面顯示
+ 去 GitHub 度報告
+ 留言
+ 相關嘅嘢
+ 描述
+ 播放唔到呢個串流
+ 發生無法復原嘅播放器錯誤
+ 外置播放器唔支援呢類型嘅連結
+ 搵唔到影像串流
+ 搵唔到聲音串流
+ 檔案搬走咗或刪除咗
+ 個檔案唔喺度,又或者欠缺讀寫權限
+ 檔名冇得留空
+ 復原緊播放器錯誤
+ 冇呢個資料夾
+ 冇呢個檔案/內容來源
+ 讀取唔到儲存咗嘅分頁,所以用返預設分頁
+ 還原返預設噉樣
+ 發生錯誤:%1$s
+ 您係咪要還原返做預設嗰個樣?
+ 複製執咗格式嘅報告
+ 乜都搵唔到
\ No newline at end of file
diff --git a/app/src/main/res/values-zh-rTW/strings.xml b/app/src/main/res/values-zh-rTW/strings.xml
index 576f9d480..4ef11b8c7 100644
--- a/app/src/main/res/values-zh-rTW/strings.xml
+++ b/app/src/main/res/values-zh-rTW/strings.xml
@@ -225,7 +225,7 @@
新的播放清單
重新命名
名稱
- 新增至播放清單
+ 新增至播放清單
設為播放清單縮圖
將播放清單加入書籤
移除書籤
@@ -657,4 +657,14 @@
以全螢幕開始主播放器
已將下一個加入佇列
將下一個加入佇列
+ 正在處理……可能需要一點時間
+ 檢查更新
+ 手動檢查新版本
+ 正在檢查更新……
+ 新 feed 項目
+ 回報播放器錯誤
+ 播放器當機
+ 完整回報播放器錯誤,而非顯示短暫的 toast 訊息(用於診斷問題)
+ 顯示「播放器當機」
+ 使用播放器時顯示當機選項
\ 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 9261dfae1..e2b797576 100644
--- a/app/src/main/res/values/settings_keys.xml
+++ b/app/src/main/res/values/settings_keys.xml
@@ -89,6 +89,8 @@
- @string/never
+ report_player_errors_key
+
seekbar_preview_thumbnail_key
seekbar_preview_thumbnail_high_quality
seekbar_preview_thumbnail_low_quality
@@ -188,6 +190,7 @@
disable_media_tunneling_key
crash_the_app_key
show_image_indicators_key
+ show_crash_the_player_key
theme
@@ -263,6 +266,7 @@
feed_update_threshold_key
300
+ feed_show_played_items
show_thumbnail_key
@@ -359,6 +363,7 @@
background_player
popup_player
download
+ add_to_playlist
always_ask_player
@@ -367,6 +372,7 @@
- @string/background_player
- @string/popup_player
- @string/download
+ - @string/add_to_playlist
- @string/always_ask_open_action
@@ -375,11 +381,13 @@
- @string/background_player_key
- @string/popup_player_key
- @string/download_key
+ - @string/add_to_playlist_key
- @string/always_ask_open_action_key
update_app_key
+ manual_update_key
update_pref_screen_key
update_expiry_key
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index 225ccd126..eeb57dcf0 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -52,6 +52,9 @@
org.xbmc.kore
Show \"Play with Kodi\" option
Display an option to play a video via Kodi media center
+ Crash the player
+ Report player errors
+ Reports player errors in full detail instead of showing a short-lived toast message (useful for diagnosing problems)
Scale thumbnail to 1:1 aspect ratio
Scale the video thumbnail shown in the notification from 16:9 to 1:1 aspect ratio (may introduce distortions)
First action button
@@ -96,9 +99,9 @@
Wipe cached metadata
Remove all cached webpage data
Metadata cache wiped
- Auto-queue next stream
+ Auto-enqueue next stream
Continue ending (non-repeating) playback queue by appending a related stream
- Auto-queue
+ Auto-enqueuing
Volume gesture control
Use gestures to control player volume
Brightness gesture control
@@ -122,7 +125,7 @@
Start main player in fullscreen
Do not start videos in the mini player, but turn to fullscreen mode directly, if auto rotation is locked. You can still access the mini player by exiting fullscreen
Autoplay
- Show \"Hold to append\" tip
+ Show \"Hold to enqueue\" tip
Show tip when pressing the background or the popup button in video \"Details:\"
Unsupported URL
Could not recognize the URL. Open with another app?
@@ -439,7 +442,8 @@
New Playlist
Rename
Name
- Add to playlist
+ Add to playlist
+ Processing… May take a moment
Mute
Unmute
Set as playlist thumbnail
@@ -472,6 +476,8 @@
Show image indicators
Show Picasso colored ribbons on top of images indicating their source: red for network, blue for disk and green for memory
Crash the app
+ Show \"crash the player\"
+ Shows a crash option when using the player
Import
Import from
@@ -516,6 +522,8 @@
Updates
Show a notification to prompt app update when a new version is available
+ Check for updates
+ Manually check for new versions
Minimize on app switch
Action when switching to other app from main video player — %s
@@ -546,6 +554,7 @@
recovering
Queue
Action denied by the system
+ Checking for updates…
Download failed
@@ -632,6 +641,7 @@
Not loaded: %d
Loading feed…
Processing feed…
+ New feed items
Select subscriptions
No subscription selected
@@ -703,4 +713,4 @@
Error at Show Channel Details
Loading Channel Details…
-
+
\ No newline at end of file
diff --git a/app/src/main/res/xml/debug_settings.xml b/app/src/main/res/xml/debug_settings.xml
index 22abebcae..5e2cc28ed 100644
--- a/app/src/main/res/xml/debug_settings.xml
+++ b/app/src/main/res/xml/debug_settings.xml
@@ -49,9 +49,26 @@
android:title="@string/show_image_indicators_title"
app:iconSpaceReserved="false" />
+
+
+
+
diff --git a/app/src/main/res/xml/update_settings.xml b/app/src/main/res/xml/update_settings.xml
index adaa47352..ef121ec4e 100644
--- a/app/src/main/res/xml/update_settings.xml
+++ b/app/src/main/res/xml/update_settings.xml
@@ -12,4 +12,11 @@
app:singleLineTitle="false"
app:iconSpaceReserved="false" />
+
+
diff --git a/app/src/main/res/xml/video_audio_settings.xml b/app/src/main/res/xml/video_audio_settings.xml
index f605fbe17..4dc5d5c9a 100644
--- a/app/src/main/res/xml/video_audio_settings.xml
+++ b/app/src/main/res/xml/video_audio_settings.xml
@@ -89,6 +89,7 @@
android:title="@string/show_play_with_kodi_title"
app:singleLineTitle="false"
app:iconSpaceReserved="false" />
+