Merge pull request #9869 from TeamNewPipe/release-0.25.1

Release v0.25.1 (993)
This commit is contained in:
Stypox 2023-04-03 14:50:23 +02:00 committed by GitHub
commit 07111d86d4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
285 changed files with 4517 additions and 1102 deletions

View File

@ -20,8 +20,8 @@ android {
resValue "string", "app_name", "NewPipe"
minSdk 21
targetSdk 33
versionCode 992
versionName "0.25.0"
versionCode 993
versionName "0.25.1"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
@ -106,7 +106,7 @@ ext {
androidxWorkVersion = '2.7.1'
icepickVersion = '3.2.0'
exoPlayerVersion = '2.18.1'
exoPlayerVersion = '2.18.5'
googleAutoServiceVersion = '1.0.1'
groupieVersion = '2.10.1'
markwonVersion = '4.6.2'
@ -191,7 +191,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:7e793c11aec46358ccbfd8bcfcf521105f4f093a'
implementation 'com.github.TeamNewPipe:NewPipeExtractor:v0.22.6'
implementation 'com.github.TeamNewPipe:NoNonsense-FilePicker:5.0.0'
/** Checkstyle **/

View File

@ -0,0 +1,19 @@
{
"data": [
{
"name": "BBC",
"additional": "12K subscribers•233 videos",
"description": "The BBC is the worlds leading public service broadcaster. Were impartial and independent, and every day we create distinctive, world-class programmes and content which inform, educate and entertain millions of people in the UK and around the world. SUBSCRIBE to our YouTube channel to get the best of BBC entertainment and comedy programmes, stories from science and nature documentaries, and much more! https://bit.ly/2IXqEIn Get ALL your fresh TV, and sofa-hugging box sets on iPlayer https://bbc.in/2J18jYJ"
},
{
"name": "Linus Tech Tips",
"additional": "1M subscribers•233 videos",
"description": "Looking for a Tech YouTuber?\n\nLinus Tech Tips is a passionate team of \"professionally curious\" experts in consumer technology and video production which aims to inform and educate people of all ages through our entertaining videos. We create product reviews, step-by-step computer build guides, and a variety of other tech-focused content.\n\nSchedule:\nNew videos every Saturday to Thursday @ 10:00am Pacific\nLive WAN Show podcasts every Friday @ ~5:00pm Pacific"
},
{
"name": "Marques Brownlee",
"additional": "13 subscribers•12K videos",
"description": "MKBHD: Quality Tech Videos | YouTuber | Geek | Consumer Electronics | Tech Head | Internet Personality!\n\nbusiness@MKBHD.com\n\nNYC"
}
]
}

View File

@ -0,0 +1,737 @@
{
"formatVersion": 1,
"database": {
"version": 7,
"identityHash": "012fc8e7ad3333f1597347f34e76a513",
"entities": [
{
"tableName": "subscriptions",
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`uid` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `service_id` INTEGER NOT NULL, `url` TEXT, `name` TEXT, `avatar_url` TEXT, `subscriber_count` INTEGER, `description` TEXT, `notification_mode` INTEGER NOT NULL)",
"fields": [
{
"fieldPath": "uid",
"columnName": "uid",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "serviceId",
"columnName": "service_id",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "url",
"columnName": "url",
"affinity": "TEXT",
"notNull": false
},
{
"fieldPath": "name",
"columnName": "name",
"affinity": "TEXT",
"notNull": false
},
{
"fieldPath": "avatarUrl",
"columnName": "avatar_url",
"affinity": "TEXT",
"notNull": false
},
{
"fieldPath": "subscriberCount",
"columnName": "subscriber_count",
"affinity": "INTEGER",
"notNull": false
},
{
"fieldPath": "description",
"columnName": "description",
"affinity": "TEXT",
"notNull": false
},
{
"fieldPath": "notificationMode",
"columnName": "notification_mode",
"affinity": "INTEGER",
"notNull": true
}
],
"primaryKey": {
"columnNames": [
"uid"
],
"autoGenerate": true
},
"indices": [
{
"name": "index_subscriptions_service_id_url",
"unique": true,
"columnNames": [
"service_id",
"url"
],
"orders": [],
"createSql": "CREATE UNIQUE INDEX IF NOT EXISTS `index_subscriptions_service_id_url` ON `${TABLE_NAME}` (`service_id`, `url`)"
}
],
"foreignKeys": []
},
{
"tableName": "search_history",
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`creation_date` INTEGER, `service_id` INTEGER NOT NULL, `search` TEXT, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)",
"fields": [
{
"fieldPath": "creationDate",
"columnName": "creation_date",
"affinity": "INTEGER",
"notNull": false
},
{
"fieldPath": "serviceId",
"columnName": "service_id",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "search",
"columnName": "search",
"affinity": "TEXT",
"notNull": false
},
{
"fieldPath": "id",
"columnName": "id",
"affinity": "INTEGER",
"notNull": true
}
],
"primaryKey": {
"columnNames": [
"id"
],
"autoGenerate": true
},
"indices": [
{
"name": "index_search_history_search",
"unique": false,
"columnNames": [
"search"
],
"orders": [],
"createSql": "CREATE INDEX IF NOT EXISTS `index_search_history_search` ON `${TABLE_NAME}` (`search`)"
}
],
"foreignKeys": []
},
{
"tableName": "streams",
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`uid` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `service_id` INTEGER NOT NULL, `url` TEXT NOT NULL, `title` TEXT NOT NULL, `stream_type` TEXT NOT NULL, `duration` INTEGER NOT NULL, `uploader` TEXT NOT NULL, `uploader_url` TEXT, `thumbnail_url` TEXT, `view_count` INTEGER, `textual_upload_date` TEXT, `upload_date` INTEGER, `is_upload_date_approximation` INTEGER)",
"fields": [
{
"fieldPath": "uid",
"columnName": "uid",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "serviceId",
"columnName": "service_id",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "url",
"columnName": "url",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "title",
"columnName": "title",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "streamType",
"columnName": "stream_type",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "duration",
"columnName": "duration",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "uploader",
"columnName": "uploader",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "uploaderUrl",
"columnName": "uploader_url",
"affinity": "TEXT",
"notNull": false
},
{
"fieldPath": "thumbnailUrl",
"columnName": "thumbnail_url",
"affinity": "TEXT",
"notNull": false
},
{
"fieldPath": "viewCount",
"columnName": "view_count",
"affinity": "INTEGER",
"notNull": false
},
{
"fieldPath": "textualUploadDate",
"columnName": "textual_upload_date",
"affinity": "TEXT",
"notNull": false
},
{
"fieldPath": "uploadDate",
"columnName": "upload_date",
"affinity": "INTEGER",
"notNull": false
},
{
"fieldPath": "isUploadDateApproximation",
"columnName": "is_upload_date_approximation",
"affinity": "INTEGER",
"notNull": false
}
],
"primaryKey": {
"columnNames": [
"uid"
],
"autoGenerate": true
},
"indices": [
{
"name": "index_streams_service_id_url",
"unique": true,
"columnNames": [
"service_id",
"url"
],
"orders": [],
"createSql": "CREATE UNIQUE INDEX IF NOT EXISTS `index_streams_service_id_url` ON `${TABLE_NAME}` (`service_id`, `url`)"
}
],
"foreignKeys": []
},
{
"tableName": "stream_history",
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`stream_id` INTEGER NOT NULL, `access_date` INTEGER NOT NULL, `repeat_count` INTEGER NOT NULL, PRIMARY KEY(`stream_id`, `access_date`), FOREIGN KEY(`stream_id`) REFERENCES `streams`(`uid`) ON UPDATE CASCADE ON DELETE CASCADE )",
"fields": [
{
"fieldPath": "streamUid",
"columnName": "stream_id",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "accessDate",
"columnName": "access_date",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "repeatCount",
"columnName": "repeat_count",
"affinity": "INTEGER",
"notNull": true
}
],
"primaryKey": {
"columnNames": [
"stream_id",
"access_date"
],
"autoGenerate": false
},
"indices": [
{
"name": "index_stream_history_stream_id",
"unique": false,
"columnNames": [
"stream_id"
],
"orders": [],
"createSql": "CREATE INDEX IF NOT EXISTS `index_stream_history_stream_id` ON `${TABLE_NAME}` (`stream_id`)"
}
],
"foreignKeys": [
{
"table": "streams",
"onDelete": "CASCADE",
"onUpdate": "CASCADE",
"columns": [
"stream_id"
],
"referencedColumns": [
"uid"
]
}
]
},
{
"tableName": "stream_state",
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`stream_id` INTEGER NOT NULL, `progress_time` INTEGER NOT NULL, PRIMARY KEY(`stream_id`), FOREIGN KEY(`stream_id`) REFERENCES `streams`(`uid`) ON UPDATE CASCADE ON DELETE CASCADE )",
"fields": [
{
"fieldPath": "streamUid",
"columnName": "stream_id",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "progressMillis",
"columnName": "progress_time",
"affinity": "INTEGER",
"notNull": true
}
],
"primaryKey": {
"columnNames": [
"stream_id"
],
"autoGenerate": false
},
"indices": [],
"foreignKeys": [
{
"table": "streams",
"onDelete": "CASCADE",
"onUpdate": "CASCADE",
"columns": [
"stream_id"
],
"referencedColumns": [
"uid"
]
}
]
},
{
"tableName": "playlists",
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`uid` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `name` TEXT, `is_thumbnail_permanent` INTEGER NOT NULL, `thumbnail_stream_id` INTEGER NOT NULL)",
"fields": [
{
"fieldPath": "uid",
"columnName": "uid",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "name",
"columnName": "name",
"affinity": "TEXT",
"notNull": false
},
{
"fieldPath": "isThumbnailPermanent",
"columnName": "is_thumbnail_permanent",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "thumbnailStreamId",
"columnName": "thumbnail_stream_id",
"affinity": "INTEGER",
"notNull": true
}
],
"primaryKey": {
"columnNames": [
"uid"
],
"autoGenerate": true
},
"indices": [
{
"name": "index_playlists_name",
"unique": false,
"columnNames": [
"name"
],
"orders": [],
"createSql": "CREATE INDEX IF NOT EXISTS `index_playlists_name` ON `${TABLE_NAME}` (`name`)"
}
],
"foreignKeys": []
},
{
"tableName": "playlist_stream_join",
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`playlist_id` INTEGER NOT NULL, `stream_id` INTEGER NOT NULL, `join_index` INTEGER NOT NULL, PRIMARY KEY(`playlist_id`, `join_index`), FOREIGN KEY(`playlist_id`) REFERENCES `playlists`(`uid`) ON UPDATE CASCADE ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED, FOREIGN KEY(`stream_id`) REFERENCES `streams`(`uid`) ON UPDATE CASCADE ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED)",
"fields": [
{
"fieldPath": "playlistUid",
"columnName": "playlist_id",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "streamUid",
"columnName": "stream_id",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "index",
"columnName": "join_index",
"affinity": "INTEGER",
"notNull": true
}
],
"primaryKey": {
"columnNames": [
"playlist_id",
"join_index"
],
"autoGenerate": false
},
"indices": [
{
"name": "index_playlist_stream_join_playlist_id_join_index",
"unique": true,
"columnNames": [
"playlist_id",
"join_index"
],
"orders": [],
"createSql": "CREATE UNIQUE INDEX IF NOT EXISTS `index_playlist_stream_join_playlist_id_join_index` ON `${TABLE_NAME}` (`playlist_id`, `join_index`)"
},
{
"name": "index_playlist_stream_join_stream_id",
"unique": false,
"columnNames": [
"stream_id"
],
"orders": [],
"createSql": "CREATE INDEX IF NOT EXISTS `index_playlist_stream_join_stream_id` ON `${TABLE_NAME}` (`stream_id`)"
}
],
"foreignKeys": [
{
"table": "playlists",
"onDelete": "CASCADE",
"onUpdate": "CASCADE",
"columns": [
"playlist_id"
],
"referencedColumns": [
"uid"
]
},
{
"table": "streams",
"onDelete": "CASCADE",
"onUpdate": "CASCADE",
"columns": [
"stream_id"
],
"referencedColumns": [
"uid"
]
}
]
},
{
"tableName": "remote_playlists",
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`uid` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `service_id` INTEGER NOT NULL, `name` TEXT, `url` TEXT, `thumbnail_url` TEXT, `uploader` TEXT, `stream_count` INTEGER)",
"fields": [
{
"fieldPath": "uid",
"columnName": "uid",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "serviceId",
"columnName": "service_id",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "name",
"columnName": "name",
"affinity": "TEXT",
"notNull": false
},
{
"fieldPath": "url",
"columnName": "url",
"affinity": "TEXT",
"notNull": false
},
{
"fieldPath": "thumbnailUrl",
"columnName": "thumbnail_url",
"affinity": "TEXT",
"notNull": false
},
{
"fieldPath": "uploader",
"columnName": "uploader",
"affinity": "TEXT",
"notNull": false
},
{
"fieldPath": "streamCount",
"columnName": "stream_count",
"affinity": "INTEGER",
"notNull": false
}
],
"primaryKey": {
"columnNames": [
"uid"
],
"autoGenerate": true
},
"indices": [
{
"name": "index_remote_playlists_name",
"unique": false,
"columnNames": [
"name"
],
"orders": [],
"createSql": "CREATE INDEX IF NOT EXISTS `index_remote_playlists_name` ON `${TABLE_NAME}` (`name`)"
},
{
"name": "index_remote_playlists_service_id_url",
"unique": true,
"columnNames": [
"service_id",
"url"
],
"orders": [],
"createSql": "CREATE UNIQUE INDEX IF NOT EXISTS `index_remote_playlists_service_id_url` ON `${TABLE_NAME}` (`service_id`, `url`)"
}
],
"foreignKeys": []
},
{
"tableName": "feed",
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`stream_id` INTEGER NOT NULL, `subscription_id` INTEGER NOT NULL, PRIMARY KEY(`stream_id`, `subscription_id`), FOREIGN KEY(`stream_id`) REFERENCES `streams`(`uid`) ON UPDATE CASCADE ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED, FOREIGN KEY(`subscription_id`) REFERENCES `subscriptions`(`uid`) ON UPDATE CASCADE ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED)",
"fields": [
{
"fieldPath": "streamId",
"columnName": "stream_id",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "subscriptionId",
"columnName": "subscription_id",
"affinity": "INTEGER",
"notNull": true
}
],
"primaryKey": {
"columnNames": [
"stream_id",
"subscription_id"
],
"autoGenerate": false
},
"indices": [
{
"name": "index_feed_subscription_id",
"unique": false,
"columnNames": [
"subscription_id"
],
"orders": [],
"createSql": "CREATE INDEX IF NOT EXISTS `index_feed_subscription_id` ON `${TABLE_NAME}` (`subscription_id`)"
}
],
"foreignKeys": [
{
"table": "streams",
"onDelete": "CASCADE",
"onUpdate": "CASCADE",
"columns": [
"stream_id"
],
"referencedColumns": [
"uid"
]
},
{
"table": "subscriptions",
"onDelete": "CASCADE",
"onUpdate": "CASCADE",
"columns": [
"subscription_id"
],
"referencedColumns": [
"uid"
]
}
]
},
{
"tableName": "feed_group",
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`uid` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `name` TEXT NOT NULL, `icon_id` INTEGER NOT NULL, `sort_order` INTEGER NOT NULL)",
"fields": [
{
"fieldPath": "uid",
"columnName": "uid",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "name",
"columnName": "name",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "icon",
"columnName": "icon_id",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "sortOrder",
"columnName": "sort_order",
"affinity": "INTEGER",
"notNull": true
}
],
"primaryKey": {
"columnNames": [
"uid"
],
"autoGenerate": true
},
"indices": [
{
"name": "index_feed_group_sort_order",
"unique": false,
"columnNames": [
"sort_order"
],
"orders": [],
"createSql": "CREATE INDEX IF NOT EXISTS `index_feed_group_sort_order` ON `${TABLE_NAME}` (`sort_order`)"
}
],
"foreignKeys": []
},
{
"tableName": "feed_group_subscription_join",
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`group_id` INTEGER NOT NULL, `subscription_id` INTEGER NOT NULL, PRIMARY KEY(`group_id`, `subscription_id`), FOREIGN KEY(`group_id`) REFERENCES `feed_group`(`uid`) ON UPDATE CASCADE ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED, FOREIGN KEY(`subscription_id`) REFERENCES `subscriptions`(`uid`) ON UPDATE CASCADE ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED)",
"fields": [
{
"fieldPath": "feedGroupId",
"columnName": "group_id",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "subscriptionId",
"columnName": "subscription_id",
"affinity": "INTEGER",
"notNull": true
}
],
"primaryKey": {
"columnNames": [
"group_id",
"subscription_id"
],
"autoGenerate": false
},
"indices": [
{
"name": "index_feed_group_subscription_join_subscription_id",
"unique": false,
"columnNames": [
"subscription_id"
],
"orders": [],
"createSql": "CREATE INDEX IF NOT EXISTS `index_feed_group_subscription_join_subscription_id` ON `${TABLE_NAME}` (`subscription_id`)"
}
],
"foreignKeys": [
{
"table": "feed_group",
"onDelete": "CASCADE",
"onUpdate": "CASCADE",
"columns": [
"group_id"
],
"referencedColumns": [
"uid"
]
},
{
"table": "subscriptions",
"onDelete": "CASCADE",
"onUpdate": "CASCADE",
"columns": [
"subscription_id"
],
"referencedColumns": [
"uid"
]
}
]
},
{
"tableName": "feed_last_updated",
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`subscription_id` INTEGER NOT NULL, `last_updated` INTEGER, PRIMARY KEY(`subscription_id`), FOREIGN KEY(`subscription_id`) REFERENCES `subscriptions`(`uid`) ON UPDATE CASCADE ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED)",
"fields": [
{
"fieldPath": "subscriptionId",
"columnName": "subscription_id",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "lastUpdated",
"columnName": "last_updated",
"affinity": "INTEGER",
"notNull": false
}
],
"primaryKey": {
"columnNames": [
"subscription_id"
],
"autoGenerate": false
},
"indices": [],
"foreignKeys": [
{
"table": "subscriptions",
"onDelete": "CASCADE",
"onUpdate": "CASCADE",
"columns": [
"subscription_id"
],
"referencedColumns": [
"uid"
]
}
]
}
],
"views": [],
"setupQueries": [
"CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)",
"INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, '012fc8e7ad3333f1597347f34e76a513')"
]
}
}

View File

@ -101,6 +101,13 @@ class DatabaseMigrationTest {
Migrations.MIGRATION_5_6
)
testHelper.runMigrationsAndValidate(
AppDatabase.DATABASE_NAME,
Migrations.DB_VER_7,
true,
Migrations.MIGRATION_6_7
)
val migratedDatabaseV3 = getMigratedDatabase()
val listFromDB = migratedDatabaseV3.streamDAO().all.blockingFirst()

View File

@ -15,7 +15,7 @@
<queries>
<intent>
<action android:name="android.intent.action.VIEW" />
<data android:scheme="http|https|market" />
<data android:scheme="http" />
</intent>
</queries>

View File

@ -6,6 +6,7 @@ import static org.schabi.newpipe.database.Migrations.MIGRATION_2_3;
import static org.schabi.newpipe.database.Migrations.MIGRATION_3_4;
import static org.schabi.newpipe.database.Migrations.MIGRATION_4_5;
import static org.schabi.newpipe.database.Migrations.MIGRATION_5_6;
import static org.schabi.newpipe.database.Migrations.MIGRATION_6_7;
import android.content.Context;
import android.database.Cursor;
@ -26,7 +27,7 @@ public final class NewPipeDatabase {
return Room
.databaseBuilder(context.getApplicationContext(), AppDatabase.class, DATABASE_NAME)
.addMigrations(MIGRATION_1_2, MIGRATION_2_3, MIGRATION_3_4, MIGRATION_4_5,
MIGRATION_5_6)
MIGRATION_5_6, MIGRATION_6_7)
.build();
}

View File

@ -6,6 +6,7 @@ import android.view.MenuItem
import android.view.View
import android.view.ViewGroup
import android.widget.Button
import androidx.annotation.StringRes
import androidx.appcompat.app.AppCompatActivity
import androidx.fragment.app.Fragment
import androidx.fragment.app.FragmentActivity
@ -57,13 +58,9 @@ class AboutActivity : AppCompatActivity() {
* A placeholder fragment containing a simple view.
*/
class AboutFragment : Fragment() {
private fun Button.openLink(url: Int) {
private fun Button.openLink(@StringRes url: Int) {
setOnClickListener {
ShareUtils.openUrlInBrowser(
context,
requireContext().getString(url),
false
)
ShareUtils.openUrlInApp(context, requireContext().getString(url))
}
}

View File

@ -66,7 +66,7 @@ fun showLicense(context: Context?, component: SoftwareComponent): Disposable {
dialog.dismiss()
}
setNeutralButton(R.string.open_website_license) { _, _ ->
ShareUtils.openUrlInBrowser(context!!, component.link)
ShareUtils.openUrlInApp(context!!, component.link)
}
}
}

View File

@ -1,6 +1,6 @@
package org.schabi.newpipe.database;
import static org.schabi.newpipe.database.Migrations.DB_VER_6;
import static org.schabi.newpipe.database.Migrations.DB_VER_7;
import androidx.room.Database;
import androidx.room.RoomDatabase;
@ -38,7 +38,7 @@ import org.schabi.newpipe.database.subscription.SubscriptionEntity;
FeedEntity.class, FeedGroupEntity.class, FeedGroupSubscriptionEntity.class,
FeedLastUpdatedEntity.class
},
version = DB_VER_6
version = DB_VER_7
)
public abstract class AppDatabase extends RoomDatabase {
public static final String DATABASE_NAME = "newpipe.db";

View File

@ -24,6 +24,7 @@ public final class Migrations {
public static final int DB_VER_4 = 4;
public static final int DB_VER_5 = 5;
public static final int DB_VER_6 = 6;
public static final int DB_VER_7 = 7;
private static final String TAG = Migrations.class.getName();
public static final boolean DEBUG = MainActivity.DEBUG;
@ -197,6 +198,43 @@ public final class Migrations {
}
};
public static final Migration MIGRATION_6_7 = new Migration(DB_VER_6, DB_VER_7) {
@Override
public void migrate(@NonNull final SupportSQLiteDatabase database) {
// Create a new column thumbnail_stream_id
database.execSQL("ALTER TABLE `playlists` ADD COLUMN `thumbnail_stream_id` "
+ "INTEGER NOT NULL DEFAULT -1");
// Migrate the thumbnail_url to the thumbnail_stream_id
database.execSQL("UPDATE playlists SET thumbnail_stream_id = ("
+ " SELECT CASE WHEN COUNT(*) != 0 then stream_uid ELSE -1 END"
+ " FROM ("
+ " SELECT p.uid AS playlist_uid, s.uid AS stream_uid"
+ " FROM playlists p"
+ " LEFT JOIN playlist_stream_join ps ON p.uid = ps.playlist_id"
+ " LEFT JOIN streams s ON s.uid = ps.stream_id"
+ " WHERE s.thumbnail_url = p.thumbnail_url) AS temporary_table"
+ " WHERE playlist_uid = playlists.uid)");
// Remove the thumbnail_url field in the playlist table
database.execSQL("CREATE TABLE IF NOT EXISTS `playlists_new`"
+ "(uid INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "
+ "name TEXT, "
+ "is_thumbnail_permanent INTEGER NOT NULL, "
+ "thumbnail_stream_id INTEGER NOT NULL)");
database.execSQL("INSERT INTO playlists_new"
+ " SELECT uid, name, is_thumbnail_permanent, thumbnail_stream_id "
+ " FROM playlists");
database.execSQL("DROP TABLE playlists");
database.execSQL("ALTER TABLE playlists_new RENAME TO playlists");
database.execSQL("CREATE INDEX IF NOT EXISTS "
+ "`index_playlists_name` ON `playlists` (`name`)");
}
};
private Migrations() {
}
}

View File

@ -32,6 +32,7 @@ abstract class FeedDAO {
* @return the feed streams filtered according to the conditions provided in the parameters
* @see StreamStateEntity.isFinished()
* @see StreamStateEntity.PLAYBACK_FINISHED_END_MILLISECONDS
* @see StreamStateEntity.PLAYBACK_SAVE_THRESHOLD_START_MILLISECONDS
*/
@Query(
"""
@ -66,6 +67,15 @@ abstract class FeedDAO {
OR s.stream_type = 'LIVE_STREAM'
OR s.stream_type = 'AUDIO_LIVE_STREAM'
)
AND (
:includePartiallyPlayed
OR sh.stream_id IS NULL
OR sst.stream_id IS NULL
OR (sst.progress_time <= ${StreamStateEntity.PLAYBACK_SAVE_THRESHOLD_START_MILLISECONDS}
AND sst.progress_time <= s.duration * 1000 / 4)
OR (sst.progress_time >= s.duration * 1000 - ${StreamStateEntity.PLAYBACK_FINISHED_END_MILLISECONDS}
AND sst.progress_time >= s.duration * 1000 * 3 / 4)
)
AND (
:uploadDateBefore IS NULL
OR s.upload_date IS NULL
@ -79,6 +89,7 @@ abstract class FeedDAO {
abstract fun getStreams(
groupId: Long,
includePlayed: Boolean,
includePartiallyPlayed: Boolean,
uploadDateBefore: OffsetDateTime?
): Maybe<List<StreamWithState>>

View File

@ -0,0 +1,24 @@
package org.schabi.newpipe.database.playlist;
import androidx.room.ColumnInfo;
/**
* This class adds a field to {@link PlaylistMetadataEntry} that contains an integer representing
* how many times a specific stream is already contained inside a local playlist. Used to be able
* to grey out playlists which already contain the current stream in the playlist append dialog.
* @see org.schabi.newpipe.local.playlist.LocalPlaylistManager#getPlaylistDuplicates(String)
*/
public class PlaylistDuplicatesEntry extends PlaylistMetadataEntry {
public static final String PLAYLIST_TIMES_STREAM_IS_CONTAINED = "timesStreamIsContained";
@ColumnInfo(name = PLAYLIST_TIMES_STREAM_IS_CONTAINED)
public final long timesStreamIsContained;
public PlaylistDuplicatesEntry(final long uid,
final String name,
final String thumbnailUrl,
final long streamCount,
final long timesStreamIsContained) {
super(uid, name, thumbnailUrl, streamCount);
this.timesStreamIsContained = timesStreamIsContained;
}
}

View File

@ -6,18 +6,23 @@ import androidx.room.RewriteQueriesToDropUnusedColumns;
import androidx.room.Transaction;
import org.schabi.newpipe.database.BasicDAO;
import org.schabi.newpipe.database.playlist.PlaylistDuplicatesEntry;
import org.schabi.newpipe.database.playlist.PlaylistMetadataEntry;
import org.schabi.newpipe.database.playlist.PlaylistStreamEntry;
import org.schabi.newpipe.database.playlist.model.PlaylistEntity;
import org.schabi.newpipe.database.playlist.model.PlaylistStreamEntity;
import java.util.List;
import io.reactivex.rxjava3.core.Flowable;
import static org.schabi.newpipe.database.playlist.PlaylistDuplicatesEntry.PLAYLIST_TIMES_STREAM_IS_CONTAINED;
import static org.schabi.newpipe.database.playlist.PlaylistMetadataEntry.PLAYLIST_STREAM_COUNT;
import static org.schabi.newpipe.database.playlist.model.PlaylistEntity.DEFAULT_THUMBNAIL;
import static org.schabi.newpipe.database.playlist.model.PlaylistEntity.PLAYLIST_ID;
import static org.schabi.newpipe.database.playlist.model.PlaylistEntity.PLAYLIST_NAME;
import static org.schabi.newpipe.database.playlist.model.PlaylistEntity.PLAYLIST_TABLE;
import static org.schabi.newpipe.database.playlist.model.PlaylistEntity.PLAYLIST_THUMBNAIL_STREAM_ID;
import static org.schabi.newpipe.database.playlist.model.PlaylistEntity.PLAYLIST_THUMBNAIL_URL;
import static org.schabi.newpipe.database.playlist.model.PlaylistStreamEntity.JOIN_INDEX;
import static org.schabi.newpipe.database.playlist.model.PlaylistStreamEntity.JOIN_PLAYLIST_ID;
@ -26,6 +31,7 @@ import static org.schabi.newpipe.database.playlist.model.PlaylistStreamEntity.PL
import static org.schabi.newpipe.database.stream.model.StreamEntity.STREAM_ID;
import static org.schabi.newpipe.database.stream.model.StreamEntity.STREAM_TABLE;
import static org.schabi.newpipe.database.stream.model.StreamEntity.STREAM_THUMBNAIL_URL;
import static org.schabi.newpipe.database.stream.model.StreamEntity.STREAM_URL;
import static org.schabi.newpipe.database.stream.model.StreamStateEntity.JOIN_STREAM_ID_ALIAS;
import static org.schabi.newpipe.database.stream.model.StreamStateEntity.STREAM_PROGRESS_MILLIS;
import static org.schabi.newpipe.database.stream.model.StreamStateEntity.STREAM_STATE_TABLE;
@ -54,14 +60,15 @@ public interface PlaylistStreamDAO extends BasicDAO<PlaylistStreamEntity> {
+ " WHERE " + JOIN_PLAYLIST_ID + " = :playlistId")
Flowable<Integer> getMaximumIndexOf(long playlistId);
@Query("SELECT CASE WHEN COUNT(*) != 0 then " + STREAM_THUMBNAIL_URL + " ELSE :defaultUrl END"
@Query("SELECT CASE WHEN COUNT(*) != 0 then " + STREAM_ID
+ " ELSE " + PlaylistEntity.DEFAULT_THUMBNAIL_ID + " END"
+ " FROM " + STREAM_TABLE
+ " LEFT JOIN " + PLAYLIST_STREAM_JOIN_TABLE
+ " ON " + STREAM_ID + " = " + JOIN_STREAM_ID
+ " WHERE " + JOIN_PLAYLIST_ID + " = :playlistId "
+ " LIMIT 1"
)
Flowable<String> getAutomaticThumbnailUrl(long playlistId, String defaultUrl);
Flowable<Long> getAutomaticThumbnailStreamId(long playlistId);
@RewriteQueriesToDropUnusedColumns
@Transaction
@ -84,13 +91,64 @@ public interface PlaylistStreamDAO extends BasicDAO<PlaylistStreamEntity> {
Flowable<List<PlaylistStreamEntry>> getOrderedStreamsOf(long playlistId);
@Transaction
@Query("SELECT " + PLAYLIST_ID + ", " + PLAYLIST_NAME + ", " + PLAYLIST_THUMBNAIL_URL + ", "
+ "COALESCE(COUNT(" + JOIN_PLAYLIST_ID + "), 0) AS " + PLAYLIST_STREAM_COUNT
@Query("SELECT " + PLAYLIST_ID + ", " + PLAYLIST_NAME + ","
+ " CASE WHEN " + PLAYLIST_THUMBNAIL_STREAM_ID + " = "
+ PlaylistEntity.DEFAULT_THUMBNAIL_ID + " THEN " + "'" + DEFAULT_THUMBNAIL + "'"
+ " ELSE (SELECT " + STREAM_THUMBNAIL_URL
+ " FROM " + STREAM_TABLE
+ " WHERE " + STREAM_TABLE + "." + STREAM_ID + " = " + PLAYLIST_THUMBNAIL_STREAM_ID
+ " ) END AS " + PLAYLIST_THUMBNAIL_URL + ", "
+ "COALESCE(COUNT(" + JOIN_PLAYLIST_ID + "), 0) AS " + PLAYLIST_STREAM_COUNT
+ " FROM " + PLAYLIST_TABLE
+ " LEFT JOIN " + PLAYLIST_STREAM_JOIN_TABLE
+ " ON " + PLAYLIST_ID + " = " + JOIN_PLAYLIST_ID
+ " ON " + PLAYLIST_TABLE + "." + PLAYLIST_ID + " = " + JOIN_PLAYLIST_ID
+ " GROUP BY " + PLAYLIST_ID
+ " ORDER BY " + PLAYLIST_NAME + " COLLATE NOCASE ASC")
Flowable<List<PlaylistMetadataEntry>> getPlaylistMetadata();
@RewriteQueriesToDropUnusedColumns
@Transaction
@Query("SELECT *, MIN(" + JOIN_INDEX + ")"
+ " FROM " + STREAM_TABLE + " INNER JOIN"
+ " (SELECT " + JOIN_STREAM_ID + "," + JOIN_INDEX
+ " FROM " + PLAYLIST_STREAM_JOIN_TABLE
+ " WHERE " + JOIN_PLAYLIST_ID + " = :playlistId)"
+ " ON " + STREAM_ID + " = " + JOIN_STREAM_ID
+ " LEFT JOIN "
+ "(SELECT " + JOIN_STREAM_ID + " AS " + JOIN_STREAM_ID_ALIAS + ", "
+ STREAM_PROGRESS_MILLIS
+ " FROM " + STREAM_STATE_TABLE + " )"
+ " ON " + STREAM_ID + " = " + JOIN_STREAM_ID_ALIAS
+ " GROUP BY " + STREAM_ID
+ " ORDER BY MIN(" + JOIN_INDEX + ") ASC")
Flowable<List<PlaylistStreamEntry>> getStreamsWithoutDuplicates(long playlistId);
@Transaction
@Query("SELECT " + PLAYLIST_TABLE + "." + PLAYLIST_ID + ", "
+ PLAYLIST_NAME + ", "
+ " CASE WHEN " + PLAYLIST_THUMBNAIL_STREAM_ID + " = "
+ PlaylistEntity.DEFAULT_THUMBNAIL_ID + " THEN " + "'" + DEFAULT_THUMBNAIL + "'"
+ " ELSE (SELECT " + STREAM_THUMBNAIL_URL
+ " FROM " + STREAM_TABLE
+ " WHERE " + STREAM_TABLE + "." + STREAM_ID + " = " + PLAYLIST_THUMBNAIL_STREAM_ID
+ " ) END AS " + PLAYLIST_THUMBNAIL_URL + ", "
+ "COALESCE(COUNT(" + JOIN_PLAYLIST_ID + "), 0) AS " + PLAYLIST_STREAM_COUNT + ", "
+ "COALESCE(SUM(" + STREAM_URL + " = :streamUrl), 0) AS "
+ PLAYLIST_TIMES_STREAM_IS_CONTAINED
+ " FROM " + PLAYLIST_TABLE
+ " LEFT JOIN " + PLAYLIST_STREAM_JOIN_TABLE
+ " ON " + PLAYLIST_TABLE + "." + PLAYLIST_ID + " = " + JOIN_PLAYLIST_ID
+ " LEFT JOIN " + STREAM_TABLE
+ " ON " + STREAM_TABLE + "." + STREAM_ID + " = " + JOIN_STREAM_ID
+ " AND :streamUrl = :streamUrl"
+ " GROUP BY " + JOIN_PLAYLIST_ID
+ " ORDER BY " + PLAYLIST_NAME + " COLLATE NOCASE ASC")
Flowable<List<PlaylistDuplicatesEntry>> getPlaylistDuplicatesMetadata(String streamUrl);
}

View File

@ -8,14 +8,22 @@ import androidx.room.PrimaryKey;
import static org.schabi.newpipe.database.playlist.model.PlaylistEntity.PLAYLIST_NAME;
import static org.schabi.newpipe.database.playlist.model.PlaylistEntity.PLAYLIST_TABLE;
import org.schabi.newpipe.R;
@Entity(tableName = PLAYLIST_TABLE,
indices = {@Index(value = {PLAYLIST_NAME})})
public class PlaylistEntity {
public static final String DEFAULT_THUMBNAIL = "drawable://"
+ R.drawable.placeholder_thumbnail_playlist;
public static final long DEFAULT_THUMBNAIL_ID = -1;
public static final String PLAYLIST_TABLE = "playlists";
public static final String PLAYLIST_ID = "uid";
public static final String PLAYLIST_NAME = "name";
public static final String PLAYLIST_THUMBNAIL_URL = "thumbnail_url";
public static final String PLAYLIST_THUMBNAIL_PERMANENT = "is_thumbnail_permanent";
public static final String PLAYLIST_THUMBNAIL_STREAM_ID = "thumbnail_stream_id";
@PrimaryKey(autoGenerate = true)
@ColumnInfo(name = PLAYLIST_ID)
@ -24,17 +32,17 @@ public class PlaylistEntity {
@ColumnInfo(name = PLAYLIST_NAME)
private String name;
@ColumnInfo(name = PLAYLIST_THUMBNAIL_URL)
private String thumbnailUrl;
@ColumnInfo(name = PLAYLIST_THUMBNAIL_PERMANENT)
private boolean isThumbnailPermanent;
public PlaylistEntity(final String name, final String thumbnailUrl,
final boolean isThumbnailPermanent) {
@ColumnInfo(name = PLAYLIST_THUMBNAIL_STREAM_ID)
private long thumbnailStreamId;
public PlaylistEntity(final String name, final boolean isThumbnailPermanent,
final long thumbnailStreamId) {
this.name = name;
this.thumbnailUrl = thumbnailUrl;
this.isThumbnailPermanent = isThumbnailPermanent;
this.thumbnailStreamId = thumbnailStreamId;
}
public long getUid() {
@ -53,12 +61,12 @@ public class PlaylistEntity {
this.name = name;
}
public String getThumbnailUrl() {
return thumbnailUrl;
public long getThumbnailStreamId() {
return thumbnailStreamId;
}
public void setThumbnailUrl(final String thumbnailUrl) {
this.thumbnailUrl = thumbnailUrl;
public void setThumbnailStreamId(final long thumbnailStreamId) {
this.thumbnailStreamId = thumbnailStreamId;
}
public boolean getIsThumbnailPermanent() {

View File

@ -30,7 +30,7 @@ public class StreamStateEntity {
/**
* Playback state will not be saved, if playback time is less than this threshold (5000ms = 5s).
*/
private static final long PLAYBACK_SAVE_THRESHOLD_START_MILLISECONDS = 5000;
public static final long PLAYBACK_SAVE_THRESHOLD_START_MILLISECONDS = 5000;
/**
* Stream will be considered finished if the playback time left exceeds this threshold

View File

@ -160,7 +160,7 @@ public class ErrorActivity extends AppCompatActivity {
.setMessage(R.string.start_accept_privacy_policy)
.setCancelable(false)
.setNeutralButton(R.string.read_privacy_policy, (dialog, which) ->
ShareUtils.openUrlInBrowser(context,
ShareUtils.openUrlInApp(context,
context.getString(R.string.privacy_policy_url)))
.setPositiveButton(R.string.accept, (dialog, which) -> {
if (action.equals("EMAIL")) { // send on email
@ -171,9 +171,9 @@ public class ErrorActivity extends AppCompatActivity {
+ getString(R.string.app_name) + " "
+ BuildConfig.VERSION_NAME)
.putExtra(Intent.EXTRA_TEXT, buildJson());
ShareUtils.openIntentInApp(context, i, true);
ShareUtils.openIntentInApp(context, i);
} else if (action.equals("GITHUB")) { // open the NewPipe issue page on GitHub
ShareUtils.openUrlInBrowser(this, ERROR_GITHUB_ISSUE_URL, false);
ShareUtils.openUrlInApp(this, ERROR_GITHUB_ISSUE_URL);
}
})
.setNegativeButton(R.string.decline, (dialog, which) -> {

View File

@ -6,7 +6,6 @@ import android.util.Log
import android.view.View
import android.widget.Button
import android.widget.TextView
import androidx.annotation.Nullable
import androidx.annotation.StringRes
import androidx.core.view.isVisible
import androidx.fragment.app.Fragment
@ -144,7 +143,7 @@ class ErrorPanelHelper(
*/
private fun showAndSetErrorButtonAction(
@StringRes resid: Int,
@Nullable listener: View.OnClickListener
listener: View.OnClickListener
) {
errorActionButton.isVisible = true
errorActionButton.setText(resid)
@ -156,7 +155,7 @@ class ErrorPanelHelper(
) {
errorOpenInBrowserButton.isVisible = true
errorOpenInBrowserButton.setOnClickListener {
ShareUtils.openUrlInBrowser(context, errorInfo.request, true)
ShareUtils.openUrlInBrowser(context, errorInfo.request)
}
}

View File

@ -7,11 +7,10 @@ import static org.schabi.newpipe.ktx.ViewUtils.animate;
import static org.schabi.newpipe.ktx.ViewUtils.animateRotation;
import static org.schabi.newpipe.player.helper.PlayerHelper.globalScreenOrientationLocked;
import static org.schabi.newpipe.player.helper.PlayerHelper.isClearingQueueConfirmationRequired;
import static org.schabi.newpipe.player.playqueue.PlayQueueItem.RECOVERY_UNSET;
import static org.schabi.newpipe.util.DependentPreferenceHelper.getResumePlaybackEnabled;
import static org.schabi.newpipe.util.ExtractorHelper.showMetaInfoInTextView;
import static org.schabi.newpipe.util.ListHelper.getUrlAndNonTorrentStreams;
import static org.schabi.newpipe.util.NavigationHelper.openPlayQueue;
import static org.schabi.newpipe.util.NavigationHelper.playWithKore;
import android.animation.ValueAnimator;
import android.annotation.SuppressLint;
@ -27,6 +26,7 @@ import android.graphics.Color;
import android.graphics.Rect;
import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
@ -54,9 +54,6 @@ import androidx.appcompat.content.res.AppCompatResources;
import androidx.appcompat.widget.Toolbar;
import androidx.coordinatorlayout.widget.CoordinatorLayout;
import androidx.core.content.ContextCompat;
import androidx.core.view.WindowCompat;
import androidx.core.view.WindowInsetsCompat;
import androidx.core.view.WindowInsetsControllerCompat;
import androidx.preference.PreferenceManager;
import com.google.android.exoplayer2.PlaybackException;
@ -485,16 +482,8 @@ public final class VideoDetailFragment
info.getThumbnailUrl())));
binding.detailControlsOpenInBrowser.setOnClickListener(makeOnClickListener(info ->
ShareUtils.openUrlInBrowser(requireContext(), info.getUrl())));
binding.detailControlsPlayWithKodi.setOnClickListener(makeOnClickListener(info -> {
try {
playWithKore(requireContext(), Uri.parse(info.getUrl()));
} catch (final Exception e) {
if (DEBUG) {
Log.i(TAG, "Failed to start kore", e);
}
KoreUtils.showInstallKoreDialog(requireContext());
}
}));
binding.detailControlsPlayWithKodi.setOnClickListener(makeOnClickListener(info ->
KoreUtils.playWithKore(requireContext(), Uri.parse(info.getUrl()))));
if (DEBUG) {
binding.detailControlsCrashThePlayer.setOnClickListener(v ->
VideoDetailPlayerCrasher.onCrashThePlayer(requireContext(), player));
@ -1457,8 +1446,8 @@ public final class VideoDetailFragment
animate(binding.detailThumbnailPlayButton, false, 50);
animate(binding.detailDurationView, false, 100);
animate(binding.detailPositionView, false, 100);
animate(binding.positionView, false, 50);
binding.detailPositionView.setVisibility(View.GONE);
binding.positionView.setVisibility(View.GONE);
binding.detailVideoTitleView.setText(title);
binding.detailVideoTitleView.setMaxLines(1);
@ -1575,7 +1564,7 @@ public final class VideoDetailFragment
binding.detailToggleSecondaryControlsView.setVisibility(View.VISIBLE);
binding.detailSecondaryControlPanel.setVisibility(View.GONE);
updateProgressInfo(info);
checkUpdateProgressInfo(info);
initThumbnailViews(info);
showMetaInfoInTextView(info.getMetaInfo(), binding.detailMetaInfoTextView,
binding.detailMetaInfoSeparator, disposables);
@ -1674,67 +1663,43 @@ public final class VideoDetailFragment
// Stream Results
//////////////////////////////////////////////////////////////////////////*/
private void updateProgressInfo(@NonNull final StreamInfo info) {
private void checkUpdateProgressInfo(@NonNull final StreamInfo info) {
if (positionSubscriber != null) {
positionSubscriber.dispose();
}
final SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(activity);
final boolean playbackResumeEnabled = prefs
.getBoolean(activity.getString(R.string.enable_watch_history_key), true)
&& prefs.getBoolean(activity.getString(R.string.enable_playback_resume_key), true);
final boolean showPlaybackPosition = prefs.getBoolean(
activity.getString(R.string.enable_playback_state_lists_key), true);
if (!playbackResumeEnabled) {
if (playQueue == null || playQueue.getStreams().isEmpty()
|| playQueue.getItem().getRecoveryPosition() == RECOVERY_UNSET
|| !showPlaybackPosition) {
binding.positionView.setVisibility(View.INVISIBLE);
binding.detailPositionView.setVisibility(View.GONE);
// TODO: Remove this check when separation of concerns is done.
// (live streams weren't getting updated because they are mixed)
if (!StreamTypeUtil.isLiveStream(info.getStreamType())) {
return;
}
} else {
// Show saved position from backStack if user allows it
showPlaybackProgress(playQueue.getItem().getRecoveryPosition(),
playQueue.getItem().getDuration() * 1000);
animate(binding.positionView, true, 500);
animate(binding.detailPositionView, true, 500);
}
if (!getResumePlaybackEnabled(activity)) {
binding.positionView.setVisibility(View.GONE);
binding.detailPositionView.setVisibility(View.GONE);
return;
}
final HistoryRecordManager recordManager = new HistoryRecordManager(requireContext());
// TODO: Separate concerns when updating database data.
// (move the updating part to when the loading happens)
positionSubscriber = recordManager.loadStreamState(info)
.subscribeOn(Schedulers.io())
.onErrorComplete()
.observeOn(AndroidSchedulers.mainThread())
.subscribe(state -> {
showPlaybackProgress(state.getProgressMillis(), info.getDuration() * 1000);
animate(binding.positionView, true, 500);
animate(binding.detailPositionView, true, 500);
updatePlaybackProgress(
state.getProgressMillis(), info.getDuration() * 1000);
}, e -> {
if (DEBUG) {
e.printStackTrace();
}
// impossible since the onErrorComplete()
}, () -> {
binding.positionView.setVisibility(View.GONE);
binding.detailPositionView.setVisibility(View.GONE);
});
}
private void showPlaybackProgress(final long progress, final long duration) {
private void updatePlaybackProgress(final long progress, final long duration) {
if (!getResumePlaybackEnabled(activity)) {
return;
}
final int progressSeconds = (int) TimeUnit.MILLISECONDS.toSeconds(progress);
final int durationSeconds = (int) TimeUnit.MILLISECONDS.toSeconds(duration);
// If the old and the new progress values have a big difference then use
// animation. Otherwise don't because it affects CPU
final boolean shouldAnimate = Math.abs(binding.positionView.getProgress()
- progressSeconds) > 2;
// If the old and the new progress values have a big difference then use animation.
// Otherwise don't because it affects CPU
final int progressDifference = Math.abs(binding.positionView.getProgress()
- progressSeconds);
binding.positionView.setMax(durationSeconds);
if (shouldAnimate) {
if (progressDifference > 2) {
binding.positionView.setProgressAnimated(progressSeconds);
} else {
binding.positionView.setProgress(progressSeconds);
@ -1829,7 +1794,7 @@ public final class VideoDetailFragment
}
if (player.getPlayQueue().getItem().getUrl().equals(url)) {
showPlaybackProgress(currentProgress, duration);
updatePlaybackProgress(currentProgress, duration);
}
}
@ -1961,17 +1926,15 @@ public final class VideoDetailFragment
return;
}
final var window = activity.getWindow();
final var windowInsetsController = WindowCompat.getInsetsController(window,
window.getDecorView());
WindowCompat.setDecorFitsSystemWindows(window, true);
windowInsetsController.setSystemBarsBehavior(WindowInsetsControllerCompat
.BEHAVIOR_SHOW_BARS_BY_TOUCH);
windowInsetsController.show(WindowInsetsCompat.Type.systemBars());
window.setStatusBarColor(ThemeHelper.resolveColorFromAttr(requireContext(),
android.R.attr.colorPrimary));
// Prevent jumping of the player on devices with cutout
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
activity.getWindow().getAttributes().layoutInDisplayCutoutMode =
WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_DEFAULT;
}
activity.getWindow().getDecorView().setSystemUiVisibility(0);
activity.getWindow().clearFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
activity.getWindow().setStatusBarColor(ThemeHelper.resolveColorFromAttr(
requireContext(), android.R.attr.colorPrimary));
}
private void hideSystemUi() {
@ -1983,19 +1946,30 @@ public final class VideoDetailFragment
return;
}
final var window = activity.getWindow();
final var windowInsetsController = WindowCompat.getInsetsController(window,
window.getDecorView());
WindowCompat.setDecorFitsSystemWindows(window, false);
windowInsetsController.setSystemBarsBehavior(WindowInsetsControllerCompat
.BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE);
windowInsetsController.hide(WindowInsetsCompat.Type.systemBars());
if (DeviceUtils.isInMultiWindow(activity) || isFullscreen()) {
window.setStatusBarColor(Color.TRANSPARENT);
window.setNavigationBarColor(Color.TRANSPARENT);
// Prevent jumping of the player on devices with cutout
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
activity.getWindow().getAttributes().layoutInDisplayCutoutMode =
WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES;
}
int visibility = View.SYSTEM_UI_FLAG_LAYOUT_STABLE
| View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
| View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
| View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
| View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY;
// In multiWindow mode status bar is not transparent for devices with cutout
// if I include this flag. So without it is better in this case
final boolean isInMultiWindow = DeviceUtils.isInMultiWindow(activity);
if (!isInMultiWindow) {
visibility |= View.SYSTEM_UI_FLAG_FULLSCREEN;
}
activity.getWindow().getDecorView().setSystemUiVisibility(visibility);
if (isInMultiWindow || isFullscreen()) {
activity.getWindow().setStatusBarColor(Color.TRANSPARENT);
activity.getWindow().setNavigationBarColor(Color.TRANSPARENT);
}
activity.getWindow().clearFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
}
// Listener implementation

View File

@ -204,8 +204,7 @@ public class ChannelFragment extends BaseListInfoFragment<StreamInfoItem, Channe
break;
case R.id.menu_item_rss:
if (currentInfo != null) {
ShareUtils.openUrlInBrowser(
requireContext(), currentInfo.getFeedUrl(), false);
ShareUtils.openUrlInApp(requireContext(), currentInfo.getFeedUrl());
}
break;
case R.id.menu_item_openInBrowser:

View File

@ -17,6 +17,7 @@ import org.schabi.newpipe.extractor.channel.ChannelInfoItem;
import org.schabi.newpipe.extractor.comments.CommentsInfoItem;
import org.schabi.newpipe.extractor.playlist.PlaylistInfoItem;
import org.schabi.newpipe.extractor.stream.StreamInfoItem;
import org.schabi.newpipe.info_list.holder.ChannelCardInfoItemHolder;
import org.schabi.newpipe.info_list.holder.ChannelGridInfoItemHolder;
import org.schabi.newpipe.info_list.holder.ChannelInfoItemHolder;
import org.schabi.newpipe.info_list.holder.ChannelMiniInfoItemHolder;
@ -73,6 +74,7 @@ public class InfoListAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolde
private static final int MINI_CHANNEL_HOLDER_TYPE = 0x200;
private static final int CHANNEL_HOLDER_TYPE = 0x201;
private static final int GRID_CHANNEL_HOLDER_TYPE = 0x202;
private static final int CARD_CHANNEL_HOLDER_TYPE = 0x203;
private static final int MINI_PLAYLIST_HOLDER_TYPE = 0x300;
private static final int PLAYLIST_HOLDER_TYPE = 0x301;
private static final int GRID_PLAYLIST_HOLDER_TYPE = 0x302;
@ -249,7 +251,9 @@ public class InfoListAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolde
return STREAM_HOLDER_TYPE;
}
case CHANNEL:
if (itemMode == ItemViewMode.GRID) {
if (itemMode == ItemViewMode.CARD) {
return CARD_CHANNEL_HOLDER_TYPE;
} else if (itemMode == ItemViewMode.GRID) {
return GRID_CHANNEL_HOLDER_TYPE;
} else if (useMiniVariant) {
return MINI_CHANNEL_HOLDER_TYPE;
@ -304,6 +308,8 @@ public class InfoListAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolde
return new ChannelMiniInfoItemHolder(infoItemBuilder, parent);
case CHANNEL_HOLDER_TYPE:
return new ChannelInfoItemHolder(infoItemBuilder, parent);
case CARD_CHANNEL_HOLDER_TYPE:
return new ChannelCardInfoItemHolder(infoItemBuilder, parent);
case GRID_CHANNEL_HOLDER_TYPE:
return new ChannelGridInfoItemHolder(infoItemBuilder, parent);
case MINI_PLAYLIST_HOLDER_TYPE:

View File

@ -99,14 +99,8 @@ public enum StreamDialogDefaultEntry {
)
),
PLAY_WITH_KODI(R.string.play_with_kodi_title, (fragment, item) -> {
final Uri videoUrl = Uri.parse(item.getUrl());
try {
NavigationHelper.playWithKore(fragment.requireContext(), videoUrl);
} catch (final Exception e) {
KoreUtils.showInstallKoreDialog(fragment.requireActivity());
}
}),
PLAY_WITH_KODI(R.string.play_with_kodi_title, (fragment, item) ->
KoreUtils.playWithKore(fragment.requireContext(), Uri.parse(item.getUrl()))),
SHARE(R.string.share, (fragment, item) ->
ShareUtils.shareText(fragment.requireContext(), item.getName(), item.getUrl(),

View File

@ -0,0 +1,22 @@
package org.schabi.newpipe.info_list.holder;
import android.view.ViewGroup;
import androidx.annotation.Nullable;
import org.schabi.newpipe.R;
import org.schabi.newpipe.info_list.InfoItemBuilder;
public class ChannelCardInfoItemHolder extends ChannelMiniInfoItemHolder {
public ChannelCardInfoItemHolder(final InfoItemBuilder infoItemBuilder,
final ViewGroup parent) {
super(infoItemBuilder, R.layout.list_channel_card_item, parent);
}
@Override
protected int getDescriptionMaxLineCount(@Nullable final String content) {
// Based on `list_channel_card_item` left side content (thumbnail 100dp
// + additional details), Right side description can grow up to 8 lines.
return 8;
}
}

View File

@ -46,6 +46,7 @@ public class ChannelMiniInfoItemHolder extends InfoItemHolder {
final ChannelInfoItem item = (ChannelInfoItem) infoItem;
itemTitleView.setText(item.getName());
itemTitleView.setSelected(true);
final String detailLine = getDetailLine(item);
if (detailLine == null) {
@ -77,11 +78,24 @@ public class ChannelMiniInfoItemHolder extends InfoItemHolder {
} else {
itemChannelDescriptionView.setVisibility(View.VISIBLE);
itemChannelDescriptionView.setText(item.getDescription());
itemChannelDescriptionView.setMaxLines(detailLine == null ? 3 : 2);
// setMaxLines utilize the line space for description if the additional details
// (sub / video count) are not present.
// Case1: 2 lines of description + 1 line additional details
// Case2: 3 lines of description (additionalDetails is GONE)
itemChannelDescriptionView.setMaxLines(getDescriptionMaxLineCount(detailLine));
}
}
}
/**
* Returns max number of allowed lines for the description field.
* @param content additional detail content (video / sub count)
* @return max line count
*/
protected int getDescriptionMaxLineCount(@Nullable final String content) {
return content == null ? 3 : 2;
}
@Nullable
private String getDetailLine(final ChannelInfoItem item) {
if (item.getStreamCount() >= 0 && item.getSubscriberCount() >= 0) {

View File

@ -1,8 +1,9 @@
package org.schabi.newpipe.info_list.holder;
import static android.text.TextUtils.isEmpty;
import android.graphics.Paint;
import android.text.Layout;
import android.text.TextUtils;
import android.text.method.LinkMovementMethod;
import android.text.style.URLSpan;
import android.util.Log;
@ -59,9 +60,9 @@ public class CommentsMiniInfoItemHolder extends InfoItemHolder {
private final TextView itemPublishedTime;
private final CompositeDisposable disposables = new CompositeDisposable();
private Description commentText;
private StreamingService streamService;
private String streamUrl;
@Nullable private Description commentText;
@Nullable private StreamingService streamService;
@Nullable private String streamUrl;
CommentsMiniInfoItemHolder(final InfoItemBuilder infoItemBuilder, final int layoutId,
final ViewGroup parent) {
@ -153,15 +154,17 @@ public class CommentsMiniInfoItemHolder extends InfoItemHolder {
if (DeviceUtils.isTv(itemBuilder.getContext())) {
openCommentAuthor(item);
} else {
ShareUtils.copyToClipboard(itemBuilder.getContext(),
itemContentView.getText().toString());
final CharSequence text = itemContentView.getText();
if (text != null) {
ShareUtils.copyToClipboard(itemBuilder.getContext(), text.toString());
}
}
return true;
});
}
private void openCommentAuthor(final CommentsInfoItem item) {
if (TextUtils.isEmpty(item.getUploaderUrl())) {
if (isEmpty(item.getUploaderUrl())) {
return;
}
final AppCompatActivity activity = (AppCompatActivity) itemBuilder.getContext();
@ -207,11 +210,12 @@ public class CommentsMiniInfoItemHolder extends InfoItemHolder {
linkifyCommentContentView(v -> {
boolean hasEllipsis = false;
if (itemContentView.getLineCount() > COMMENT_DEFAULT_LINES) {
final CharSequence charSeqText = itemContentView.getText();
if (charSeqText != null && itemContentView.getLineCount() > COMMENT_DEFAULT_LINES) {
// Note that converting to String removes spans (i.e. links), but that's something
// we actually want since when the text is ellipsized we want all clicks on the
// comment to expand the comment, not to open links.
final String text = itemContentView.getText().toString();
final String text = charSeqText.toString();
final Layout layout = itemContentView.getLayout();
final float lineWidth = layout.getLineWidth(COMMENT_DEFAULT_LINES - 1);
@ -252,7 +256,7 @@ public class CommentsMiniInfoItemHolder extends InfoItemHolder {
private void toggleEllipsize() {
final CharSequence text = itemContentView.getText();
if (text.charAt(text.length() - 1) == ELLIPSIS.charAt(0)) {
if (!isEmpty(text) && text.charAt(text.length() - 1) == ELLIPSIS.charAt(0)) {
expand();
} else if (itemContentView.getLineCount() > COMMENT_DEFAULT_LINES) {
ellipsize();

View File

@ -14,6 +14,7 @@ import org.schabi.newpipe.extractor.stream.StreamInfoItem;
import org.schabi.newpipe.info_list.InfoItemBuilder;
import org.schabi.newpipe.ktx.ViewUtils;
import org.schabi.newpipe.local.history.HistoryRecordManager;
import org.schabi.newpipe.util.DependentPreferenceHelper;
import org.schabi.newpipe.util.Localization;
import org.schabi.newpipe.util.PicassoHelper;
import org.schabi.newpipe.util.StreamTypeUtil;
@ -60,8 +61,12 @@ public class StreamMiniInfoItemHolder extends InfoItemHolder {
R.color.duration_background_color));
itemDurationView.setVisibility(View.VISIBLE);
final StreamStateEntity state2 = historyRecordManager.loadStreamState(infoItem)
.blockingGet()[0];
StreamStateEntity state2 = null;
if (DependentPreferenceHelper
.getPositionsInListsEnabled(itemProgressView.getContext())) {
state2 = historyRecordManager.loadStreamState(infoItem)
.blockingGet()[0];
}
if (state2 != null) {
itemProgressView.setVisibility(View.VISIBLE);
itemProgressView.setMax((int) item.getDuration());
@ -111,9 +116,12 @@ public class StreamMiniInfoItemHolder extends InfoItemHolder {
final HistoryRecordManager historyRecordManager) {
final StreamInfoItem item = (StreamInfoItem) infoItem;
final StreamStateEntity state = historyRecordManager
.loadStreamState(infoItem)
.blockingGet()[0];
StreamStateEntity state = null;
if (DependentPreferenceHelper.getPositionsInListsEnabled(itemProgressView.getContext())) {
state = historyRecordManager
.loadStreamState(infoItem)
.blockingGet()[0];
}
if (state != null && item.getDuration() > 0
&& !StreamTypeUtil.isLiveStream(item.getStreamType())) {
itemProgressView.setMax((int) item.getDuration());

View File

@ -280,10 +280,10 @@ public final class BookmarkFragment extends BaseLocalListFragment<List<PlaylistL
showDeleteDialog(selectedItem.name,
localPlaylistManager.deletePlaylist(selectedItem.uid));
} else if (isThumbnailPermanent && items.get(index).equals(unsetThumbnail)) {
final String thumbnailUrl = localPlaylistManager
.getAutomaticPlaylistThumbnail(selectedItem.uid);
final long thumbnailStreamId = localPlaylistManager
.getAutomaticPlaylistThumbnailStreamId(selectedItem.uid);
localPlaylistManager
.changePlaylistThumbnail(selectedItem.uid, thumbnailUrl, false)
.changePlaylistThumbnail(selectedItem.uid, thumbnailStreamId, false)
.observeOn(AndroidSchedulers.mainThread())
.subscribe();
}

View File

@ -4,6 +4,7 @@ import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import android.widget.Toast;
import androidx.annotation.NonNull;
@ -13,7 +14,8 @@ import androidx.recyclerview.widget.RecyclerView;
import org.schabi.newpipe.NewPipeDatabase;
import org.schabi.newpipe.R;
import org.schabi.newpipe.database.playlist.PlaylistMetadataEntry;
import org.schabi.newpipe.database.playlist.model.PlaylistEntity;
import org.schabi.newpipe.database.playlist.PlaylistDuplicatesEntry;
import org.schabi.newpipe.database.stream.model.StreamEntity;
import org.schabi.newpipe.local.LocalItemListAdapter;
import org.schabi.newpipe.local.playlist.LocalPlaylistManager;
@ -28,6 +30,7 @@ public final class PlaylistAppendDialog extends PlaylistDialog {
private RecyclerView playlistRecyclerView;
private LocalItemListAdapter playlistAdapter;
private TextView playlistDuplicateIndicator;
private final CompositeDisposable playlistDisposables = new CompositeDisposable();
@ -63,8 +66,9 @@ public final class PlaylistAppendDialog extends PlaylistDialog {
playlistAdapter = new LocalItemListAdapter(getActivity());
playlistAdapter.setSelectedListener(selectedItem -> {
final List<StreamEntity> entities = getStreamEntities();
if (selectedItem instanceof PlaylistMetadataEntry && entities != null) {
onPlaylistSelected(playlistManager, (PlaylistMetadataEntry) selectedItem, entities);
if (selectedItem instanceof PlaylistDuplicatesEntry && entities != null) {
onPlaylistSelected(playlistManager,
(PlaylistDuplicatesEntry) selectedItem, entities);
}
});
@ -72,10 +76,13 @@ public final class PlaylistAppendDialog extends PlaylistDialog {
playlistRecyclerView.setLayoutManager(new LinearLayoutManager(requireContext()));
playlistRecyclerView.setAdapter(playlistAdapter);
playlistDuplicateIndicator = view.findViewById(R.id.playlist_duplicate);
final View newPlaylistButton = view.findViewById(R.id.newPlaylist);
newPlaylistButton.setOnClickListener(ignored -> openCreatePlaylistDialog());
playlistDisposables.add(playlistManager.getPlaylists()
playlistDisposables.add(playlistManager
.getPlaylistDuplicates(getStreamEntities().get(0).getUrl())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(this::onPlaylistsReceived));
}
@ -117,31 +124,50 @@ public final class PlaylistAppendDialog extends PlaylistDialog {
requireDialog().dismiss();
}
private void onPlaylistsReceived(@NonNull final List<PlaylistMetadataEntry> playlists) {
if (playlistAdapter != null && playlistRecyclerView != null) {
private void onPlaylistsReceived(@NonNull final List<PlaylistDuplicatesEntry> playlists) {
if (playlistAdapter != null
&& playlistRecyclerView != null
&& playlistDuplicateIndicator != null) {
playlistAdapter.clearStreamItemList();
playlistAdapter.addItems(playlists);
playlistRecyclerView.setVisibility(View.VISIBLE);
playlistDuplicateIndicator.setVisibility(
anyPlaylistContainsDuplicates(playlists) ? View.VISIBLE : View.GONE);
}
}
private void onPlaylistSelected(@NonNull final LocalPlaylistManager manager,
@NonNull final PlaylistMetadataEntry playlist,
@NonNull final List<StreamEntity> streams) {
final Toast successToast = Toast.makeText(getContext(),
R.string.playlist_add_stream_success, Toast.LENGTH_SHORT);
private boolean anyPlaylistContainsDuplicates(final List<PlaylistDuplicatesEntry> playlists) {
return playlists.stream()
.anyMatch(playlist -> playlist.timesStreamIsContained > 0);
}
if (playlist.thumbnailUrl
.equals("drawable://" + R.drawable.placeholder_thumbnail_playlist)) {
playlistDisposables.add(manager
.changePlaylistThumbnail(playlist.uid, streams.get(0).getThumbnailUrl(), false)
.observeOn(AndroidSchedulers.mainThread())
.subscribe(ignored -> successToast.show()));
private void onPlaylistSelected(@NonNull final LocalPlaylistManager manager,
@NonNull final PlaylistDuplicatesEntry playlist,
@NonNull final List<StreamEntity> streams) {
final String toastText;
if (playlist.timesStreamIsContained > 0) {
toastText = getString(R.string.playlist_add_stream_success_duplicate,
playlist.timesStreamIsContained);
} else {
toastText = getString(R.string.playlist_add_stream_success);
}
final Toast successToast = Toast.makeText(getContext(), toastText, Toast.LENGTH_SHORT);
playlistDisposables.add(manager.appendToPlaylist(playlist.uid, streams)
.observeOn(AndroidSchedulers.mainThread())
.subscribe(ignored -> successToast.show()));
.subscribe(ignored -> {
successToast.show();
if (playlist.thumbnailUrl.equals(PlaylistEntity.DEFAULT_THUMBNAIL)) {
playlistDisposables.add(manager
.changePlaylistThumbnail(playlist.uid, streams.get(0).getUid(),
false)
.observeOn(AndroidSchedulers.mainThread())
.subscribe(ignore -> successToast.show()));
}
}));
requireDialog().dismiss();
}

View File

@ -43,11 +43,13 @@ class FeedDatabaseManager(context: Context) {
fun getStreams(
groupId: Long,
includePlayedStreams: Boolean,
includePartiallyPlayedStreams: Boolean,
includeFutureStreams: Boolean
): Maybe<List<StreamWithState>> {
return feedTable.getStreams(
groupId,
includePlayedStreams,
includePartiallyPlayedStreams,
if (includeFutureStreams) null else OffsetDateTime.now()
)
}

View File

@ -37,11 +37,9 @@ import android.view.View
import android.view.ViewGroup
import android.widget.Button
import androidx.appcompat.app.AlertDialog
import androidx.appcompat.content.res.AppCompatResources
import androidx.core.content.edit
import androidx.core.math.MathUtils
import androidx.core.os.bundleOf
import androidx.core.view.MenuItemCompat
import androidx.core.view.isVisible
import androidx.lifecycle.ViewModelProvider
import androidx.preference.PreferenceManager
@ -100,8 +98,6 @@ class FeedFragment : BaseStateFragment<FeedState>() {
private var oldestSubscriptionUpdate: OffsetDateTime? = null
private lateinit var groupAdapter: GroupieAdapter
@State @JvmField var showPlayedItems: Boolean = true
@State @JvmField var showFutureItems: Boolean = true
private var onSettingsChangeListener: SharedPreferences.OnSharedPreferenceChangeListener? = null
private var updateListViewModeOnResume = false
@ -140,8 +136,6 @@ class FeedFragment : BaseStateFragment<FeedState>() {
val factory = FeedViewModel.getFactory(requireContext(), groupId)
viewModel = ViewModelProvider(this, factory)[FeedViewModel::class.java]
showPlayedItems = viewModel.getShowPlayedItemsFromPreferences()
showFutureItems = viewModel.getShowFutureItemsFromPreferences()
viewModel.stateLiveData.observe(viewLifecycleOwner) { it?.let(::handleResult) }
groupAdapter = GroupieAdapter().apply {
@ -216,8 +210,6 @@ class FeedFragment : BaseStateFragment<FeedState>() {
activity.supportActionBar?.subtitle = groupName
inflater.inflate(R.menu.menu_feed_fragment, menu)
updateTogglePlayedItemsButton(menu.findItem(R.id.menu_item_feed_toggle_played_items))
updateToggleFutureItemsButton(menu.findItem(R.id.menu_item_feed_toggle_future_items))
}
override fun onOptionsItemSelected(item: MenuItem): Boolean {
@ -243,20 +235,43 @@ class FeedFragment : BaseStateFragment<FeedState>() {
.show()
return true
} else if (item.itemId == R.id.menu_item_feed_toggle_played_items) {
showPlayedItems = !item.isChecked
updateTogglePlayedItemsButton(item)
viewModel.togglePlayedItems(showPlayedItems)
viewModel.saveShowPlayedItemsToPreferences(showPlayedItems)
} else if (item.itemId == R.id.menu_item_feed_toggle_future_items) {
showFutureItems = !item.isChecked
updateToggleFutureItemsButton(item)
viewModel.toggleFutureItems(showFutureItems)
viewModel.saveShowFutureItemsToPreferences(showFutureItems)
showStreamVisibilityDialog()
}
return super.onOptionsItemSelected(item)
}
private fun showStreamVisibilityDialog() {
val dialogItems = arrayOf(
getString(R.string.feed_show_watched),
getString(R.string.feed_show_partially_watched),
getString(R.string.feed_show_upcoming)
)
val checkedDialogItems = booleanArrayOf(
viewModel.getShowPlayedItemsFromPreferences(),
viewModel.getShowPartiallyPlayedItemsFromPreferences(),
viewModel.getShowFutureItemsFromPreferences()
)
val builder = AlertDialog.Builder(context!!)
builder.setTitle(R.string.feed_hide_streams_title)
builder.setMultiChoiceItems(dialogItems, checkedDialogItems) { _, which, isChecked ->
checkedDialogItems[which] = isChecked
}
builder.setPositiveButton(R.string.ok) { _, _ ->
viewModel.setSaveShowPlayedItems(checkedDialogItems[0])
viewModel.setSaveShowPartiallyPlayedItems(checkedDialogItems[1])
viewModel.setSaveShowFutureItems(checkedDialogItems[2])
}
builder.setNegativeButton(R.string.cancel, null)
builder.create().show()
}
override fun onDestroyOptionsMenu() {
super.onDestroyOptionsMenu()
activity?.supportActionBar?.subtitle = null
@ -283,40 +298,6 @@ class FeedFragment : BaseStateFragment<FeedState>() {
super.onDestroyView()
}
private fun updateTogglePlayedItemsButton(menuItem: MenuItem) {
menuItem.isChecked = showPlayedItems
menuItem.icon = AppCompatResources.getDrawable(
requireContext(),
if (showPlayedItems) R.drawable.ic_visibility_on else R.drawable.ic_visibility_off
)
MenuItemCompat.setTooltipText(
menuItem,
getString(
if (showPlayedItems)
R.string.feed_toggle_hide_played_items
else
R.string.feed_toggle_show_played_items
)
)
}
private fun updateToggleFutureItemsButton(menuItem: MenuItem) {
menuItem.isChecked = showFutureItems
menuItem.icon = AppCompatResources.getDrawable(
requireContext(),
if (showFutureItems) R.drawable.ic_history_future else R.drawable.ic_history
)
MenuItemCompat.setTooltipText(
menuItem,
getString(
if (showFutureItems)
R.string.feed_toggle_hide_future_items
else
R.string.feed_toggle_show_future_items
)
)
}
// //////////////////////////////////////////////////////////////////////////
// Handling
// //////////////////////////////////////////////////////////////////////////

View File

@ -11,7 +11,7 @@ import androidx.lifecycle.viewmodel.viewModelFactory
import androidx.preference.PreferenceManager
import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers
import io.reactivex.rxjava3.core.Flowable
import io.reactivex.rxjava3.functions.Function5
import io.reactivex.rxjava3.functions.Function6
import io.reactivex.rxjava3.processors.BehaviorProcessor
import io.reactivex.rxjava3.schedulers.Schedulers
import org.schabi.newpipe.App
@ -31,18 +31,24 @@ import java.util.concurrent.TimeUnit
class FeedViewModel(
private val application: Application,
groupId: Long = FeedGroupEntity.GROUP_ALL_ID,
initialShowPlayedItems: Boolean = true,
initialShowFutureItems: Boolean = true
initialShowPlayedItems: Boolean,
initialShowPartiallyPlayedItems: Boolean,
initialShowFutureItems: Boolean
) : ViewModel() {
private val feedDatabaseManager = FeedDatabaseManager(application)
private val toggleShowPlayedItems = BehaviorProcessor.create<Boolean>()
private val toggleShowPlayedItemsFlowable = toggleShowPlayedItems
private val showPlayedItems = BehaviorProcessor.create<Boolean>()
private val showPlayedItemsFlowable = showPlayedItems
.startWithItem(initialShowPlayedItems)
.distinctUntilChanged()
private val toggleShowFutureItems = BehaviorProcessor.create<Boolean>()
private val toggleShowFutureItemsFlowable = toggleShowFutureItems
private val showPartiallyPlayedItems = BehaviorProcessor.create<Boolean>()
private val showPartiallyPlayedItemsFlowable = showPartiallyPlayedItems
.startWithItem(initialShowPartiallyPlayedItems)
.distinctUntilChanged()
private val showFutureItems = BehaviorProcessor.create<Boolean>()
private val showFutureItemsFlowable = showFutureItems
.startWithItem(initialShowFutureItems)
.distinctUntilChanged()
@ -52,23 +58,24 @@ class FeedViewModel(
private var combineDisposable = Flowable
.combineLatest(
FeedEventManager.events(),
toggleShowPlayedItemsFlowable,
toggleShowFutureItemsFlowable,
showPlayedItemsFlowable,
showPartiallyPlayedItemsFlowable,
showFutureItemsFlowable,
feedDatabaseManager.notLoadedCount(groupId),
feedDatabaseManager.oldestSubscriptionUpdate(groupId),
Function5 { t1: FeedEventManager.Event, t2: Boolean, t3: Boolean,
t4: Long, t5: List<OffsetDateTime> ->
return@Function5 CombineResultEventHolder(t1, t2, t3, t4, t5.firstOrNull())
Function6 { t1: FeedEventManager.Event, t2: Boolean, t3: Boolean, t4: Boolean,
t5: Long, t6: List<OffsetDateTime> ->
return@Function6 CombineResultEventHolder(t1, t2, t3, t4, t5, t6.firstOrNull())
}
)
.throttleLatest(DEFAULT_THROTTLE_TIMEOUT, TimeUnit.MILLISECONDS)
.subscribeOn(Schedulers.io())
.observeOn(Schedulers.io())
.map { (event, showPlayedItems, showFutureItems, notLoadedCount, oldestUpdate) ->
.map { (event, showPlayedItems, showPartiallyPlayedItems, showFutureItems, notLoadedCount, oldestUpdate) ->
val streamItems = if (event is SuccessResultEvent || event is IdleEvent)
feedDatabaseManager
.getStreams(groupId, showPlayedItems, showFutureItems)
.getStreams(groupId, showPlayedItems, showPartiallyPlayedItems, showFutureItems)
.blockingGet(arrayListOf())
else
arrayListOf()
@ -100,8 +107,9 @@ class FeedViewModel(
val t1: FeedEventManager.Event,
val t2: Boolean,
val t3: Boolean,
val t4: Long,
val t5: OffsetDateTime?
val t4: Boolean,
val t5: Long,
val t6: OffsetDateTime?
)
private data class CombineResultDataHolder(
@ -111,37 +119,49 @@ class FeedViewModel(
val t4: OffsetDateTime?
)
fun togglePlayedItems(showPlayedItems: Boolean) {
toggleShowPlayedItems.onNext(showPlayedItems)
}
fun saveShowPlayedItemsToPreferences(showPlayedItems: Boolean) =
fun setSaveShowPlayedItems(showPlayedItems: Boolean) {
this.showPlayedItems.onNext(showPlayedItems)
PreferenceManager.getDefaultSharedPreferences(application).edit {
this.putBoolean(application.getString(R.string.feed_show_played_items_key), showPlayedItems)
this.putBoolean(application.getString(R.string.feed_show_watched_items_key), showPlayedItems)
this.apply()
}
}
fun getShowPlayedItemsFromPreferences() = getShowPlayedItemsFromPreferences(application)
fun toggleFutureItems(showFutureItems: Boolean) {
toggleShowFutureItems.onNext(showFutureItems)
fun setSaveShowPartiallyPlayedItems(showPartiallyPlayedItems: Boolean) {
this.showPartiallyPlayedItems.onNext(showPartiallyPlayedItems)
PreferenceManager.getDefaultSharedPreferences(application).edit {
this.putBoolean(application.getString(R.string.feed_show_partially_watched_items_key), showPartiallyPlayedItems)
this.apply()
}
}
fun saveShowFutureItemsToPreferences(showFutureItems: Boolean) =
fun getShowPartiallyPlayedItemsFromPreferences() = getShowPartiallyPlayedItemsFromPreferences(application)
fun setSaveShowFutureItems(showFutureItems: Boolean) {
this.showFutureItems.onNext(showFutureItems)
PreferenceManager.getDefaultSharedPreferences(application).edit {
this.putBoolean(application.getString(R.string.feed_show_future_items_key), showFutureItems)
this.apply()
}
}
fun getShowFutureItemsFromPreferences() = getShowFutureItemsFromPreferences(application)
companion object {
private fun getShowPlayedItemsFromPreferences(context: Context) =
PreferenceManager.getDefaultSharedPreferences(context)
.getBoolean(context.getString(R.string.feed_show_played_items_key), true)
.getBoolean(context.getString(R.string.feed_show_watched_items_key), true)
private fun getShowPartiallyPlayedItemsFromPreferences(context: Context) =
PreferenceManager.getDefaultSharedPreferences(context)
.getBoolean(context.getString(R.string.feed_show_partially_watched_items_key), true)
private fun getShowFutureItemsFromPreferences(context: Context) =
PreferenceManager.getDefaultSharedPreferences(context)
.getBoolean(context.getString(R.string.feed_show_future_items_key), true)
fun getFactory(context: Context, groupId: Long) = viewModelFactory {
initializer {
FeedViewModel(
@ -149,6 +169,7 @@ class FeedViewModel(
groupId,
// Read initial value from preferences
getShowPlayedItemsFromPreferences(context.applicationContext),
getShowPartiallyPlayedItemsFromPreferences(context.applicationContext),
getShowFutureItemsFromPreferences(context.applicationContext)
)
}

View File

@ -87,7 +87,7 @@ public class HistoryRecordManager {
* Marks a stream item as watched such that it is hidden from the feed if watched videos are
* hidden. Adds a history entry and updates the stream progress to 100%.
*
* @see FeedViewModel#togglePlayedItems
* @see FeedViewModel#setSaveShowPlayedItems
* @param info the item to mark as watched
* @return a Maybe containing the ID of the item if successful
*/

View File

@ -4,6 +4,7 @@ import android.view.View;
import android.view.ViewGroup;
import org.schabi.newpipe.database.LocalItem;
import org.schabi.newpipe.database.playlist.PlaylistDuplicatesEntry;
import org.schabi.newpipe.database.playlist.PlaylistMetadataEntry;
import org.schabi.newpipe.local.LocalItemBuilder;
import org.schabi.newpipe.local.history.HistoryRecordManager;
@ -13,6 +14,9 @@ import org.schabi.newpipe.util.Localization;
import java.time.format.DateTimeFormatter;
public class LocalPlaylistItemHolder extends PlaylistItemHolder {
private static final float GRAYED_OUT_ALPHA = 0.6f;
public LocalPlaylistItemHolder(final LocalItemBuilder infoItemBuilder, final ViewGroup parent) {
super(infoItemBuilder, parent);
}
@ -38,6 +42,13 @@ public class LocalPlaylistItemHolder extends PlaylistItemHolder {
PicassoHelper.loadPlaylistThumbnail(item.thumbnailUrl).into(itemThumbnailView);
if (item instanceof PlaylistDuplicatesEntry
&& ((PlaylistDuplicatesEntry) item).timesStreamIsContained > 0) {
itemView.setAlpha(GRAYED_OUT_ALPHA);
} else {
itemView.setAlpha(1.0f);
}
super.updateFromItem(localItem, historyRecordManager, dateTimeFormatter);
}
}

View File

@ -14,6 +14,7 @@ import org.schabi.newpipe.database.playlist.PlaylistStreamEntry;
import org.schabi.newpipe.ktx.ViewUtils;
import org.schabi.newpipe.local.LocalItemBuilder;
import org.schabi.newpipe.local.history.HistoryRecordManager;
import org.schabi.newpipe.util.DependentPreferenceHelper;
import org.schabi.newpipe.util.Localization;
import org.schabi.newpipe.util.PicassoHelper;
import org.schabi.newpipe.util.ServiceHelper;
@ -68,7 +69,8 @@ public class LocalPlaylistStreamItemHolder extends LocalItemHolder {
R.color.duration_background_color));
itemDurationView.setVisibility(View.VISIBLE);
if (item.getProgressMillis() > 0) {
if (DependentPreferenceHelper.getPositionsInListsEnabled(itemProgressView.getContext())
&& item.getProgressMillis() > 0) {
itemProgressView.setVisibility(View.VISIBLE);
itemProgressView.setMax((int) item.getStreamEntity().getDuration());
itemProgressView.setProgress((int) TimeUnit.MILLISECONDS
@ -109,7 +111,8 @@ public class LocalPlaylistStreamItemHolder extends LocalItemHolder {
}
final PlaylistStreamEntry item = (PlaylistStreamEntry) localItem;
if (item.getProgressMillis() > 0 && item.getStreamEntity().getDuration() > 0) {
if (DependentPreferenceHelper.getPositionsInListsEnabled(itemProgressView.getContext())
&& item.getProgressMillis() > 0 && item.getStreamEntity().getDuration() > 0) {
itemProgressView.setMax((int) item.getStreamEntity().getDuration());
if (itemProgressView.getVisibility() == View.VISIBLE) {
itemProgressView.setProgressAnimated((int) TimeUnit.MILLISECONDS

View File

@ -14,6 +14,7 @@ import org.schabi.newpipe.database.stream.StreamStatisticsEntry;
import org.schabi.newpipe.ktx.ViewUtils;
import org.schabi.newpipe.local.LocalItemBuilder;
import org.schabi.newpipe.local.history.HistoryRecordManager;
import org.schabi.newpipe.util.DependentPreferenceHelper;
import org.schabi.newpipe.util.Localization;
import org.schabi.newpipe.util.PicassoHelper;
import org.schabi.newpipe.util.ServiceHelper;
@ -97,7 +98,8 @@ public class LocalStatisticStreamItemHolder extends LocalItemHolder {
R.color.duration_background_color));
itemDurationView.setVisibility(View.VISIBLE);
if (item.getProgressMillis() > 0) {
if (DependentPreferenceHelper.getPositionsInListsEnabled(itemProgressView.getContext())
&& item.getProgressMillis() > 0) {
itemProgressView.setVisibility(View.VISIBLE);
itemProgressView.setMax((int) item.getStreamEntity().getDuration());
itemProgressView.setProgress((int) TimeUnit.MILLISECONDS
@ -141,7 +143,8 @@ public class LocalStatisticStreamItemHolder extends LocalItemHolder {
}
final StreamStatisticsEntry item = (StreamStatisticsEntry) localItem;
if (item.getProgressMillis() > 0 && item.getStreamEntity().getDuration() > 0) {
if (DependentPreferenceHelper.getPositionsInListsEnabled(itemProgressView.getContext())
&& item.getProgressMillis() > 0 && item.getStreamEntity().getDuration() > 0) {
itemProgressView.setMax((int) item.getStreamEntity().getDuration());
if (itemProgressView.getVisibility() == View.VISIBLE) {
itemProgressView.setProgressAnimated((int) TimeUnit.MILLISECONDS

View File

@ -35,6 +35,7 @@ import org.schabi.newpipe.R;
import org.schabi.newpipe.database.LocalItem;
import org.schabi.newpipe.database.history.model.StreamHistoryEntry;
import org.schabi.newpipe.database.playlist.PlaylistStreamEntry;
import org.schabi.newpipe.database.playlist.model.PlaylistEntity;
import org.schabi.newpipe.database.stream.model.StreamEntity;
import org.schabi.newpipe.databinding.DialogEditTextBinding;
import org.schabi.newpipe.databinding.LocalPlaylistHeaderBinding;
@ -95,8 +96,8 @@ public class LocalPlaylistFragment extends BaseLocalListFragment<List<PlaylistSt
private AtomicBoolean isLoadingComplete;
/* Has the playlist been modified (e.g. items reordered or deleted) */
private AtomicBoolean isModified;
/* Is the playlist currently being processed to remove watched videos */
private boolean isRemovingWatched = false;
/* Flag to prevent simultaneous rewrites of the playlist */
private boolean isRewritingPlaylist = false;
public static LocalPlaylistFragment getInstance(final long playlistId, final String name) {
final LocalPlaylistFragment instance = new LocalPlaylistFragment();
@ -353,7 +354,7 @@ public class LocalPlaylistFragment extends BaseLocalListFragment<List<PlaylistSt
} else if (item.getItemId() == R.id.menu_item_rename_playlist) {
createRenameDialog();
} else if (item.getItemId() == R.id.menu_item_remove_watched) {
if (!isRemovingWatched) {
if (!isRewritingPlaylist) {
new AlertDialog.Builder(requireContext())
.setMessage(R.string.remove_watched_popup_warning)
.setTitle(R.string.remove_watched_popup_title)
@ -367,6 +368,10 @@ public class LocalPlaylistFragment extends BaseLocalListFragment<List<PlaylistSt
.create()
.show();
}
} else if (item.getItemId() == R.id.menu_item_remove_duplicates) {
if (!isRewritingPlaylist) {
openRemoveDuplicatesDialog();
}
} else {
return super.onOptionsItemSelected(item);
}
@ -388,10 +393,10 @@ public class LocalPlaylistFragment extends BaseLocalListFragment<List<PlaylistSt
}
public void removeWatchedStreams(final boolean removePartiallyWatched) {
if (isRemovingWatched) {
if (isRewritingPlaylist) {
return;
}
isRemovingWatched = true;
isRewritingPlaylist = true;
showLoading();
final var recordManager = new HistoryRecordManager(getContext());
@ -417,8 +422,8 @@ public class LocalPlaylistFragment extends BaseLocalListFragment<List<PlaylistSt
if (indexInHistory < 0) {
itemsToKeep.add(playlistItem);
} else if (!isThumbnailPermanent && !thumbnailVideoRemoved
&& playlistManager.getPlaylistThumbnail(playlistId)
.equals(playlistItem.getStreamEntity().getThumbnailUrl())) {
&& playlistManager.getPlaylistThumbnailStreamId(playlistId)
== playlistItem.getStreamEntity().getUid()) {
thumbnailVideoRemoved = true;
}
}
@ -438,8 +443,8 @@ public class LocalPlaylistFragment extends BaseLocalListFragment<List<PlaylistSt
&& !streamStateEntity.isFinished(duration))) {
itemsToKeep.add(playlistItem);
} else if (!isThumbnailPermanent && !thumbnailVideoRemoved
&& playlistManager.getPlaylistThumbnail(playlistId)
.equals(playlistItem.getStreamEntity().getThumbnailUrl())) {
&& playlistManager.getPlaylistThumbnailStreamId(playlistId)
== playlistItem.getStreamEntity().getUid()) {
thumbnailVideoRemoved = true;
}
}
@ -469,7 +474,7 @@ public class LocalPlaylistFragment extends BaseLocalListFragment<List<PlaylistSt
}
hideLoading();
isRemovingWatched = false;
isRewritingPlaylist = false;
}, throwable -> showError(new ErrorInfo(throwable, UserAction.REQUESTED_BOOKMARK,
"Removing watched videos, partially watched=" + removePartiallyWatched))));
}
@ -587,7 +592,7 @@ public class LocalPlaylistFragment extends BaseLocalListFragment<List<PlaylistSt
disposables.add(disposable);
}
private void changeThumbnailUrl(final String thumbnailUrl, final boolean isPermanent) {
private void changeThumbnailStreamId(final long thumbnailStreamId, final boolean isPermanent) {
if (playlistManager == null || (!isPermanent && playlistManager
.getIsPlaylistThumbnailPermanent(playlistId))) {
return;
@ -599,11 +604,11 @@ public class LocalPlaylistFragment extends BaseLocalListFragment<List<PlaylistSt
if (DEBUG) {
Log.d(TAG, "Updating playlist id=[" + playlistId + "] "
+ "with new thumbnail url=[" + thumbnailUrl + "]");
+ "with new thumbnail stream id=[" + thumbnailStreamId + "]");
}
final Disposable disposable = playlistManager
.changePlaylistThumbnail(playlistId, thumbnailUrl, isPermanent)
.changePlaylistThumbnail(playlistId, thumbnailStreamId, isPermanent)
.observeOn(AndroidSchedulers.mainThread())
.subscribe(ignore -> successToast.show(), throwable ->
showError(new ErrorInfo(throwable, UserAction.REQUESTED_BOOKMARK,
@ -616,16 +621,53 @@ public class LocalPlaylistFragment extends BaseLocalListFragment<List<PlaylistSt
return;
}
final String newThumbnailUrl;
final long thumbnailStreamId;
if (!itemListAdapter.getItemsList().isEmpty()) {
newThumbnailUrl = ((PlaylistStreamEntry) itemListAdapter.getItemsList().get(0))
.getStreamEntity().getThumbnailUrl();
thumbnailStreamId = ((PlaylistStreamEntry) itemListAdapter.getItemsList().get(0))
.getStreamEntity().getUid();
} else {
newThumbnailUrl = "drawable://" + R.drawable.placeholder_thumbnail_playlist;
thumbnailStreamId = PlaylistEntity.DEFAULT_THUMBNAIL_ID;
}
changeThumbnailUrl(newThumbnailUrl, false);
changeThumbnailStreamId(thumbnailStreamId, false);
}
private void openRemoveDuplicatesDialog() {
final AlertDialog.Builder builder = new AlertDialog.Builder(this.getActivity());
builder.setTitle(R.string.remove_duplicates_title)
.setMessage(R.string.remove_duplicates_message)
.setPositiveButton(R.string.ok,
(dialog, i) -> removeDuplicatesInPlaylist())
.setNeutralButton(R.string.cancel, null);
builder.create().show();
}
private void removeDuplicatesInPlaylist() {
if (isRewritingPlaylist) {
return;
}
isRewritingPlaylist = true;
showLoading();
final var streamsMaybe = playlistManager
.getDistinctPlaylistStreams(playlistId).firstElement();
disposables.add(streamsMaybe.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(itemsToKeep -> {
itemListAdapter.clearStreamItemList();
itemListAdapter.addItems(itemsToKeep);
setVideoCount(itemListAdapter.getItemsList().size());
saveChanges();
hideLoading();
isRewritingPlaylist = false;
}, throwable -> showError(new ErrorInfo(throwable, UserAction.REQUESTED_BOOKMARK,
"Removing duplicated streams"))));
}
private void deleteItem(final PlaylistStreamEntry item) {
@ -634,8 +676,7 @@ public class LocalPlaylistFragment extends BaseLocalListFragment<List<PlaylistSt
}
itemListAdapter.removeItem(item);
if (playlistManager.getPlaylistThumbnail(playlistId)
.equals(item.getStreamEntity().getThumbnailUrl())) {
if (playlistManager.getPlaylistThumbnailStreamId(playlistId) == item.getStreamId()) {
updateThumbnailUrl();
}
@ -793,7 +834,7 @@ public class LocalPlaylistFragment extends BaseLocalListFragment<List<PlaylistSt
.setAction(
StreamDialogDefaultEntry.SET_AS_PLAYLIST_THUMBNAIL,
(f, i) ->
changeThumbnailUrl(item.getStreamEntity().getThumbnailUrl(),
changeThumbnailStreamId(item.getStreamEntity().getUid(),
true))
.setAction(
StreamDialogDefaultEntry.DELETE,

View File

@ -2,8 +2,8 @@ package org.schabi.newpipe.local.playlist;
import androidx.annotation.Nullable;
import org.schabi.newpipe.R;
import org.schabi.newpipe.database.AppDatabase;
import org.schabi.newpipe.database.playlist.PlaylistDuplicatesEntry;
import org.schabi.newpipe.database.playlist.PlaylistMetadataEntry;
import org.schabi.newpipe.database.playlist.PlaylistStreamEntry;
import org.schabi.newpipe.database.playlist.dao.PlaylistDAO;
@ -23,6 +23,8 @@ import io.reactivex.rxjava3.core.Single;
import io.reactivex.rxjava3.schedulers.Schedulers;
public class LocalPlaylistManager {
private static final long THUMBNAIL_ID_LEAVE_UNCHANGED = -2;
private final AppDatabase database;
private final StreamDAO streamTable;
private final PlaylistDAO playlistTable;
@ -40,30 +42,34 @@ public class LocalPlaylistManager {
if (streams.isEmpty()) {
return Maybe.empty();
}
final StreamEntity defaultStream = streams.get(0);
final PlaylistEntity newPlaylist =
new PlaylistEntity(name, defaultStream.getThumbnailUrl(), false);
return Maybe.fromCallable(() -> database.runInTransaction(() ->
upsertStreams(playlistTable.insert(newPlaylist), streams, 0))
).subscribeOn(Schedulers.io());
return Maybe.fromCallable(() -> database.runInTransaction(() -> {
final List<Long> streamIds = streamTable.upsertAll(streams);
final PlaylistEntity newPlaylist = new PlaylistEntity(name, false,
streamIds.get(0));
return insertJoinEntities(playlistTable.insert(newPlaylist),
streamIds, 0);
}
)).subscribeOn(Schedulers.io());
}
public Maybe<List<Long>> appendToPlaylist(final long playlistId,
final List<StreamEntity> streams) {
return playlistStreamTable.getMaximumIndexOf(playlistId)
.firstElement()
.map(maxJoinIndex -> database.runInTransaction(() ->
upsertStreams(playlistId, streams, maxJoinIndex + 1))
).subscribeOn(Schedulers.io());
.map(maxJoinIndex -> database.runInTransaction(() -> {
final List<Long> streamIds = streamTable.upsertAll(streams);
return insertJoinEntities(playlistId, streamIds, maxJoinIndex + 1);
}
)).subscribeOn(Schedulers.io());
}
private List<Long> upsertStreams(final long playlistId,
final List<StreamEntity> streams,
final int indexOffset) {
private List<Long> insertJoinEntities(final long playlistId, final List<Long> streamIds,
final int indexOffset) {
final List<PlaylistStreamEntity> joinEntities = new ArrayList<>(streamIds.size());
final List<PlaylistStreamEntity> joinEntities = new ArrayList<>(streams.size());
final List<Long> streamIds = streamTable.upsertAll(streams);
for (int index = 0; index < streamIds.size(); index++) {
joinEntities.add(new PlaylistStreamEntity(playlistId, streamIds.get(index),
index + indexOffset));
@ -87,6 +93,23 @@ public class LocalPlaylistManager {
return playlistStreamTable.getPlaylistMetadata().subscribeOn(Schedulers.io());
}
public Flowable<List<PlaylistStreamEntry>> getDistinctPlaylistStreams(final long playlistId) {
return playlistStreamTable
.getStreamsWithoutDuplicates(playlistId).subscribeOn(Schedulers.io());
}
/**
* Get playlists with attached information about how many times the provided stream is already
* contained in each playlist.
*
* @param streamUrl the stream url for which to check for duplicates
* @return a list of {@link PlaylistDuplicatesEntry}
*/
public Flowable<List<PlaylistDuplicatesEntry>> getPlaylistDuplicates(final String streamUrl) {
return playlistStreamTable.getPlaylistDuplicatesMetadata(streamUrl)
.subscribeOn(Schedulers.io());
}
public Flowable<List<PlaylistStreamEntry>> getPlaylistStreams(final long playlistId) {
return playlistStreamTable.getOrderedStreamsOf(playlistId).subscribeOn(Schedulers.io());
}
@ -97,17 +120,17 @@ public class LocalPlaylistManager {
}
public Maybe<Integer> renamePlaylist(final long playlistId, final String name) {
return modifyPlaylist(playlistId, name, null, false);
return modifyPlaylist(playlistId, name, THUMBNAIL_ID_LEAVE_UNCHANGED, false);
}
public Maybe<Integer> changePlaylistThumbnail(final long playlistId,
final String thumbnailUrl,
final long thumbnailStreamId,
final boolean isPermanent) {
return modifyPlaylist(playlistId, null, thumbnailUrl, isPermanent);
return modifyPlaylist(playlistId, null, thumbnailStreamId, isPermanent);
}
public String getPlaylistThumbnail(final long playlistId) {
return playlistTable.getPlaylist(playlistId).blockingFirst().get(0).getThumbnailUrl();
public long getPlaylistThumbnailStreamId(final long playlistId) {
return playlistTable.getPlaylist(playlistId).blockingFirst().get(0).getThumbnailStreamId();
}
public boolean getIsPlaylistThumbnailPermanent(final long playlistId) {
@ -115,14 +138,18 @@ public class LocalPlaylistManager {
.getIsThumbnailPermanent();
}
public String getAutomaticPlaylistThumbnail(final long playlistId) {
final String def = "drawable://" + R.drawable.placeholder_thumbnail_playlist;
return playlistStreamTable.getAutomaticThumbnailUrl(playlistId, def).blockingFirst();
public long getAutomaticPlaylistThumbnailStreamId(final long playlistId) {
final long streamId = playlistStreamTable.getAutomaticThumbnailStreamId(playlistId)
.blockingFirst();
if (streamId < 0) {
return PlaylistEntity.DEFAULT_THUMBNAIL_ID;
}
return streamId;
}
private Maybe<Integer> modifyPlaylist(final long playlistId,
@Nullable final String name,
@Nullable final String thumbnailUrl,
final long thumbnailStreamId,
final boolean isPermanent) {
return playlistTable.getPlaylist(playlistId)
.firstElement()
@ -132,8 +159,8 @@ public class LocalPlaylistManager {
if (name != null) {
playlist.setName(name);
}
if (thumbnailUrl != null) {
playlist.setThumbnailUrl(thumbnailUrl);
if (thumbnailStreamId != THUMBNAIL_ID_LEAVE_UNCHANGED) {
playlist.setThumbnailStreamId(thumbnailStreamId);
playlist.setIsThumbnailPermanent(isPermanent);
}
return playlistTable.update(playlist);

View File

@ -60,7 +60,6 @@ import org.schabi.newpipe.util.NavigationHelper
import org.schabi.newpipe.util.OnClickGesture
import org.schabi.newpipe.util.ServiceHelper
import org.schabi.newpipe.util.ThemeHelper.getGridSpanCountChannels
import org.schabi.newpipe.util.ThemeHelper.shouldUseGridLayout
import org.schabi.newpipe.util.external_communication.ShareUtils
import java.text.SimpleDateFormat
import java.util.Date
@ -245,7 +244,7 @@ class SubscriptionFragment : BaseStateFragment<SubscriptionState>() {
super.initViews(rootView, savedInstanceState)
_binding = FragmentSubscriptionBinding.bind(rootView)
groupAdapter.spanCount = if (shouldUseGridLayout(context)) getGridSpanCountChannels(context) else 1
groupAdapter.spanCount = if (SubscriptionViewModel.shouldUseGridForSubscription(requireContext())) getGridSpanCountChannels(context) else 1
binding.itemsList.layoutManager = GridLayoutManager(requireContext(), groupAdapter.spanCount).apply {
spanSizeLookup = groupAdapter.spanSizeLookup
}
@ -380,15 +379,15 @@ class SubscriptionFragment : BaseStateFragment<SubscriptionState>() {
override fun handleResult(result: SubscriptionState) {
super.handleResult(result)
val shouldUseGridLayout = shouldUseGridLayout(context)
when (result) {
is SubscriptionState.LoadedState -> {
result.subscriptions.forEach {
if (it is ChannelItem) {
it.gesturesListener = listenerChannelItem
it.itemVersion = when {
shouldUseGridLayout -> ChannelItem.ItemVersion.GRID
else -> ChannelItem.ItemVersion.MINI
it.itemVersion = if (SubscriptionViewModel.shouldUseGridForSubscription(requireContext())) {
ChannelItem.ItemVersion.GRID
} else {
ChannelItem.ItemVersion.MINI
}
}
}

View File

@ -1,6 +1,7 @@
package org.schabi.newpipe.local.subscription
import android.app.Application
import android.content.Context
import androidx.lifecycle.AndroidViewModel
import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
@ -8,12 +9,13 @@ import com.xwray.groupie.Group
import io.reactivex.rxjava3.core.Flowable
import io.reactivex.rxjava3.processors.BehaviorProcessor
import io.reactivex.rxjava3.schedulers.Schedulers
import org.schabi.newpipe.info_list.ItemViewMode
import org.schabi.newpipe.local.feed.FeedDatabaseManager
import org.schabi.newpipe.local.subscription.item.ChannelItem
import org.schabi.newpipe.local.subscription.item.FeedGroupCardGridItem
import org.schabi.newpipe.local.subscription.item.FeedGroupCardItem
import org.schabi.newpipe.util.DEFAULT_THROTTLE_TIMEOUT
import org.schabi.newpipe.util.ThemeHelper
import org.schabi.newpipe.util.ThemeHelper.getItemViewMode
import java.util.concurrent.TimeUnit
class SubscriptionViewModel(application: Application) : AndroidViewModel(application) {
@ -22,7 +24,7 @@ class SubscriptionViewModel(application: Application) : AndroidViewModel(applica
// true -> list view, false -> grid view
private val listViewMode = BehaviorProcessor.createDefault(
!ThemeHelper.shouldUseGridLayout(application)
!shouldUseGridForSubscription(application)
)
private val listViewModeFlowable = listViewMode.distinctUntilChanged()
@ -77,4 +79,26 @@ class SubscriptionViewModel(application: Application) : AndroidViewModel(applica
data class LoadedState(val subscriptions: List<Group>) : SubscriptionState()
data class ErrorState(val error: Throwable? = null) : SubscriptionState()
}
companion object {
/**
* Returns whether to use GridLayout mode for Subscription Fragment.
*
* ### Current mapping:
*
* | ItemViewMode | ItemVersion | Span count |
* |---|---|---|
* | AUTO | MINI | 1 |
* | LIST | MINI | 1 |
* | CARD | GRID | > 1 (ThemeHelper defined) |
* | GRID | GRID | > 1 (ThemeHelper defined) |
*
* @see [SubscriptionViewModel.shouldUseGridForSubscription] to modify Layout Manager
*/
fun shouldUseGridForSubscription(context: Context): Boolean {
val itemViewMode = getItemViewMode(context)
return itemViewMode == ItemViewMode.GRID || itemViewMode == ItemViewMode.CARD
}
}
}

View File

@ -29,7 +29,6 @@ import static com.google.android.exoplayer2.Player.REPEAT_MODE_ONE;
import static com.google.android.exoplayer2.Player.RepeatMode;
import static org.schabi.newpipe.extractor.ServiceList.YouTube;
import static org.schabi.newpipe.extractor.utils.Utils.isNullOrEmpty;
import static org.schabi.newpipe.player.helper.PlayerHelper.isPlaybackResumeEnabled;
import static org.schabi.newpipe.player.helper.PlayerHelper.nextRepeatMode;
import static org.schabi.newpipe.player.helper.PlayerHelper.retrievePlaybackParametersFromPrefs;
import static org.schabi.newpipe.player.helper.PlayerHelper.retrieveSeekDurationFromPreferences;
@ -115,6 +114,7 @@ import org.schabi.newpipe.player.ui.PlayerUi;
import org.schabi.newpipe.player.ui.PlayerUiList;
import org.schabi.newpipe.player.ui.PopupPlayerUi;
import org.schabi.newpipe.player.ui.VideoPlayerUi;
import org.schabi.newpipe.util.DependentPreferenceHelper;
import org.schabi.newpipe.util.DeviceUtils;
import org.schabi.newpipe.util.ListHelper;
import org.schabi.newpipe.util.NavigationHelper;
@ -391,7 +391,7 @@ public final class Player implements PlaybackListener, Listener {
simpleExoPlayer.setPlayWhenReady(playWhenReady);
} else if (intent.getBooleanExtra(RESUME_PLAYBACK, false)
&& isPlaybackResumeEnabled(this)
&& DependentPreferenceHelper.getResumePlaybackEnabled(context)
&& !samePlayQueue
&& !newQueue.isEmpty()
&& newQueue.getItem() != null

View File

@ -14,6 +14,7 @@ import static java.lang.annotation.RetentionPolicy.SOURCE;
import android.annotation.SuppressLint;
import android.content.Context;
import android.content.SharedPreferences;
import android.content.pm.PackageManager;
import android.provider.Settings;
import android.view.accessibility.CaptioningManager;
@ -382,8 +383,11 @@ public final class PlayerHelper {
public static boolean globalScreenOrientationLocked(final Context context) {
// 1: Screen orientation changes using accelerometer
// 0: Screen orientation is locked
// if the accelerometer sensor is missing completely, assume locked orientation
return android.provider.Settings.System.getInt(
context.getContentResolver(), Settings.System.ACCELEROMETER_ROTATION, 0) == 0;
context.getContentResolver(), Settings.System.ACCELEROMETER_ROTATION, 0) == 0
|| !context.getPackageManager()
.hasSystemFeature(PackageManager.FEATURE_SENSOR_ACCELEROMETER);
}
public static int getProgressiveLoadIntervalBytes(@NonNull final Context context) {
@ -425,13 +429,6 @@ public final class PlayerHelper {
// Utils used by player
////////////////////////////////////////////////////////////////////////////
public static boolean isPlaybackResumeEnabled(final Player player) {
return player.getPrefs().getBoolean(
player.getContext().getString(R.string.enable_watch_history_key), true)
&& player.getPrefs().getBoolean(
player.getContext().getString(R.string.enable_playback_resume_key), true);
}
@RepeatMode
public static int nextRepeatMode(@RepeatMode final int repeatMode) {
switch (repeatMode) {

View File

@ -3,6 +3,7 @@ package org.schabi.newpipe.player.mediasession;
import static org.schabi.newpipe.MainActivity.DEBUG;
import android.content.Intent;
import android.content.SharedPreferences;
import android.graphics.Bitmap;
import android.support.v4.media.MediaMetadataCompat;
import android.support.v4.media.session.MediaSessionCompat;
@ -23,14 +24,20 @@ import org.schabi.newpipe.util.StreamTypeUtil;
import java.util.Optional;
public class MediaSessionPlayerUi extends PlayerUi {
public class MediaSessionPlayerUi extends PlayerUi
implements SharedPreferences.OnSharedPreferenceChangeListener {
private static final String TAG = "MediaSessUi";
private MediaSessionCompat mediaSession;
private MediaSessionConnector sessionConnector;
private final String ignoreHardwareMediaButtonsKey;
private boolean shouldIgnoreHardwareMediaButtons = false;
public MediaSessionPlayerUi(@NonNull final Player player) {
super(player);
ignoreHardwareMediaButtonsKey =
context.getString(R.string.ignore_hardware_media_buttons_key);
}
@Override
@ -45,6 +52,15 @@ public class MediaSessionPlayerUi extends PlayerUi {
sessionConnector.setQueueNavigator(new PlayQueueNavigator(mediaSession, player));
sessionConnector.setPlayer(getForwardingPlayer());
// It seems like events from the Media Control UI in the notification area don't go through
// this function, so it's safe to just ignore all events in case we want to ignore the
// hardware media buttons. Returning true stops all further event processing of the system.
sessionConnector.setMediaButtonEventHandler((p, i) -> shouldIgnoreHardwareMediaButtons);
// listen to changes to ignore_hardware_media_buttons_key
updateShouldIgnoreHardwareMediaButtons(player.getPrefs());
player.getPrefs().registerOnSharedPreferenceChangeListener(this);
sessionConnector.setMetadataDeduplicationEnabled(true);
sessionConnector.setMediaMetadataProvider(exoPlayer -> buildMediaMetadata());
}
@ -52,7 +68,9 @@ public class MediaSessionPlayerUi extends PlayerUi {
@Override
public void destroyPlayer() {
super.destroyPlayer();
player.getPrefs().unregisterOnSharedPreferenceChangeListener(this);
if (sessionConnector != null) {
sessionConnector.setMediaButtonEventHandler(null);
sessionConnector.setPlayer(null);
sessionConnector.setQueueNavigator(null);
sessionConnector = null;
@ -74,6 +92,20 @@ public class MediaSessionPlayerUi extends PlayerUi {
}
@Override
public void onSharedPreferenceChanged(final SharedPreferences sharedPreferences,
final String key) {
if (key == null || key.equals(ignoreHardwareMediaButtonsKey)) {
updateShouldIgnoreHardwareMediaButtons(sharedPreferences);
}
}
public void updateShouldIgnoreHardwareMediaButtons(final SharedPreferences sharedPreferences) {
shouldIgnoreHardwareMediaButtons =
sharedPreferences.getBoolean(ignoreHardwareMediaButtonsKey, false);
}
public void handleMediaButtonIntent(final Intent intent) {
MediaButtonReceiver.handleIntent(mediaSession, intent);
}

View File

@ -1,27 +1,21 @@
package org.schabi.newpipe.player.mediasource;
import androidx.annotation.NonNull;
import com.google.android.exoplayer2.MediaItem;
import com.google.android.exoplayer2.Timeline;
import com.google.android.exoplayer2.source.CompositeMediaSource;
import com.google.android.exoplayer2.source.MediaPeriod;
import com.google.android.exoplayer2.source.MediaSource;
import com.google.android.exoplayer2.upstream.Allocator;
import com.google.android.exoplayer2.upstream.TransferListener;
import com.google.android.exoplayer2.source.WrappingMediaSource;
import org.schabi.newpipe.player.mediaitem.MediaItemTag;
import org.schabi.newpipe.player.playqueue.PlayQueueItem;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
public class LoadedMediaSource extends CompositeMediaSource<Integer> implements ManagedMediaSource {
private final MediaSource source;
public class LoadedMediaSource extends WrappingMediaSource implements ManagedMediaSource {
private final PlayQueueItem stream;
private final MediaItem mediaItem;
private final long expireTimestamp;
/**
* Uses a {@link CompositeMediaSource} to wrap one or more child {@link MediaSource}s
* Uses a {@link WrappingMediaSource} to wrap one child {@link MediaSource}s
* containing actual media. This wrapper {@link LoadedMediaSource} holds the expiration
* timestamp as a {@link ManagedMediaSource} to allow explicit playlist management under
* {@link ManagedMediaSourcePlaylist}.
@ -36,7 +30,7 @@ public class LoadedMediaSource extends CompositeMediaSource<Integer> implements
@NonNull final MediaItemTag tag,
@NonNull final PlayQueueItem stream,
final long expireTimestamp) {
this.source = source;
super(source);
this.stream = stream;
this.expireTimestamp = expireTimestamp;
@ -51,51 +45,6 @@ public class LoadedMediaSource extends CompositeMediaSource<Integer> implements
return System.currentTimeMillis() >= expireTimestamp;
}
/**
* Delegates the preparation of child {@link MediaSource}s to the
* {@link CompositeMediaSource} wrapper. Since all {@link LoadedMediaSource}s use only
* a single child media, the child id of 0 is always used (sonar doesn't like null as id here).
*
* @param mediaTransferListener A data transfer listener that will be registered by the
* {@link CompositeMediaSource} for child source preparation.
*/
@Override
protected void prepareSourceInternal(@Nullable final TransferListener mediaTransferListener) {
super.prepareSourceInternal(mediaTransferListener);
prepareChildSource(0, source);
}
/**
* When any child {@link MediaSource} is prepared, the refreshed {@link Timeline} can
* be listened to here. But since {@link LoadedMediaSource} has only a single child source,
* this method is called only once until {@link #releaseSourceInternal()} is called.
* <br><br>
* On refresh, the {@link CompositeMediaSource} delegate will be notified with the
* new {@link Timeline}, otherwise {@link #createPeriod(MediaPeriodId, Allocator, long)}
* will not be called and playback may be stalled.
*
* @param id The unique id used to prepare the child source.
* @param mediaSource The child source whose source info has been refreshed.
* @param timeline The new timeline of the child source.
*/
@Override
protected void onChildSourceInfoRefreshed(final Integer id,
final MediaSource mediaSource,
final Timeline timeline) {
refreshSourceInfo(timeline);
}
@Override
public MediaPeriod createPeriod(final MediaPeriodId id, final Allocator allocator,
final long startPositionUs) {
return source.createPeriod(id, allocator, startPositionUs);
}
@Override
public void releasePeriod(final MediaPeriod mediaPeriod) {
source.releasePeriod(mediaPeriod);
}
@NonNull
@Override
public MediaItem getMediaItem() {

View File

@ -32,6 +32,7 @@ import android.view.KeyEvent;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewParent;
import android.view.WindowManager;
import android.widget.FrameLayout;
import android.widget.LinearLayout;
@ -39,8 +40,6 @@ import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.content.res.AppCompatResources;
import androidx.core.view.WindowCompat;
import androidx.core.view.WindowInsetsCompat;
import androidx.fragment.app.FragmentActivity;
import androidx.recyclerview.widget.ItemTouchHelper;
import androidx.recyclerview.widget.RecyclerView;
@ -453,9 +452,11 @@ public final class MainPlayerUi extends VideoPlayerUi implements View.OnLayoutCh
getParentActivity().map(Activity::getWindow).ifPresent(window -> {
window.setStatusBarColor(Color.TRANSPARENT);
window.setNavigationBarColor(Color.TRANSPARENT);
WindowCompat.setDecorFitsSystemWindows(window, false);
WindowCompat.getInsetsController(window, window.getDecorView())
.show(WindowInsetsCompat.Type.systemBars());
final int visibility = View.SYSTEM_UI_FLAG_LAYOUT_STABLE
| View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
| View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION;
window.getDecorView().setSystemUiVisibility(visibility);
window.clearFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
});
}
}

View File

@ -1420,14 +1420,7 @@ public abstract class VideoPlayerUi extends PlayerUi implements SeekBar.OnSeekBa
private void onPlayWithKodiClicked() {
if (player.getCurrentMetadata() != null) {
player.pause();
try {
NavigationHelper.playWithKore(context, Uri.parse(player.getVideoUrl()));
} catch (final Exception e) {
if (DEBUG) {
Log.i(TAG, "Failed to start kore", e);
}
KoreUtils.showInstallKoreDialog(player.getContext());
}
KoreUtils.playWithKore(context, Uri.parse(player.getVideoUrl()));
}
}

View File

@ -0,0 +1,51 @@
package org.schabi.newpipe.util;
import android.content.Context;
import android.content.SharedPreferences;
import androidx.preference.PreferenceManager;
import org.schabi.newpipe.R;
/**
* For preferences with dependencies and multiple use case,
* this class can be used to reduce the lines of code.
*/
public final class DependentPreferenceHelper {
private DependentPreferenceHelper() {
// no instance
}
/**
* Option `Resume playback` depends on `Watch history`, this method can be used to retrieve if
* `Resume playback` and its dependencies are all enabled.
*
* @param context the Android context
* @return returns true if `Resume playback` and `Watch history` are both enabled
*/
public static boolean getResumePlaybackEnabled(final Context context) {
final SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
return prefs.getBoolean(context.getString(
R.string.enable_watch_history_key), true)
&& prefs.getBoolean(context.getString(
R.string.enable_playback_resume_key), true);
}
/**
* Option `Position in lists` depends on `Watch history`, this method can be used to retrieve if
* `Position in lists` and its dependencies are all enabled.
*
* @param context the Android context
* @return returns true if `Positions in lists` and `Watch history` are both enabled
*/
public static boolean getPositionsInListsEnabled(final Context context) {
final SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
return prefs.getBoolean(context.getString(
R.string.enable_watch_history_key), true)
&& prefs.getBoolean(context.getString(
R.string.enable_playback_state_lists_key), true);
}
}

View File

@ -1,6 +1,6 @@
package org.schabi.newpipe.util;
import static org.schabi.newpipe.util.external_communication.ShareUtils.installApp;
import static org.schabi.newpipe.util.ListHelper.getUrlAndNonTorrentStreams;
import android.annotation.SuppressLint;
import android.app.Activity;
@ -50,9 +50,9 @@ import org.schabi.newpipe.local.history.StatisticsPlaylistFragment;
import org.schabi.newpipe.local.playlist.LocalPlaylistFragment;
import org.schabi.newpipe.local.subscription.SubscriptionFragment;
import org.schabi.newpipe.local.subscription.SubscriptionsImportFragment;
import org.schabi.newpipe.player.PlayerService;
import org.schabi.newpipe.player.PlayQueueActivity;
import org.schabi.newpipe.player.Player;
import org.schabi.newpipe.player.PlayerService;
import org.schabi.newpipe.player.PlayerType;
import org.schabi.newpipe.player.helper.PlayerHelper;
import org.schabi.newpipe.player.helper.PlayerHolder;
@ -63,8 +63,6 @@ import org.schabi.newpipe.util.external_communication.ShareUtils;
import java.util.List;
import static org.schabi.newpipe.util.ListHelper.getUrlAndNonTorrentStreams;
public final class NavigationHelper {
public static final String MAIN_FRAGMENT_TAG = "main_fragment_tag";
public static final String SEARCH_FRAGMENT_TAG = "search_fragment_tag";
@ -323,15 +321,13 @@ public final class NavigationHelper {
public static void resolveActivityOrAskToInstall(@NonNull final Context context,
@NonNull final Intent intent) {
if (intent.resolveActivity(context.getPackageManager()) != null) {
ShareUtils.openIntentInApp(context, intent, false);
} else {
if (!ShareUtils.tryOpenIntentInApp(context, intent)) {
if (context instanceof Activity) {
new AlertDialog.Builder(context)
.setMessage(R.string.no_player_found)
.setPositiveButton(R.string.install,
(dialog, which) -> ShareUtils.openUrlInBrowser(context,
context.getString(R.string.fdroid_vlc_url), false))
(dialog, which) -> ShareUtils.installApp(context,
context.getString(R.string.vlc_package)))
.setNegativeButton(R.string.cancel, (dialog, which)
-> Log.i("NavigationHelper", "You unlocked a secret unicorn."))
.show();
@ -684,34 +680,6 @@ public final class NavigationHelper {
return getOpenIntent(context, url, serviceId, StreamingService.LinkType.CHANNEL);
}
/**
* Start an activity to install Kore.
*
* @param context the context
*/
public static void installKore(final Context context) {
installApp(context, context.getString(R.string.kore_package));
}
/**
* Start Kore app to show a video on Kodi.
* <p>
* For a list of supported urls see the
* <a href="https://github.com/xbmc/Kore/blob/master/app/src/main/AndroidManifest.xml">
* Kore source code
* </a>.
*
* @param context the context to use
* @param videoURL the url to the video
*/
public static void playWithKore(final Context context, final Uri videoURL) {
final Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setPackage(context.getString(R.string.kore_package));
intent.setData(videoURL);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(intent);
}
/**
* Finish this <code>Activity</code> as well as all <code>Activities</code> running below it
* and then start <code>MainActivity</code>.

View File

@ -1,6 +1,11 @@
package org.schabi.newpipe.util.external_communication;
import static org.schabi.newpipe.util.external_communication.ShareUtils.installApp;
import static org.schabi.newpipe.util.external_communication.ShareUtils.tryOpenIntentInApp;
import android.content.Context;
import android.content.Intent;
import android.net.Uri;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AlertDialog;
@ -8,7 +13,6 @@ import androidx.preference.PreferenceManager;
import org.schabi.newpipe.R;
import org.schabi.newpipe.extractor.ServiceList;
import org.schabi.newpipe.util.NavigationHelper;
/**
* Util class that provides methods which are related to the Kodi Media Center and its Kore app.
@ -29,13 +33,39 @@ public final class KoreUtils {
.getBoolean(context.getString(R.string.show_play_with_kodi_key), false);
}
public static void showInstallKoreDialog(@NonNull final Context context) {
final AlertDialog.Builder builder = new AlertDialog.Builder(context);
builder.setMessage(R.string.kore_not_found)
.setPositiveButton(R.string.install, (dialog, which) ->
NavigationHelper.installKore(context))
.setNegativeButton(R.string.cancel, (dialog, which) -> {
});
builder.create().show();
/**
* Start an activity to install Kore.
*
* @param context the context to use
*/
public static void installKore(final Context context) {
installApp(context, context.getString(R.string.kore_package));
}
/**
* Start Kore app to show a video on Kodi, and if the app is not installed ask the user to
* install it.
* <p>
* For a list of supported urls see the
* <a href="https://github.com/xbmc/Kore/blob/master/app/src/main/AndroidManifest.xml">
* Kore source code
* </a>.
*
* @param context the context to use
* @param streamUrl the url to the stream to play
*/
public static void playWithKore(final Context context, final Uri streamUrl) {
final Intent intent = new Intent(Intent.ACTION_VIEW)
.setPackage(context.getString(R.string.kore_package))
.setData(streamUrl)
.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
if (!tryOpenIntentInApp(context, intent)) {
final AlertDialog.Builder builder = new AlertDialog.Builder(context);
builder.setMessage(R.string.kore_not_found)
.setPositiveButton(R.string.install, (dialog, which) -> installKore(context))
.setNegativeButton(R.string.cancel, (dialog, which) -> { });
builder.create().show();
}
}
}

View File

@ -41,60 +41,71 @@ public final class ShareUtils {
* second param (a system chooser will be opened if there are multiple markets and no default)
* and falls back to Google Play Store web URL if no app to handle the market scheme was found.
* <p>
* It uses {@link #openIntentInApp(Context, Intent, boolean)} to open market scheme
* and {@link #openUrlInBrowser(Context, String, boolean)} to open Google Play Store
* web URL with false for the boolean param.
* It uses {@link #openIntentInApp(Context, Intent)} to open market scheme and {@link
* #openUrlInBrowser(Context, String)} to open Google Play Store web URL.
*
* @param context the context to use
* @param packageId the package id of the app to be installed
*/
public static void installApp(@NonNull final Context context, final String packageId) {
// Try market scheme
final boolean marketSchemeResult = openIntentInApp(context, new Intent(Intent.ACTION_VIEW,
final Intent marketSchemeIntent = new Intent(Intent.ACTION_VIEW,
Uri.parse("market://details?id=" + packageId))
.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK), false);
if (!marketSchemeResult) {
.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
if (!tryOpenIntentInApp(context, marketSchemeIntent)) {
// Fall back to Google Play Store Web URL (F-Droid can handle it)
openUrlInBrowser(context,
"https://play.google.com/store/apps/details?id=" + packageId, false);
openUrlInApp(context, "https://play.google.com/store/apps/details?id=" + packageId);
}
}
/**
* Open the url with the system default browser.
* Open the url with the system default browser. If no browser is set as default, falls back to
* {@link #openAppChooser(Context, Intent, boolean)}.
* <p>
* If no browser is set as default, fallbacks to
* {@link #openAppChooser(Context, Intent, boolean)}
* This function selects the package to open based on which apps respond to the {@code http://}
* schema alone, which should exclude special non-browser apps that are can handle the url (e.g.
* the official YouTube app).
* <p>
* Therefore <b>please prefer {@link #openUrlInApp(Context, String)}</b>, that handles package
* resolution in a standard way, unless this is the action of an explicit "Open in browser"
* button.
*
* @param context the context to use
* @param url the url to browse
* @param httpDefaultBrowserTest the boolean to set if the test for the default browser will be
* for HTTP protocol or for the created intent
* @return true if the URL can be opened or false if it cannot
*/
public static boolean openUrlInBrowser(@NonNull final Context context,
final String url,
final boolean httpDefaultBrowserTest) {
final String defaultPackageName;
* @param context the context to use
* @param url the url to browse
**/
public static void openUrlInBrowser(@NonNull final Context context, final String url) {
// Resolve using a generic http://, so we are sure to get a browser and not e.g. the yt app.
// Note that this requires the `http` schema to be added to `<queries>` in the manifest.
final ResolveInfo defaultBrowserInfo;
final Intent browserIntent = new Intent(Intent.ACTION_VIEW, Uri.parse("http://"));
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
defaultBrowserInfo = context.getPackageManager().resolveActivity(browserIntent,
PackageManager.ResolveInfoFlags.of(PackageManager.MATCH_DEFAULT_ONLY));
} else {
defaultBrowserInfo = context.getPackageManager().resolveActivity(browserIntent,
PackageManager.MATCH_DEFAULT_ONLY);
}
final Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(url))
.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
if (httpDefaultBrowserTest) {
defaultPackageName = getDefaultAppPackageName(context, new Intent(Intent.ACTION_VIEW,
Uri.parse("http://")).setFlags(Intent.FLAG_ACTIVITY_NEW_TASK));
} else {
defaultPackageName = getDefaultAppPackageName(context, intent);
if (defaultBrowserInfo == null) {
// No app installed to open a web URL, but it may be handled by other apps so try
// opening a system chooser for the link in this case (it could be bypassed by the
// system if there is only one app which can open the link or a default app associated
// with the link domain on Android 12 and higher)
openAppChooser(context, intent, true);
return;
}
if (defaultPackageName.equals("android")) {
final String defaultBrowserPackage = defaultBrowserInfo.activityInfo.packageName;
if (defaultBrowserPackage.equals("android")) {
// No browser set as default (doesn't work on some devices)
openAppChooser(context, intent, true);
} else {
try {
// will be empty on Android 12+
if (!defaultPackageName.isEmpty()) {
intent.setPackage(defaultPackageName);
}
intent.setPackage(defaultBrowserPackage);
context.startActivity(intent);
} catch (final ActivityNotFoundException e) {
// Not a browser but an app chooser because of OEMs changes
@ -102,61 +113,56 @@ public final class ShareUtils {
openAppChooser(context, intent, true);
}
}
return true;
}
/**
* Open the url with the system default browser.
* <p>
* If no browser is set as default, fallbacks to
* {@link #openAppChooser(Context, Intent, boolean)}
* <p>
* This calls {@link #openUrlInBrowser(Context, String, boolean)} with true
* for the boolean parameter
* Open a url with the system default app using {@link Intent#ACTION_VIEW}, showing a toast in
* case of failure.
*
* @param context the context to use
* @param url the url to browse
* @return true if the URL can be opened or false if it cannot be
**/
public static boolean openUrlInBrowser(@NonNull final Context context, final String url) {
return openUrlInBrowser(context, url, true);
* @param url the url to open
*/
public static void openUrlInApp(@NonNull final Context context, final String url) {
openIntentInApp(context, new Intent(Intent.ACTION_VIEW, Uri.parse(url))
.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK));
}
/**
* Open an intent with the system default app.
* <p>
* The intent can be of every type, excepted a web intent for which
* {@link #openUrlInBrowser(Context, String, boolean)} should be used.
* <p>
* If no app can open the intent, a toast with the message {@code No app on your device can
* open this} is shown.
* Use {@link #openIntentInApp(Context, Intent)} to show a toast in case of failure.
*
* @param context the context to use
* @param intent the intent to open
* @param showToast a boolean to set if a toast is displayed to user when no app is installed
* to open the intent (true) or not (false)
* @return true if the intent can be opened or false if it cannot be
* @param context the context to use
* @param intent the intent to open
* @return true if the intent could be opened successfully, false otherwise
*/
public static boolean openIntentInApp(@NonNull final Context context,
@NonNull final Intent intent,
final boolean showToast) {
final String defaultPackageName = getDefaultAppPackageName(context, intent);
if (defaultPackageName.isEmpty()) {
// No app installed to open the intent
if (showToast) {
Toast.makeText(context, R.string.no_app_to_open_intent, Toast.LENGTH_LONG)
.show();
}
return false;
} else {
public static boolean tryOpenIntentInApp(@NonNull final Context context,
@NonNull final Intent intent) {
try {
context.startActivity(intent);
} catch (final ActivityNotFoundException e) {
return false;
}
return true;
}
/**
* Open an intent with the system default app, showing a toast in case of failure.
* <p>
* Use {@link #tryOpenIntentInApp(Context, Intent)} if you don't want the toast. Use {@link
* #openUrlInApp(Context, String)} as a shorthand for {@link Intent#ACTION_VIEW} with urls.
*
* @param context the context to use
* @param intent the intent to
*/
public static void openIntentInApp(@NonNull final Context context,
@NonNull final Intent intent) {
if (!tryOpenIntentInApp(context, intent)) {
Toast.makeText(context, R.string.no_app_to_open_intent, Toast.LENGTH_LONG)
.show();
}
}
/**
* Open the system chooser to launch an intent.
* <p>
@ -203,31 +209,11 @@ public final class ShareUtils {
chooserIntent.addFlags(permFlags);
}
}
context.startActivity(chooserIntent);
}
/**
* Get the default app package name.
* <p>
* If no app is set as default, it will return "android" (not on some devices because some
* OEMs changed the app chooser).
* <p>
* If no app is installed on user's device to handle the intent, it will return an empty string.
*
* @param context the context to use
* @param intent the intent to get default app
* @return the package name of the default app, an empty string if there's no app installed to
* handle the intent or the app chooser if there's no default
*/
private static String getDefaultAppPackageName(@NonNull final Context context,
@NonNull final Intent intent) {
final ResolveInfo resolveInfo = context.getPackageManager().resolveActivity(intent,
PackageManager.MATCH_DEFAULT_ONLY);
if (resolveInfo == null) {
return "";
} else {
return resolveInfo.activityInfo.packageName;
try {
context.startActivity(chooserIntent);
} catch (final ActivityNotFoundException e) {
Toast.makeText(context, R.string.no_app_to_open_intent, Toast.LENGTH_LONG).show();
}
}

View File

@ -30,7 +30,7 @@ final class UrlLongPressClickableSpan extends LongPressClickableSpan {
public void onClick(@NonNull final View view) {
if (!InternalUrlsHandler.handleUrlDescriptionTimestamp(
disposables, context, url)) {
ShareUtils.openUrlInBrowser(context, url, false);
ShareUtils.openUrlInApp(context, url);
}
}

View File

@ -1,6 +1,5 @@
package us.shandian.giga.ui.adapter;
import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK;
import static android.content.Intent.FLAG_GRANT_PREFIX_URI_PERMISSION;
import static android.content.Intent.FLAG_GRANT_READ_URI_PERMISSION;
import static us.shandian.giga.get.DownloadMission.ERROR_CONNECT_HOST;
@ -345,16 +344,7 @@ public class MissionAdapter extends Adapter<ViewHolder> implements Handler.Callb
intent.setDataAndType(resolveShareableUri(mission), mimeType);
intent.addFlags(FLAG_GRANT_READ_URI_PERMISSION);
intent.addFlags(FLAG_GRANT_PREFIX_URI_PERMISSION);
if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.M) {
intent.addFlags(FLAG_ACTIVITY_NEW_TASK);
}
if (intent.resolveActivity(mContext.getPackageManager()) != null) {
ShareUtils.openIntentInApp(mContext, intent, false);
} else {
Toast.makeText(mContext, R.string.toast_no_player, Toast.LENGTH_LONG).show();
}
ShareUtils.openIntentInApp(mContext, intent);
}
private void shareFile(Mission mission) {

View File

@ -34,11 +34,26 @@
tools:ignore="RtlHardcoded" />
</RelativeLayout>
<org.schabi.newpipe.views.NewPipeTextView
android:id="@+id/playlist_duplicate"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@+id/newPlaylist"
android:layout_marginHorizontal="@dimen/video_item_search_padding"
android:layout_marginBottom="@dimen/video_item_search_padding"
android:gravity="center"
android:text="@string/duplicate_in_playlist"
android:textAppearance="?android:attr/textAppearanceMedium"
android:textSize="13sp"
android:visibility="gone"
tools:text="@tools:sample/lorem[20]"
tools:visibility="visible" />
<View
android:id="@+id/separator"
android:layout_width="match_parent"
android:layout_height="1dp"
android:layout_below="@+id/newPlaylist"
android:layout_below="@+id/playlist_duplicate"
android:layout_marginLeft="@dimen/video_item_search_padding"
android:layout_marginRight="@dimen/video_item_search_padding"
android:background="?attr/separator_color" />

View File

@ -0,0 +1,74 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/itemRoot"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?attr/selectableItemBackground"
android:clickable="true"
android:focusable="true"
android:padding="@dimen/channel_item_grid_padding">
<com.google.android.material.imageview.ShapeableImageView
android:id="@+id/itemThumbnailView"
android:layout_width="@dimen/channel_item_card_thumbnail_image_size"
android:layout_height="@dimen/channel_item_card_thumbnail_image_size"
android:layout_centerHorizontal="true"
android:contentDescription="@string/detail_uploader_thumbnail_view_description"
android:src="@drawable/placeholder_person"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:shapeAppearance="@style/CircularImageView"
tools:ignore="RtlHardcoded"
tools:src="@tools:sample/avatars" />
<TextView
android:id="@+id/itemTitleView"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="@dimen/spacing_mid"
android:ellipsize="end"
android:lines="1"
android:textAppearance="?android:attr/textAppearanceLarge"
android:textSize="@dimen/video_item_search_title_text_size"
android:textStyle="normal"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@id/itemThumbnailView"
app:layout_constraintTop_toTopOf="@id/itemThumbnailView"
tools:ignore="RtlHardcoded"
tools:text="@sample/channels.json/data/name" />
<TextView
android:id="@+id/itemChannelDescriptionView"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_below="@id/itemTitleView"
android:layout_centerHorizontal="true"
android:ellipsize="end"
android:maxLines="8"
android:textAppearance="?android:attr/textAppearanceSmall"
android:textSize="@dimen/video_item_search_upload_date_text_size"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="@id/itemTitleView"
app:layout_constraintTop_toBottomOf="@id/itemTitleView"
tools:ignore="RtlHardcoded"
tools:text="@sample/channels.json/data/description" />
<TextView
android:id="@+id/itemAdditionalDetails"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/spacing_micro"
android:gravity="center"
android:lines="2"
android:textAppearance="?android:attr/textAppearanceSmall"
android:textSize="@dimen/video_item_search_upload_date_text_size"
android:textStyle="normal"
app:layout_constraintEnd_toEndOf="@id/itemThumbnailView"
app:layout_constraintStart_toStartOf="@id/itemThumbnailView"
app:layout_constraintTop_toBottomOf="@id/itemThumbnailView"
tools:ignore="RtlHardcoded"
tools:text="@sample/channels.json/data/additional" />
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@ -86,7 +86,7 @@
<org.schabi.newpipe.views.AnimatedProgressBar
android:id="@+id/itemProgressView"
style="@style/Widget.AppCompat.ProgressBar.Horizontal"
android:layout_width="wrap_content"
android:layout_width="0dp"
android:layout_height="4dp"
android:progressDrawable="?progress_horizontal_drawable"
app:layout_constraintBottom_toBottomOf="@id/itemThumbnailView"

View File

@ -5,19 +5,8 @@
<item
android:id="@+id/menu_item_feed_toggle_played_items"
android:orderInCategory="2"
android:checkable="true"
android:checked="true"
android:icon="@drawable/ic_visibility_on"
android:title="@string/feed_toggle_show_played_items"
app:showAsAction="ifRoom" />
<item
android:id="@+id/menu_item_feed_toggle_future_items"
android:orderInCategory="3"
android:checkable="true"
android:checked="true"
android:icon="@drawable/ic_history_future"
android:title="@string/feed_toggle_show_future_items"
android:title="@string/feed_show_hide_streams"
app:showAsAction="ifRoom" />
<item

View File

@ -12,8 +12,14 @@
android:id="@+id/menu_item_rename_playlist"
android:title="@string/rename_playlist"
app:showAsAction="never" />
<item
android:id="@+id/menu_item_remove_watched"
android:title="@string/remove_watched"
app:showAsAction="never" />
<item
android:id="@+id/menu_item_remove_duplicates"
android:title="@string/remove_duplicates"
app:showAsAction="never" />
</menu>

View File

@ -105,7 +105,7 @@
<string name="player_unrecoverable_failure">حدث خطأ للمشغل غير قابل للاسترداد</string>
<string name="player_recoverable_failure">استرداد المشغل من الخطأ</string>
<string name="sorry_string">عذرًا، لم ينبغِ أن يحدث ذلك.</string>
<string name="error_report_button_text">الإبلاغ عن هذا الخطأ عبر البريد الإلكتروني</string>
<string name="error_report_button_text">الإبلاغ عن طريق البريد الإلكتروني</string>
<string name="error_snackbar_message">عذرًا، حدث خطأ ما.</string>
<string name="error_snackbar_action">أبلِغ</string>
<string name="what_device_headline">معلومات:</string>
@ -288,7 +288,6 @@
<string name="invalid_file">الملف غير موجود أو الإذن بالقراءة أو الكتابة إليه غير موجود</string>
<string name="no_streams_available_download">لا يوجد بث متاح للتنزيل</string>
<string name="one_item_deleted">تم حذف عنصر واحد.</string>
<string name="toast_no_player">لم يتم تثبيت أي تطبيق لتشغيل هذا الملف</string>
<string name="app_license">NewPipe هو برنامج مفتوح المصدر وبحقوق متروكة: يمكنك استخدام الكود ودراسته وتحسينه كما شئت. وعلى وجه التحديد يمكنك إعادة توزيعه / أو تعديله تحت شروط رخصة GNU العمومية والتي نشرتها مؤسسة البرمجيات الحرة، سواء الإصدار 3 من الرخصة، أو (باختيارك) أي إصدار أحدث.</string>
<string name="title_last_played">آخر ما تم تشغيله</string>
<string name="title_most_played">الأكثر تشغيلا</string>
@ -784,4 +783,14 @@
<string name="card">البطاقة</string>
<string name="playlist_add_stream_success_duplicate">تمت إضافة وقت (أوقات) مكررة %d</string>
<string name="duplicate_in_playlist">تحتوي قوائم التشغيل رمادية اللون بالفعل على هذا العنصر.</string>
<string name="ignore_hardware_media_buttons_summary">مفيد ، على سبيل المثال ، إذا كنت تستخدم سماعة رأس بأزرار مادية مكسورة</string>
<string name="ignore_hardware_media_buttons_title">تجاهل أحداث ازرار الوسائط الأجهزة</string>
<string name="remove_duplicates_message">هل تريد إزالة جميع التدفقات المكررة في قائمة التشغيل هذه؟</string>
<string name="feed_show_hide_streams">إظهار/إخفاء التدفقات</string>
<string name="feed_show_partially_watched">تمت مشاهدته جزئيا</string>
<string name="feed_show_upcoming">القادمة</string>
<string name="remove_duplicates">إزالة التكرارات</string>
<string name="remove_duplicates_title">إزالة التكرارات؟</string>
<string name="feed_hide_streams_title">إظهار التدفقات التالية</string>
<string name="feed_show_watched">شاهدت بالكامل</string>
</resources>

View File

@ -39,7 +39,7 @@
<string name="show_higher_resolutions_title">উচ্চ ৰিজ\'লিউচন দেখুৱাওক</string>
<string name="show_higher_resolutions_summary">কেৱল কিছুমান ডিভাইচেহে 2K/4K ভিডিঅ’ বজাব পাৰে</string>
<string name="play_with_kodi_title">Kodi ৰ সৈতে বজাওক</string>
<string name="kore_not_found">Kore এপ ইনষ্টল\?</string>
<string name="kore_not_found">Kode এপ ইনষ্টল\?</string>
<string name="show_play_with_kodi_title">\"Kodi ৰ সৈতে খোলক\" বিকল্প দেখুৱাওক</string>
<string name="show_play_with_kodi_summary">Kodi মিডিয়া চেণ্টাৰৰ জৰিয়তে এটা ভিডিঅ\' চলাবলৈ এটা বিকল্প প্ৰদৰ্শন কৰক</string>
<string name="crash_the_player">প্লেয়াৰটো ক্ৰেচ কৰক</string>

View File

@ -303,7 +303,7 @@
<string name="saved_tabs_invalid_json">Saxlanmış tabları oxumaq mümkün olmadı, buna görə standart tabları istifadə et</string>
<string name="error_report_notification_title">NewPipe xəta ilə qarşılaşdı, bildirmək üçün toxun</string>
<string name="sorry_string">Bağışla, o baş verməməli idi.</string>
<string name="error_report_button_text">Bu xətanı e-poçt-dan bildir</string>
<string name="error_report_button_text">E-poçt- dan məlumat ver</string>
<string name="error_report_open_issue_button_text">GitHub\'da Məlumat Ver</string>
<string name="error_report_open_github_notice">Zəhmət olmasa, xətanızı müzakirə edən məsələnin mövcud olub-olmadığını yoxlayın. Dublikat biletləri yaradarkən, bizdən faktiki səhvi düzəltməyə sərf edəcəyimiz vaxt alırsınız.</string>
<string name="error_snackbar_action">Məlumat Ver</string>
@ -588,7 +588,6 @@
<string name="play_queue_remove">Sil</string>
<string name="app_description">Android\'də pulsuz yüngül yayımlayıcı.</string>
<string name="copyright">© %1$s, %2$s tərəfindən %3$s altında</string>
<string name="toast_no_player">Bu faylı oynatmaq üçün heç bir tətbiq quraşdırılmayıb</string>
<string name="settings_category_downloads_title">Endirmə</string>
<string name="msg_popup_permission">Bu icazə, ani görüntü rejimində
\naçmaq üçün lazımdır</string>
@ -732,4 +731,14 @@
<string name="msg_failed_to_copy">Buferə kopyalamaq alınmadı</string>
<string name="duplicate_in_playlist">Boz rəngdə olan pleylistlərdə artıq bu element var.</string>
<string name="playlist_add_stream_success_duplicate">Dublikat %d dəfə əlavə edildi</string>
<string name="ignore_hardware_media_buttons_title">Aparat mühiti media düyməsi hadisələrinə məhəl qoyma</string>
<string name="ignore_hardware_media_buttons_summary">Məsələn, fiziki düymələri qırılan qulaqlıq işlədirsinizsə faydalıdır</string>
<string name="remove_duplicates">Dublikatları sil</string>
<string name="remove_duplicates_title">Dublikatlar silinsin\?</string>
<string name="feed_hide_streams_title">Aşağıdakı yayımları göstər</string>
<string name="feed_show_hide_streams">Yayımları Göstər/Gizlə</string>
<string name="feed_show_watched">Tam baxılıb</string>
<string name="feed_show_partially_watched">Qismən baxılıb</string>
<string name="remove_duplicates_message">Bu pleylistdəki bütün dublikat yayımları silmək istəyirsiniz\?</string>
<string name="feed_show_upcoming">Yaxınlaşan</string>
</resources>

View File

@ -277,7 +277,7 @@
<string name="metadata_cache_wipe_summary">Desanicia tolos datos na caché de les páxines web</string>
<string name="metadata_cache_wipe_title">Llimpiar los metadatos de la caché</string>
<string name="thumbnail_cache_wipe_complete_notice">Llimpióse la caché d\'imáxenes</string>
<string name="kore_not_found">¿Instalar Kore\?</string>
<string name="kore_not_found">¿Instalar Kode\?</string>
<string name="info_labels">Qué asocedió:\\nSolicitú:\\nLlingua del conteníu:\\nPaís del conteníu:\\nLlingua de l\'aplicación:\\nServiciu:\\nHora en GMT:\\nPaquete:\\nVersión de l\'aplicación:\\nVersión del SO:</string>
<string name="no_player_found_toast">Nun s\'atopó nengún reproductor de fluxos (pues instalar VLC pa reproducilos).</string>
<string name="show_thumbnail_summary">Amuesa una miniatura nel fondu de la pantalla de bloquéu y dientro de los avisos</string>
@ -425,7 +425,6 @@
<string name="privacy_policy_encouragement">El proyeutu de NewPipe toma mui en serio la privacidá. Poro, l\'aplicación nun recueye nengún datu ensin el to consentimientu.
\nLa política de privacidá de NewPipe desplica en detalle los datos que s\'unvien y atroxen cuando unvies un informe de casque.</string>
<string name="app_description">Un aplicación llibre pa ver/sentir plataformes de tresmisión n\'Android.</string>
<string name="toast_no_player">Nun hai nenguna aplicación pa reproducir esti ficheru</string>
<string name="settings_file_replacement_character_title">Caráuteres de troquéu</string>
<string name="settings_file_replacement_character_summary">Los caráuteres que nun son válidos van trocase por esti valor</string>
<string name="recaptcha_done_button">Fecho</string>

View File

@ -214,7 +214,6 @@
<string name="copyright">© %1$s tomonidan %2$s gacha %3$s</string>
<string name="title_licenses">Uchinchi tomon litsenziyalari</string>
<string name="title_activity_about">NewPipe haqida</string>
<string name="toast_no_player">Ushbu faylni ijro etish uchun dastur o\'rnatilmagan</string>
<string name="charset_most_special_characters">Ko\'pchilik maxsus belgilar</string>
<string name="charset_letters_and_digits">Yozuvlar va raqamlar</string>
<string name="settings_file_replacement_character_title">O\'zgartirish belgisi</string>

View File

@ -1,8 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="main_bg_subtitle">Націсніце \"Пошук\", каб пачаць</string>
<string name="main_bg_subtitle">Націсніце «Пошук», каб пачаць.</string>
<string name="upload_date_text">Апублікавана %1$s</string>
<string name="no_player_found">Патокавы плэер не знойдзены. Усталяваць VLC?</string>
<string name="no_player_found">Патокавы прайгравальнік не знойдзены. Усталяваць VLC\?</string>
<string name="no_player_found_toast">Патокавы плэер не знойдзены (вы можаце ўсталяваць VLC).</string>
<string name="install">Усталяваць</string>
<string name="cancel">Скасаваць</string>
@ -16,7 +16,7 @@
<string name="did_you_mean">Магчыма, вы мелі на ўвазе \"%1$s\"\?</string>
<string name="share_dialog_title">Падзяліцца з дапамогай</string>
<string name="use_external_video_player_title">Знешні відэаплэер</string>
<string name="use_external_video_player_summary">Прыбірае гук у некаторых разрозненнях</string>
<string name="use_external_video_player_summary">Адключае гук для некаторых раздзяленнях</string>
<string name="use_external_audio_player_title">Знешні аўдыяплэер</string>
<string name="subscribe_button_title">Падпісацца</string>
<string name="subscribed_button_title">Вы падпісаныя</string>
@ -30,19 +30,19 @@
<string name="controls_background_title">У фоне</string>
<string name="controls_popup_title">У акне</string>
<string name="controls_add_to_playlist_title">Дадаць да</string>
<string name="download_path_title">Каталог для спампаванага відэа</string>
<string name="download_path_summary">Папка для спампаванга відэа</string>
<string name="download_path_dialog_title">Увядзіце шлях да папкі для спампавання відэа</string>
<string name="download_path_title">Тэчка загрузкі відэа</string>
<string name="download_path_summary">Загружаныя відэафайлы захоўваюцца тут</string>
<string name="download_path_dialog_title">Абярыце тэчку загрузкі для відэафайлаў</string>
<string name="download_path_audio_title">Тэчка загрузкі аўдыё</string>
<string name="download_path_audio_summary">Папка для спампаванага аўдыя</string>
<string name="download_path_audio_dialog_title">Увядзіце шлях да папкі для спампавання аўдыя</string>
<string name="download_path_audio_summary">Загружаныя аўдыёфайлы захоўваюцца тут</string>
<string name="download_path_audio_dialog_title">Абярыце тэчку загрузкі для аўдыёфайлаў</string>
<string name="default_resolution_title">Разрознянне па змаўчанні</string>
<string name="default_popup_resolution_title">Разрозненне усплываючага акна</string>
<string name="show_higher_resolutions_title">Высокія разрозненні</string>
<string name="show_higher_resolutions_summary">Толькі некаторыя прылады могуць прайграваць відэа ў 2K/4K</string>
<string name="play_with_kodi_title">Прайграць у Kodi</string>
<string name="kore_not_found">Дадатак Kore не знойдзены. Усталяваць яго?</string>
<string name="show_play_with_kodi_title">\"Прайграць у Kodi\"</string>
<string name="kore_not_found">Усталяваць адсутную праграму Kore\?</string>
<string name="show_play_with_kodi_title">Паказаць опцыю \"Прайграць у Kodi\"</string>
<string name="show_play_with_kodi_summary">Паказаць опцыю прайгравання відэа праз медыяцэнтр Kodi</string>
<string name="play_audio">Аўдыё</string>
<string name="default_audio_format_title">Фармат аўдыё па змаўчанні</string>
@ -54,27 +54,27 @@
<string name="popup_remember_size_pos_title">Аднавіць акно</string>
<string name="popup_remember_size_pos_summary">Запамінаць памер і становішча ўсплываючага акна</string>
<string name="use_inexact_seek_title">Хуткі пошук пазіцыі</string>
<string name="use_inexact_seek_summary">Недакладны пошук дазваляе плэеру шукаць пазіцыю хутчэй, але менш дакладна. Не працуе для перамоткі на 5, 15 ці 25 секунд</string>
<string name="use_inexact_seek_summary">Недакладны пошук дазваляе плэеру знаходзіць пазіцыі хутчэй са зніжанай дакладнасцю. Пошук цягам 5, 15 ці 25 секунд пры гэтым немажлівы</string>
<string name="download_thumbnail_title">Загружаць мініяцюры</string>
<string name="download_thumbnail_summary">Адключыце, каб не загружаць мініяцюры і зэканоміць трафік і памяць. Змена налады ачысьціць кэш малюнкаў</string>
<string name="thumbnail_cache_wipe_complete_notice">Кэш малюнкаў ачышчаны</string>
<string name="metadata_cache_wipe_title">Ачысціць кэш метададзеных</string>
<string name="metadata_cache_wipe_summary">Выдаліць усе загружаныя дадзеныя вэб-старонак</string>
<string name="metadata_cache_wipe_complete_notice">Кэш метададзеных ачышчаны</string>
<string name="auto_queue_title">Аўтадапаўненне чаргі</string>
<string name="auto_queue_title">Аўта- чарга наступнага патока</string>
<string name="auto_queue_summary">Дадаваць падобныя патокі ў чаргу пры прайграванні апошняга, калі не ўключаны паўтор</string>
<string name="show_search_suggestions_title">Варыянты пошуку</string>
<string name="show_search_suggestions_summary">Адлюстроўваць падказкі пры пошуку</string>
<string name="show_search_suggestions_summary">Выберыце прапановы для паказу пры пошуку</string>
<string name="enable_search_history_title">Гісторыя пошуку</string>
<string name="enable_search_history_summary">Захоўваць пошукавыя запыты лакальна</string>
<string name="enable_watch_history_title">Гісторыя праглядаў</string>
<string name="enable_watch_history_summary">Запамінаць прагледжаныя відэа</string>
<string name="resume_on_audio_focus_gain_title">Аднавіць пры фокусе</string>
<string name="resume_on_audio_focus_gain_summary">Аднаўляць прайграванне пасля перапынкаў (напрыклад, тэлефонных званкоў)</string>
<string name="download_dialog_title">Спампаваць</string>
<string name="resume_on_audio_focus_gain_title">Узнавіць прайграванне</string>
<string name="resume_on_audio_focus_gain_summary">Працягваць прайграванне пасля перапынкаў (напрыклад, тэлефонных званкоў)</string>
<string name="download_dialog_title">Загрузіць</string>
<string name="show_next_and_similar_title">\"Наступнае\" и \"Прапанаванае\" відэа</string>
<string name="show_hold_to_append_title">\"Зацісніце, каб дадаць\"</string>
<string name="show_hold_to_append_summary">Паказаць падказку пры націсканні \"У акне\" ці \"У фоне\" на старонцы звестак аб відэа</string>
<string name="show_hold_to_append_title">Паказаць падказку \"Утрымлівайце, каб паставіць у чаргу\"</string>
<string name="show_hold_to_append_summary">Паказаць падказку пры націсканні фонавай або ўсплывальнай кнопкі ў відэа \"Падрабязнасці:\"</string>
<string name="unsupported_url">URL не падтрымліваецца</string>
<string name="default_content_country_title">Краіна кантэнту па змаўчанні</string>
<string name="content_language_title">Мова кантэнту па змаўчанні</string>
@ -87,7 +87,7 @@
<string name="background_player_playing_toast">Прайграванне ў фонавым рэжыме</string>
<string name="popup_playing_toast">Прайграванне ва ўсплываючым акне</string>
<string name="content">Кантэнт</string>
<string name="show_age_restricted_content_title">Кантэнт 18+</string>
<string name="show_age_restricted_content_title">Паказаць кантэнт 18+</string>
<string name="duration_live">Трансляцыя</string>
<string name="downloads">Загрузкі</string>
<string name="downloads_title">Загрузкі</string>
@ -106,23 +106,23 @@
<string name="just_once">Толькі цяпер</string>
<string name="file">Файл</string>
<string name="notification_channel_name">Апавяшчэнне NewPipe</string>
<string name="notification_channel_description">Апавяшчэнні для NewPipe ў фоне і ва ўсплываючым акне</string>
<string name="notification_channel_description">Апавяшчэнні для прайгравальніка NewPipe</string>
<string name="unknown_content">[Невядома]</string>
<string name="switch_to_background">Перайсці ў фон</string>
<string name="switch_to_popup">Перайсці ў акно</string>
<string name="switch_to_main">Перайсці ў галоўнае акно</string>
<string name="import_data_title">Імпарт дадзеных</string>
<string name="export_data_title">Экспарт дадзеных</string>
<string name="import_data_summary">Бягучыя падпіскі, плэйлісты і гісторыя будуць заменены</string>
<string name="export_data_summary">Экспарт гісторыі, падпісак і плэйлістоў</string>
<string name="import_data_summary">Перавызначае вашу бягучую гісторыю, падпіскі, плэйлісты і (неабавязкова) налады</string>
<string name="export_data_summary">Экспарт гісторыі, падпісак, плэйлістоў і налад</string>
<string name="clear_views_history_title">Ачысціць гісторыю праглядаў</string>
<string name="clear_views_history_summary">Выдаліць гісторыю прайграных патокаў</string>
<string name="clear_views_history_summary">Выдаліць гісторыю прайграных патокаў і пазіцыі прайгравання</string>
<string name="delete_view_history_alert">Выдаліць усю гісторыю праглядаў\?</string>
<string name="watch_history_deleted">Гісторыя праглядаў выдалена.</string>
<string name="watch_history_deleted">Гісторыя праглядаў выдалена</string>
<string name="clear_search_history_title">Ачысціць гісторыю пошуку</string>
<string name="clear_search_history_summary">Выдаліць гісторыю пошукавых запытаў</string>
<string name="delete_search_history_alert">Выдаліць усю гісторыю пошуку\?</string>
<string name="search_history_deleted">Гісторыя пошуку выдалена.</string>
<string name="search_history_deleted">Гісторыя пошуку выдалена</string>
<string name="general_error">Памылка</string>
<string name="network_error">Памылка сеткі</string>
<string name="could_not_load_thumbnails">Не атрымалася загрузіць усе мініяцюры</string>
@ -142,22 +142,22 @@
<string name="invalid_file">Файл не існуе або няма дазволу на яго чытанне або запіс</string>
<string name="file_name_empty_error">Імя файла не можа быць пустым</string>
<string name="error_occurred_detail">Адбылася памылка: %1$s</string>
<string name="no_streams_available_download">Няма патокаў, даступных для загрузкі</string>
<string name="no_streams_available_download">Няма трансляцый, даступных для загрузкі</string>
<string name="sorry_string">Прабачце, гэта не павінна было адбыцца.</string>
<string name="error_report_button_text">Адправіць справаздачу па e-mail</string>
<string name="error_snackbar_message">Прабачце, адбыліся памылкі.</string>
<string name="error_snackbar_action">СПРАВАЗДАЧА</string>
<string name="error_report_button_text">Паведаміць па электроннай пошце</string>
<string name="error_snackbar_message">На жаль, нешта пайшло не так.</string>
<string name="error_snackbar_action">Справаздача</string>
<string name="what_device_headline">Інфармацыя:</string>
<string name="what_happened_headline">Што адбылося:</string>
<string name="info_labels">Што:\\nЗапыт:\\nМова кантэнту:\\nСэрвіс:\\nЧас па Грынвічы:\\nПакет:\\nВерсія:\\nВерсія АС:</string>
<string name="info_labels">Што:\\nЗапыт:\\nМова кантэнту:\\nКраіна кантэнту:\\nМова праграмы:\\nСэрвіс:\\nЧас GMT:\\nПакет:\\nВерсія:\\nВерсія АС:</string>
<string name="your_comment">Ваш каментар (English):</string>
<string name="error_details_headline">Падрабязнасці:</string>
<string name="detail_thumbnail_view_description">Мініяцюра відэа-прэв\'ю</string>
<string name="detail_thumbnail_view_description">Прайграць відэа, працягласць:</string>
<string name="detail_uploader_thumbnail_view_description">Мініяцюра аватара карыстальніка</string>
<string name="detail_likes_img_view_description">Спадабалася</string>
<string name="detail_dislikes_img_view_description">Не спадабалася</string>
<string name="search_no_results">Няма вынікаў</string>
<string name="empty_list_subtitle">Нічога няма</string>
<string name="empty_list_subtitle">Нічога няма, акрамя цвыркуноў</string>
<string name="detail_drag_description">Перацягніце, каб змяніць парадак</string>
<string name="video">Відэа</string>
<string name="audio">Аўдыё</string>
@ -182,6 +182,7 @@
<item quantity="one">%s Відэа</item>
<item quantity="few">%s відэа</item>
<item quantity="many">%s відэа</item>
<item quantity="other">%s відэа</item>
</plurals>
<string name="start">Пачаць</string>
<string name="pause">Паўза</string>
@ -210,18 +211,17 @@
<string name="settings_file_replacement_character_title">Сімвал для замены</string>
<string name="charset_letters_and_digits">Літары і лічбы</string>
<string name="charset_most_special_characters">Большасць спецзнакаў</string>
<string name="toast_no_player">Прыкладанне для прайгравання гэтага файла не ўстаноўлена</string>
<string name="title_activity_about">Аб NewPipe</string>
<string name="title_licenses">Іншыя ліцэнзіі</string>
<string name="copyright" formatted="true">© %1$s %2$s пад ліцэнзіяй %3$s</string>
<string name="tab_about">Аб дадатку</string>
<string name="tab_about">Аб праграме</string>
<string name="tab_licenses">Ліцэнзіі</string>
<string name="app_description">Свабоднае легкавагавае патокавае прайграванне на Android.</string>
<string name="contribution_title">Дапамога праекту</string>
<string name="contribution_encouragement">Вітаецца ўсё - ідэі, пераклад, змены дызайну, чыстка кода або велізарныя змены ў кодзе. Чым больш зроблена, тым лепш!</string>
<string name="view_on_github">Адкрыць на GitHub</string>
<string name="donation_title">Ахвяраваць</string>
<string name="donation_encouragement">Распрацоўшчыкі NewPipe цаной свайго вольнага часу робяць ваша жыццё крышачку зручней. Адплаціце ім тым жа - атрымліваючы асалоду ад кубачка кавы, яны змогуць зрабіць NewPipe яшчэ лепей.</string>
<string name="donation_encouragement">NewPipe распрацаваны добраахвотнікамі, якія праводзяць свой вольны час, забяспечваючы лепшы карыстацкі досвед. Дапамажыце распрацоўшчыкам зрабіць NewPipe яшчэ лепшым, пакуль яны атрымліваюць асалоду ад кавы.</string>
<string name="give_back">Аддаць належнае</string>
<string name="website_title">Вэб-сайт</string>
<string name="website_encouragement">Дзеля атрымання больш падрабязнай інфармацыі і апошніх навін аб NewPipe наведайце наш вэб-сайт.</string>
@ -230,7 +230,7 @@
\nПалітыка прыватнасці NewPipe падрабязна тлумачыць, якія дадзеныя адпраўляюцца і захоўваюцца пры адпраўцы справаздачы аб збоях.</string>
<string name="read_privacy_policy">Прачытаць палітыку</string>
<string name="app_license_title">Ліцэнзія NewPipe</string>
<string name="app_license">NewPipe - свабоднае праграмнае забеспячэнне: вы можаце выкарыстоўваць, вывучаць і паляпшаць яго па сваім меркаванні. У прыватнасці, вы можаце распаўсюджваць і / або змяняць яго ў адпаведнасці з умовамі GNU General Public License, апублікаванай Free Software Foundation, альбо версіі 3, альбо (па вашаму выбару) любой больш позняй версіі.</string>
<string name="app_license">NewPipe - гэта праграмнае забеспячэнне, свабоднае ад копілефта: вы можаце выкарыстоўваць, вывучаць, дзяліцца і паляпшаць яго па жаданні. У прыватнасці, вы можаце распаўсюджваць і/ці змяняць яго ў адпаведнасці з умовамі Агульнай грамадскай ліцэнзіі GNU, апублікаванай Фондам свабоднага праграмнага забеспячэння, альбо версіі 3 Ліцэнзіі, альбо (на ваш выбар) любой пазнейшай версіі.</string>
<string name="read_full_license">Прачытаць ліцэнзію</string>
<string name="title_activity_history">Гісторыя</string>
<string name="action_history">Гісторыя</string>
@ -258,7 +258,7 @@
<string name="play_queue_audio_settings">Налады аўдыё</string>
<string name="hold_to_append">Утрымлівайце, каб дадаць у чаргу</string>
<string name="start_here_on_background">Пачаць адсюль у фоне</string>
<string name="start_here_on_popup">Пачаць адсюль у акне</string>
<string name="start_here_on_popup">Пачніце гуляць ва ўсплываючым акне</string>
<string name="drawer_open">Адкрыць бакавую панэль</string>
<string name="drawer_close">Зачыніць бакавую панэль</string>
<string name="preferred_open_action_settings_title">Пры адкрыцці кантэнту</string>
@ -273,20 +273,20 @@
<string name="rename_playlist">Перайменаваць</string>
<string name="name">Імя</string>
<string name="add_to_playlist">Дадаць у плэйліст</string>
<string name="set_as_playlist_thumbnail">На мініяцюру плэйліста</string>
<string name="set_as_playlist_thumbnail">Усталяваць як мініяцюру плэйліста</string>
<string name="bookmark_playlist">Дадаць плэйліст у закладкі</string>
<string name="unbookmark_playlist">Выдаліць закладку</string>
<string name="delete_playlist_prompt">Выдаліць плэйліст\?</string>
<string name="playlist_creation_success">Плэйліст створаны</string>
<string name="playlist_add_stream_success">Дададзена ў плэйліст</string>
<string name="playlist_thumbnail_change_success">Мініяцюра плэйліста зменена</string>
<string name="playlist_thumbnail_change_success">Мініяцюра плэйліста зменена.</string>
<string name="caption_none">Без тытраў</string>
<string name="resize_fit">Падагнаць</string>
<string name="resize_fill">Запоўніць</string>
<string name="resize_zoom">Наблізіць</string>
<string name="caption_auto_generated">Створаны аўтаматычна</string>
<string name="caption_setting_title">Тытры</string>
<string name="caption_setting_description">Змяніць памер тэкста і фон тытраў. Патрэбен перазапуск</string>
<string name="caption_setting_description">Змяніць маштаб тэксту субтытраў гульца і стылі фону. Патрабуецца перазапуск праграмы, каб яна ўступіла ў сілу</string>
<string name="enable_leak_canary_summary">Маніторынг уцечкі памяці можа прывесці да завісання прыкладання</string>
<string name="enable_disposed_exceptions_title">Паведамляць пра памылкі жыццёвага цыклу</string>
<string name="enable_disposed_exceptions_summary">Прымусова паведамляць пра недастаўляемыя Rx-выключэнні па-за фрагментам або жыццёвым цыкле пасля выдалення</string>
@ -299,11 +299,15 @@
<string name="previous_export">Папярэдні экспарт</string>
<string name="subscriptions_import_unsuccessful">Не атрымалася імпартаваць падпіскі</string>
<string name="subscriptions_export_unsuccessful">Не атрымалася экспартаваць падпіскі</string>
<string name="import_youtube_instructions">Імпарт падпісак з YouTube загрузкай файла экспарту:
\n
\n1. Перайдзіце на: %1$s
\n2. Увайдзіце, калі неабходна
\n3. Павінна пачацца загрузка (гэта будзе файл экспарту)</string>
<string name="import_youtube_instructions">Імпарт падпісак YouTube з Google Takeout:
\n
\n1. Перайдзіце па гэтым URL: %1$s
\n2. Увайдзіце, калі вас папросяць
\n3. Націсніце на «Усе дадзеныя ўключаны», затым на «Адмяніць выбар усіх», затым выберыце толькі «падпіскі» і націсніце «ОК»
\n4. Націсніце на «Наступны крок», а затым на «Стварыць экспарт»
\n5. Націсніце на кнопку «Спампаваць» пасля таго, як яна з\'явіцца
\n6. Пстрыкніце ФАЙЛ ІМПАРТУВАЦЬ ніжэй і выберыце спампаваны файл .zip
\n7. [Калі імпарт .zip не ўдаецца] Распакуйце файл .csv (звычайна ў раздзеле \"YouTube і YouTube Music/subscriptions/subscriptions.csv\"), націсніце ФАЙЛ ІМПАРТУВАЦЬ ніжэй і выберыце выняты файл CSV</string>
<string name="import_soundcloud_instructions">Імпарт падпісак з SoundCloud набраўшы альбо URL, альбо ваш ID:
\n
\n1. Уключыце \"рэжым працоўнага стала\" у браўзэры (сайт недаступны на тэлефоне)
@ -317,11 +321,11 @@
<string name="playback_speed_control">Кіраванне хуткасцю прайгравання</string>
<string name="playback_tempo">Тэмп</string>
<string name="playback_pitch">Тон</string>
<string name="unhook_checkbox">Незалежна (скажэнні)</string>
<string name="unhook_checkbox">Адчапіць (можа выклікаць скажэнне)</string>
<string name="skip_silence_checkbox">Прапускаць цішыню</string>
<string name="playback_step">Крок</string>
<string name="playback_reset">Скід</string>
<string name="start_accept_privacy_policy">У адпаведнасці з Агульным рэгламентам па абароне дадзеных ЕС (GDPR), звяртаем вашу ўвагу на палітыку прыватнасці NewPipe. Калі ласка, уважліва азнаёмцеся з ёй.
<string name="start_accept_privacy_policy">У адпаведнасці з Агульным рэгламентам па абароне дадзеных ЕС (GDPR), звяртаем вашу ўвагу на палітыку прыватнасці NewPipe. Калі ласка, уважліва азнаёмцеся з ёй.
\nВам неабходна прыняць яе ўмовы, каб адправіць нам справаздачу пра памылку.</string>
<string name="accept">Прыняць</string>
<string name="decline">Адмовіцца</string>
@ -335,13 +339,13 @@
<string name="unsubscribe">Адпісацца</string>
<string name="tab_choose">Абярыце ўкладку</string>
<string name="volume_gesture_control_title">Жэст гучнасці</string>
<string name="volume_gesture_control_summary">Мяняць гучнасць плэера жэстам</string>
<string name="volume_gesture_control_summary">Мяняць гучнасць плэера жэстамі</string>
<string name="brightness_gesture_control_title">Жэст яркасці</string>
<string name="brightness_gesture_control_summary">Мяняць яркасць плэера жэстам</string>
<string name="brightness_gesture_control_summary">Мяняць яркасць плэера жэстамі</string>
<string name="settings_category_updates_title">Абнаўленні</string>
<string name="file_deleted">Файл выдалены</string>
<string name="app_update_notification_channel_name">Апавяшчэнне аб абнаўленні</string>
<string name="app_update_notification_channel_description">Апавяшчэння аб новай версіі NewPipe</string>
<string name="app_update_notification_channel_name">Апавяшчэнне аб абнаўленні праграмы</string>
<string name="app_update_notification_channel_description">Апавяшчэнні пра новыя версіі NewPipe</string>
<string name="download_to_sdcard_error_title">Знешняе сховішча недаступна</string>
<string name="download_to_sdcard_error_message">Загрузка на знешнюю SD-карту немагчымая. Скінуць размяшчэнне тэчкі загрузкі\?</string>
<string name="saved_tabs_invalid_json">Памылка чытання захаваных укладак. Выкарыстоўваюцца ўкладкі па змаўчанні</string>
@ -349,7 +353,7 @@
<string name="restore_defaults_confirmation">Аднавіць значэнні па змаўчанні\?</string>
<string name="subscribers_count_not_available">Колькасць падпісчыкаў недаступная</string>
<string name="main_page_content_summary">Ўкладкі, бачныя на галоўнай старонцы</string>
<string name="updates_setting_title">Абнаўлення</string>
<string name="updates_setting_title">Абнаўленні</string>
<string name="updates_setting_description">Паказаць апавяшчэнне пры наяўнасці новай версіі</string>
<string name="list_view_mode">Выгляд спісу</string>
<string name="list">Спіс</string>
@ -361,18 +365,18 @@
<string name="paused">прыпынена</string>
<string name="queued">у чарзе</string>
<string name="post_processing">постапрацоўка</string>
<string name="enqueue">Чарга</string>
<string name="enqueue">Паставіць у чаргу</string>
<string name="permission_denied">Дзеянне забаронена сістэмай</string>
<string name="download_failed">Памылка загрузкі</string>
<string name="generate_unique_name">Стварыць унікальнае імя</string>
<string name="overwrite">Перазапісаць</string>
<string name="download_already_running">Загрузка з такім імем ужо выконваецца</string>
<string name="show_error">Паказаць тэкст памылкі</string>
<string name="error_path_creation">Тэчка прызначэння не можа быць створана</string>
<string name="error_file_creation">Файл не можа быць створаны</string>
<string name="error_ssl_exception">Немагчыма ўсталяваць абароненае злучэнне</string>
<string name="error_path_creation">Немагчыма стварыць папку прызначэння</string>
<string name="error_file_creation">Немагчыма стварыць файл</string>
<string name="error_ssl_exception">Не атрымалася ўсталяваць бяспечнае злучэнне</string>
<string name="error_unknown_host">Сервер не знойдзены</string>
<string name="error_connect_host">Немагчыма злучыцца з серверам</string>
<string name="error_connect_host">Немагчыма падключыцца да сервера</string>
<string name="error_http_no_content">Не атрымалася атрымаць дадзеныя з сервера</string>
<string name="error_http_unsupported_range">Сервер не падтрымлівае шматструменную загрузку, паспрабуйце з @string/msg_threads = 1</string>
<string name="error_http_not_found">Не знойдзена</string>
@ -411,19 +415,19 @@
<string name="start_downloads">Пачаць загрузку</string>
<string name="pause_downloads">Прыпыніць загрузку</string>
<string name="downloads_storage_ask_title">Запытваць тэчку загрузкі</string>
<string name="downloads_storage_ask_summary">Для кожнай загрузкі запытваць тэчку для захавання</string>
<string name="downloads_storage_use_saf_title">Выкарыстоўваць SAF</string>
<string name="downloads_storage_use_saf_summary">Storage Framework Access дазваляе захоўваць файлы на вонкавым назапашвальніку.
\nПадтрымліваецца не ўсімі прыладамі</string>
<string name="downloads_storage_ask_summary">Вам будзе прапанавана ўказаць месца захавання кожнай загрузкі.
\nУключыце сістэмны выбарнік тэчкі (SAF), калі вы хочаце загружаць файлы на знешнюю SD-картку</string>
<string name="downloads_storage_use_saf_title">Выкарыстоўвайце сродак выбару сістэмных тэчак (SAF)</string>
<string name="downloads_storage_use_saf_summary">\'Storage Access Framework\' дазваляе загружаць на знешнюю SD-картку</string>
<string name="drawer_header_description">Пераключыць службу, выбраную ў дадзены момант:</string>
<string name="clear_playback_states_summary">Выдаліць ўсе пазіцыі прайгравання</string>
<string name="youtube_restricted_mode_enabled_title">Абмежаваны рэжым YouTube</string>
<string name="youtube_restricted_mode_enabled_title">Уключыце \"Абмежаваны рэжым\" YouTube</string>
<string name="peertube_instance_add_https_only">Падтрымліваюцца толькі адрасы URL HTTPS</string>
<string name="peertube_instance_add_title">Дадаць экзэмпляр</string>
<string name="peertube_instance_url_title">Экзэмпляры PeerTube</string>
<string name="search_showing_result_for">Вынікі для: %s</string>
<string name="notification_scale_to_square_image_title">Мініяцюра відэа ў 1:1</string>
<string name="notification_scale_to_square_image_summary">Мініяцюра відэа ў апавяшчэнні з 16:9 да 1:1 (магчымі скажэнні)</string>
<string name="notification_scale_to_square_image_title">Абрэжце мініяцюру да прапорцый 1:1</string>
<string name="notification_scale_to_square_image_summary">Абрэжце мініяцюру відэа паказванае ў апавяшчэнні з прапорцый 16:9 да 1:1</string>
<string name="notification_action_3_title">Кнопка чацвёртага дзеяння</string>
<string name="notification_action_2_title">Кнопка трэцяга дзеяння</string>
<string name="notification_action_1_title">Кнопка другога дзеяння</string>
@ -435,10 +439,10 @@
<string name="delete_downloaded_files">Выдаліць загружаныя файлы</string>
<string name="show_original_time_ago_summary">Арыгінальныя тэксты з сэрвісаў будуць бачны ў ленце элементаў</string>
<string name="clear_cookie_summary">Ачысціце cookie, якія NewPipe захоўвае пры рашэнні reCAPTCHA</string>
<string name="peertube_instance_add_exists">Экзэмпляр ужо існуе</string>
<string name="peertube_instance_add_exists">Інстанцыя ўжо існуе</string>
<string name="peertube_instance_add_fail">Немагчыма праверыць экзэмпляр</string>
<string name="peertube_instance_add_help">Увесці URL экзэмпляра</string>
<string name="peertube_instance_url_summary">Абярыце любімыя экзэмпляры PeerTube</string>
<string name="peertube_instance_add_help">Увядзіце адрас URL інстанцыі</string>
<string name="peertube_instance_url_summary">Выбярыце улюбёныя інстанцыі PeerTube</string>
<string name="clear_queue_confirmation_description">Актыўны плэер быў зменены</string>
<string name="clear_queue_confirmation_summary">Змена плэера можа замяніць вашу чаргу</string>
<string name="clear_queue_confirmation_title">Запытаць, перш чым ачысціць чаргу</string>
@ -454,7 +458,7 @@
<string name="local">Лакальнае</string>
<string name="recently_added">Нядаўна дададзенае</string>
<string name="no_playlist_bookmarked_yet">Няма закладак у плейлісце</string>
<string name="select_a_playlist">Абярыце плэйліст</string>
<string name="select_a_playlist">Выберыце плэйліст</string>
<string name="default_kiosk_page_summary">Кіёск па змаўчанні</string>
<string name="recaptcha_done_button">Так</string>
<string name="subtitle_activity_recaptcha">Націсніце \"Так\" калі вырашана</string>
@ -464,7 +468,7 @@
<string name="copy_for_github">Скапіруйце адфарматаваны багрэпарт</string>
<string name="permission_display_over_apps">Дайце дазвол на адлюстраванне паверх іншых праграм</string>
<string name="delete_playback_states_alert">Выдаліць усе пазіцыі прайгравання\?</string>
<string name="clear_playback_states_title">Выдаліць пазіцыі прайгравання</string>
<string name="clear_playback_states_title">Выдаліць пазіцыю прайгравання</string>
<string name="clear_cookie_title">Ачысціць reCAPTCHA cookies</string>
<string name="recaptcha_cookies_cleared">reCAPTCHA cookies былі ачышчаны</string>
<string name="artists">Выканаўцы</string>
@ -472,7 +476,7 @@
<string name="songs">Песні</string>
<string name="videos_string">Відэа</string>
<string name="auto_queue_toggle">Аўтаматычная чарга</string>
<string name="seek_duration_title">Працягласць перамоткі ўперад/назад</string>
<string name="seek_duration_title">Крок перамотвання</string>
<string name="notification_colorize_title">Каляровыя апавяшчэнні</string>
<string name="notification_action_nothing">Нічога</string>
<string name="notification_action_buffering">Буферызацыя</string>
@ -482,4 +486,283 @@
<string name="notification_colorize_summary">Афарбоўваць апавяшчэнне асноўным колерам мініяцюры. Падтрымваецца не ўсімі прыладамі</string>
<string name="notification_actions_at_most_three">У кампактным апавяшчэнні дасяжна не больш за тры дзеянні!</string>
<string name="notification_actions_summary">Дзеянні можна змяніць, націснуўшы на іх. Адзначце не больш за трох для адлюстравання ў кампактным апавяшчэнні</string>
<string name="unsupported_url_dialog_message">Не ўдалося распазнаць URL-адрас. Адкрыць у іншай праграме\?</string>
<string name="settings_category_player_notification_title">Апавяшченне плэера</string>
<string name="notifications">Апавяшчэнні</string>
<string name="streams_notification_channel_name">Новыя трансляцыі</string>
<string name="streams_notification_channel_description">Апавяшчэнні пра новыя трансляцыі ў падпісках</string>
<string name="description_tab_description">Апісанне</string>
<string name="related_items_tab_description">Падобныя матэрыялы</string>
<string name="no_one_watching">Ніхто не праглядае</string>
<string name="recovering">аднаўленне</string>
<plurals name="watching">
<item quantity="one">%s глядач</item>
<item quantity="few">%s глядача</item>
<item quantity="many">%s глядачоў</item>
<item quantity="other">%s глядачоў</item>
</plurals>
<string name="feed_group_dialog_empty_selection">Падпіскі не выбраны</string>
<string name="feed_oldest_subscription_update">Апошняе абнаўленне: %s</string>
<string name="feed_toggle_show_played_items">Паказаць прагледжаныя матэрыялы</string>
<string name="feed_toggle_hide_played_items">Схаваць прагледжаныя матэрыялы</string>
<string name="auto_device_theme_title">Аўтаматычна (тэма прылады)</string>
<string name="night_theme_summary">Выберыце ўлюбёную начную тэму - %s</string>
<string name="description_select_enable">Дазвол вылучэння тэксту ў апісанні</string>
<string name="select_night_theme_toast">Ніжэй вы можаце абраць улюбёную начную тэму</string>
<string name="night_theme_available">Гэта опцыя даступна толькі тады, калі %s будзе выбранай тэмаю</string>
<string name="download_has_started">Загрузка пачалась</string>
<string name="notifications_disabled">Апавяшчэнні адключаныя</string>
<string name="tablet_mode_title">Рэжым планшета</string>
<string name="off">Адключыць</string>
<string name="no_audio_streams_available_for_external_players">Няма аўдыётрансляцый даступных для знешніх плэераў</string>
<string name="get_notified">Апавяшчаць</string>
<string name="no_video_streams_available_for_external_players">Няма даступных відэатрансляцый для знешніх плэераў</string>
<string name="selected_stream_external_player_not_supported">Выбраная трансляцыя не падтрымліваецца знешнімі плэерамі</string>
<string name="select_quality_external_players">Выберыце якасць для знешніх плэераў</string>
<string name="unknown_quality">Невядомая якасць</string>
<string name="unknown_format">Невядомы фармат</string>
<string name="feed_toggle_show_future_items">Паказаць наступны матэрыял</string>
<string name="feed_toggle_hide_future_items">Схаваць наступныя матэрыялы</string>
<string name="sort">Сартаваць</string>
<string name="new_seek_duration_toast">З-за абмежаванняў ExoPlayer працягласць пошуку была ўсталявана на %d сякундаў</string>
<string name="chapters">Раздзелы</string>
<string name="mark_as_watched">Пазначыць прагледжаным</string>
<string name="open_with">Адкрыць з дапамогай</string>
<string name="night_theme_title">Начная тэма</string>
<string name="open_website_license">Адкрыць вэб-сайт</string>
<string name="description_select_note">Цяпер Вы можаце вылучаць тэкст у апісанні. Звярніце ўвагу, што ў рэжыме вылучэння старонка можа мігацець, а спасылкі могуць быць недаступныя для націскання.</string>
<string name="start_main_player_fullscreen_title">Запусціць галоўны прайгравальнік у поўнаэкранным рэжыме</string>
<string name="show_channel_details">Паказаць дэталі канала</string>
<string name="low_quality_smaller">Нізкая якасць (менш)</string>
<string name="hash_channel_name">Апавяшчэнне пра відэахэшуванне</string>
<string name="progressive_load_interval_title">Памер інтэрвалу загрузкі прайгравання</string>
<string name="show_description_title">Паказаць апісанне</string>
<string name="comments_are_disabled">Каментары адключаны</string>
<plurals name="listening">
<item quantity="one">%s слухач</item>
<item quantity="few">%s слухача</item>
<item quantity="many">%s слухачоў</item>
<item quantity="other">%s слухачоў</item>
</plurals>
<plurals name="seconds">
<item quantity="one">%d сякунда</item>
<item quantity="few">%d сякунды</item>
<item quantity="many">%d сякундаў</item>
<item quantity="other">%d сякундаў</item>
</plurals>
<plurals name="hours">
<item quantity="one">%d гадзіна</item>
<item quantity="few">%d гадзіны</item>
<item quantity="many">%d гадзін</item>
<item quantity="other">%d гадзін</item>
</plurals>
<plurals name="days">
<item quantity="one">%d дзень</item>
<item quantity="few">%d дня</item>
<item quantity="many">%d дзён</item>
<item quantity="other">%d дзён</item>
</plurals>
<string name="clear_download_history">Ачысціць гісторыю загрузак</string>
<string name="localization_changes_requires_app_restart">Мова зменіцца пасля перазапуску праграмы</string>
<string name="no_one_listening">Ніхто не слухае</string>
<string name="on">Уключыць</string>
<string name="hash_channel_description">Апавяшчэнні пра ход відэахэшування</string>
<string name="create_error_notification">Стварыць паведамленне пра памылку</string>
<string name="feed_group_dialog_select_subscriptions">Выберыце падпіскі</string>
<string name="import_subscriptions_hint">Імпарт ці экспарт падпісак з 3-кропкавага меню</string>
<string name="description_select_disable">Забарона вылучэння тэксту ў апісанні</string>
<string name="fast_mode">Хуткі рэжым</string>
<string name="faq_description">Калі ў Вас узніклі праблемы з выкарыстаннем праграмы, абавязкова азнаёмцеся з адказамі на пашыраныя пытанні!</string>
<string name="disable_media_tunneling_title">Адключыць тунэляванне медыя</string>
<string name="seekbar_preview_thumbnail_title">Прагляд мініяцюры над паўзунком часу</string>
<string name="high_quality_larger">Высокая якасць (больш)</string>
<string name="dont_show">Не паказваць</string>
<string name="app_update_unavailable_toast">Вы выкарыстоўваеце апошнюю версію NewPipe</string>
<string name="error_download_resource_gone">Немажліва аднавіць гэту загрузку</string>
<plurals name="deleted_downloads_toast">
<item quantity="one">Выдалена %1$s зазагрузка</item>
<item quantity="few">Выдалена %1$s зазагрузкі</item>
<item quantity="many">Выдалена %1$s зазагрузак</item>
<item quantity="other">Выдалена %1$s зазагрузак</item>
</plurals>
<string name="delete_downloaded_files_confirm">Выдаліць усе загружаныя файлы з дыска\?</string>
<plurals name="minutes">
<item quantity="one">%d хвіліна</item>
<item quantity="few">%d хвіліны</item>
<item quantity="many">%d хвілінаў</item>
<item quantity="other">%d хвілінаў</item>
</plurals>
<string name="progressive_load_interval_summary">Змяніць памер інтэрвалу загрузкі (зараз %s). Меншае значэнне можа паскорыць пачатковую загрузку відэа. Змены патрабуюць перазапуск плэера</string>
<string name="show_description_summary">Выключыце, каб схаваць апісанне відэа і дадатковую інфармацыю</string>
<string name="local_search_suggestions">Прапановы лакальнага пошуку</string>
<string name="settings_category_player_notification_summary">Наладзіць апавяшчэнне аб бягучым прайграванні патоку</string>
<string name="restricted_video">Гэта відэа абмежавана па ўзросце.
\n
\nУключыце \"%1$s\" у наладах, калі хочаце бачыць гэта.</string>
<string name="error_report_channel_name">Апавяшчэнне аб памылцы</string>
<string name="error_report_channel_description">Апавяшчэнні для паведамлення аб памылках</string>
<string name="error_report_notification_title">NewPipe выявіў памылку, націсніце, каб паведаміць</string>
<string name="start_main_player_fullscreen_summary">Не запускайце відэа ў міні-прайгравальніку, а пераключыце непасрэдна ў поўнаэкранны рэжым, калі аўтаматычны паварот заблакіраваны. Вы ўсё яшчэ можаце атрымаць доступ да міні-плэера, выйшоўшы з поўнаэкраннага рэжыму</string>
<string name="peertube_instance_url_help">Знайдзіце асобнікі, якія вам падабаюцца, на %s</string>
<string name="show_meta_info_title">Паказаць метаінфармацыю</string>
<string name="ignore_hardware_media_buttons_title">Ігнараваць падзеі апаратных медыякнопак</string>
<string name="show_age_restricted_content_summary">Паказваць змесціва, магчыма непрыдатнае для дзяцей, таму што яно мае ўзроставыя абмежаванні (напрыклад, 18+)</string>
<string name="error_report_open_github_notice">Калі ласка, праверце, ці існуе ўжо праблема з абмеркаваннем вашага збою. Пры стварэнні дублікатаў тыкетаў вы забіраеце ў нас час, які мы маглі б патраціць на выпраўленне фактычнай памылкі.</string>
<string name="error_report_notification_toast">Адбылася памылка, глядзіце апавяшчэнне</string>
<string name="crash_the_player">Збой плэера</string>
<string name="ignore_hardware_media_buttons_summary">Карысна, напрыклад, калі вы карыстаецеся гарнітурай са зламанымі фізічнымі кнопкамі</string>
<string name="show_meta_info_summary">Адключыце, каб схаваць поля метаінфармацыі з дадатковай інфармацыяй пра стваральніка патоку, змесціва патоку або пошукавы запыт</string>
<string name="remote_search_suggestions">Прапановы аддаленага пошуку</string>
<string name="restricted_video_no_stream">Гэта відэа абмежавана па ўзросце.
\nУ сувязі з новай палітыкай YouTube у дачыненні да відэа з узроставымі абмежаваннямі, NewPipe не можа атрымаць доступ ні да аднаго са сваіх відэапатокаў і, такім чынам, не можа іх прайграваць.</string>
<string name="youtube_restricted_mode_enabled_summary">YouTube забяспечвае \"Абмежаваны рэжым\", які хавае патэнцыйна змесціва для дарослых</string>
<string name="msg_calculating_hash">Разлік хэша</string>
<string name="recaptcha_solve">Вырашана</string>
<string name="playlist_no_uploader">Створана аўтаматычна (запампавальнік не знойдзены)</string>
<string name="duplicate_in_playlist">Плэйлісты, якія пазначаны шэрым, ужо ўтрымліваюць гэты элемент.</string>
<plurals name="new_streams">
<item quantity="one">%s новы стрым</item>
<item quantity="few">%s новыя стрымы</item>
<item quantity="many">%s новых стрымаў</item>
<item quantity="other">%s новых стрымаў</item>
</plurals>
<string name="comments_tab_description">Каментарыі</string>
<string name="enqueue_next_stream">У чаргу далей</string>
<string name="enqueued_next">У чарзе наступны</string>
<string name="loading_stream_details">Загрузка звестак аб стрыме…</string>
<string name="processing_may_take_a_moment">Апрацоўка... Можа заняць некаторы час</string>
<string name="playlist_add_stream_success_duplicate">Дублікат дададзены %d раз</string>
<string name="leak_canary_not_available">LeakCanary недаступны</string>
<string name="show_memory_leaks">Паказаць уцечкі памяці</string>
<string name="disable_media_tunneling_summary">Адключыце мультымедыйнае тунэляванне, калі ў вас з\'яўляецца чорны экран або заіканне падчас прайгравання відэа</string>
<string name="msg_failed_to_copy">Не ўдалося скапіраваць у буфер абмену</string>
<string name="no_dir_yet">Папка спампоўкі пакуль не ўстаноўлена, выберыце папку спампоўкі па змаўчанні</string>
<string name="faq_title">Часта задаюць пытанні</string>
<string name="faq">Перайсці на вэбсайт</string>
<string name="main_page_content_swipe_remove">Правядзіце пальцам па элементах, каб выдаліць іх</string>
<string name="unset_playlist_thumbnail">Адмяніць пастаянную мініяцюру</string>
<string name="show_image_indicators_title">Паказаць індыкатары выявы</string>
<string name="show_image_indicators_summary">Паказваць каляровыя стужкі Пікаса на выявах, якія пазначаюць іх крыніцу: чырвоная для сеткі, сіняя для дыска і зялёная для памяці</string>
<string name="feed_processing_message">Апрацоўка стужкі…</string>
<string name="downloads_storage_ask_summary_no_saf_notice">Вам будзе прапанавана, дзе захоўваць кожную спампоўку</string>
<string name="feed_notification_loading">Загрузка стужкі…</string>
<string name="remove_watched_popup_title">Выдаліць прагледжаныя відэа\?</string>
<string name="remove_watched_popup_yes_and_partially_watched_videos">Ды і відэа часткова прагледзеў</string>
<string name="percent">Працэнт</string>
<string name="remove_watched_popup_warning">Відэа, якія былі прагледжаны да і пасля дадання ў спіс прайгравання, будуць выдалены.
\nВы ўпэўнены\? Гэта не можа быць адменена!</string>
<string name="show_crash_the_player_summary">Паказвае варыянт збою пры выкарыстанні плэера</string>
<string name="remove_watched">Выдаліць прагледжанае</string>
<string name="show_error_snackbar">Паказаць панэль памылак</string>
<string name="semitone">Паўтон</string>
<string name="any_network">Любая сетка</string>
<string name="feed_subscription_not_loaded_count">Не загружана: %d</string>
<string name="downloads_storage_use_saf_summary_api_29">Пачынаючы з Android 10 падтрымліваецца толькі \"Storage Access Framework\"</string>
<string name="checking_updates_toast">Праверка абнаўленняў…</string>
<string name="remove_duplicates_title">Выдаліць дублікаты\?</string>
<string name="remove_duplicates">Выдаліць дублікаты</string>
<string name="remove_duplicates_message">Вы хочаце выдаліць усе паўтаральныя стрымы ў гэтым плэйлісце\?</string>
<string name="feed_new_items">Новыя элементы стужкі</string>
<plurals name="feed_group_dialog_selection_count">
<item quantity="one">%d выбраны</item>
<item quantity="few">%d выбраныя</item>
<item quantity="many">%d выбраных</item>
<item quantity="other">%d выбраных</item>
</plurals>
<string name="feed_group_dialog_empty_name">Пустая назва групы</string>
<string name="feed_group_dialog_delete_message">Вы хочаце выдаліць гэту групу\?</string>
<string name="feed_create_new_group_button_title">Новы</string>
<string name="feed_group_show_only_ungrouped_subscriptions">Паказаць толькі разгрупаваныя падпіскі</string>
<string name="feed_show_upcoming">Маючыя адбыцца</string>
<string name="show_crash_the_player_title">Паказаць «Збой плэера»</string>
<string name="check_new_streams">Запусціце праверку новых патокаў</string>
<string name="crash_the_app">Збой праграмы</string>
<string name="enable_streams_notifications_title">Апавяшчэнні аб новых стрымах</string>
<string name="enable_streams_notifications_summary">Апавяшчаць аб новых стрымах з падпісак</string>
<string name="streams_notifications_interval_title">Частата праверкі</string>
<string name="streams_notifications_network_title">Патрабуецца падключэнне да сеткі</string>
<string name="manual_update_title">Праверце наяўнасць абнаўленняў</string>
<string name="manual_update_description">Праверце новыя версіі ўручную</string>
<string name="autoplay_summary">Аўтаматычны запуск прайгравання — %s</string>
<string name="card">Картка</string>
<string name="app_update_available_notification_text">Націсніце, каб спампаваць %s</string>
<plurals name="download_finished_notification">
<item quantity="one">Загрузка скончана</item>
<item quantity="few">%s загрузкі скончаны</item>
<item quantity="many">%s загрузак скончана</item>
<item quantity="other">%s загрузак скончана</item>
</plurals>
<string name="feed_update_threshold_option_always_update">Заўсёды абнаўляць</string>
<string name="feed_update_threshold_title">Парог абнаўлення стужкі</string>
<string name="feed_load_error_account_info">Немагчыма загрузіць канал для «%s».</string>
<string name="settings_category_feed_title">Стужка</string>
<string name="feed_update_threshold_summary">Час пасля апошняга абнаўлення, перш чым падпіска лічыцца састарэлай — %s</string>
<string name="feed_load_error">Памылка загрузкі стужкі</string>
<string name="feed_load_error_terminated">Уліковы запіс аўтара быў спынены.
\nNewPipe не зможа загрузіць гэты канал у будучыні.
\nВы хочаце адмовіцца ад падпіскі на гэты канал\?</string>
<string name="feed_load_error_fast_unknown">Рэжым хуткай загрузкі стужкі не дае дадатковай інфармацыі аб гэтым.</string>
<string name="feed_use_dedicated_fetch_method_title">Атрымлівайце са спецыяльнага канала, калі ён даступны</string>
<string name="feed_use_dedicated_fetch_method_enable_button">Уключыць хуткі рэжым</string>
<string name="metadata_category">Катэгорыя</string>
<string name="metadata_tags">Тэгі</string>
<string name="metadata_licence">Ліцэнзія</string>
<string name="metadata_host">Хост</string>
<string name="metadata_thumbnail_url">URL мініяцюры</string>
<string name="metadata_privacy_unlisted">Не ў спісе</string>
<string name="metadata_privacy_private">Прыватная</string>
<string name="enumeration_comma">,</string>
<string name="toggle_all">Пераключыць усё</string>
<string name="streams_not_yet_supported_removed">Стрымы, якія яшчэ не падтрымліваюцца загрузчыкам, не адлюстроўваюцца</string>
<string name="detail_sub_channel_thumbnail_view_description">Мініяцюра аватара канала</string>
<string name="video_detail_by">Аўтар: %s</string>
<string name="detail_heart_img_view_description">Аўтару відэа спадабалася гэта</string>
<string name="channel_created_by">Створана %s</string>
<string name="feed_use_dedicated_fetch_method_disable_button">Адключыць хуткі рэжым</string>
<string name="metadata_privacy_public">Публічная</string>
<string name="detail_pinned_comment_view_description">Замацаваны каментар</string>
<string name="you_successfully_subscribed">Вы падпісаліся на канал</string>
<string name="recent">Апошнія</string>
<string name="radio">Радыё</string>
<string name="feed_hide_streams_title">Паказаць наступныя стрымы</string>
<string name="feed_show_hide_streams">Паказаць/схаваць стрымы</string>
<string name="content_not_supported">Гэты кантэнт яшчэ не падтрымліваецца NewPipe.
\n
\nСпадзяюся, ён будзе падтрымлівацца ў наступных версіях.</string>
<string name="playlist_page_summary">Старонка плэйліста</string>
<string name="show_thumbnail_title">Паказаць мініяцюру</string>
<string name="show_thumbnail_summary">Выкарыстоўвайце мініяцюру як для фону экрана блакіроўкі, так і для апавяшчэнняў</string>
<string name="no_appropriate_file_manager_message">Для гэтага дзеяння не знойдзены адпаведны дыспетчар файлаў.
\nКалі ласка, усталюйце файлавы мэнэджар або паспрабуйце адключыць «%s» у наладах загрузкі</string>
<string name="georestricted_content">Гэты кантэнт недаступны ў вашай краіне.</string>
<string name="soundcloud_go_plus_content">Гэта трэк SoundCloud Go+, прынамсі ў вашай краіне, таму NewPipe не можа трансляваць ці спампоўваць яго.</string>
<string name="private_content">Гэта змесціва з\'яўляецца прыватным, таму NewPipe не можа яго трансляваць або спампоўваць.</string>
<string name="youtube_music_premium_content">Гэта відэа даступна толькі для падпісчыкаў YouTube Music Premium, таму NewPipe не можа яго трансляваць або спампоўваць.</string>
<string name="account_terminated">Уліковы запіс спынены</string>
<string name="service_provides_reason">%s дае наступную прычыну:</string>
<string name="featured">Рэкамендаваны</string>
<string name="metadata_privacy_internal">Унутраная</string>
<string name="feed_show_watched">Цалкам прагледзеў</string>
<string name="paid_content">Гэты кантэнт даступны толькі для аплачаных карыстальнікаў, таму NewPipe не можа яго трансляваць або спампоўваць.</string>
<string name="feed_use_dedicated_fetch_method_summary">Даступны ў некаторых службах, звычайна нашмат хутчэй, але можа вяртаць абмежаваную колькасць элементаў і часта няпоўную інфармацыю (напрыклад, без працягласці, тыпу элемента, без актыўнага стану)</string>
<string name="metadata_age_limit">Узроставае абмежаванне</string>
<string name="no_appropriate_file_manager_message_android_10">Для гэтага дзеяння не знойдзены адпаведны дыспетчар файлаў.
\nКалі ласка, усталюйце файлавы менеджэр, сумяшчальны з Storage Access Framework</string>
<string name="no_app_to_open_intent">Ніякая праграма на вашай прыладзе не можа адкрыць гэта</string>
<string name="progressive_load_interval_exoplayer_default">Стандартнае значэнне ExoPlayer</string>
<string name="feed_show_partially_watched">Часткова прагледжана</string>
<string name="feed_use_dedicated_fetch_method_help_text">Як вы думаеце, загрузка корму адбываецца занадта павольна\? Калі так, паспрабуйце ўключыць хуткую загрузку (гэта можна змяніць у наладах або націснуўшы кнопку ніжэй).
\n
\nNewPipe прапануе дзве стратэгіі загрузкі корму:
\n• Атрыманне ўсяго канала падпіскі павольнае, але поўнае.
\n• Выкарыстанне спецыяльнай канчатковай кропкі абслугоўвання, якая працуе хутка, але звычайна не поўная.
\n
\nРозніца паміж імі заключаецца ў тым, што хуткаму звычайна не хапае некаторай інфармацыі, напрыклад, працягласці або тыпу элемента (не можа адрозніць жывыя відэа ад звычайных), і ён можа вяртаць менш элементаў.
\n
\nYouTube з\'яўляецца прыкладам сэрвісу, які прапануе гэты хуткі метад са сваім RSS-каналам.
\n
\nТакім чынам, выбар зводзіцца да таго, што вы аддаеце перавагу: хуткасць або дакладная інфармацыя.</string>
<string name="metadata_privacy">Прыватнасць</string>
<string name="metadata_language">Мова</string>
<string name="metadata_support">Падтрымка</string>
</resources>

View File

@ -36,7 +36,7 @@
<string name="show_higher_resolutions_title">Покажи по-високи резолюции</string>
<string name="show_higher_resolutions_summary">Само някои устройства могат да възпроизвеждат 2K/4K видео</string>
<string name="play_with_kodi_title">Въпроизвеждане с Kodi</string>
<string name="kore_not_found">Инсталиране на липсващото приложение \"Kore\"\?</string>
<string name="kore_not_found">Инсталиране на липсващото приложение \"Kode\"\?</string>
<string name="show_play_with_kodi_title">Покажи „Възпроизвеждане с Kodi“</string>
<string name="show_play_with_kodi_summary">Показване на опция за възпроизвеждане на видео чрез „Kodi media center“</string>
<string name="play_audio">Аудио</string>
@ -191,7 +191,6 @@
<string name="no_subscribers">Няма абонати</string>
<string name="create">Създай</string>
<string name="dismiss">Откажи</string>
<string name="toast_no_player">Няма инсталирано приложение, което да изпълни този файл</string>
<string name="copyright" formatted="true">© %1$s от %2$s под лиценза %3$s</string>
<string name="contribution_title">Съдействайте</string>
<string name="contribution_encouragement">За всичко, което се сетите: превод, промени по дизайна, изчистване на кода или много сериозни промени по кода помощта е винаги добре дошла. Колкото повече развитие, толкова по-добре!</string>

View File

@ -303,7 +303,6 @@
<string name="notification_action_0_title">প্রথম ক্রিয়া বোতাম</string>
<string name="notification_scale_to_square_image_title">থাম্বনেল ১:১ অনুপাতে সেট করো</string>
<string name="systems_language">সিস্টেম ডিফল্ট</string>
<string name="toast_no_player">এ ফাইলটি চালানোর জন্য কোন অ্যাপ ইন্সটলকৃত নেই</string>
<string name="bookmark_playlist">প্লেলিস্ট বুকমার্ক করুন</string>
<string name="feed_use_dedicated_fetch_method_title">"যখন পর্যাপ্ত নিবেদিত ফিড থেকে ডাটা সংগ্রহ করুন"</string>
<string name="feed_update_threshold_option_always_update">সবসময় হালনগাদ করুন</string>

View File

@ -101,7 +101,7 @@
<string name="play_audio">অডিও</string>
<string name="show_play_with_kodi_summary">Kodi মিডিয়া সেন্টারে এর মাধ্যমে ভিডিও প্লে করার জন্য একটি বিকল্প প্রদর্শন কর</string>
<string name="show_play_with_kodi_title">দেখাও \"Kodi এর মাধ্যমে চালাও \" বিকল্প</string>
<string name="kore_not_found">হারানো কোর ইনস্টল করবেন\?</string>
<string name="kore_not_found">অনুপস্থিত কোড অ্যাপ ইনস্টল করবেন\?</string>
<string name="play_with_kodi_title">Kodi এর মাধ্যমে চালান</string>
<string name="show_higher_resolutions_summary">শুধুমাত্র কিছু ডিভাইস 2K/4K ভিডিও চালাতে পারে</string>
<string name="show_higher_resolutions_title">উচ্চ রেজোল্যুশন দেখাও</string>

View File

@ -251,7 +251,7 @@
<string name="notification_scale_to_square_image_title">থাম্বনেলে ১:১ অনুপাতে করো</string>
<string name="show_play_with_kodi_summary">Kodi মিডিয়া সেন্টারে এর মাধ্যমে ভিডিও প্লে করার জন্য একটি বিকল্প প্রদর্শন কর</string>
<string name="show_play_with_kodi_title">\"Kodi দ্বারা চালান\" বিকল্পটি প্রদর্শন কর</string>
<string name="kore_not_found">হারানো কোর ইনস্টল করবে\?</string>
<string name="kore_not_found">অনুপস্থিত কোড অ্যাপ ইনস্টল করবেন\?</string>
<string name="play_with_kodi_title">Kodi দ্বারা চালাও</string>
<string name="show_higher_resolutions_summary">শুধুমাত্র কিছু ডিভাইস 2K/4K ভিডিও চালাতে পারে</string>
<string name="show_higher_resolutions_title">উচ্চতর রেজুলেশন প্রদর্শন করা হবে</string>
@ -491,7 +491,6 @@
<string name="feed_update_threshold_summary">শেষ হালনাগাদের পর একটি সাবস্ক্রিপশনের আগের সময় সেকেলে বিবেচিত — %s</string>
<string name="feed_group_dialog_delete_message">তুমি কি এ গ্রুপটি মুছতে চাও\?</string>
<string name="website_encouragement">আরও তথ্য এবং খবরের জন্য নিউপাইপ ওয়েবসাইট দেখো।</string>
<string name="toast_no_player">এ ফাইলটি চালানোর জন্য কোন অ্যাপ ইন্সটলকৃত নেই</string>
<string name="override_current_data">এতে তোমার বর্তমান অবস্থা সরানো হবে।</string>
<string name="could_not_import_all_files">সতর্কতা: সব তথ্য আনা যায়নি।</string>
<string name="copyright">© %3$s এর মাধ্যমে %2$s দিয়ে %1$s</string>

View File

@ -28,7 +28,7 @@
<string name="channel_unsubscribed">Otkazana pratnja kanala</string>
<string name="subscription_change_failed">Nije moguće promijeniti pratnju</string>
<string name="subscription_update_failed">Nije moguće ažurirati pratnju</string>
<string name="kore_not_found">Instalirajte nedostajeću Kore aplikaciju\?</string>
<string name="kore_not_found">Instalirajte nedostajeću Kode aplikaciju\?</string>
<string name="tab_bookmarks">Obilježeni Popisi</string>
<string name="controls_popup_title">Iskačni prozor</string>
<string name="tab_choose">Izaberite Podprozor</string>

View File

@ -114,7 +114,7 @@
<string name="show_higher_resolutions_title">Mostra resolucions superiors</string>
<string name="show_higher_resolutions_summary">Només alguns dispositius poden reproduir vídeos en 2K/4K</string>
<string name="play_with_kodi_title">Reprodueix amb el Kodi</string>
<string name="kore_not_found">No s\'ha trobat l\'aplicació Kore. Voleu instal·lar-la\?</string>
<string name="kore_not_found">No s\'ha trobat l\'aplicació Kode. Voleu instal·lar-la\?</string>
<string name="show_play_with_kodi_title">Mostra «Reprodueix amb el Kodi»</string>
<string name="show_play_with_kodi_summary">Mostra una opció per reproduir un vídeo amb el centre multimèdia Kodi</string>
<string name="popup_remember_size_pos_title">Reproductor emergent intel·ligent</string>
@ -299,7 +299,6 @@
<string name="no_streams_available_download">No hi ha vídeos que es puguin baixar</string>
<string name="caption_setting_title">Subtítols</string>
<string name="caption_setting_description">Modifica la mida i el fons dels subtítols. Cal reiniciar l\'aplicació per aplicar els canvis</string>
<string name="toast_no_player">No s\'ha trobat cap aplicació instal·lada que pugui reproduir aquest fitxer</string>
<string name="clear_views_history_title">Neteja l\'historial de reproduccions</string>
<string name="clear_views_history_summary">Neteja l\'historial dels vídeos reproduïts i les posicions de reproducció</string>
<string name="delete_view_history_alert">Voleu suprimir tot l\'historial de reproduccions\?</string>

View File

@ -319,7 +319,6 @@
<string name="preferred_open_action_settings_summary">کرداری بنەڕەتی لەکاتی کردنەوەی بابەتدا — %s</string>
<string name="select_a_kiosk">هکیۆسکێک دیار بکە</string>
<string name="conferences">کۆنفرانسەکان</string>
<string name="toast_no_player">هیچ به‌رنامه‌یه‌ك دانەمەزراوە بۆ لێدانی ئەم فایله‌</string>
<string name="open_in_popup_mode">كردنه‌وه‌ له‌ دۆخی په‌نجه‌ره‌</string>
<string name="limit_mobile_data_usage_title">سنووری قەبارە لەکاتی بەکارهێنانی ڕایه‌ڵه‌ی مۆبایل</string>
<string name="drawer_close">داخستنی پلیکانە</string>

View File

@ -67,7 +67,7 @@
<string name="what_happened_headline">Co se stalo:</string>
<string name="error_snackbar_action">Nahlásit</string>
<string name="sorry_string">Omlouváme se, tohle se nemělo stát.</string>
<string name="error_report_button_text">Nahlásit tuto chybu přes e-mail</string>
<string name="error_report_button_text">Nahlásit přes e-mail</string>
<string name="error_snackbar_message">Omlouváme se, něco se pokazilo.</string>
<string name="app_ui_crash">Aplikace/UI spadlo</string>
<string name="could_not_setup_download_menu">Nepodařilo se nastavit menu stahování</string>
@ -115,7 +115,7 @@
<string name="resume_on_audio_focus_gain_summary">Pokračovat v přehrávání po přerušení (např. hovor)</string>
<string name="settings_category_player_title">Přehrávač</string>
<string name="settings_category_player_behavior_title">Chování</string>
<string name="settings_category_history_title">Historie a mezipamět</string>
<string name="settings_category_history_title">Historie a mezipaměť</string>
<string name="popup_playing_toast">Přehrávání v okně</string>
<string name="disabled">Vypnuto</string>
<string name="clear">Vyčistit</string>
@ -163,7 +163,7 @@
<string name="contribution_title">Podílet se</string>
<string name="title_activity_history">Historie</string>
<string name="action_history">Historie</string>
<string name="show_hold_to_append_title">Zobrazit tip „Podržet pro vložení do fronty“</string>
<string name="show_hold_to_append_title">Zobrazit tip „Podržte pro zařazení do fronty“</string>
<string name="show_hold_to_append_summary">Zobrazit tip po klepnutí na pozadí nebo na vyskakovací tlačítko v „Podrobnostech“ videa</string>
<string name="play_all">Přehrát vše</string>
<string name="player_stream_failure">Tento stream nelze přehrát</string>
@ -183,7 +183,7 @@
<string name="play_queue_remove">Odebrat</string>
<string name="play_queue_stream_detail">Podrobnosti</string>
<string name="play_queue_audio_settings">Nastavení zvuku</string>
<string name="hold_to_append">Podrž pro zařazení do fronty</string>
<string name="hold_to_append">Podržte pro zařazení do fronty</string>
<string name="unknown_content">[Neznámý]</string>
<string name="start_here_on_background">Začít přehrávat na pozadí</string>
<string name="start_here_on_popup">Začít přehrávat v pop-upu</string>
@ -219,7 +219,7 @@
<string name="preferred_player_fetcher_notification_title">Získávám informace…</string>
<string name="preferred_player_fetcher_notification_message">Načítání požadovaného obsahu</string>
<string name="controls_download_desc">Stáhnout soubor streamu</string>
<string name="show_info">Ukázat informace</string>
<string name="show_info">Zobrazit informace</string>
<string name="tab_bookmarks">Uložené playlisty</string>
<string name="controls_add_to_playlist_title">Přidat do</string>
<string name="detail_drag_description">Táhnout pro přeskupení</string>
@ -252,10 +252,10 @@
<string name="use_inexact_seek_title">Použít rychlé nepřesné hledání</string>
<string name="use_inexact_seek_summary">Nepřesné hledání umožní přehrávači posouvat se rychleji, ale se sníženou přesností. Posouvání po 5, 15 nebo 25 vteřinách s tímto nefunguje</string>
<string name="download_thumbnail_title">Načítat náhledy</string>
<string name="download_thumbnail_summary">Vypnout, aby se zabránilo načítání náhledů a tím se ušetřily data a používání paměti. Změna tohoto nastavení vyčistí mezipamět obrázků v paměti i na disku</string>
<string name="download_thumbnail_summary">Vypnutím zabráníte načítání miniatur, ukládání dat a spotřebě paměti. Změny vymažou mezipaměť obrázků v paměti i na disku</string>
<string name="thumbnail_cache_wipe_complete_notice">Mezipaměť obrázků vymazána</string>
<string name="metadata_cache_wipe_title">Vymazat metadata v mezipaměti</string>
<string name="metadata_cache_wipe_summary">Odebrat všechna data uložená v mezipaměti</string>
<string name="metadata_cache_wipe_summary">Odstranit všechna data webových stránek v mezipaměti</string>
<string name="metadata_cache_wipe_complete_notice">Mezipaměť metadat vymazána</string>
<string name="auto_queue_title">Další stream automaticky vložit do fronty</string>
<string name="auto_queue_summary">Pokračovat konečnou (neopakující se) frontu playbacku připojením souvisejícího streamu</string>
@ -302,7 +302,6 @@
<string name="preferred_open_action_settings_summary">Výchozí chování při otevírání obsahu — %s</string>
<string name="caption_setting_title">Titulky</string>
<string name="caption_setting_description">Upravuje velikost textu titulků a styly pozadí. Změny se projeví po restartu aplikace</string>
<string name="toast_no_player">K přehrání tohoto souboru chybí vhodná aplikace</string>
<string name="clear_views_history_title">Vymazat historii sledování</string>
<string name="clear_views_history_summary">Vymaže historii přehraných streamů pozic playbacku</string>
<string name="delete_view_history_alert">Vymazat celkovou historii sledování\?</string>
@ -313,7 +312,7 @@
<string name="search_history_deleted">Historie vyhledávání smazána</string>
<string name="one_item_deleted">Jedna položka smazána.</string>
<string name="app_license">NewPipe je svobodný software s copyleft licencí: Můžete jej libovolně používat, studovat, sdílet a vylepšovat. Konkrétně jej můžete šířit a/nebo upravovat za podmínek Obecné veřejné licence GNU (GNU GPL) vydané nadací Free Software Foundation, a to buď za podmínek Licence verze 3 nebo (dle vaší volby) jakékoli pozdější verze.</string>
<string name="channels">kanály</string>
<string name="channels">Kanály</string>
<string name="playlists">Playlisty</string>
<string name="tracks">Stopy</string>
<string name="users">Uživatelé</string>
@ -525,7 +524,7 @@
<string name="more_than_100_videos">100+ videí</string>
<string name="artists">Umělci</string>
<string name="albums">Alba</string>
<string name="songs">Písně</string>
<string name="songs">Skladby</string>
<string name="restricted_video">Toto video má věkové omezení.
\n
\nPokud jej chcete vidět, povolte „%1$s“ v nastavení.</string>
@ -541,7 +540,7 @@
<string name="channel_created_by">Vytvořil %s</string>
<string name="detail_sub_channel_thumbnail_view_description">Ikona kanálu</string>
<string name="playlist_page_summary">Strana playlistů</string>
<string name="feed_group_show_only_ungrouped_subscriptions">Ukázat jen neseskupené objednávky</string>
<string name="feed_group_show_only_ungrouped_subscriptions">Zobrazit jen neseskupené odběry</string>
<string name="no_playlist_bookmarked_yet">Zatím žádné záložky playlistů</string>
<string name="select_a_playlist">Vybrat playlist</string>
<string name="error_report_open_github_notice">Prosím, ověřte, zda chyba již existuje. Pokud založíte duplikovaný tiket, obíráte nás o čas, který bychom mohli věnovat řešení skutečných chyb.</string>
@ -552,8 +551,8 @@
<string name="wifi_only">Pouze na Wi-Fi</string>
<string name="autoplay_summary">Automaticky zahájit přehrávání — %s</string>
<string name="title_activity_play_queue">Přehrát frontu</string>
<string name="unsupported_url_dialog_message">Nelze rozpoznat zadané URL. Otevřít pomocí jiné aplikace\?</string>
<string name="auto_queue_toggle">Auto-fronta</string>
<string name="unsupported_url_dialog_message">Nelze rozpoznat zadanou adresu URL. Otevřít pomocí jiné aplikace\?</string>
<string name="auto_queue_toggle">Automatické přehravání</string>
<string name="clear_queue_confirmation_description">Fronta aktivního přehrávače bude smazána</string>
<string name="clear_queue_confirmation_summary">Při přechodu z jednoho přehrávače do druhého může dojít k smazání fronty</string>
<string name="clear_queue_confirmation_title">Žádat potvrzení před vyklizením fronty</string>
@ -570,7 +569,7 @@
<string name="notification_action_0_title">První akční tlačítko</string>
<string name="notification_scale_to_square_image_summary">Oříznout miniaturu videa zobrazenou v oznámení z poměru stran 16:9 na 1:1</string>
<string name="notification_scale_to_square_image_title">Oříznout poměr stran miniatury na 1:1</string>
<string name="show_memory_leaks">Ukázat memory leaks</string>
<string name="show_memory_leaks">Zobrazit úniky paměti</string>
<string name="enqueued">Zařazeno do fronty</string>
<string name="enqueue_stream">Zařadit do fronty</string>
<string name="clear_cookie_summary">Vymazat cookies, které NewPipe uloží, po vyřešení reCAPTCHA</string>
@ -646,7 +645,7 @@
<string name="off">Vypnuto</string>
<string name="on">Zapnuto</string>
<string name="tablet_mode_title">Režim tabletu</string>
<string name="feed_toggle_show_played_items">Ukázat přehrané položky</string>
<string name="feed_toggle_show_played_items">Zobrazit zhlédnuté položky</string>
<string name="dont_show">Nezobrazovat</string>
<string name="low_quality_smaller">Nízká kvalita (menší)</string>
<string name="high_quality_larger">Vysoká kvalita (větší)</string>
@ -664,8 +663,8 @@
<item quantity="few">%s stahování dokončena</item>
<item quantity="other">%s stahováních dokončeno</item>
</plurals>
<string name="show_image_indicators_summary">Ukázat zabarvené stužky Picasso na obrázcích k indikaci zdroje: červená indikuje síť, modrá disk a zelená paměť</string>
<string name="show_image_indicators_title">Ukázat indikátory obrázků</string>
<string name="show_image_indicators_summary">Zobrazit barevné pásky Picasso na obrázcích označujících jejich zdroj: červená pro síť, modrá pro disk a zelená pro paměť</string>
<string name="show_image_indicators_title">Zobrazit indikátory obrázků</string>
<string name="remote_search_suggestions">Vzdálené návrhy vyhledávání</string>
<string name="local_search_suggestions">Lokální návrhy vyhledávání</string>
<string name="start_main_player_fullscreen_summary">Pokud je vypnuté automatické otáčení, nespouštět video v mini přehrávači, ale přepnout se přímo do režimu celé obrazovky. Do mini přehrávače se lze i nadále dostat ukončením režimu celé obrazovky</string>
@ -689,7 +688,7 @@
<string name="no_appropriate_file_manager_message">Pro tuto akci nebyl nalezen žádný vhodný správce souborů.
\nNainstalujte správce souborů nebo zkuste vypnout \'%s\' v nastavení stahování</string>
<string name="show_crash_the_player_summary">Ukáže volbu pro zřícení během používání přehrávače</string>
<string name="show_error_snackbar">Ukázat krátké oznámení o chybě</string>
<string name="show_error_snackbar">Zobrazit krátké oznámení o chybě</string>
<string name="detail_pinned_comment_view_description">Připnutý komentář</string>
<string name="crash_the_player">Shodit přehrávač</string>
<string name="progressive_load_interval_summary">Změnit interval načítání (aktuálně %s). Menší hodnota může zrychlit počáteční načítání videa. Změna vyžaduje restart přehrávače</string>
@ -700,7 +699,7 @@
<string name="enable_streams_notifications_summary">Oznámit o nových streamech od vašich odběrů</string>
<string name="streams_notifications_interval_title">Frekvence kontroly</string>
<string name="any_network">Jakákoli síť</string>
<string name="streams_notifications_network_title">Nutné síťové připojení</string>
<string name="streams_notifications_network_title">Požadované síťové připojení</string>
<string name="delete_downloaded_files_confirm">Smazat všechny stažené soubory z disku\?</string>
<string name="you_successfully_subscribed">Objednali jste si nyní tento kanál</string>
<string name="toggle_all">Všechny přepnout</string>
@ -745,4 +744,14 @@
<string name="msg_failed_to_copy">Kopírování do schránky se nezdařilo</string>
<string name="duplicate_in_playlist">Zašedlé playlisty již obsahují tuto položku.</string>
<string name="playlist_add_stream_success_duplicate">Duplikát přidán %dkrát</string>
<string name="ignore_hardware_media_buttons_title">Ignorovat události hardwarových tlačítek médií</string>
<string name="ignore_hardware_media_buttons_summary">Užitečné například v případě, že používáte sluchátka s rozbitými fyzickými tlačítky</string>
<string name="remove_duplicates_title">Odstranit duplicity\?</string>
<string name="feed_hide_streams_title">Zobrazit následující streamy</string>
<string name="feed_show_hide_streams">Zobrazit/skrýt streamy</string>
<string name="feed_show_watched">Celé zhlédnuto</string>
<string name="feed_show_partially_watched">Částečně zhlédnuto</string>
<string name="feed_show_upcoming">Nadcházející</string>
<string name="remove_duplicates">Odstranit duplicity</string>
<string name="remove_duplicates_message">Chcete odstranit všechny duplicitní streamy v tomto playlistu\?</string>
</resources>

View File

@ -43,7 +43,7 @@
<string name="show_higher_resolutions_title">Vis højere opløsninger</string>
<string name="show_higher_resolutions_summary">Kun nogle enheder kan afspille 2K-/4K-videoer</string>
<string name="play_with_kodi_title">Afspil med Kodi</string>
<string name="kore_not_found">Installer manglede Kore-app\?</string>
<string name="kore_not_found">Installer manglede Kode-app\?</string>
<string name="show_play_with_kodi_title">Vis valgmuligheden \"Afspil med Kodi\"</string>
<string name="show_play_with_kodi_summary">Vis en knap til at afspille en video via Kodi-mediecenteret</string>
<string name="play_audio">Lyd</string>
@ -163,7 +163,7 @@
<string name="restore_defaults">Genskab standardindstillinger</string>
<string name="restore_defaults_confirmation">Vil du genoprette standardindstillingerne\?</string>
<string name="sorry_string">Undskyld, dette skulle ikke være sket.</string>
<string name="error_report_button_text">Rapporter denne fejl via e-mail</string>
<string name="error_report_button_text">Rapporter via e-mail</string>
<string name="error_snackbar_message">Beklager, noget gik galt.</string>
<string name="error_snackbar_action">Rapporter</string>
<string name="what_device_headline">Information:</string>
@ -213,7 +213,6 @@
<string name="settings_file_replacement_character_title">Erstatningstegn</string>
<string name="charset_letters_and_digits">Bogstaver og cifre</string>
<string name="charset_most_special_characters">De fleste specialtegn</string>
<string name="toast_no_player">Der ingen app installeret der kan afspille denne fil</string>
<string name="title_activity_about">Om NewPipe</string>
<string name="title_licenses">Tredjepartslicenser</string>
<string name="copyright" formatted="true">© %1$s af %2$s under %3$s</string>
@ -727,4 +726,9 @@
<string name="select_quality_external_players">Vælg kvalitet til eksterne afspillere</string>
<string name="feed_toggle_show_future_items">Vis fremtidige elementer</string>
<string name="sort">Sortér</string>
<string name="ignore_hardware_media_buttons_title">Ignorer hardware medie knapper</string>
<string name="ignore_hardware_media_buttons_summary">Brugbart f.eks. hvis du bruger et headset med ødelagte fysiske knapper</string>
<string name="duplicate_in_playlist">Playlists der er grået ud, indeholder allerede dette objekt.</string>
<string name="unset_playlist_thumbnail">Inaktiver permanent thumbnail</string>
<string name="msg_failed_to_copy">Fejlede at kopiere til udklipsholderen</string>
</resources>

View File

@ -49,7 +49,7 @@
<string name="content">Inhalt</string>
<string name="show_age_restricted_content_title">Altersbeschränkte Inhalte anzeigen</string>
<string name="could_not_setup_download_menu">Konnte Downloadmenü nicht einrichten</string>
<string name="error_report_button_text">Fehler via E-Mail melden</string>
<string name="error_report_button_text">Per E-Mail melden</string>
<string name="copy_for_github">Formatierten Fehlerbericht kopieren</string>
<string name="error_report_open_issue_button_text">Über GitHub melden</string>
<string name="error_snackbar_action">Melden</string>
@ -75,7 +75,7 @@
<string name="short_billion">Mrd.</string>
<string name="msg_name">Dateiname</string>
<string name="msg_error">Fehler</string>
<string name="msg_wait">Bitte warten </string>
<string name="msg_wait">Bitte warten </string>
<string name="msg_copied">In Zwischenablage kopiert</string>
<string name="no_available_dir">Bitte gib später in den Einstellungen einen Downloadordner an</string>
<string name="start">Starten</string>
@ -136,7 +136,7 @@
<string name="action_history">Verlauf</string>
<string name="subscription_change_failed">Abonnement konnte nicht geändert werden</string>
<string name="subscription_update_failed">Abonnement konnte nicht aktualisiert werden</string>
<string name="resume_on_audio_focus_gain_summary">Nach Unterbrechungen (z.B. Telefonaten) Wiedergabe fortsetzen</string>
<string name="resume_on_audio_focus_gain_summary">Nach Unterbrechungen (z. B. Telefonaten) Wiedergabe fortsetzen</string>
<string name="notification_channel_name">NewPipe-Benachrichtigung</string>
<string name="notification_channel_description">Benachrichtigungen für den NewPipe-Player</string>
<string name="settings_category_player_behavior_title">Verhalten</string>
@ -295,13 +295,12 @@
\n2. Gehe zu dieser URL: %1$s
\n3. Melde dich an, falls du dazu aufgefordert wirst
\n4. Kopiere die Profil-URL, zu der du weitergeleitet wurdest.</string>
<string name="import_soundcloud_instructions_hint">yourID, soundcloud.com/yourid</string>
<string name="import_soundcloud_instructions_hint">deineID, soundcloud.com/deineid</string>
<string name="no_streams_available_download">Keine Streams zum Download verfügbar</string>
<string name="preferred_open_action_settings_title">Bevorzugte „Öffnen“-Aktion</string>
<string name="preferred_open_action_settings_summary">Standardaktion beim Öffnen von Inhalten — %s</string>
<string name="caption_setting_title">Untertitel</string>
<string name="caption_setting_description">Textgröße und Hintergrund der Untertitel im Player anpassen. Erfordert Neustart der App</string>
<string name="toast_no_player">Keine App zum Abspielen dieser Datei installiert</string>
<string name="clear_views_history_title">Wiedergabeverlauf löschen</string>
<string name="clear_views_history_summary">Den Verlauf der wiedergegebenen Streams und die Wiedergabepositionen löschen</string>
<string name="delete_view_history_alert">Den ganzen Wiedergabeverlauf löschen\?</string>
@ -573,7 +572,7 @@
<string name="clear_cookie_summary">Lösche Cookies, die NewPipe speichert, wenn du ein reCAPTCHA löst</string>
<string name="recaptcha_cookies_cleared">reCAPTCHA-Cookies wurden gelöscht</string>
<string name="clear_cookie_title">reCAPTCHA-Cookies löschen</string>
<string name="show_age_restricted_content_summary">Inhalte mit Altersbegrenzung (z. B. ab 18) anzeigen, die für Kinder möglicherweise ungeeignet sind</string>
<string name="show_age_restricted_content_summary">Für Kinder möglicherweise ungeeignete Inhalte anzeigen (bspw. ab 18)</string>
<string name="enqueue_stream">In Wiedergabe einreihen</string>
<string name="notification_colorize_summary">Android kann die Farbe der Benachrichtigung entsprechend der Hauptfarbe in der Miniaturansicht anpassen (beachte, dass dies nicht auf allen Geräten verfügbar ist)</string>
<string name="notification_colorize_title">Benachrichtigung farblich anpassen</string>
@ -732,4 +731,14 @@
<string name="card">Karte</string>
<string name="playlist_add_stream_success_duplicate">Duplikat %d mal hinzugefügt</string>
<string name="duplicate_in_playlist">Die ausgegrauten Wiedergabelisten enthalten dieses Element bereits.</string>
<string name="ignore_hardware_media_buttons_summary">Nützlich, wenn z. B. ein Headset mit defekten physischen Tasten verwendet wird</string>
<string name="ignore_hardware_media_buttons_title">Ereignisse der Hardware-Medientasten ignorieren</string>
<string name="remove_duplicates">Duplikate entfernen</string>
<string name="remove_duplicates_title">Duplikate entfernen\?</string>
<string name="remove_duplicates_message">Möchtest du alle doppelten Streams in dieser Wiedergabeliste entfernen\?</string>
<string name="feed_show_hide_streams">Streams anzeigen/ausblenden</string>
<string name="feed_hide_streams_title">Folgende Streams anzeigen</string>
<string name="feed_show_upcoming">Demnächst</string>
<string name="feed_show_watched">Vollständig angeschaut</string>
<string name="feed_show_partially_watched">Teilweise angeschaut</string>
</resources>

View File

@ -165,7 +165,7 @@
<string name="error_occurred_detail">Προέκυψε ένα σφάλμα: %1$s</string>
<string name="no_streams_available_download">Δεν υπάρχουν διαθέσιμες ροές για λήψη</string>
<string name="sorry_string">Λυπούμαστε, αυτό δεν έπρεπε να έχει συμβεί.</string>
<string name="error_report_button_text">Αναφορά αυτού του σφάλματος μέσω ηλεκτρονικού ταχυδρομείου</string>
<string name="error_report_button_text">Αναφορά μέσω ηλεκτρονικού ταχυδρομείου</string>
<string name="error_snackbar_message">Συγγνώμη, κάτι πήγε στραβά.</string>
<string name="info_labels">Τι:\\nΑίτημα:\\nΓλώσσα περιεχομένου:\\nΧώρα περιεχομένου:\\nΓλώσσα εφαρμογής:\\nΥπηρεσία:\\nΏρα GMT:\\nΠακέτο:\\nΈκδοση:\\nΈκδοση λειτουργικού συστήματος:</string>
<string name="search_no_results">Κανένα αποτέλεσμα</string>
@ -210,7 +210,6 @@
<string name="settings_file_replacement_character_summary">Οι μη έγκυροι χαρακτήρες αντικαθίστανται με αυτήν την τιμή</string>
<string name="settings_file_replacement_character_title">Αντικαταστάτης χαρακτήρας</string>
<string name="charset_most_special_characters">Οι περισσότεροι ειδικοί χαρακτήρες</string>
<string name="toast_no_player">Δεν υπάρχει εγκατεστημένη εφαρμογή για την αναπαραγωγή αυτού του αρχείου</string>
<string name="title_activity_about">Σχετικά με το NewPipe</string>
<string name="title_licenses">Άδειες Τρίτων</string>
<string name="copyright" formatted="true">© %1$s από %2$s υπό %3$s</string>
@ -732,4 +731,14 @@
<string name="card">Κάρτα</string>
<string name="duplicate_in_playlist">Οι λίστες αναπαραγωγής που είναι γκριζαρισμένες περιέχουν ήδη αυτό το στοιχείο.</string>
<string name="playlist_add_stream_success_duplicate">Προστέθηκε διπλότυπο %d φορά(ες)</string>
<string name="ignore_hardware_media_buttons_title">Αγνοήστε τα συμβάντα κουμπιών πολυμέσων υλικού</string>
<string name="ignore_hardware_media_buttons_summary">Χρήσιμο, για παράδειγμα, εάν χρησιμοποιείτε ακουστικά με χαλασμένα φυσικά κουμπιά</string>
<string name="feed_hide_streams_title">Εμφάνιση των ακόλουθων ροών</string>
<string name="feed_show_watched">Θεαθέντα πλήρως</string>
<string name="feed_show_upcoming">Προσεχή</string>
<string name="feed_show_hide_streams">Εμφάνιση/Απόκρυψη ροών</string>
<string name="remove_duplicates_title">Αφαίρεση διπλοτύπων;</string>
<string name="remove_duplicates_message">Θέλετε να καταργήσετε όλες τις διπλότυπες ροές σε αυτήν τη λίστα αναπαραγωγής;</string>
<string name="remove_duplicates">Αφαίρεση διπλοτύπων</string>
<string name="feed_show_partially_watched">Θεαθέντα μερικώς</string>
</resources>

View File

@ -187,7 +187,6 @@
<string name="metadata_cache_wipe_summary">Vakigi tutajn kaŝmemorigitajn retpaĝajn datumojn</string>
<string name="metadata_cache_wipe_complete_notice">Kaŝmemorojn de metadatumojn vakigis</string>
<string name="no_streams_available_download">Neniuj torentoj haveblaj por elŝuti</string>
<string name="toast_no_player">Neniu apo instalita por ludi ĉi tiun dosieron</string>
<string name="clear_views_history_title">Forviŝi vidohistorion</string>
<string name="clear_views_history_summary">Forviŝi la historion de viditaj filmetojn kaj ludajn poziciojn</string>
<string name="delete_view_history_alert">Ĉu vi volas forviŝi la tutan historion \?</string>

View File

@ -16,7 +16,7 @@
<string name="download_path_dialog_title">Elija la carpeta de descarga para los archivos de vídeo</string>
<string name="default_resolution_title">Resolución predefinida</string>
<string name="play_with_kodi_title">Reproducir con Kodi</string>
<string name="kore_not_found">¿Instalar la aplicación Kore que falta\?</string>
<string name="kore_not_found">¿Instalar la aplicación Kode que falta\?</string>
<string name="show_play_with_kodi_title">Mostrar opción «Reproducir con Kodi»</string>
<string name="show_play_with_kodi_summary">Mostrar una opción para reproducir un vídeo a través de Kodi media center</string>
<string name="play_audio">Audio</string>
@ -55,7 +55,7 @@
<string name="error_report_title">Informe de error</string>
<string name="could_not_setup_download_menu">No se pudo configurar el menú de descarga</string>
<string name="sorry_string">Lo siento, esto no debería haber ocurrido.</string>
<string name="error_report_button_text">Informar de este error vía correo electrónico</string>
<string name="error_report_button_text">Informar por correo electrónico</string>
<string name="error_snackbar_message">Lo siento, algo salió mal.</string>
<string name="error_snackbar_action">Informar</string>
<string name="what_device_headline">Información:</string>
@ -301,7 +301,6 @@
<string name="no_streams_available_download">No hay streams disponibles para descargar</string>
<string name="preferred_open_action_settings_title">Acción de apertura preferida</string>
<string name="preferred_open_action_settings_summary">Acción predefinida al abrir contenido: %s</string>
<string name="toast_no_player">No se encontró ninguna aplicación que reproduzca este archivo</string>
<string name="caption_setting_title">Subtítulos</string>
<string name="caption_setting_description">Modificar la escala de texto de los subtítulos y los estilos de fondo. Requiere reiniciar la aplicación para que surta efecto</string>
<string name="clear_views_history_title">Vaciar historial de reproducciones</string>
@ -748,4 +747,14 @@
<string name="card">Tarjeta</string>
<string name="playlist_add_stream_success_duplicate">Duplicado añadido %d vez/veces</string>
<string name="duplicate_in_playlist">Las listas de reproducción que están en gris ya contienen este elemento.</string>
<string name="ignore_hardware_media_buttons_summary">Útil, por ejemplo, si está utilizando un auricular con botones físicos rotos</string>
<string name="ignore_hardware_media_buttons_title">Ignorar eventos para botones multimedia de hardware</string>
<string name="remove_duplicates_title">¿Eliminar los duplicados\?</string>
<string name="remove_duplicates_message">¿Desea eliminar todas las secuencias duplicadas de esta lista de reproducción\?</string>
<string name="feed_hide_streams_title">Mostrar las siguientes secuencias</string>
<string name="feed_show_hide_streams">Mostrar/Ocultar secuencias</string>
<string name="feed_show_upcoming">Próximamente</string>
<string name="remove_duplicates">Eliminar los duplicados</string>
<string name="feed_show_watched">Completamente visto</string>
<string name="feed_show_partially_watched">Parcialmente visto</string>
</resources>

View File

@ -41,7 +41,7 @@
<string name="show_higher_resolutions_title">Kuva kõrgemaid lahutusi</string>
<string name="show_higher_resolutions_summary">Ainult mõned seadmed suudavad esitada 2K/4K videoid</string>
<string name="play_with_kodi_title">Esita Kodi abil</string>
<string name="kore_not_found">Kas paigaldada puuduv Kore rakendus\?</string>
<string name="kore_not_found">Kas paigaldame puuduva Kore rakenduse\?</string>
<string name="show_play_with_kodi_title">Kuva valik \"Esita Kodi abil\"</string>
<string name="show_play_with_kodi_summary">Kuva valik video esitamiseks Kodi meediakeskuse kaudu</string>
<string name="play_audio">Heli</string>
@ -139,7 +139,7 @@
<string name="error_occurred_detail">Ilmnes viga: %1$s</string>
<string name="no_streams_available_download">Allalaaditavaid videovooge pole</string>
<string name="sorry_string">Vabandust, seda poleks pidanud juhtuma.</string>
<string name="error_report_button_text">Teata sellest veast e-posti kaudu</string>
<string name="error_report_button_text">Teata e-posti teel</string>
<string name="error_snackbar_message">Vabandust, midagi läks valesti.</string>
<string name="error_snackbar_action">Teata</string>
<string name="what_device_headline">Info:</string>
@ -200,7 +200,6 @@
<string name="settings_file_replacement_character_title">Asendustähemärk</string>
<string name="charset_letters_and_digits">Tähed ja numbrid</string>
<string name="charset_most_special_characters">Erimärgid</string>
<string name="toast_no_player">Selle faili esitamiseks puudub rakendus</string>
<string name="title_activity_about">NewPipe rakendusest</string>
<string name="title_licenses">Kolmanda osapoole litsentsid</string>
<string name="tab_about">Rakenduse teave ja KKK</string>
@ -732,4 +731,14 @@
<string name="card">Kaart</string>
<string name="duplicate_in_playlist">Hallina kuvatud esitusloendid juba sisaldavad seda kirjet.</string>
<string name="playlist_add_stream_success_duplicate">Topeltkirje lisatud %d kord(a)</string>
<string name="ignore_hardware_media_buttons_summary">Kasulik näiteks kui olukorras kui kõrvaklappide nupud on katki</string>
<string name="ignore_hardware_media_buttons_title">Eira nutiseadmes asuvate või seotud seadmete meedianuppude vajutusi</string>
<string name="remove_duplicates">Eemalda topeltkirjed</string>
<string name="remove_duplicates_title">Kas eemaldame topeltkirjed\?</string>
<string name="remove_duplicates_message">Kas sa soovid eemaldada kõik topelt meediavood sellest esitusloendist\?</string>
<string name="feed_hide_streams_title">Näita järgmisi meediavooge</string>
<string name="feed_show_hide_streams">Näita/peida meediavood</string>
<string name="feed_show_upcoming">Tulemas</string>
<string name="feed_show_watched">Lõpuni vaadatud</string>
<string name="feed_show_partially_watched">Osaliselt vaadatud</string>
</resources>

View File

@ -14,7 +14,7 @@
<string name="download_path_dialog_title">Aukeratu bideoak deskargatzeko karpeta</string>
<string name="default_resolution_title">Lehenetsitako bereizmena</string>
<string name="play_with_kodi_title">Jo Kodirekin</string>
<string name="kore_not_found">Kore aplikazioa instalatu\?</string>
<string name="kore_not_found">Kode aplikazioa instalatu\?</string>
<string name="show_play_with_kodi_title">Erakutsi \"Jo Kodirekin\" aukera</string>
<string name="show_play_with_kodi_summary">Erakutsi bideoa Kodi multimedia zentroarekin erreproduzitzeko aukera</string>
<string name="play_audio">Audioa</string>
@ -74,7 +74,7 @@
<string name="could_not_setup_download_menu">Ezin izan da deskargen menua ezarri</string>
<string name="app_ui_crash">Aplikazioa/interfazea kraskatu da</string>
<string name="sorry_string">Hori ez litzateke gertatu behar.</string>
<string name="error_report_button_text">Eman errore honen berri e-posta bidez</string>
<string name="error_report_button_text">Eman honen berri e-posta bidez</string>
<string name="error_snackbar_message">Barkatu, zerbait gaizki atera da.</string>
<string name="error_snackbar_action">Salatu</string>
<string name="what_device_headline">Informazioa:</string>
@ -243,7 +243,6 @@
<string name="dismiss">Baztertu</string>
<string name="rename">Aldatu izena</string>
<string name="one_item_deleted">Elementu 1 ezabatuta.</string>
<string name="toast_no_player">Ez dago fitxategi hau erreproduzitzeko aplikaziorik instalatuta</string>
<string name="title_last_played">Jotako azkena</string>
<string name="title_most_played">Ikusiena</string>
<string name="export_complete_toast">Esportatuta</string>
@ -732,4 +731,14 @@
<string name="fast_mode">Modu azkarra</string>
<string name="import_subscriptions_hint">Hiru-puntutako menutik harpidetzak inportatu edo esportatu</string>
<string name="faq_title">Maiz galdetutako galderak</string>
<string name="ignore_hardware_media_buttons_title">Ezikusi hardware multimedia botoien gertaerak</string>
<string name="ignore_hardware_media_buttons_summary">Erabilgarria, adibidez, botoi fisiko hautsiak dituen entzungailua erabiltzen ari bazara</string>
<string name="remove_duplicates">Kendu bikoiztuak</string>
<string name="remove_duplicates_title">Kendu bikoiztuak\?</string>
<string name="remove_duplicates_message">Jario bikoiztu guztiak kendu nahi dituzu erreprodukzio-zerrenda honetatik\?</string>
<string name="feed_hide_streams_title">Erakutsi hurrengo jarioak</string>
<string name="feed_show_hide_streams">Erakutsi/Ezkutatu jarioak</string>
<string name="feed_show_partially_watched">Partzialki ikusita</string>
<string name="feed_show_watched">Guztiz ikusia</string>
<string name="feed_show_upcoming">Laster agertzeko</string>
</resources>

View File

@ -51,7 +51,7 @@
<string name="content_not_available">محتوا در دسترس نیست</string>
<string name="could_not_setup_download_menu">نمی‌توان فهرست بارگیری را برپا ساخت</string>
<string name="sorry_string">ببخشید! نباید این اتّفاق زخ می‌داد.</string>
<string name="error_report_button_text">این خطا را با رایانامه گزارش کنید</string>
<string name="error_report_button_text">گزارش با رایانامه</string>
<string name="error_snackbar_message">ببخشید، چیزی به درستی پیش نرفت.</string>
<string name="error_snackbar_action">گزارش</string>
<string name="what_device_headline">اطّلاعات:</string>
@ -176,7 +176,6 @@
<string name="settings_file_replacement_character_title">نویسه جایگزین</string>
<string name="charset_letters_and_digits">حروف و اعداد</string>
<string name="charset_most_special_characters">مهم‌ترین نویسه‌های خاص</string>
<string name="toast_no_player">کاره‌ای برای پخش این پرونده نصب نشده است</string>
<string name="title_activity_about">درباره نیوپایپ</string>
<string name="tab_about">درباره و سوالات‌متداول</string>
<string name="tab_licenses">پروانه‌ها</string>
@ -730,4 +729,12 @@
<string name="card">کارت</string>
<string name="msg_failed_to_copy">شکست در رونوشت به تخته‌گیره</string>
<string name="unset_playlist_thumbnail">ناتنظیم بندانگشتی ثابت</string>
<string name="ignore_hardware_media_buttons_title">چشم‌پوشی از رخدادهای دکمهٔ رسانهٔ سخت‌افزاری</string>
<string name="remove_duplicates">برداشتن تکراری‌ها</string>
<string name="remove_duplicates_title">برداشتن تکراری‌ها؟</string>
<string name="feed_show_hide_streams">نمایش یا نهفتن جریان‌ها</string>
<string name="feed_hide_streams_title">نمایش جریان‌های زیر</string>
<string name="feed_show_upcoming">پیش رو</string>
<string name="feed_show_watched">کامل دیده شده</string>
<string name="feed_show_partially_watched">نیمه دیده شده</string>
</resources>

View File

@ -36,7 +36,7 @@
<string name="show_higher_resolutions_title">Näytä korkeammat resoluutiot</string>
<string name="show_higher_resolutions_summary">Vain jotkin laitteet voivat toistaa 2K/4K-videota</string>
<string name="play_with_kodi_title">Toista Kodissa</string>
<string name="kore_not_found">Asennetaanko puuttuva Kore-sovellus\?</string>
<string name="kore_not_found">Asennetaanko puuttuva Kode-sovellus\?</string>
<string name="show_play_with_kodi_title">Näytä ”Toista Kodissa”-vaihtoehto</string>
<string name="show_play_with_kodi_summary">Näyttää vaihtoehdon videon toistamiseen Kodi-mediasoittimessa</string>
<string name="play_audio">Ääni</string>
@ -240,7 +240,6 @@
<string name="dismiss">Hylkää</string>
<string name="rename">Nimeä uudelleen</string>
<string name="one_item_deleted">1 poistettu.</string>
<string name="toast_no_player">Ohjelmaa tämän toistamiseen ei ole asennettu</string>
<string name="privacy_policy_title">NewPipen tietosuojakäytäntö</string>
<string name="privacy_policy_encouragement">NewPipe ottaa yksityisyytesi tosissaan. Siksi se ei kerää sinulta mitään tietoja ilman lupaasi.
\nNewPipen tietosuojakäytännössä selitetään tarkasti mitä tietoja lähetetään tai tallennetaan virheraportin yhteydessä.</string>

View File

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="main_bg_subtitle">Pindutin ang magnifying glass upang magsimula.</string>
<string name="main_bg_subtitle">Pindutin ang magnifying glass para magsimula.</string>
<string name="upload_date_text">Inilathala noong %1$s</string>
<string name="no_player_found">Walang nakitang stream player. I-install ang VLC\?</string>
<string name="no_player_found_toast">Walang nakitang stream player (pwede mong i-install ang VLC para ma-play ito).</string>
@ -16,11 +16,11 @@
<string name="did_you_mean">\"%1$s\" ba ang tinutukoy mo\?</string>
<string name="share_dialog_title">Ibahagi sa</string>
<string name="use_external_video_player_title">Gumamit ng ibang video player</string>
<string name="use_external_video_player_summary">Natatanggal ang tunog sa ilang mga resolusyon</string>
<string name="use_external_video_player_summary">Nawawala ang tunog sa ilang resolusyon</string>
<string name="use_external_audio_player_title">Gumamit ng ibang audio player</string>
<string name="subscribe_button_title">Sumubaybay</string>
<string name="subscribed_button_title">Sinusubaybayan</string>
<string name="unsubscribe">Ihinto ang pagsubaybay</string>
<string name="subscribed_button_title">Sumusubaybay</string>
<string name="unsubscribe">Tumigil sa pagsubaybay</string>
<string name="channel_unsubscribed">Hininto ang pagsubaybay sa channel</string>
<string name="subscription_change_failed">Hindi mabago ang pagsubaybay</string>
<string name="subscription_update_failed">Hindi ma-update ang pagsubaybay</string>
@ -58,7 +58,7 @@
<string name="theme_title">Tema</string>
<string name="local_search_suggestions">Lokal na mungkahi</string>
<string name="remote_search_suggestions">Remote na mungkahi</string>
<string name="mark_as_watched">Markahan bilang napanood</string>
<string name="mark_as_watched">Markahan bilang napanood na</string>
<string name="auto_queue_toggle">Kusang ipila</string>
<string name="notification_action_repeat">Ulitin</string>
<string name="notification_action_shuffle">Halo-halo</string>
@ -104,7 +104,7 @@
<string name="popup_remember_size_pos_title">Tandaan ang mga property ng popup</string>
<string name="default_popup_resolution_title">Panimulang linaw ng popup</string>
<string name="show_higher_resolutions_summary">Mape-play lang ng ilang device ang mga video na 2K/4K</string>
<string name="kore_not_found">I-install ang nawawalang Kore app\?</string>
<string name="kore_not_found">I-install ang nawawalang Kode app\?</string>
<string name="notification_scale_to_square_image_title">I-scale ang thumbnail sa 1:1 aspect ratio</string>
<string name="notification_scale_to_square_image_summary">I-scale ang thumbnail ng video sa abiso mula 16:9 papuntang 1:1 aspect ratio (pwedeng magkaroon ng distortion)</string>
<string name="notification_action_0_title">Unang action button</string>

View File

@ -53,7 +53,7 @@
<string name="could_not_load_thumbnails">Impossible de charger toutes les miniatures</string>
<string name="youtube_signature_deobfuscation_error">Impossible de déchiffrer la signature URL de la vidéo</string>
<string name="sorry_string">Désolé, cela naurait pas dû se produire.</string>
<string name="error_report_button_text">Signaler cette erreur par courriel</string>
<string name="error_report_button_text">Signaler par courriel</string>
<string name="what_device_headline">Information :</string>
<string name="what_happened_headline">Ce qui sest passé :</string>
<string name="your_comment">Votre commentaire (en anglais) :</string>
@ -302,7 +302,6 @@
<string name="caption_setting_title">Sous-titres</string>
<string name="caption_setting_description">Modifier la taille du texte et les styles darrière-plan des sous-titres du lecteur. Le redémarrage de lapplication est requis pour appliquer les changements</string>
<string name="playback_pitch">Ton</string>
<string name="toast_no_player">Aucune application installée pour lire ce fichier</string>
<string name="clear_views_history_title">Effacer lhistorique des vues</string>
<string name="clear_views_history_summary">Supprime lhistorique des flux lus et des positions de reprise de lecture</string>
<string name="delete_view_history_alert">Voulez-vous supprimer entièrement lhistorique des vues\?</string>
@ -745,4 +744,16 @@
<string name="night_theme_available">Cette option est disponible seulement si %s est sélectionné pour le thème</string>
<string name="duplicate_in_playlist">Les listes de lecture grisées contiennent déjà cet élément.</string>
<string name="card">Carte</string>
<string name="ignore_hardware_media_buttons_summary">Utile si vous utilisez un casque avec des boutons dysfonctionnels, par exemple</string>
<string name="remove_duplicates">Effacer les doublons</string>
<string name="remove_duplicates_title">Effacer les doublons \?</string>
<string name="remove_duplicates_message">Voulez-vous retirer tous les doublons de cette liste \?</string>
<string name="feed_hide_streams_title">Afficher les flux suivants</string>
<string name="feed_show_watched">Entièrement vu</string>
<string name="feed_show_partially_watched">Partiellement vu</string>
<string name="feed_show_upcoming">À venir</string>
<string name="ignore_hardware_media_buttons_title">Ignorer les évènements des boutons média des périphériques</string>
<string name="playlist_add_stream_success_duplicate">Doublon ajouté %d fois</string>
<string name="feed_show_hide_streams">Afficher/Cacher les flux</string>
<string name="unset_playlist_thumbnail">Enlever la miniature permanente</string>
</resources>

View File

@ -41,7 +41,7 @@
<string name="show_higher_resolutions_title">Mostrar resolucións máis altas</string>
<string name="show_higher_resolutions_summary">Só algúns dispositivos poden reproducir vídeos en 2K/4K</string>
<string name="play_with_kodi_title">Reproducir co Kodi</string>
<string name="kore_not_found">Quere instalar o aplicativo Kore que falta\?</string>
<string name="kore_not_found">Quere instalar o aplicativo Kode que falta\?</string>
<string name="show_play_with_kodi_title">Mostrar a opción «Reproducir co Kodi»</string>
<string name="show_play_with_kodi_summary">Mostrar unha opción para reproducir o vídeo co Kodi Media Center</string>
<string name="play_audio">Audio</string>
@ -143,7 +143,7 @@
<string name="error_occurred_detail">Ocorreu un erro: %1$s</string>
<string name="no_streams_available_download">Non hai emisións para descargar</string>
<string name="sorry_string">Deculpe, isto non debería ter acontecido.</string>
<string name="error_report_button_text">Informar deste erro por enderezo electrónico</string>
<string name="error_report_button_text">Informar por correo electrónico</string>
<string name="error_snackbar_message">Desculpe, algo foi mal.</string>
<string name="error_snackbar_action">Informe</string>
<string name="what_device_headline">Información:</string>
@ -206,7 +206,6 @@
<string name="settings_file_replacement_character_title">Carácter de substitución</string>
<string name="charset_letters_and_digits">Letras e díxitos</string>
<string name="charset_most_special_characters">A maioría dos caracteres especiais</string>
<string name="toast_no_player">Non hai ningún aplicativo instalado para reproducir este ficheiro</string>
<string name="title_activity_about">Sobre o NewPipe</string>
<string name="title_licenses">Licenzas de terceiros</string>
<string name="copyright" formatted="true">© %1$s de %2$s, so %3$s</string>
@ -732,4 +731,14 @@
<string name="card">Tarxeta</string>
<string name="duplicate_in_playlist">As listas de reprodución que se atopan atenuadas xa conteñen este elemento.</string>
<string name="playlist_add_stream_success_duplicate">Duplicado engadido %d vez/veces</string>
<string name="feed_show_hide_streams">Mostrar/Ocultar emisións</string>
<string name="ignore_hardware_media_buttons_title">Ignorar eventos con botóns multimedia físicos</string>
<string name="ignore_hardware_media_buttons_summary">Útil, por exemplo, se estiver usando un auricular con botóns rotos</string>
<string name="remove_duplicates">Eliminar duplicados</string>
<string name="remove_duplicates_title">Eliminar duplicados\?</string>
<string name="remove_duplicates_message">Desexa eliminar todas as emisións duplicadas nesta lista de reprodución\?</string>
<string name="feed_hide_streams_title">Mostrar os seguintes vídeos</string>
<string name="feed_show_watched">Completamente visto</string>
<string name="feed_show_partially_watched">Parcialmente visto</string>
<string name="feed_show_upcoming">Proximamente</string>
</resources>

View File

@ -24,7 +24,7 @@
<string name="notification_scale_to_square_image_summary">સૂચનામાં 16: 9 થી 1: 1 અસ્પેક્ટ રેશિયોમાં બતાવેલ વિડિઓ થંબનેલને સ્કેલ કરો (વિકૃતિ રજૂ કરી શકે છે)</string>
<string name="notification_scale_to_square_image_title">સ્કેલ થંબનેલથી 1: 1 પાસા રેશિયો</string>
<string name="show_play_with_kodi_summary">કોડી મીડિયા સેન્ટર દ્વારા વિડિઓ ચલાવવાનો વિકલ્પ દર્શાવો</string>
<string name="kore_not_found">અનુપસ્થિત Kore એપ્લિકેશન ઇન્સ્ટોલ કરીએ\?</string>
<string name="kore_not_found">અનુપસ્થિત Kode એપ્લિકેશન ઇન્સ્ટોલ કરીએ\?</string>
<string name="show_higher_resolutions_summary">ફક્ત થોડા ઉપકરણો 2K / 4K વિડિઓઝ ચલાવી શકે છે</string>
<string name="show_higher_resolutions_title">ઉચ્ચ રીઝોલ્યુશન બતાવો</string>
<string name="default_popup_resolution_title">ડિફોલ્ટ પોપઅપ રીઝોલ્યુશન</string>

View File

@ -29,7 +29,7 @@
<string name="show_higher_resolutions_title">הצגת רזולוציות גבוהות יותר</string>
<string name="show_higher_resolutions_summary">רק חלק מהמכשירים יכולים לנגן סרטונים ב־2K/4K</string>
<string name="play_with_kodi_title">נגינה ב־Kodi</string>
<string name="kore_not_found">להתקין את יישומון Kore החסר\?</string>
<string name="kore_not_found">להתקין את יישומון Kode החסר\?</string>
<string name="show_play_with_kodi_title">הצגת האפשרות לניגון עם Kodi</string>
<string name="show_play_with_kodi_summary">הצגת אפשרות לנגן סרטון דרך מרכז המדיה Kodi</string>
<string name="play_audio">שמע</string>
@ -69,7 +69,7 @@
<string name="could_not_setup_download_menu">לא הייתה אפשרות להכין את תפריט ההורדה</string>
<string name="app_ui_crash">היישומון או מנשק המשתמש קרסו</string>
<string name="sorry_string">זה לא אמור היה לקרות, עמך הסליחה.</string>
<string name="error_report_button_text">דיווח על השגיאה דרך דוא״ל</string>
<string name="error_report_button_text">דיווח דרך דוא״ל</string>
<string name="error_snackbar_message">משהו השתבש, עמך הסליחה.</string>
<string name="error_snackbar_action">דיווח</string>
<string name="what_device_headline">מידע:</string>
@ -225,7 +225,6 @@
<string name="dismiss">התעלמות</string>
<string name="rename">שינוי שם</string>
<string name="one_item_deleted">פריט אחד נמחק.</string>
<string name="toast_no_player">לא מותקן יישומון שמתאים לנגינת הקובץ הזה</string>
<string name="export_complete_toast">הייצוא הסתיים</string>
<string name="import_complete_toast">הייבוא הסתיים</string>
<string name="no_valid_zip_file">אין קובץ ZIP תקין</string>
@ -758,4 +757,6 @@
<string name="msg_failed_to_copy">ההעתקה ללוח הגזירים נכשלה</string>
<string name="duplicate_in_playlist">רשימות הנגינה שבוטלו וסומנו באפור כבר מכילות את הפריט הזה.</string>
<string name="playlist_add_stream_success_duplicate">הכפיל נוסף %d פעמים</string>
<string name="ignore_hardware_media_buttons_title">התעלמות מאירועי כפתורי מדיה חומרתיים</string>
<string name="ignore_hardware_media_buttons_summary">שימושי, למשל, אם יש לך אוזניות עם כפתורי חומרה מקולקלים</string>
</resources>

View File

@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="upload_date_text">%1$s पे प्रकाशित हुआ</string>
<string name="no_player_found">स्ट्रीमिंग के लिए चालक नहीं मिला। क्या आप VLC इंस्टॉल करना चाहेंगे\?</string>
<string name="no_player_found">स्ट्रीमिंग के लिए चालक नहीं मिला। क्या आप वीएलसी इंस्टॉल करना चाहेंगे\?</string>
<string name="install">स्थापित करें</string>
<string name="open_in_browser">ब्राउज़र में खोलें</string>
<string name="open_in_popup_mode">पॉपअप मोड में खोलें</string>
@ -10,7 +10,7 @@
<string name="search">खोजें</string>
<string name="settings">सेटिंग्स</string>
<string name="subscribe_button_title">सब्सक्राइब करें</string>
<string name="subscribed_button_title">सब्सक्राइ है</string>
<string name="subscribed_button_title">सब्सक्राइ है</string>
<string name="channel_unsubscribed">चैनल अनसब्सक्राईब हुआ</string>
<string name="tab_subscriptions">सब्सक्रिप्शनस</string>
<string name="controls_background_title">बैकग्राउंड</string>
@ -46,7 +46,7 @@
<string name="use_external_audio_player_title">कोई दूसरा ध्वनि चालक उपयोग करें</string>
<string name="subscription_change_failed">सब्सक्रिप्शन बदली नहीं जा सकी</string>
<string name="subscription_update_failed">सब्सक्रिप्शन अपडेट नहीं किया जा सका</string>
<string name="fragment_feed_title">देखें कि क्या नया है</string>
<string name="fragment_feed_title">क्या नया है</string>
<string name="download_path_title">वीडियो डाउनलोड का फ़ोल्डर</string>
<string name="download_path_summary">डाउनलोड की गई वीडियो फ़ाइलें यहां संग्रहीत हैं</string>
<string name="download_path_dialog_title">वीडियो फ़ाइलों के लिए डाउनलोड फ़ोल्डर चुनें</string>
@ -56,10 +56,10 @@
<string name="default_resolution_title">प्रथम स्थापित गुणवत्ता स्तर</string>
<string name="default_popup_resolution_title">पॉपअप का प्रथम स्थापित गुणवत्ता स्तर</string>
<string name="show_higher_resolutions_title">उच्च गुणवत्ता स्तर दिखाएं</string>
<string name="show_higher_resolutions_summary">केवल कुछ ही यंत्र 2K/4K मे वीडियो चला सकते हैं</string>
<string name="play_with_kodi_title">Kodi मे चलाए</string>
<string name="kore_not_found">Kore ऐप नहीं मिली, इसे स्थापित करें\?</string>
<string name="show_play_with_kodi_title">\"Kodi मे चलाएं\" वाला विकल्प दिखाएँ</string>
<string name="show_higher_resolutions_summary">केवल कुछ ही डिवाईस 2के/4के मे वीडियो चला सकते हैं</string>
<string name="play_with_kodi_title">कोडी मे चलाए</string>
<string name="kore_not_found">लापता Kode ऐप स्थापित करें\?</string>
<string name="show_play_with_kodi_title">\"कोडी मे चलाएं\" वाला विकल्प दिखाएँ</string>
<string name="show_play_with_kodi_summary">कोडी मीडिया सेंटर से वीडियो चलने के लिए विकल्प प्रदर्शित करें</string>
<string name="default_audio_format_title">प्रथम स्थापित ध्वनि फॉर्मेट</string>
<string name="default_video_format_title">प्रथम स्थापित वीडियो फॉर्मेट</string>
@ -110,8 +110,8 @@
<string name="player_unrecoverable_failure">कभी ठीक न होने वाले वीडियो प्लेयर की त्रुटी आ रही है</string>
<string name="player_recoverable_failure">वीडियो प्लेयर त्रुटी से ठीक हो रहा है</string>
<string name="sorry_string">खेद है की, ऐसा होना नहीं चाहिए था.</string>
<string name="error_report_button_text">त्रुटी की रिपोर्ट को ईमेल से भेजे</string>
<string name="error_snackbar_message">माफ़ करे , कुछ त्रुटियाँ हो रही है</string>
<string name="error_report_button_text">रिपोर्ट को ईमेल से भेजे</string>
<string name="error_snackbar_message">माफ़ करे, कुछ त्रुटि हो गई।</string>
<string name="error_snackbar_action">रिपोर्ट करें</string>
<string name="what_device_headline">जानकारी:</string>
<string name="what_happened_headline">क्या हुआ:</string>
@ -133,7 +133,7 @@
<string name="no_subscribers">कोई सब्सक्राइबर नहीं है</string>
<plurals name="subscribers">
<item quantity="one">%s सब्सक्राइबर</item>
<item quantity="other">%s सब्सक्राइबर</item>
<item quantity="other">%s सब्सक्राइबर्स</item>
</plurals>
<plurals name="views">
<item quantity="one">%s दर्शक</item>
@ -141,7 +141,7 @@
</plurals>
<plurals name="videos">
<item quantity="one">%s वीडियो</item>
<item quantity="other">%s वीडियो</item>
<item quantity="other">%s वीडियोस्</item>
</plurals>
<string name="start">शुरू</string>
<string name="pause">रोकें</string>
@ -184,7 +184,7 @@
<string name="hold_to_append">जोड़ने के लिए पकड़ें रहे</string>
<string name="start_here_on_background">पृष्टभूमि में चलाना शुरू करे</string>
<string name="start_here_on_popup">पॉपअप में चलाना शुरू करे</string>
<string name="no_player_found_toast">स्ट्रीमिंग करने के लिए कोई चालक उपलब्ध नहीं है (आप इसे चलाने के लिए VLC चालक स्थापित कर सकते हैं)।</string>
<string name="no_player_found_toast">स्ट्रीमिंग करने के लिए कोई चालक उपलब्ध नहीं है (आप इसे चलाने के लिए वीएलसी चालक स्थापित कर सकते हैं)।</string>
<string name="controls_download_desc">स्ट्रीम फाइल डाउनलोड करें</string>
<string name="show_info">जानकारी दिखाएं</string>
<string name="tab_bookmarks">बुकमार्क की गई प्लेलिस्टें</string>
@ -247,7 +247,7 @@
<string name="enable_disposed_exceptions_title">Out-of-Lifecycle त्रुटियों की रिपोर्ट करें</string>
<string name="download_thumbnail_title">थंमनेल लोड करें</string>
<string name="use_inexact_seek_title">तेज और अनिश्चित तलाश का प्रयोग करें</string>
<string name="use_inexact_seek_summary">अनिश्चित खोज से प्लेयर में कम सटीकता से लेकिन तेजी से वीडियो पोजीशन्स की तलाश कर सकता हैं। 5,15 या 25 सेकंड की तलाश में यह काम नहीं करता</string>
<string name="use_inexact_seek_summary">अनिश्चित खोज से प्लेयर में कम सटीकता से लेकिन तेजी से वीडियो पोजीशन्स की तलाश कर सकता हैं। 5, 15 या 25 सेकंड की तलाश में यह काम नहीं करता</string>
<string name="download_thumbnail_summary">थंमनेल लोड करने, डेटा और मेमोरी उपयोग को रोकने के लिए बंद करें। इन-मेमोरी और ऑन-डिस्क छवि कैश दोनों को बदलता है</string>
<string name="thumbnail_cache_wipe_complete_notice">चित्र कैश मिटाया गया</string>
<string name="metadata_cache_wipe_title">कैश मेटाडेटा मिटाएं</string>
@ -275,7 +275,6 @@
<string name="error_occurred_detail">एक भूल हुई: %1$s</string>
<string name="no_streams_available_download">डाउनलोड करने के लिए कोई स्ट्रीम उपलब्ध नही है</string>
<string name="one_item_deleted">एक चीज़ साफ कर दी गई।</string>
<string name="toast_no_player">इस फ़ाइल को चलाने के लिए कोई ऐप स्थापित नही है</string>
<string name="privacy_policy_title">न्यूपाइप की गोपनीयता नीति</string>
<string name="privacy_policy_encouragement">न्यूपाइप परियोजना आपकी गोपनीयता को बहोत गंभीर रूप से लेता है। इसलिए, ऐप आपकी अनुमति के बिना कोई डेटा जमा नही करता।
\nन्यूपाइप की गोपनीयता नीति विस्तार से समज़ाती है कि कोनसा डेटा भेजा या संग्रह किया जाता है जब आप क्रेश विवरण भेजते है।</string>
@ -296,14 +295,14 @@
<string name="subscriptions_export_unsuccessful">सब्सक्रिप्शन निर्यात नही कर सके</string>
<string name="import_youtube_instructions">गूगल टेकआउट से यूट्यूब सदस्यता आयात करें:
\n
\n1. इस URL पर जाएं:%1$s
\n1. इस यूआरएल पर जाएं: %1$s
\n2. पूछे जाने पर लॉग इन करें
\n3. \"सभी डटा शामिल करें\" पर क्लिक करें, फिर \"सभी को अचयनित करें\" पर, फिर केवल \"सदस्यताएँ\" चुनें और \"ओके\" पर क्लिक करें
\n3. \"सभी डटा शामिल करें\" पर क्लिक करें, फिर \"सभी को अचयनित करें\" पर, फिर केवल \"सदस्यताएँ\" चुनें और \" ठीक है\" पर क्लिक करें
\n4. \"अगला चरण\" पर क्लिक करें और फिर \"निर्यात बनाएं\"
\n5. प्रकट होने के बाद \"डाउनलोड\" बटन पर क्लिक करें
\n6. नीचे आयात फ़ाइल पर क्लिक करें और डाउनलोड की गई .zip फ़ाइल चुनें
\n7. [यदि .zip आयात विफल हो जाता है] .csv फ़ाइल निकालें (आमतौर पर \"YouTube और YouTube Music/subscriptions/subscriptions.csv\" के अंतर्गत), नीचे आयात फ़ाइल पर क्लिक करें और निकाली गई csv फ़ाइल चुनें</string>
<string name="import_soundcloud_instructions_hint">आपका आई डी, soundcloud.com/(आपका आई डी)</string>
\n7. [यदि .zip आयात विफल हो जाता है] .csv फ़ाइल निकालें (आमतौर पर \"यूट्यूब और यूट्यूब म्युज़िक/सब्सक्रिपशन/subscriptions.csv\" के अंतर्गत), नीचे आयात फ़ाइल पर क्लिक करें और निकाली गई सीएसवी फ़ाइल चुनें</string>
<string name="import_soundcloud_instructions_hint">आपका आईडी, soundcloud.com/(आपका आईडी)</string>
<string name="import_network_expensive_warning">ध्यान रखे, यह तरीका नेटवर्क साधनो के लिए मंहगा हो सकता है।
\n
\nक्या आप आगे बढ़ना चाहते है?</string>
@ -313,16 +312,16 @@
<string name="unhook_checkbox">अनहुक (बिगाड़ सकता है)</string>
<string name="skip_silence_checkbox">खामोशी के समय तेज़ी से आगे बढ़े</string>
<string name="playback_step">कदम</string>
<string name="playback_reset">िसेट</string>
<string name="playback_reset">सेट</string>
<string name="accept">स्वीकारे</string>
<string name="decline">अस्वीकार करे</string>
<string name="limit_data_usage_none_description">असीमित</string>
<string name="limit_mobile_data_usage_title">मोबाइल डेटा उपयोग करते समय रेसॉल्युसेन को सिमित करे</string>
<string name="limit_mobile_data_usage_title">मोबाइल डेटा उपयोग करते समय रिजॉल्युशन को सिमित करे</string>
<string name="minimize_on_exit_title">ऐप बदलते समय उसे मिनिमाइज करे</string>
<string name="minimize_on_exit_summary">मुख्य वीडियो चालक से दूसरी ऐप पर जाने पर — %s</string>
<string name="minimize_on_exit_none_description">कोई नही</string>
<string name="minimize_on_exit_background_description">बैकग्राउंड प्लेयर में बदले</string>
<string name="minimize_on_exit_popup_description">पॉप अप प्लेयर में बदले</string>
<string name="minimize_on_exit_popup_description">पॉपअप प्लेयर में बदले</string>
<string name="app_license">न्यूपाइप एक काॅपीलेफ़्ट फ़्री साॅफ़्टवेर है: इसे आप अपनी इच्छा के अनुसार इस्तेमाल, जाँच, बाँट तथा और बेहतर बना सकते है। खास तौर पर आप इसे फ़्री साॅफ़्टवेर फ़ाउंडेशन के द्वारा जारी जीएनयू जनरल पब्लिक लाइसेंस के तीसरे या उसके बाद आने वाले कोई भी वर्णन के शर्तों के मुताबिक फिर से बाँट या बदल सकते हैं।</string>
<string name="unsubscribe">अनसब्सक्राईब करें</string>
<string name="tab_choose">टैब चुने</string>
@ -362,11 +361,11 @@
<string name="error_http_no_content">सर्वर डेटा नहीं भेजता है</string>
<string name="error_http_not_found">नहीं मिला</string>
<string name="error_postprocessing_failed">प्रक्रिया के बाद का कार्य विफल रहा</string>
<string name="stop">ुक</string>
<string name="stop">रोके</string>
<string name="max_retry_msg">अधिकतम पुनर्प्रयास</string>
<string name="max_retry_desc">डाउनलोड रद्द करने से पहले प्रयासों की अधिकतम संख्या</string>
<string name="pause_downloads_on_mobile">मीटर्ड नेटवर्क पर रोके</string>
<string name="pause_downloads_on_mobile_desc">मोबाइल डाटा का इस्तेमाल करते समय उपयोगी है, परन्तु कुछ डौन्लोडस रोके नहीं जा सकते है</string>
<string name="pause_downloads_on_mobile_desc">मोबाइल डाटा का इस्तेमाल करते समय उपयोगी है, परंतु कुछ डाउन्लोड रोके नहीं जा सकते है</string>
<string name="events">घटनायें</string>
<string name="conferences">सम्मेलनों</string>
<string name="show_comments_title">टिप्पणियां दिखाएं</string>
@ -383,10 +382,10 @@
<string name="watch_history_states_deleted">प्लेबैक स्थान मिटा दिए गए</string>
<string name="missing_file">फाइल की जगह बदली गयी या फिर फाइल मिटा दी गयी</string>
<string name="overwrite_unrelated_warning">इस नाम की कोई फ़ाइल पहले से मौजूद है</string>
<string name="overwrite_finished_warning">इस नाम की एक डाउनलोड की गई फ़ाइल पहले से मौजूद है</string>
<string name="overwrite_failed">फाइल के ऊपर नहीं लिख सकते</string>
<string name="overwrite_finished_warning">इस नाम की डाउनलोड फ़ाइल पहले से मौजूद है</string>
<string name="overwrite_failed">फाइल को ओवरराइट नहीं कर सकते</string>
<string name="download_already_pending">इस नाम का एक डाउनलोड बाकी है</string>
<string name="error_postprocessing_stopped">फ़ाइल पर कार्य करते समय NewPipe बंद किया गया</string>
<string name="error_postprocessing_stopped">फ़ाइल पर कार्य करते समय न्यूपाइप बंद किया गया</string>
<string name="error_insufficient_storage">डिवाइस पर जगह समाप्त</string>
<string name="error_progress_lost">प्रगति खो गई, क्योंकि फ़ाइल मिटा दी गई थी</string>
<string name="error_timeout">कनेक्शन का समय समाप्त</string>
@ -397,28 +396,28 @@
<string name="pause_downloads">डाउनलोड रोकें</string>
<string name="downloads_storage_ask_title">डाउनलोड कहाँ करने के लिए पूछे</string>
<string name="downloads_storage_ask_summary">आपको हर डाउनलोड का स्थान पूछा जाएगा
\nयदि आप बाहरी एसडी कार्ड में डाउनलोड करना चाहते हैं तो सिस्टम फोल्डर पिकर (SAF) को सक्षम करें</string>
\nयदि आप बाहरी एसडी कार्ड में डाउनलोड करना चाहते हैं तो सिस्टम फोल्डर पिकर (एसएएफ) को सक्षम करें</string>
<string name="downloads_storage_use_saf_title">सिस्टम फोल्डर पिकर (एसएएफ) का प्रयोग करें</string>
<string name="clear_playback_states_title">प्लेबैक स्थानों को मिटाये</string>
<string name="clear_playback_states_summary">सारे प्लेबैक स्थानों को मिटाये</string>
<string name="delete_playback_states_alert">सारे प्लेबैक स्थानों को मिटाये\?</string>
<string name="enable_disposed_exceptions_summary">फ्रेगमेंट या एक्टिविटी लाइफसाइकिल के बाद Rx सन्देश ना पहुँचाया जा सके तोह ज़रूर कोशिश करे</string>
<string name="import_soundcloud_instructions">SoundCloud प्रोफाइल निर्यात करने के लिए आईडी या युआरएल दीजिये:
<string name="import_soundcloud_instructions">साउंडक्लाउड प्रोफाइल निर्यात करने के लिए आईडी या युआरएल दीजिये:
\n
\n1. अपने वेब ब्राउज़र मं \"डेस्कटॉप मोड\" चालू करे (वेबसाइट मोबाइल उपकरणों के लिए उपलब्ध नहीं है)
\n1. अपने वेब ब्राउज़र मं \"डेस्कटॉप मोड\" चालू करे (वेबसाइट मोबाइल उपकरणों के लिए उपलब्ध नहीं है)
\n2. इस युआरएल को खोले: %1$s
\n3. लग इन करे
\n3. लग इन करे
\n4. आप जिस प्रोफाइल युआरएल पे भेजे जाते है उसे कॉपी करे।</string>
<string name="start_accept_privacy_policy">यूरोप के जनरल डाटा प्रोटेक्शन रेगुलेशन (जी डी पी आर) का पालन करने के लिए, हम आपका ध्यान न्यूपाइप की नयी प्राइवेसी पालिसी पी डालना चाहते है।इसे बारीकी से पढ़िए।
\nआपको अगर हमें किसी मुसीबत का सन्देश भेजना हो तो इसे स्वीकार करे।</string>
<string name="start_accept_privacy_policy">यूरोप के जरल डाटा प्रोटेक्शन रेगुलेशन (जीडीपीआर) का पालन करने के लिए, हम आपका ध्यान न्यूपाइप की नयी प्राइवेसी पालिसी पे डालना चाहते है। इसे बारीकी से पढ़िए।
\nआपको अगर हमें कोई त्रुटि रिपोर्ट भेजना हो तो इसे स्वीकार करे।</string>
<string name="saved_tabs_invalid_json">सामान्य टैब्स का इस्तेमाल, सहेजे टैब्स को पढ़ने में रूकावट</string>
<string name="updates_setting_description">जब इस ऐप के लिए अपडेट उपलब्ध हो, अधिसूचना दिखाई जाये</string>
<string name="updates_setting_description">जब इस ऐप के लिए अपडेट उपलब्ध हो, तब अधिसूचना दिखाई जाये</string>
<string name="list_view_mode">सूचि देखने वाला ढंग</string>
<string name="grid">ग्रिड</string>
<string name="auto">ऑटो</string>
<string name="show_error">मुसीबत दिखाए</string>
<string name="show_error">्रुटि दिखाए</string>
<string name="error_http_unsupported_range">सर्वर मल्टी थ्रेडेड डाउनलोड स्वीकार नहीं करता, पुनः कोशिश करे @string/msg_threads = 1 के साथ</string>
<string name="downloads_storage_use_saf_summary">स्टोरेज एक्सेस फ्रेमवर्क (एस ऐ ऍफ़) आपको एस डी कार्ड पर डाउनलोड करने देता है</string>
<string name="downloads_storage_use_saf_summary">\'स्टोरेज एक्सेस फ्रेमवर्क\' आपको बाहरी एसडी कार्ड पर डाउनलोड करने देता है</string>
<string name="drawer_header_description">सेवा चुने, वर्तमान चुनाव :</string>
<string name="default_kiosk_page_summary">सामान्य कीओस्क</string>
<string name="no_one_watching">कोई नहीं देख रहा है</string>
@ -429,23 +428,23 @@
<string name="no_one_listening">कोई नहीं सुन रहा है</string>
<plurals name="listening">
<item quantity="one">%s श्रोता</item>
<item quantity="other">%s श्रोता</item>
<item quantity="other">%s श्रोता</item>
</plurals>
<string name="localization_changes_requires_app_restart">ऐप के पुनः आरंभ होने के बाद भाषा बदल जाएगी</string>
<string name="feed_use_dedicated_fetch_method_enable_button">तेज मोड सक्षम करें</string>
<string name="feed_use_dedicated_fetch_method_disable_button">तेज मोड अक्षम करें</string>
<string name="feed_use_dedicated_fetch_method_help_text">क्या आपको लगता है कि फीड लोडिंग बहुत धीमी है\? यदि ऐसा है, तो तेज़ लोडिंग को सक्षम करने का प्रयास करें (आप इसे सेटिंग्स में या नीचे दिए गए बटन को दबाकर बदल सकते हैं)।
\n
\nNewPipe दो फीड लोडिंग रणनीति प्रदान करता है:
\nन्यूपाइप दो फीड लोडिंग रणनीति प्रदान करता है:
\n• संपूर्ण सदस्यता चैनल प्राप्त करना, जो धीमा है लेकिन पूरा होता है।
\n• एक समर्पित सेवा के समापन बिंदु का उपयोग करना, जो तेज़ है लेकिन आमतौर पर पूरा नहीं होता है।
\n
\nदोनों के बीच अंतर यह है कि तेज वाली रणनीति में आमतौर पर कुछ जानकारी का अभाव होता है, जैसे कि आइटम की अवधि या प्रकार (लाइव वीडियो और सामान्य वीडियो के बीच अंतर पता नहीं लगा सकते हैं) और ऐसा भी हो सकता है कि ये कम आइटम दिखाए।
\n
\nYouTube उस सेवा का एक उदाहरण है जो RSS फ़ीड के साथ तेज़ विधि प्रदान करता है।
\nयूट्यूब ऐसी सेवा का एक उदाहरण है जो आरएसएस फ़ीड के साथ ये तेज़ विधि प्रदान करता है।
\n
\nतो आखिर में चुनाव आपकी पसंद पर है: गति या फिर सटीक जानकारी।</string>
<string name="content_not_supported">यह सामग्री फिलहाल NewPipe सपोर्ट नहीं करता है।
<string name="content_not_supported">यह सामग्री फिलहाल न्यूपाइप सपोर्ट नहीं करता है।
\n
\nइसे आशा से भविष्य के संस्करणों में सपोर्ट किया जायेगा।</string>
<string name="detail_sub_channel_thumbnail_view_description">चैनल का अवतार थंमनेल</string>
@ -472,27 +471,27 @@
<string name="auto_queue_toggle">अपने आप कतार में जोड़े</string>
<string name="clear_queue_confirmation_title">कतार को मिटाने से पहले सत्यापन के लिए पूछें</string>
<string name="seek_duration_title">तलाश अवधि फास्ट-फ़ॉरवर्ड /- रिवाइंड करे</string>
<string name="notification_colorize_summary">एंड्रॉइड को थमनेल में मुख्य रंग के अनुसार अधिसूचना रंग को अनुकूलित करें (ध्यान दें कि यह सभी उपकरणों पर उपलब्ध नहीं है)</string>
<string name="notification_colorize_title">सूचनापत्र को रंगीन करें</string>
<string name="notification_colorize_summary">एंड्रॉइड को थम्बनेल में मुख्य रंग के अनुसार अधिसूचना रंग को अनुकूलित करने की अनुमति दे (ध्यान दें कि यह सभी उपकरणों पर उपलब्ध नहीं है)</string>
<string name="notification_colorize_title">अभिसूचना को रंगीन करें</string>
<string name="notification_action_nothing">कुछ नहीं</string>
<string name="notification_action_buffering">बफरिंग</string>
<string name="notification_action_shuffle">Shuffle करे</string>
<string name="notification_action_shuffle">शफल करे</string>
<string name="notification_action_repeat">दोहराएं</string>
<string name="notification_actions_at_most_three">आप संछिप्त सूचनापत्र में दिखाए जाने वाले विकल्प में से अधिकतम 3 को चुन सकते है !</string>
<string name="notification_actions_at_most_three">आप संछिप्त अभिसूचना में दिखाए जाने वाले विकल्प में से अधिकतम 3 को चुन सकते है !</string>
<string name="notification_actions_summary">नीचे दी गई प्रत्येक अधिसूचना क्रिया को उस पर टैप करके संपादित करें। दाईं ओर चेकबॉक्स का उपयोग करके उनमें से अधिकतम तीन का चयन करें जिन्हें कॉम्पैक्ट अधिसूचना में दिखाया जाना है</string>
<string name="notification_action_4_title">पांचवा एक्शन बटन</string>
<string name="notification_action_3_title">चतुर्थी एक्शन बटन</string>
<string name="notification_action_2_title">तृतीय एक्शन बटन</string>
<string name="notification_action_1_title">द्वितीय एक्शन बटन</string>
<string name="notification_action_0_title">प्रथम एक्शन बटन</string>
<string name="notification_scale_to_square_image_summary">नोटिफिकेशन में दिखाए गए वीडियो थमनेल को 16: 9 के बजाय 1: 1 के अनुपात में दिखाए</string>
<string name="notification_scale_to_square_image_title">मनेल को 1:1 के अनुपात में दिखाएं</string>
<string name="notification_scale_to_square_image_summary">नोटिफिकेशन में दिखाए गए वीडियो थम्बनेल को 16:9 के बजाय 1:1 के अनुपात में दिखाए</string>
<string name="notification_scale_to_square_image_title">थम्बनेल को 1:1 के अनुपात में दिखाएं</string>
<plurals name="hours">
<item quantity="one">%d घंटा</item>
<item quantity="other">%d घंटे</item>
</plurals>
<plurals name="seconds">
<item quantity="one">%d सेकेड</item>
<item quantity="one">%d सेके</item>
<item quantity="other">%d सेकंड्स</item>
</plurals>
<string name="remove_watched_popup_title">देखे गए वीडियो हटायें\?</string>
@ -601,7 +600,7 @@
<string name="feed_update_threshold_title">फ़ीड अपडेट चरणसीमा</string>
<string name="feed_load_error">फ़ीड लोड करने में गड़बड़ी</string>
<string name="feed_load_error_account_info">\'%s\' के लिए फ़ीड लोड नहीं कर सका।</string>
<string name="recent">रीसैंट</string>
<string name="recent">हाल ही के</string>
<string name="description_select_enable">विवरण में पाठ का चयन सक्षम करें</string>
<string name="metadata_privacy">गोपनीयता</string>
<string name="description_select_note">अब आप विवरण के अंदर पाठ का चयन कर सकते हैं। ध्यान दें कि पृष्ठ झिलमिला सकता है और चयन मोड में लिंक क्लिक करने योग्य नहीं हो सकते हैं।</string>
@ -610,13 +609,13 @@
<string name="metadata_host">होसट</string>
<string name="notifications_disabled">अधिसूचनाएं अक्षम हैं</string>
<string name="metadata_privacy_unlisted">गैर-सूचीबद्ध</string>
<string name="toggle_all">ंयुक्त टॉगल करें</string>
<string name="get_notified">सूचना पायें</string>
<string name="toggle_all">बको टॉगल करें</string>
<string name="get_notified">अधिसूचना पायें</string>
<string name="enumeration_comma">,</string>
<string name="manual_update_description">नए संस्करणों के लिए मैन्युअल रूप से जांचें</string>
<string name="new_seek_duration_toast">कसोप्लेयर की कमी के कारण खोज की अवधि %d सेकंड पर सेट की गई</string>
<string name="new_seek_duration_toast">ग्ज़ोप्लेयर के कमी के कारण खोज की अवधि %d सेकंड पर सेट की गई</string>
<string name="account_terminated">खाता समाप्त किया गया</string>
<string name="streams_not_yet_supported_removed">स्ट्रीम जो अभी तक डाउनलोडर द्वारा समर्थित नहीं हैं, नहीं दिखाई जाती हैं</string>
<string name="streams_not_yet_supported_removed">जो स्ट्रीम अभी तक डाउनलोडर द्वारा समर्थित नहीं हैं, वो नहीं दिखाई जाती</string>
<string name="select_quality_external_players">बाहरी प्लेयरस के लिए क्वालिटी का चयन करें</string>
<string name="unknown_format">अज्ञात प्रारूप</string>
<string name="unknown_quality">अज्ञात क्वालिटी</string>
@ -642,36 +641,36 @@
</plurals>
<plurals name="days">
<item quantity="one">%d दिन</item>
<item quantity="other">%d दिन</item>
<item quantity="other">%d दिन</item>
</plurals>
<plurals name="feed_group_dialog_selection_count">
<item quantity="one">%d चयनित</item>
<item quantity="other">%d चयनित</item>
<item quantity="other">%d चयनित हुए</item>
</plurals>
<string name="progressive_load_interval_exoplayer_default">क्सोप्लेयर डिफ़ॉल्ट</string>
<string name="progressive_load_interval_exoplayer_default">ग्ज़ोप्लेयर डिफ़ॉल्ट</string>
<string name="progressive_load_interval_title">प्लेबैक लोड अंतराल आकार</string>
<string name="feed_group_dialog_empty_name">समूह का नाम नहीं</string>
<string name="feed_group_dialog_select_subscriptions">सब्सक्रिप्शनस चुनें</string>
<string name="feed_group_dialog_delete_message">क्या आप इस समूह को हटाना चाहते हैं\?</string>
<string name="feed_create_new_group_button_title">नया</string>
<string name="settings_category_feed_title">फ़ीड</string>
<string name="feed_toggle_show_future_items">भविष्य की आइटम दिखाएं</string>
<string name="feed_toggle_show_future_items">भविष्य आइटम दिखाएं</string>
<string name="feed_new_items">नई फ़ीड आइटम</string>
<string name="feed_processing_message">फ़ीड संसाधित हो रही है …</string>
<string name="open_website_license">वेबसाइट खोलें</string>
<string name="feed_use_dedicated_fetch_method_title">उपलब्ध होने पर समर्पित फ़ीड से प्राप्त करें</string>
<string name="metadata_language">भाषा</string>
<string name="on"></string>
<string name="on"></string>
<string name="playlist_no_uploader">स्वतः बने (कोई अपलोडर नहीं मिला)</string>
<string name="feed_groups_header_title">चैनल समूह</string>
<string name="feed_toggle_hide_played_items">देखे गए आइटम छुपाएं</string>
<string name="feed_toggle_hide_future_items">भविष्य की आइटम छुपाएं</string>
<string name="faq_title">बार बार पूछे जाने वाले प्रश्न</string>
<string name="feed_toggle_hide_future_items">भविष्य आइटम छुपाएं</string>
<string name="faq_title">कई बार पूछे प्रश्न</string>
<string name="faq">वेबसाइट पर देखें</string>
<string name="main_page_content_swipe_remove">आइटम हटाने के लिए स्वाइप करें</string>
<string name="disable_media_tunneling_title">मीडिया टनलिंग अक्षम करें</string>
<string name="show_crash_the_player_title">\"क्रैश द प्लेयर\" दिखाएं</string>
<string name="feed_subscription_not_loaded_count">लोड नहीं हुआ: %d</string>
<string name="feed_subscription_not_loaded_count">लोड नहीं हुआ: %d</string>
<string name="service_provides_reason">%s इसका कारण प्रदान करता है:</string>
<string name="metadata_tags">टैग</string>
<string name="metadata_licence">लाइसेंस</string>
@ -693,9 +692,9 @@
\nक्या यक़ीनन आप ऐसा चाह्ते हैं\? इसे असंपादित नहीं किया जा सकेगा!</string>
<plurals name="minutes">
<item quantity="one">%d मिनट</item>
<item quantity="other">%d मिनट</item>
<item quantity="other">%d मिनट्स</item>
</plurals>
<string name="feed_oldest_subscription_update">अंतिम अपडेट फ़ीड: %s</string>
<string name="feed_oldest_subscription_update">फीड अंतिम अपडेट: %s</string>
<string name="feed_group_dialog_empty_selection">कोई सदस्यता चयनित नहीं है</string>
<string name="feed_group_show_only_ungrouped_subscriptions">केवल असमूहीकृत सब्सक्रिप्शनस दिखाएं</string>
<string name="feed_load_error_fast_unknown">फ़ास्ट फ़ीड मोड इस पर अधिक जानकारी प्रदान नहीं करता है।</string>
@ -711,7 +710,7 @@
<string name="detail_pinned_comment_view_description">पिन की हुई टिप्पणी</string>
<string name="detail_heart_img_view_description">निर्माता द्वारा दिया दिल</string>
<string name="tablet_mode_title">टैबलेट मोड</string>
<string name="you_successfully_subscribed">आपने इस चैनल को अ सब्सक्राइब किया है</string>
<string name="you_successfully_subscribed">आपने इस चैनल को अभी सब्सक्राइब किया है</string>
<string name="no_video_streams_available_for_external_players">बाहरी प्लेयरस के लिए कोई वीडियो स्ट्रीम उपलब्ध नहीं है</string>
<string name="no_audio_streams_available_for_external_players">बाहरी प्लेयरस के लिए कोई ऑडियो स्ट्रीम उपलब्ध नहीं है</string>
<string name="feed_use_dedicated_fetch_method_summary">कुछ सेवाओं में उपलब्ध, यह आमतौर पर बहुत तेज होता है लेकिन सीमित मात्रा में आइटम और अक्सर अधूरी जानकारी (जैसे कोई अवधि नहीं, आइटम प्रकार, कोई लाइव स्थिति नहीं) लौटा सकता है</string>
@ -719,7 +718,7 @@
\nकृपया फ़ाइल प्रबंधक स्थापित करें या डाउनलोड सेटिंग में \'%s\' को अक्षम करने का प्रयास करें</string>
<plurals name="deleted_downloads_toast">
<item quantity="one">%1$s डाउनलोड हटाए गए</item>
<item quantity="other">%1$s डाउनलोड हटाए गए</item>
<item quantity="other">%1$s डाउनलोड्स हटाए गए</item>
</plurals>
<string name="sort">क्रमबद्ध करें</string>
<string name="fast_mode">तेज मोड</string>
@ -730,4 +729,16 @@
<string name="unset_playlist_thumbnail">स्थायी थंमनेल अनसेट करें</string>
<string name="card">कार्ड</string>
<string name="msg_failed_to_copy">क्लिपबोर्ड पर कॉपी करने में विफल</string>
<string name="duplicate_in_playlist">धुंधली की गई प्‍लेलिस्‍ट में पहले से ही यह आइटम है।</string>
<string name="playlist_add_stream_success_duplicate">डुप्लीकेट जोड़ा गया %d बार</string>
<string name="remove_duplicates">डुप्लीकेट हटाएं</string>
<string name="remove_duplicates_title">डुप्लीकेट हटाएं\?</string>
<string name="remove_duplicates_message">क्या आप इस प्लेलिस्ट की सभी डुप्लीकेट स्ट्रीम हटाना चाहते हैं\?</string>
<string name="feed_hide_streams_title">निम्नलिखित स्ट्रीम दिखाएँ</string>
<string name="feed_show_upcoming">आगामी</string>
<string name="ignore_hardware_media_buttons_title">हार्डवेयर मीडिया बटन घटनाओं की अनदेखी करें</string>
<string name="ignore_hardware_media_buttons_summary">उपयोगी है, उदाहरण के लिए, यदि आप टूटे हुए भौतिक बटन वाले हेडसेट का उपयोग कर रहे हैं</string>
<string name="feed_show_hide_streams">स्ट्रीम दिखाएँ / छिपाएँ</string>
<string name="feed_show_watched">पूरा देखा</string>
<string name="feed_show_partially_watched">आंशिक रूप से देखा गया</string>
</resources>

View File

@ -36,7 +36,7 @@
<string name="show_higher_resolutions_title">Prikaži veće rezolucije</string>
<string name="show_higher_resolutions_summary">Samo neki uređaji podržavaju reprodukciju 2K/4K videa</string>
<string name="play_with_kodi_title">Reproduciraj s Kodijem</string>
<string name="kore_not_found">Instalirati nedostajući Kore program\?</string>
<string name="kore_not_found">Instalirati nedostajući Kode program\?</string>
<string name="show_play_with_kodi_title">Prikaži opciju „Reproduciraj pomoću Kodija”</string>
<string name="show_play_with_kodi_summary">Prikaži opciju za reproduciranje videozapisa putem Kodija</string>
<string name="play_audio">Audiosnimka</string>
@ -250,7 +250,6 @@
<string name="dismiss">Odbaci</string>
<string name="rename">Preimenuj</string>
<string name="one_item_deleted">1 stavka izbrisana.</string>
<string name="toast_no_player">Nijedan program nije instaliran za reprodukciju ove datoteke</string>
<string name="give_back">Vrati</string>
<string name="website_encouragement">Posjeti NewPipe web-stranicu za više informacija i vijesti.</string>
<string name="privacy_policy_title">NewPipe pravila o privatnosti</string>

View File

@ -16,7 +16,7 @@
<string name="download_path_dialog_title">Válasszon letöltési mappát a videófájloknak</string>
<string name="default_resolution_title">Alapértelmezett felbontás</string>
<string name="play_with_kodi_title">Lejátszás Kodival</string>
<string name="kore_not_found">Telepíti a hiányzó Kore alkalmazást\?</string>
<string name="kore_not_found">Telepíti a hiányzó Kode alkalmazást\?</string>
<string name="show_play_with_kodi_title">A „Lejátszás Kodival” lehetőség megjelenítése</string>
<string name="show_play_with_kodi_summary">A videók Kodi médiaközponttal történő lejátszásának megjelenítése</string>
<string name="play_audio">Hang</string>
@ -200,7 +200,6 @@
<string name="settings_file_replacement_character_title">Csere karakter</string>
<string name="charset_letters_and_digits">Betűk és számok</string>
<string name="charset_most_special_characters">Legtöbb speciális karakter</string>
<string name="toast_no_player">Nincs a fájl lejátszásához szükséges alkalmazás telepítve</string>
<string name="title_activity_about">A NewPipe névjegye</string>
<string name="tab_about">Névjegy és GYIK</string>
<string name="tab_licenses">Licencek</string>

View File

@ -20,7 +20,7 @@
<string name="download_path_audio_dialog_title">Pilih folder unduhan untuk berkas audio</string>
<string name="default_resolution_title">Pilih kualitas</string>
<string name="play_with_kodi_title">Putar dengan Kodi</string>
<string name="kore_not_found">Instal aplikasi Kore yang hilang\?</string>
<string name="kore_not_found">Instal aplikasi Kode yang hilang\?</string>
<string name="show_play_with_kodi_title">Tampilkan opsi \"Putar dengan Kodi\"</string>
<string name="show_play_with_kodi_summary">Tampilkan opsi untuk memutar video via Kodi</string>
<string name="play_audio">Audio</string>
@ -48,7 +48,7 @@
<string name="content_not_available">Konten tidak tersedia</string>
<string name="could_not_setup_download_menu">Tidak bisa menyiapkan menu unduh</string>
<string name="sorry_string">Maaf, hal tersebut seharusnya tidak terjadi.</string>
<string name="error_report_button_text">Laporkan kesalahan via surel</string>
<string name="error_report_button_text">Laporkan via surel</string>
<string name="error_snackbar_message">Maaf, telah terjadi kesalahan.</string>
<string name="error_snackbar_action">Lapor</string>
<string name="what_device_headline">Info:</string>
@ -255,7 +255,6 @@
<string name="search_history_deleted">Riwayat pencarian dihapus</string>
<string name="no_streams_available_download">Tidak ada video yang tersedia untuk diunduh</string>
<string name="one_item_deleted">1 item dihapus.</string>
<string name="toast_no_player">Tidak ada aplikasi terpasang untuk memutar berkas ini</string>
<string name="tab_bookmarks">Daftar Putar</string>
<string name="auto_queue_title">Putar otomatis video berikutnya</string>
<string name="channel_unsubscribed">Berhenti berlanggan channel</string>
@ -719,4 +718,14 @@
<string name="card">Kartu</string>
<string name="duplicate_in_playlist">Daftar putar yang bewarna abu-abu sudah berisi item ini.</string>
<string name="playlist_add_stream_success_duplicate">Duplikat ditambahkan %d kali</string>
<string name="ignore_hardware_media_buttons_summary">Berguna, misalnya, jika Anda menggunakan sebuah headset dengan tombol fisik yang rusak</string>
<string name="ignore_hardware_media_buttons_title">Abaikan peristiwa tombol media perangkat keras</string>
<string name="remove_duplicates">Hapus duplikat</string>
<string name="feed_show_watched">Ditonton secara lengkap</string>
<string name="feed_show_partially_watched">Ditonton sebagian</string>
<string name="feed_show_upcoming">Mendatang</string>
<string name="feed_show_hide_streams">Tampilkan/Sembunyikan saluran</string>
<string name="remove_duplicates_title">Hapus duplikat\?</string>
<string name="remove_duplicates_message">Apakah Anda ingin menghapus semua saluran duplikat di daftar putar ini\?</string>
<string name="feed_hide_streams_title">Tampilkan saluran berikut</string>
</resources>

View File

@ -253,7 +253,6 @@
<string name="recaptcha_solve">Leysa</string>
<string name="recaptcha_done_button">Lokið</string>
<string name="recaptcha_request_toast">Beðið eftir þraut reCAPTCHA</string>
<string name="toast_no_player">Ekkert forrit er uppsett til að spila þessa skrá</string>
<string name="title_licenses">Leyfi þriðja aðila</string>
<string name="tab_licenses">Hugbúnaðarleyfi</string>
<string name="copyright">© %1$s • %2$s • %3$s</string>

View File

@ -52,7 +52,7 @@
<string name="main_bg_subtitle">Tocca la lente d\'ingrandimento per iniziare.</string>
<string name="duration_live">In diretta</string>
<string name="sorry_string">Spiacenti, non sarebbe dovuto succedere.</string>
<string name="error_report_button_text">Segnala l\'errore via e-mail</string>
<string name="error_report_button_text">Segnala via e-mail</string>
<string name="error_snackbar_message">Spiacente, qualcosa è andato storto.</string>
<string name="error_snackbar_action">Segnala</string>
<string name="what_device_headline">Info:</string>
@ -302,7 +302,6 @@
<string name="preferred_open_action_settings_summary">Azione predefinita all\'apertura del contenuto — %s</string>
<string name="caption_setting_title">Sottotitoli</string>
<string name="caption_setting_description">Modifica dimensione e stile dei sottotitoli. Riavviare per applicare le modifiche</string>
<string name="toast_no_player">Nessuna app installata per riprodurre questo file</string>
<string name="clear_views_history_title">Elimina la cronologia delle visualizzazioni</string>
<string name="clear_views_history_summary">Elimina la cronologia degli elementi riprodotti e le posizioni di riproduzione</string>
<string name="delete_view_history_alert">Eliminare la cronologia delle visualizzazioni\?</string>
@ -745,4 +744,14 @@
<string name="unset_playlist_thumbnail">Disattiva copertina permanente</string>
<string name="duplicate_in_playlist">Le playlist in grigio contengono già questo elemento.</string>
<string name="playlist_add_stream_success_duplicate">Doppione aggiunto %d volta/e</string>
<string name="ignore_hardware_media_buttons_title">Ignora eventi dei pulsanti multimediali hardware</string>
<string name="ignore_hardware_media_buttons_summary">Utile usando cuffie con tasti fisici rotti</string>
<string name="remove_duplicates">Rimuovi elementi doppi</string>
<string name="remove_duplicates_title">Rimuovere gli elementi doppi\?</string>
<string name="remove_duplicates_message">Rimuovere tutti gli elementi doppi di questa playlist\?</string>
<string name="feed_hide_streams_title">Mostra gli elementi seguenti</string>
<string name="feed_show_hide_streams">Mostra/Nascondi elementi</string>
<string name="feed_show_partially_watched">Visto parzialmente</string>
<string name="feed_show_watched">Visto completamente</string>
<string name="feed_show_upcoming">Prossimamente</string>
</resources>

View File

@ -16,7 +16,7 @@
<string name="download_path_dialog_title">動画ファイルをダウンロードするフォルダーを選択して下さい</string>
<string name="default_resolution_title">デフォルトの画質</string>
<string name="play_with_kodi_title">Kodi で再生</string>
<string name="kore_not_found">Kore をインストールしますか?</string>
<string name="kore_not_found">Kode をインストールしますか?</string>
<string name="show_play_with_kodi_title">「Kodi で再生」オプションを表示</string>
<string name="show_play_with_kodi_summary">Kodi メディアセンター経由で動画を再生するための設定を表示します</string>
<string name="play_audio">音声</string>
@ -50,7 +50,7 @@
<string name="content">コンテンツ</string>
<string name="show_age_restricted_content_title">年齢制限のあるコンテンツを表示</string>
<string name="sorry_string">申し訳ありません。想定外のエラーが発生しました。</string>
<string name="error_report_button_text">不具合をメールで報告</string>
<string name="error_report_button_text">メールで送る</string>
<string name="error_snackbar_message">申し訳ありません、不具合が発生しました。</string>
<string name="error_snackbar_action">報告</string>
<string name="what_device_headline">情報:</string>
@ -245,7 +245,6 @@
<string name="clear_search_history_title">検索履歴を消去</string>
<string name="clear_search_history_summary">検索キーワードの履歴を削除します</string>
<string name="search_history_deleted">検索履歴を削除しました</string>
<string name="toast_no_player">このファイルを再生するためのアプリがインストールされていません</string>
<string name="import_settings">設定もインポートしますか?</string>
<string name="caption_setting_title">字幕</string>
<string name="channels">チャンネル</string>
@ -713,9 +712,20 @@
<string name="faq_description">アプリの使い方に困ったときは、よくある質問に答えていますので、ぜひご覧ください!</string>
<string name="night_theme_available">%sがテーマに選択された場合のみ、この選択肢が利用可能です</string>
<string name="fast_mode">高速モード</string>
<string name="import_subscriptions_hint">3 点メニューから登録チャンネルをインポートまたはエクスポートします</string>
<string name="import_subscriptions_hint">3点メニューから登録チャンネルの読み込みまたは書き出しが可能</string>
<string name="card">カード</string>
<string name="msg_failed_to_copy">クリップボードへのコピーに失敗しました</string>
<string name="duplicate_in_playlist">灰色で表示されているプレイリストには、すでにこのアイテムが含まれています。</string>
<string name="playlist_add_stream_success_duplicate">%d 回重複追加されました</string>
<string name="unset_playlist_thumbnail">固定サムネイルの設定を解除</string>
<string name="remove_duplicates_title">重複を削除しますか\?</string>
<string name="ignore_hardware_media_buttons_summary">たとえば、物理ボタンが壊れたヘッドセットを使用している場合に便利です</string>
<string name="remove_duplicates_message">この再生リスト内の重複したストリームをすべて削除しますか\?</string>
<string name="ignore_hardware_media_buttons_title">ハードウェア メディア ボタン イベントを無視する</string>
<string name="remove_duplicates">重複を削除</string>
<string name="feed_hide_streams_title">次のストリームを表示</string>
<string name="feed_show_hide_streams">ストリームの表示/非表示</string>
<string name="feed_show_watched">完全に視聴済み</string>
<string name="feed_show_partially_watched">一部視聴済み</string>
<string name="feed_show_upcoming">今後</string>
</resources>

View File

@ -89,7 +89,7 @@
<string name="download_path_summary">გადმოწერილი ვიდეო ფაილები ინახება აქ</string>
<string name="download_path_audio_title">აუდიოს ჩამოტვირთვის საქაღალდე</string>
<string name="show_higher_resolutions_title">უფრო მაღალი რეზოლუციის ჩვენება</string>
<string name="kore_not_found">დააინსტალიროთ დაკარგული Kore აპი\?</string>
<string name="kore_not_found">დააინსტალიროთ დაკარგული Kode აპი\?</string>
<string name="show_play_with_kodi_title">აჩვენეთ \"დაუკარი კოდით\" ვარიანტი</string>
<string name="show_play_with_kodi_summary">აჩვენეთ ვიდეოს დაკვრის ვარიანტი Kodi მედია ცენტრის საშუალებით</string>
<string name="notification_scale_to_square_image_summary">შეტყობინებაში ნაჩვენები ვიდეოს ესკიზის ამოჭრა 16:9-დან 1:1-მდე ასპექტის თანაფარდობით</string>
@ -633,7 +633,6 @@
<string name="settings_file_charset_title">დაშვებული სიმბოლოები ფაილის სახელებში</string>
<string name="settings_file_replacement_character_summary">არასწორი სიმბოლოები ჩანაცვლებულია ამ მნიშვნელობით</string>
<string name="tab_about">შესახებ &amp; ხშირად დასმული კითხვები</string>
<string name="toast_no_player">ამ ფაილის დასაკრავად აპი არ არის დაინსტალირებული</string>
<string name="title_licenses">მესამე მხარის ლიცენზიები</string>
<string name="copyright">© %1$s მიერ %2$s %3$s-ის ქვეშ</string>
<string name="donation_encouragement">NewPipe შემუშავებულია მოხალისეების მიერ, რომლებიც ატარებენ თავისუფალ დროს და მოგაქვთ საუკეთესო მომხმარებლის გამოცდილება. დაეხმარეთ დეველოპერებს, გააუმჯობესონ NewPipe, სანამ ფინჯანი ყავით ტკბებიან.</string>

View File

@ -538,7 +538,6 @@
<string name="contribution_title">Paraxwe dayin</string>
<string name="app_description">Li Android-ê veguhastina ronahiya sivik.</string>
<string name="title_activity_about">Derbarê NewPipe</string>
<string name="toast_no_player">Ji bo lîstina vê pelê tu bername nehat saz kirin</string>
<string name="charset_most_special_characters">Pir karakterên taybetî</string>
<string name="charset_letters_and_digits">Name û reqem</string>
<string name="settings_file_replacement_character_title">Karaktera guheztinê</string>

View File

@ -16,7 +16,7 @@
<string name="download_path_dialog_title">비디오 파일이 다운로드 될 폴더를 선택하세요</string>
<string name="default_resolution_title">기본 해상도</string>
<string name="play_with_kodi_title">Kodi로 재생</string>
<string name="kore_not_found">Kore 앱이 발견되지 않았습니다. Kore를 설치할까요\?</string>
<string name="kore_not_found">누락된 한국어 앱을 설치하시겠습니까\?</string>
<string name="show_play_with_kodi_title">\"Kodi로 재생\" 옵션 표시</string>
<string name="show_play_with_kodi_summary">비디오를 Kodi 미디어 센터를 사용해 재생하는 옵션을 표시합니다</string>
<string name="play_audio">오디오</string>
@ -36,8 +36,8 @@
<string name="download_path_audio_summary">다운로드된 오디오 파일이 이 곳에 저장됩니다</string>
<string name="download_path_audio_dialog_title">오디오 파일이 다운로드 될 폴더를 선택하세요</string>
<string name="theme_title">테마</string>
<string name="dark_theme_title">어두운 테마</string>
<string name="light_theme_title">밝은 테마</string>
<string name="dark_theme_title">다크 테마</string>
<string name="light_theme_title">라이트 테마</string>
<string name="settings_category_appearance_title">외관</string>
<string name="background_player_playing_toast">백그라운드에서 재생 중</string>
<string name="network_error">네트워크 오류</string>
@ -52,7 +52,7 @@
<string name="content_not_available">컨텐츠를 사용할 수 없습니다</string>
<string name="could_not_setup_download_menu">다운로드 메뉴를 설정할 수 없습니다</string>
<string name="sorry_string">죄송합니다. 오류가 발생했습니다.</string>
<string name="error_report_button_text">이메일을 통해 이 오류 보고</string>
<string name="error_report_button_text">이메일을 통해 보고</string>
<string name="error_snackbar_message">죄송합니다. 문제가 발생했습니다.</string>
<string name="error_snackbar_action">보고</string>
<string name="what_device_headline">정보:</string>
@ -83,7 +83,7 @@
<string name="show_higher_resolutions_title">높은 해상도 표시</string>
<string name="show_higher_resolutions_summary">일부 기기에서만 2K/4K 해상도 재생이 지원됩니다</string>
<string name="default_video_format_title">기본 비디오 형식</string>
<string name="black_theme_title">검은 테마</string>
<string name="black_theme_title">블랙 테마</string>
<string name="popup_remember_size_pos_title">팝업 크기 및 위치 기억</string>
<string name="popup_remember_size_pos_summary">마지막으로 사용한 팝업 위치 및 크기를 기억합니다</string>
<string name="show_search_suggestions_title">검색 제안</string>
@ -131,7 +131,7 @@
<string name="no_videos">비디오 없음</string>
<string name="ok">OK</string>
<string name="msg_name">파일명</string>
<string name="msg_threads">레드</string>
<string name="msg_threads">레드</string>
<string name="msg_error">오류</string>
<string name="msg_running">NewPipe 다운로드 중</string>
<string name="msg_running_detail">터치해서 상세 정보 확인</string>
@ -150,7 +150,7 @@
<string name="title_activity_about">NewPipe에 대해서</string>
<string name="title_licenses">제3자 라이센스</string>
<string name="copyright" formatted="true">© %3$s 하에서 %2$s 에 의한 %1$s</string>
<string name="tab_about">정보 및 자주 묻는 질문</string>
<string name="tab_about">정보 및 자주 묻는 질문</string>
<string name="tab_licenses">라이센스</string>
<string name="app_description">가볍고 빠른 자유 안드로이드 스트리밍 앱입니다.</string>
<string name="contribution_title">기여</string>
@ -181,14 +181,14 @@
<string name="play_queue_audio_settings">오디오 설정</string>
<string name="hold_to_append">눌러서 대기열에 추가</string>
<string name="start_here_on_background">백그라운드에서 재생</string>
<string name="start_here_on_popup">팝업에서 재생 시작</string>
<string name="start_here_on_popup">팝업으로 재생</string>
<string name="no_player_found_toast">스트림 플레이어를 찾을 수 없습니다 (VLC를 설치하여 동영상을 재생할 수 있습니다).</string>
<string name="controls_download_desc">스트림 파일 다운로드하기</string>
<string name="show_info">정보 보기</string>
<string name="tab_bookmarks">재생목록 북마크</string>
<string name="controls_add_to_playlist_title">이곳에 추가</string>
<string name="use_inexact_seek_title">정확하지는 않지만 빠른 탐색</string>
<string name="use_inexact_seek_summary">정확하지 않은 탐색은 더 빠르게 위치를 탐색할 수 있지만 정확도는 떨어집니다. 5, 15 또는 25초 탐색기능은 같이 동작하지 않음</string>
<string name="use_inexact_seek_title">정확하지 않은 빠른 탐색 사용</string>
<string name="use_inexact_seek_summary">정확하지 않은 탐색을 사용하면 정확도가 떨어지는 대신 더 빠르게 위치를 탐색할 수 있습니다. 5초, 15초 또는 25초 탐색 기능은 이 기능과 같이 동작하지 않습니다</string>
<string name="auto_queue_title">다음 스트림을 자동 대기열에 추가</string>
<string name="auto_queue_summary">이전 스트림이 반복 재생 대기열이 아닐 경우, 관련 스트림을 자동 재생</string>
<string name="default_content_country_title">기본 콘텐츠 국가</string>
@ -259,15 +259,15 @@
<string name="previous_export">이전 내보내기</string>
<string name="subscriptions_import_unsuccessful">구독 목록 가져오기 실패</string>
<string name="subscriptions_export_unsuccessful">구독 목록 내보내기 실패</string>
<string name="import_youtube_instructions">구글 테이크아웃에서 유튜브 구독 가져오기:
<string name="import_youtube_instructions">Google 테이크아웃에서 YouTube 구독 가져오기:
\n
\n1. 다음 URL로 이동: %1$s
\n2. 요청 시 로그인
\n3. \"모든 데이터 포함\"을 클릭한 다음 \"모두 선택 취소\"를 클릭한 후 \"구독\"만 선택하고 \"확인\" 클릭
\n4. \"다음 단계\"를 클릭한 다음 \"내보내기 만들기\" 클릭
\n5. \"다운로드\" 버튼이 나타나면 클릭
\n6. 아래 파일 가져오기를 클릭하고 다운로드한 .zip 파일 선택
\n7. [.zip 가져오기가 실패한 경우] .csv 파일(일반적으로 \"YouTube 및 YouTube Music/subscriptions/subscriptions.csv\" 아래에 있음)의 압축을 풀고, 아래 파일 가져오기를 클릭하고 압축을 푼 csv 파일 선택</string>
\n1. 이 URL로 이동합니다: %1$s
\n2. 요청에 따라 로그인을 합니다
\n3. \"모든 데이터 포함됨\"을 클릭한 다음 \"모두 선택 해제\"를 클릭한 후 \"구독정보\"만 선택하고 \"확인\"을 클릭합니다
\n4. \"다음 단계\"를 클릭한 다음 \"내보내기 생성\"을 클릭합니다
\n5. \"다운로드\" 버튼이 나타나면 클릭합니다
\n6. 아래 \"파일 가져오기\"를 클릭하고 다운로드한 .zip 파일 선택합니다
\n7. [.zip 파일 가져오기를 실패한 경우] .csv 파일(일반적으로 \"YouTube 및 YouTube Music/구독정보/구독정보.csv\")을 추출하고, 아래의 \"파일 가져오기\"를 클릭한 후 추출한 csv 파일을 선택합니다</string>
<string name="import_soundcloud_instructions">URL 또는 ID를 입력하여 SoundCloud 프로필을 가져옵니다:
\n
\n1. 웹 브라우저에서 \"데스크톱 모드\"를 활성화합니다(모바일 장치에서는 사이트를 사용할 수 없습니다)
@ -289,7 +289,6 @@
<string name="playback_pitch">피치</string>
<string name="unhook_checkbox">영상과 소리 분리 (왜곡이 발생할 수 있음)</string>
<string name="no_streams_available_download">다운로드 가능한 스트림이 없습니다</string>
<string name="toast_no_player">이 파일을 재생할 수 있는 플레이어 앱이 없습니다</string>
<string name="preferred_open_action_settings_title">선호하는 열기 동작</string>
<string name="preferred_open_action_settings_summary">컨텐츠를 열 때 사용할 기본 동작 — %s</string>
<string name="caption_setting_title">자막</string>
@ -320,9 +319,9 @@
<string name="unsubscribe">구독 취소</string>
<string name="tab_choose">탭 선택</string>
<string name="volume_gesture_control_title">제스처 음량 조작</string>
<string name="volume_gesture_control_summary">제스처를 사용하여 재생기 볼륨 제어하기</string>
<string name="volume_gesture_control_summary">제스처를 사용하여 플레이어의 볼륨 제어</string>
<string name="brightness_gesture_control_title">제스처 밝기 조작</string>
<string name="brightness_gesture_control_summary">제스처를 사용하여 플레이어 밝기 제어</string>
<string name="brightness_gesture_control_summary">제스처를 사용하여 플레이어 밝기 제어</string>
<string name="settings_category_updates_title">업데이트</string>
<string name="tracks">트랙</string>
<string name="users">사용자</string>
@ -387,7 +386,7 @@
<string name="no_comments">댓글 없음</string>
<string name="error_unable_to_load_comments">댓글을 불러올 수 없음</string>
<string name="close">닫기</string>
<string name="enable_playback_resume_title">재생 재개</string>
<string name="enable_playback_resume_title">재생 위치 기억</string>
<string name="enable_playback_resume_summary">마지막 재생 위치부터 재생</string>
<string name="enable_playback_state_lists_title">리스트 내 위치 표시</string>
<string name="enable_playback_state_lists_summary">리스트에서 재생 위치를 표시합니다</string>
@ -481,16 +480,16 @@
<string name="show_thumbnail_title">썸네일 보기</string>
<string name="feed_group_dialog_empty_name">그룹 이름이 없음</string>
<plurals name="days">
<item quantity="other">%d </item>
<item quantity="other">%d일</item>
</plurals>
<plurals name="hours">
<item quantity="other">%d 시간</item>
<item quantity="other">%d시간</item>
</plurals>
<plurals name="minutes">
<item quantity="other">%d </item>
<item quantity="other">%d분</item>
</plurals>
<plurals name="seconds">
<item quantity="other">%d </item>
<item quantity="other">%d초</item>
</plurals>
<string name="remove_watched_popup_title">시청 기록을 지우겠습니까\?</string>
<string name="remove_watched">시청 기록 지우기</string>
@ -511,7 +510,7 @@
<string name="mark_as_watched">시청한 것으로 처리</string>
<string name="show_description_summary">비활성화하면 비디오 설명과 추가 정보를 표시하지 않습니다</string>
<string name="show_description_title">설명 표시하기</string>
<string name="clear_queue_confirmation_summary">한 플레이어에서 다른 플레이어로 전환하면 대기열이 대체될 수 있</string>
<string name="clear_queue_confirmation_summary">한 플레이어에서 다른 플레이어로 전환하면 대기열이 대체될 수 있습니다</string>
<string name="night_theme_title">어두운 테마</string>
<string name="notification_actions_at_most_three">최대 3개까지 축소 알림에 표시될 항목을 고를 수 있습니다!</string>
<string name="notification_actions_summary">아래의 각 알림 작업을 눌러 편집하세요. 오른쪽에 있는 확인란을 사용하여 압축 알림에 표시할 항목을 최대 3개까지 선택</string>
@ -523,7 +522,7 @@
<string name="recaptcha_cookies_cleared">reCAPTCHA 쿠키를 비웠습니다</string>
<string name="settings_category_player_notification_title">플레이어 알림</string>
<string name="notifications">알림</string>
<string name="youtube_restricted_mode_enabled_summary">유튜브는 잔인할 수 있는 컨텐츠를 숨겨주는 \"제한 모드\"를 제공합니다</string>
<string name="youtube_restricted_mode_enabled_summary">YouTube는 잠재적으로 성인용 콘텐츠를 숨기는 \'제한 모드\'를 제공합니다</string>
<string name="clear_cookie_title">reCAPTCHA 쿠키 비우기</string>
<string name="crash_the_player">플레이어 크래시 발생</string>
<string name="notification_action_nothing">존재하지 않음</string>
@ -533,7 +532,7 @@
<string name="enqueued_next">다음에 대기열에 추가됨</string>
<string name="enqueue_next_stream">다음 대기열에 넣기</string>
<string name="settings_category_player_notification_summary">현재 재생 중인 스트림 알림 구성</string>
<string name="show_age_restricted_content_summary">연령 제한(예: 18세 이상)이 있으므로 어린이에게 적합하지 않을 수 있는 콘텐츠 표시</string>
<string name="show_age_restricted_content_summary">연령 제한(예: 18세 이상)이 있 어린이에게 적합하지 않을 수 있는 콘텐츠 표시</string>
<string name="error_report_channel_description">오류 보고 알림</string>
<string name="error_report_notification_title">NewPipe에 오류가 발생했습니다. 보고하려면 탭하세요</string>
<string name="error_report_notification_toast">오류가 발생했습니다. 알림을 참조하세요</string>
@ -562,17 +561,17 @@
<string name="show_error_snackbar">오류 스낵바 표시</string>
<string name="enable_streams_notifications_title">새로운 스트림 알림</string>
<string name="enable_streams_notifications_summary">구독에서 새로운 스트림에 대해 알림</string>
<string name="streams_notifications_interval_title">주파수 확인</string>
<string name="streams_notifications_interval_title">확인 빈도</string>
<string name="streams_notifications_network_title">필요한 네트워크 연결</string>
<string name="any_network">모든 네트워크</string>
<string name="manual_update_title">업데이트 확인</string>
<string name="manual_update_description">새로운 버전을 수동으로 확인</string>
<string name="autoplay_summary">자동으로 재생 시작 — %s</string>
<string name="wifi_only">Wi-Fi에서만</string>
<string name="never">절대</string>
<string name="never">사용하지 않음</string>
<string name="seekbar_preview_thumbnail_title">탐색막대 썸네일 미리보기</string>
<string name="high_quality_larger">고품질 (크게)</string>
<string name="low_quality_smaller">저품질 (작)</string>
<string name="low_quality_smaller">저품질 (작)</string>
<string name="dont_show">표시하지 않음</string>
<string name="checking_updates_toast">업데이트 확인 중…</string>
<string name="delete_downloaded_files_confirm">디스크에서 다운로드한 모든 파일을 지우겠습니까\?</string>
@ -589,10 +588,10 @@
<string name="local_search_suggestions">지역 검색 제안</string>
<string name="remote_search_suggestions">원격 검색 제안</string>
<string name="restricted_video_no_stream">이 동영상은 연령 제한이 있습니다.
\n연령 제한 동영상에 대한 새로운 유튜브 정책으로 인해 NewPipe는 동영상 스트림에 접속할 수 없으므로 재생할 수 없습니다.</string>
\n연령 제한 동영상에 대한 새로운 YouTube 정책으로 인해 NewPipe는 동영상 스트림에 접속할 수 없으므로 재생할 수 없습니다.</string>
<string name="clear_cookie_summary">reCAPTCHA를 해결할 때 NewPipe가 저장하는 쿠키 지우기</string>
<string name="description_tab_description">설명</string>
<string name="comments_tab_description">코멘트</string>
<string name="comments_tab_description">댓글</string>
<string name="recaptcha_solve">해결</string>
<string name="show_thumbnail_summary">잠금 화면 배경과 알림 모두에 썸네일 사용</string>
<string name="feed_group_dialog_empty_selection">선택한 구독이 없습니다</string>
@ -605,8 +604,8 @@
<string name="remove_watched_popup_yes_and_partially_watched_videos">예, 부분적으로 본 비디오</string>
<string name="metadata_category">카테고리</string>
<string name="video_detail_by">%s에 의해</string>
<string name="select_night_theme_toast">아래에서 좋아하는 밤 테마를 선택할 수 있습니다</string>
<string name="youtube_music_premium_content">이 영상은 유튜브 뮤직 프리미엄 회원만 볼 수 있어 뉴파이프에서 스트리밍이나 다운로드가 불가능합니다.</string>
<string name="select_night_theme_toast">아래에서 선호하는 어두운 테마를 선택할 수 있습니다</string>
<string name="youtube_music_premium_content">이 영상은 YouTube Music Premium 회원만 볼 수 있기 때문에 NewPipe에서 스트리밍이나 다운로드가 불가능합니다.</string>
<string name="private_content">이 콘텐츠는 비공개이므로 NewPipe에서 스트리밍하거나 다운로드할 수 없습니다.</string>
<string name="metadata_privacy_internal">내부</string>
<string name="processing_may_take_a_moment">처리 중... 시간이 걸릴 수 있습니다</string>
@ -656,7 +655,7 @@
<string name="feed_use_dedicated_fetch_method_enable_button">빠른 모드 활성화</string>
<string name="channel_created_by">%s에 의해 제작</string>
<string name="detail_sub_channel_thumbnail_view_description">채널의 아바타 썸네일</string>
<string name="chapters"></string>
<string name="chapters">챕터</string>
<string name="recent">최근</string>
<string name="account_terminated">계정이 해지됨</string>
<string name="service_provides_reason">%s은(는) 다음과 같은 이유를 제공:</string>
@ -677,29 +676,29 @@
<string name="downloads_storage_use_saf_summary_api_29">안드로이드 10부터 \'저장영역 접속 프레임워크\'만 지원됩니다</string>
<string name="remove_watched_popup_warning">재생 목록에 추가되기 전과 후에 시청한 동영상은 제거됩니다.
\n확실합니까\? 이것은 취소 할 수 없습니다!</string>
<string name="start_main_player_fullscreen_summary">미니 플레이어에서 동영상을 시작하지 말고 자동 회전이 잠겨 있는 경우 전체 화면 모드로 직접 전환하십시오. 전체 화면을 종료하여 미니 플레이어에 계속 접속할 수 있습니다</string>
<string name="start_main_player_fullscreen_summary">화면 자동 회전이 잠겨 있는 경우 미니 플레이어에서 동영상을 시작하지 말고 바로 전체 화면 모드로 재생하세요. 전체 화면을 종료해서 미니 플레이어를 이용할 수도 있습니다</string>
<string name="metadata_privacy_public">공식</string>
<string name="radio">라디오</string>
<string name="description_select_enable">설명에서 텍스트 선택 활성화</string>
<string name="georestricted_content">이 콘텐츠는 귀하의 국가에서 사용할 수 없습니다.</string>
<string name="night_theme_summary">좋아하는 밤 테마 선택 — %s</string>
<string name="night_theme_summary">선호하는 어두운 테마 선택 — %s</string>
<string name="download_has_started">다운로드가 시작되었습니다</string>
<string name="description_select_note">이제 설명 내에서 텍스트를 선택할 수 있습니다. 선택 모드에서는 페이지가 깜박이고 링크를 클릭할 수 없는 경우가 있습니다.</string>
<string name="no_appropriate_file_manager_message_android_10">이 작업에 적합한 파일 관리자를 찾을 수 없습니다.
\n저장영역 접속 프레임워크 호환 파일 관리자를 설치하십시오</string>
<string name="no_appropriate_file_manager_message">이 작업에 적합한 파일 관리자를 찾을 수 없습니다.
\n파일 관리자를 설치하거나 다운로드 설정에서 \'%s\'을(를) 비활성화하십시오</string>
<string name="feed_use_dedicated_fetch_method_help_text">피드 로딩이 너무 느리다고 생각하십니까\? 그렇다면 빠른 로딩을 활성화해 보십시오 (설정에서 변경하거나 아래 버튼을 눌러 변경할 수 있습니다).
<string name="feed_use_dedicated_fetch_method_help_text">피드 로딩이 너무 느리다고 생각하시나요\? 그렇다면 빠른 로딩을 활성화해 보세요. (설정에서 변경하거나 아래 버튼을 눌러 변경할 수 있습니다)
\n
\nNewPipe는 두 가지 피드 로딩 전략을 제공합니다:
\n• 느리지만 완전한 전체 구독 채널을 가져옵니다.
\n• 빠르지만 일반적으로 완전하지는 않은 전용 서비스 엔드포인트를 사용합니다.
\n• 전체 구독 채널 가져오기: 느리지만 완전합니다.
\n• 전용 서비스 엔드포인트 사용: 빠르지만 일반적으로 완전하지 않습니다.
\n
\n둘의 차이점은 빠른 동영상은 일반적으로 항목의 길이나 유형(라이브 동영상과 일반 동영상을 구분할 수 없음)과 같은 일부 정보가 부족하고 더 적은 항목을 반환할 수 있다는 입니다.
\n이 두 가지의 차이점은 빠른 방식이 일반적으로 항목의 길이나 유형(실시간 동영상과 일반 동영상을 구분할 수 없음)과 같은 일부 정보가 부족하고 더 적은 항목을 반환할 수 있다는 입니다.
\n
\n유튜브는 RSS 피드로 이 빠른 방법을 제공하는 서비스의 한 예입니다.
\nYouTube는 RSS 피드를 통해 이 빠른 방법을 제공하는 서비스의 예입니다.
\n
\n따라서 선택은 속도 또는 정확한 정보 중에서 선호하는 것으로 귀결됩니다.</string>
\n따라서 선택은 속도와 정확한 정보 중 무엇을 선호하느냐에 달려 있습니다.</string>
<string name="content_not_supported">이 기능은 아직 NewPipe에서 지원하지 않습니다.
\n
\n이후 버전에서 지원될 예정입니다.</string>
@ -711,12 +710,22 @@
<string name="sort">정렬</string>
<string name="fast_mode">빠른 모드</string>
<string name="import_subscriptions_hint">점 3개 메뉴에서 구독 가져오기 또는 내보내기</string>
<string name="app_update_unavailable_toast">최신 버전의 NewPipe를 실행 중입니다.</string>
<string name="app_update_unavailable_toast">최신 버전의 NewPipe를 실행 중입니다</string>
<string name="app_update_available_notification_text">%s를 다운로드하려면 탭하세요.</string>
<string name="unset_playlist_thumbnail">영구 썸네일 설정 해제</string>
<string name="night_theme_available">이 옵션은 테마로 %s를 선택한 경우에만 사용할 수 있음</string>
<string name="night_theme_available">이 옵션은 테마로 %s을 선택한 경우에만 사용할 수 있습니다</string>
<string name="playlist_add_stream_success_duplicate">중복 추가 %d 번</string>
<string name="duplicate_in_playlist">회색으로 표시된 재생 목록에 이미 이 항목이 포함되어 있습니다.</string>
<string name="card">카드</string>
<string name="msg_failed_to_copy">클립보드 복사 실패</string>
<string name="remove_duplicates">복제 삭제</string>
<string name="remove_duplicates_title">복제를 삭제하시겠습니까\?</string>
<string name="remove_duplicates_message">이 재생목록의 모든 스트림 복사본을 삭제하겠습니까\?</string>
<string name="feed_hide_streams_title">다음 스트림 표시</string>
<string name="feed_show_partially_watched">부분적 시청</string>
<string name="feed_show_watched">완전 시청</string>
<string name="feed_show_upcoming">예정</string>
<string name="ignore_hardware_media_buttons_title">하드웨어 미디어 버튼 이벤트 무시</string>
<string name="ignore_hardware_media_buttons_summary">예를 들어, 물리적 버튼이 망가진 헤드셋을 사용하는 경우 유용합니다</string>
<string name="feed_show_hide_streams">스트림 보이기/숨기기</string>
</resources>

View File

@ -256,7 +256,6 @@
<string name="no_streams_available_download">هیچ پەخشێک نییە بۆ دابەزاندن</string>
<string name="caption_setting_title">ژێرنووسەکان</string>
<string name="caption_setting_description">بەهۆی گۆڕانکاری لە شێوەی ژێرنووسکردنەکە. پێویستە ئەپەکە دابخەیت و دیسانەوە بیکەیتەوە.</string>
<string name="toast_no_player">هیچ ئەپێک دانەمەزراوە بۆ کارپێکردنی ئەم فایلە</string>
<string name="clear_views_history_title">سڕینەوەی مێژووی تەماشاکردن</string>
<string name="clear_views_history_summary">مێژوو دەسڕێتەوە لەگەڵ ڤیدیۆ کارپێکراوەکان و شوێنی لیستە ڤیدیۆییەکان</string>
<string name="delete_view_history_alert">تەواوی مێژووی تەماشاکردن بسڕدرێتەوە؟</string>

View File

@ -29,7 +29,7 @@
<string name="show_higher_resolutions_title">Rodyti didesnes raiškas</string>
<string name="show_higher_resolutions_summary">Tik kai kurie įrenginiai palaiko 2K/4K vaizdo įrašų peržiūrą</string>
<string name="play_with_kodi_title">Groti su Kodi</string>
<string name="kore_not_found">Įdiegti nereastą Kore programėlę\?</string>
<string name="kore_not_found">Įdiegti nereastą Kode programėlę\?</string>
<string name="show_play_with_kodi_title">Rodyti „Peržiūra su Kodi“ pasirinkimą</string>
<string name="show_play_with_kodi_summary">Rodyti pasirinkimą peržiūrėti vaizdo įrašus per Kodi mediacentrą</string>
<string name="play_audio">Garso įrašas</string>
@ -512,7 +512,6 @@
<string name="privacy_policy_encouragement">NewPipe į jūsų privatumą žiūri labai rimtai. Programa be jūsų sutikimo nerenka jokių duomenų.
\nNewPipe privatumo politika išsamiai parodo kokie duomenys siunčiami ir saugomi pranešant apie problemą.</string>
<string name="privacy_policy_title">NewPipe privatumo politika</string>
<string name="toast_no_player">Šio failo atkūrimui nėra įdiegtos programos</string>
<string name="recaptcha_done_button">Atlikta</string>
<string name="recaptcha_solve">Išspręsta</string>
<string name="subtitle_activity_recaptcha">Paspauskite \"atlikta\" kai išspręsta</string>

View File

@ -71,7 +71,6 @@
<string name="tab_about">Par</string>
<string name="title_licenses">Trešo pušu Licences</string>
<string name="title_activity_about">Par NewPipe</string>
<string name="toast_no_player">Nav instalētu aplikāciju, lai atskaņotu šo failu</string>
<string name="charset_most_special_characters">Lielākā daļa īpašo rakstzīmju</string>
<string name="charset_letters_and_digits">Burti un cipari</string>
<string name="settings_file_replacement_character_title">Aizvietošanas rakstzīme</string>
@ -563,7 +562,7 @@
<string name="notification_scale_to_square_image_title">Piemērot video attēlu 1:1 proporcijai</string>
<string name="show_play_with_kodi_summary">Rādīt opciju atskaņot video ar Kodi mediju centru</string>
<string name="show_play_with_kodi_title">Rādīt \"Atskaņot ar Kodi\" opciju</string>
<string name="kore_not_found">Instalēt trūkstošo Kore aplikāciju\?</string>
<string name="kore_not_found">Instalēt trūkstošo Kode aplikāciju\?</string>
<string name="play_with_kodi_title">Atskaņot ar Kodi</string>
<string name="show_higher_resolutions_summary">Tikai dažas ierīcas var atskaņot 2K/4K videoklipus</string>
<string name="show_higher_resolutions_title">Rādīt augstākas izšķirtspējas</string>

View File

@ -300,7 +300,6 @@
<string name="search_history_deleted">Избришана е историјата на пребарувања.</string>
<string name="no_streams_available_download">Нема стримови за симнување</string>
<string name="one_item_deleted">1 ставка избришана.</string>
<string name="toast_no_player">Нема апликација за пуштање на овој фајл</string>
<string name="app_license">NewPipe е „copyleft“ слободен софтвер: Можеш да ја користиш, истражуваш и подобруваш по твоја желба. Можеш да ја редистрибуираш и/или да ја промениш под условите на GNU GPL лиценцата, публикувана од фондацијата FSF - или верзија 3 од лиценцата, или (по можност) понова верзија.</string>
<string name="import_settings">Дали сакаш да се внесат и подесувањата?</string>
<string name="preferred_open_action_settings_title">Претпочитана акција за „отворање“</string>

View File

@ -125,7 +125,6 @@
<string name="copyright" formatted="true">%3$s ന്റെ കീഴിൽ %2$s ന്റെ ©%1$s</string>
<string name="title_licenses">തേർഡ്-പാർട്ടി ലൈസൻസുകൾ</string>
<string name="title_activity_about">ന്യൂപൈപ്പിനെക്കുറിച്ച്</string>
<string name="toast_no_player">ഈ ഫയൽ പ്ലേ ചെയ്യാൻ കഴിയുന്ന ഒരു അപ്പും ഇൻസ്റ്റാൾ ചെയ്തിട്ടില്ല</string>
<string name="charset_most_special_characters">പ്രത്യേക അടയാളങ്ങൾ</string>
<string name="charset_letters_and_digits">അക്ഷരങ്ങളും അക്കങ്ങളും</string>
<string name="settings_file_replacement_character_title">പകരം ഉപയോഗിക്കാവുന്ന അടയാളം</string>

View File

@ -34,11 +34,27 @@
<string name="install">इंस्टॉल</string>
<string name="no_player_found_toast">प्लेअर सापडले नाही (तुम्ही VLC player वापरून फाईल चालवू शकता).</string>
<string name="no_player_found">प्लेअर सापडले नाही. VLC प्लेअर इंस्टॉल करू इच्छिता का\?</string>
<string name="main_bg_subtitle">सुरू करण्यासाठी \"शोधा\" दाबा</string>
<string name="main_bg_subtitle">प्रारंभ करण्यासाठी मॅग्निफाइंग ग्लासवर टॅप करा.</string>
<string name="play_with_kodi_title">कोडी वापरून चालवा</string>
<string name="show_higher_resolutions_summary">फक्त काही उपकरणे 2k/4k व्हिडिओ चालवू शकतात</string>
<string name="show_higher_resolutions_title">वरचे रेसॉल्युशन दाखवा</string>
<string name="default_popup_resolution_title">डिफॉल्ट पॉप अप रेसिल्युशन</string>
<string name="default_resolution_title">डीफॉल्ट रेसोल्युशन निवडा</string>
<string name="controls_add_to_playlist_title">मध्ये टाका</string>
<string name="upload_date_text">%1$s रोजी प्रकाशित</string>
<string name="show_play_with_kodi_title">\"कोडीबरोबर प्ले करा\" हा पर्याय दाखवा</string>
<string name="show_play_with_kodi_summary">कोडी मीडिया सेंटरद्वारे व्हिडिओ प्ले करण्याचा पर्याय प्रदर्शित करा</string>
<string name="mark_as_watched">पाहिले म्हणून चिन्हांकित करा</string>
<string name="ok">ठीक आहे</string>
<string name="crash_the_player">प्लेअर क्रॅश करा</string>
<string name="notification_action_1_title">दुसरे क्रिया बटण</string>
<string name="notification_action_2_title">तिसरे क्रिया बटण</string>
<string name="notification_action_3_title">चौथे क्रिया बटण</string>
<string name="notification_action_4_title">पाचवे क्रिया बटण</string>
<string name="did_you_mean">तुम्हाला \"%1$s\" म्हणायचे आहे का\?</string>
<string name="use_external_video_player_summary">काही रेसॉल्युशनवर ऑडिओ काढून टाकते</string>
<string name="kore_not_found">गहाळ Kode ॲप इंस्टॉल करायचे\?</string>
<string name="notification_scale_to_square_image_summary">16:9 ते 1:1 आस्पेक्ट रेशो पर्यंत नोटिफिकेशनमध्ये दाखवलेली व्हिडिओ थंबनेल क्रॉप करा</string>
<string name="notification_action_0_title">प्रथम क्रिया बटण</string>
<string name="notification_scale_to_square_image_title">1:1 आस्पेक्ट रेशोवर थंबनेल क्रॉप करा</string>
</resources>

View File

@ -43,7 +43,7 @@
<string name="show_higher_resolutions_title">Papar resolusi yang lebih tinggi</string>
<string name="show_higher_resolutions_summary">Hanya peranti tertentu yang boleh bermain video 2K/4K</string>
<string name="play_with_kodi_title">Main dengan Kodi</string>
<string name="kore_not_found">Pasangkan aplikasi Kore yang tidak dijumpai\?</string>
<string name="kore_not_found">Pasangkan aplikasi Kode yang tidak dijumpai\?</string>
<string name="show_play_with_kodi_title">Paparkan opsyen \"Main dengan Kodi\"</string>
<string name="show_play_with_kodi_summary">Paparkan opsyen untuk memain video dengan Kodi</string>
<string name="play_audio">Audio</string>
@ -218,7 +218,6 @@
<string name="settings_file_replacement_character_title">Karakter pengganti</string>
<string name="charset_letters_and_digits">Huruf dan angka</string>
<string name="charset_most_special_characters">Karakter yang paling istimewa</string>
<string name="toast_no_player">Tiada app dipasang untuk memainkan fail ini</string>
<string name="title_activity_about">Tentang NewPipe</string>
<string name="title_licenses">Lesen Pihak Ketiga</string>
<string name="copyright" formatted="true">© %1$s oleh %2$s di bawah %3$s</string>

Some files were not shown because too many files have changed in this diff Show More