Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
38 commits
Select commit Hold shift + click to select a range
54f9bcb
Upgrade AGP to 9.0.0
theimpulson Jan 17, 2026
4f70235
Enable proguard android optimizations
theimpulson Jan 17, 2026
d045b27
Migrate to built-in Kotlin
theimpulson Jan 17, 2026
a3301dc
Enable resValues as build feature
theimpulson Jan 17, 2026
7758a27
Migrate from deprecated android block to ApplicationExtension
theimpulson Jan 17, 2026
19e94bd
Migrate from deprecated srcDir to directories method
theimpulson Jan 17, 2026
fd192b4
Drop default properties
theimpulson Jan 17, 2026
a7aad63
Upgrade Kotlin and KSP
theimpulson Jan 29, 2026
51e62f0
Upgrade GitHub Actions for Node 24 compatibility
salmanmkc Jan 30, 2026
d051e8e
Upgrade GitHub Actions to latest versions
salmanmkc Jan 30, 2026
cc33b68
Merge pull request #13140 from salmanmkc/upgrade-github-actions-node24
TobiGr Jan 30, 2026
739b6ae
Merge pull request #13141 from salmanmkc/upgrade-github-actions-node2…
TobiGr Jan 30, 2026
ae60f7d
FeedLoadManager: Shuffle the order outdated subscriptions are updated in
jpds Jan 31, 2026
15b5cef
Merge pull request #13136 from TeamNewPipe/agp9
theimpulson Feb 1, 2026
8d6e68d
Partially revert upgrade to AGP 9.0.0
theimpulson Feb 4, 2026
85d43fe
proguard: Keep fields of generated proguard files
theimpulson Feb 4, 2026
83f9646
Merge pull request #13190 from TeamNewPipe/agp9fixes
Stypox Feb 4, 2026
5525d20
Small refactor getPlayQueueFromCache
absurdlylongusername Feb 5, 2026
725cb70
Update useVideoAndSubtitles rename in comment
absurdlylongusername Feb 5, 2026
118def0
Add conditional guard to prevent useVideoAndSubtitles overwriting rec…
absurdlylongusername Feb 5, 2026
1554f77
Fix additional setRecovery from rebase errors
absurdlylongusername Feb 5, 2026
e749075
Merge pull request #13195 from absurdlylongusername/fix-13139-resume-…
TobiGr Feb 5, 2026
045e91d
Small refactor getPlayQueueFromCache
absurdlylongusername Feb 5, 2026
90d5d5f
Update useVideoAndSubtitles rename in comment
absurdlylongusername Feb 5, 2026
2027b6d
Add conditional guard to prevent useVideoAndSubtitles overwriting rec…
absurdlylongusername Feb 5, 2026
fcb77fe
Fix additional setRecovery from rebase errors
absurdlylongusername Feb 5, 2026
5112acf
Merge pull request #13197 from TeamNewPipe/backport-13195-to-release-…
TobiGr Feb 5, 2026
955844b
Translated using Weblate (Basque)
weblate Feb 5, 2026
d2a8955
Translated using Weblate (Basque)
weblate Feb 5, 2026
74d5a8b
Update extractor to version 0.25.2
TobiGr Feb 5, 2026
dc8a629
Add changelog for NewPipe 0.28.3
TobiGr Feb 5, 2026
13577f5
NewPipe 0.28.3 (1008)
TobiGr Feb 5, 2026
8578bd9
Merge pull request #13200 from TeamNewPipe/release-0.28.3
TobiGr Feb 5, 2026
85abc58
Merge branch 'master' into dev
TobiGr Feb 5, 2026
56a0436
Merge pull request #13161 from jpds/outdated-subscription-shuffle
TobiGr Feb 6, 2026
e006328
Merge branch 'dev' into refactor
TobiGr Feb 6, 2026
a430517
Re-add PlayQueueItem.RECOVERY_UNSET
TobiGr Feb 6, 2026
aa8aa6a
Update hilt for compatibility with newer kotlin version
TobiGr Feb 6, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/backport-pr.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ jobs:
github.event.comment.author_association == 'MEMBER'
)
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v6
- name: Get backport metadata
# the target branch is the first argument after `/backport`
env:
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ jobs:

steps:
- uses: actions/checkout@v6
- uses: gradle/actions/wrapper-validation@v4
- uses: gradle/actions/wrapper-validation@v5

- name: create and checkout branch
# push events already checked out the branch
Expand Down
16 changes: 11 additions & 5 deletions app/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
*/
import com.mikepenz.aboutlibraries.plugin.DuplicateMode

import com.android.build.api.dsl.ApplicationExtension

plugins {
alias(libs.plugins.android.application)
alias(libs.plugins.jetbrains.kotlin.android)
Expand Down Expand Up @@ -37,7 +39,7 @@ kotlin {
}
}

android {
configure<ApplicationExtension> {
compileSdk = 36
namespace = "org.schabi.newpipe"

Expand All @@ -47,9 +49,9 @@ android {
minSdk = 23
targetSdk = 35

versionCode = System.getProperty("versionCodeOverride")?.toInt() ?: 1007
versionCode = System.getProperty("versionCodeOverride")?.toInt() ?: 1008

versionName = "0.28.2"
versionName = "0.28.3"
System.getProperty("versionNameSuffix")?.let { versionNameSuffix = it }

testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
Expand Down Expand Up @@ -83,7 +85,10 @@ android {
}
isMinifyEnabled = true
isShrinkResources = false // disabled to fix F-Droid"s reproducible build
proguardFiles(getDefaultProguardFile("proguard-android.txt"), "proguard-rules.pro")
proguardFiles(
getDefaultProguardFile("proguard-android-optimize.txt"),
"proguard-rules.pro"
)
}
}

Expand All @@ -105,7 +110,7 @@ android {

sourceSets {
getByName("androidTest") {
assets.srcDir("$projectDir/schemas")
assets.directories += "$projectDir/schemas"
}
}

Expand All @@ -117,6 +122,7 @@ android {
viewBinding = true
compose = true
buildConfig = true
resValues = true
}

packaging {
Expand Down
5 changes: 5 additions & 0 deletions app/proguard-rules.pro
Original file line number Diff line number Diff line change
Expand Up @@ -54,3 +54,8 @@
-keepclasseswithmembers class org.schabi.newpipe.** {
kotlinx.serialization.KSerializer serializer(...);
}

# Prevent R8 from stripping or renaming Protobuf internal fields
-keepclassmembers class * extends com.google.protobuf.GeneratedMessageLite {
<fields>;
}
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,8 @@ class FeedLoadManager(private val context: Context) {
broadcastProgress()
}
.observeOn(Schedulers.io())
.flatMap { Flowable.fromIterable(it) }
// Randomize user subscription ordering to attempt to resist fingerprinting
.flatMap { Flowable.fromIterable(it.shuffled()) }
.takeWhile { !cancelSignal.get() }
.doOnNext { subscriptionEntity ->
// throttle YouTube extractions once every BATCH_SIZE to avoid being rate limited
Expand Down
31 changes: 20 additions & 11 deletions app/src/main/java/org/schabi/newpipe/player/Player.java
Original file line number Diff line number Diff line change
Expand Up @@ -480,7 +480,7 @@ public void handleIntent(@NonNull final Intent intent) {
&& newQueue.size() == 1 && newQueue.getItem() != null
&& playQueue != null && playQueue.size() == 1 && playQueue.getItem() != null
&& newQueue.getItem().equals(playQueue.getItem())
&& newQueue.getItem().getRecoveryPosition() != Long.MIN_VALUE) {
&& newQueue.getItem().getRecoveryPosition() != PlayQueueItem.RECOVERY_UNSET) {
// Player can have state = IDLE when playback is stopped or failed
// and we should retry in this case
if (simpleExoPlayer.getPlaybackState()
Expand Down Expand Up @@ -509,7 +509,7 @@ public void handleIntent(@NonNull final Intent intent) {
&& (playQueue == null || !playQueue.equalStreamsAndIndex(newQueue))
&& !newQueue.isEmpty()
&& newQueue.getItem() != null
&& newQueue.getItem().getRecoveryPosition() == Long.MIN_VALUE) {
&& newQueue.getItem().getRecoveryPosition() == PlayQueueItem.RECOVERY_UNSET) {
databaseUpdateDisposable.add(recordManager.loadStreamState(newQueue.getItem())
.observeOn(AndroidSchedulers.mainThread())
// Do not place initPlayback() in doFinally() because
Expand Down Expand Up @@ -562,11 +562,7 @@ private static PlayQueue getPlayQueueFromCache(@NonNull final Intent intent) {
if (queueCache == null) {
return null;
}
final PlayQueue newQueue = SerializedCache.getInstance().take(queueCache, PlayQueue.class);
if (newQueue == null) {
return null;
}
return newQueue;
return SerializedCache.getInstance().take(queueCache, PlayQueue.class);
}

private void initUIsForCurrentPlayerType() {
Expand Down Expand Up @@ -1704,7 +1700,7 @@ public void onPlaybackSynchronize(@NonNull final PlayQueueItem item, final boole
}

// sync the player index with the queue index, and seek to the correct position
if (item.getRecoveryPosition() != Long.MIN_VALUE) {
if (item.getRecoveryPosition() != PlayQueueItem.RECOVERY_UNSET) {
simpleExoPlayer.seekTo(playQueueIndex, item.getRecoveryPosition());
playQueue.unsetRecovery(playQueueIndex);
} else {
Expand Down Expand Up @@ -2033,7 +2029,7 @@ public MediaSource sourceOf(final PlayQueueItem item, final StreamInfo info) {
// resolver was called when the app was in background, the app will only stream audio when
// the user come back to the app and will never fetch the video stream.
// Note that the video is not fetched when the app is in background because the video
// renderer is fully disabled (see useVideoSource method), except for HLS streams
// renderer is fully disabled (see useVideoAndSubtitles method), except for HLS streams
// (see https://github.com/google/ExoPlayer/issues/9282).
return videoResolver.resolve(info);
}
Expand Down Expand Up @@ -2214,13 +2210,23 @@ public void useVideoAndSubtitles(final boolean videoAndSubtitlesEnabled) {

isAudioOnly = !videoAndSubtitlesEnabled;

final var item = playQueue.getItem();
final boolean hasPendingRecovery =
item != null && item.getRecoveryPosition() != PlayQueueItem.RECOVERY_UNSET;
final boolean hasTimeline =
!exoPlayerIsNull() && !simpleExoPlayer.getCurrentTimeline().isEmpty();


getCurrentStreamInfo().ifPresentOrElse(info -> {
// In case we don't know the source type, fall back to either video-with-audio, or
// audio-only source type
final SourceType sourceType = videoResolver.getStreamSourceType()
.orElse(SourceType.VIDEO_WITH_AUDIO_OR_AUDIO_ONLY);

setRecovery(); // making sure to save playback position before reloadPlayQueueManager()
if (hasTimeline || !hasPendingRecovery) {
// making sure to save playback position before reloadPlayQueueManager()
setRecovery();
}

if (playQueueManagerReloadingNeeded(sourceType, info, getVideoRendererIndex())) {
reloadPlayQueueManager();
Expand All @@ -2233,7 +2239,10 @@ The current metadata may be null sometimes (for e.g. when using an unstable conn
Reload the play queue manager in this case, which is the behavior when we don't know the
index of the video renderer or playQueueManagerReloadingNeeded returns true
*/
setRecovery(); // making sure to save playback position before reloadPlayQueueManager()
if (hasTimeline || !hasPendingRecovery) {
// making sure to save playback position before reloadPlayQueueManager()
setRecovery();
}
reloadPlayQueueManager();
});

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import org.schabi.newpipe.player.playqueue.PlayQueueEvent.RecoveryEvent
import org.schabi.newpipe.player.playqueue.PlayQueueEvent.RemoveEvent
import org.schabi.newpipe.player.playqueue.PlayQueueEvent.ReorderEvent
import org.schabi.newpipe.player.playqueue.PlayQueueEvent.SelectEvent
import org.schabi.newpipe.player.playqueue.PlayQueueItem

/**
* PlayQueue is responsible for keeping track of a list of streams and the index of
Expand Down Expand Up @@ -390,7 +391,7 @@ abstract class PlayQueue internal constructor(
*/
@Synchronized
fun unsetRecovery(index: Int) {
setRecovery(index, Long.Companion.MIN_VALUE)
setRecovery(index, PlayQueueItem.RECOVERY_UNSET)
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ class PlayQueueItem private constructor(
var isAutoQueued: Boolean = false

// package-private
var recoveryPosition = Long.Companion.MIN_VALUE
var recoveryPosition = RECOVERY_UNSET
var error: Throwable? = null
private set

Expand Down Expand Up @@ -68,4 +68,8 @@ class PlayQueueItem private constructor(
override fun equals(o: Any?) = o is PlayQueueItem && serviceId == o.serviceId && url == o.url

override fun hashCode() = Objects.hash(url, serviceId)

companion object {
const val RECOVERY_UNSET = Long.MIN_VALUE
}
}
4 changes: 2 additions & 2 deletions app/src/main/res/values-az/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -397,7 +397,7 @@
<string name="error_http_unsupported_range">Server çox iş parçalı endirmələri qəbul etmir, @string/msg_threads = 1 ilə yenidən cəhd edin</string>
<string name="delete_downloaded_files_confirm">Bütün endirilmiş fayllar diskdən silinsin\?</string>
<string name="max_retry_msg">Maksimum təkrar cəhdlər</string>
<string name="remove_watched_popup_warning">Pleylistə əlavə olunandan əvvəl və sonrakı baxılmış videolar silinəcək. \nSiz əminsiniz? Bu geri qaytarıla bilməz!</string>
<string name="remove_watched_popup_warning">Pleylistə əlavə olunandan əvvəl və sonrakı baxılan yayımlar silinəcək. \nSiz əminsiniz?</string>
<string name="feed_groups_header_title">Kanal qrupları</string>
<string name="feed_new_items">Yeni axın elementləri</string>
<string name="feed_update_threshold_summary">Abunəlik köhnəlmiş hesab edilənə qədərki son yeniləmədən sonrakı vaxt — %s</string>
Expand Down Expand Up @@ -526,7 +526,7 @@
</plurals>
<string name="progressive_load_interval_exoplayer_default">ExoPlayer standartı</string>
<string name="feed_use_dedicated_fetch_method_title">Mövcud olduqda xüsusi axından al</string>
<string name="remove_watched_popup_title">Baxılmış videolar silinsin?</string>
<string name="remove_watched_popup_title">Baxılan yayımlar silinsin?</string>
<string name="remove_watched">İzləniləni sil</string>
<string name="downloads_storage_use_saf_title">Sistem qovluğu seçicisini (SAF) istifadə et</string>
<string name="error_timeout">Bağlantı fasiləsi</string>
Expand Down
4 changes: 2 additions & 2 deletions app/src/main/res/values-bg/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -464,7 +464,7 @@
\nЕвентуално може да бъде поддържано в бъдещи версии.</string>
<string name="processing_may_take_a_moment">Обработка… Ще отнеме момент</string>
<string name="new_seek_duration_toast">Поради ограничения в ExoPlayer, стъпката за превъртане е зададена на %d секунди</string>
<string name="remove_watched_popup_warning">Видата, които са били изгледани преди и след добавянето към плейлиста ще бъдат премахнати. \nСигурни ли сте? Това не може да бъде отменено!</string>
<string name="remove_watched_popup_warning">Потоците, които са били гледани преди и след добавянето им към плейлиста, ще бъдат премахнати. \nСигурни ли сте?</string>
<string name="downloads_storage_use_saf_summary">„Storage Access Framework“ позволява изтегляния във външна SD-карта</string>
<string name="start_downloads">Започни изтеглянията</string>
<string name="close">Затвори</string>
Expand Down Expand Up @@ -500,7 +500,7 @@
<string name="channel_created_by">Създаден от %s</string>
<string name="paid_content">Съдържанието е достъпно само за хора, които са си платили, затова не може да бъде гледано или изтеглено с NewPipe.</string>
<string name="youtube_music_premium_content">Това видео е достъпно за абонати на YouTube Music Premium, затова не може да бъде гледано или изтеглено с NewPipe.</string>
<string name="remove_watched_popup_title">Премахни изгледаните видеа?</string>
<string name="remove_watched_popup_title">Премахни изгледаните потоци?</string>
<string name="remove_watched_popup_partially_watched_streams">Да, както и само частично изгледаните видеа</string>
<string name="subscribers_count_not_available">Брой на абонати не е наличен</string>
<string name="peertube_instance_add_exists">Инстанцията вече съществува</string>
Expand Down
6 changes: 3 additions & 3 deletions app/src/main/res/values-cs/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -518,9 +518,9 @@
\n
\nPokud jej chcete vidět, povolte „%1$s“ v nastavení.</string>
<string name="remove_watched_popup_partially_watched_streams">Ano, i zčásti zhlédnutá videa</string>
<string name="remove_watched_popup_title">Odstranit zhlédnutá videa?</string>
<string name="remove_watched">Odstranit zhlédnutá</string>
<string name="remove_watched_popup_warning">Videa, která jste zhlédli před a po jejich přidání do playlistu, budou odstraněna. \nJste se jisti? Tato akce je nevratná!</string>
<string name="remove_watched_popup_title">Odstranit zhlédnuté streamy?</string>
<string name="remove_watched">Odstranit zhlédnuté</string>
<string name="remove_watched_popup_warning">Streamy, které jste zhlédli před a po jejich přidání do playlistu, budou odstraněny. \nJste se jisti?</string>
<string name="show_original_time_ago_summary">Původní texty služeb budou viditelné u položek streamů</string>
<string name="show_original_time_ago_title">U položek zobrazit původní čas</string>
<string name="youtube_restricted_mode_enabled_title">Zapnout „Omezený režim“ YouTube</string>
Expand Down
6 changes: 3 additions & 3 deletions app/src/main/res/values-de/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -516,10 +516,10 @@
<string name="restricted_video">Dieses Video ist altersbeschränkt.
\n
\nAktiviere in den Einstellungen „%1$s“, falls du diese sehen möchtest.</string>
<string name="remove_watched_popup_warning">Videos, die vor und nach dem Hinzufügen zur Wiedergabeliste angeschaut wurden, werden entfernt. \nBist du sicher? Dies kann nicht rückgängig gemacht werden!</string>
<string name="remove_watched_popup_partially_watched_streams">Ja, und teilweise gesehene Videos</string>
<string name="remove_watched_popup_warning">Streams, die vor und nach dem Hinzufügen zur Wiedergabeliste angeschaut wurden, werden entfernt. \nBist du sicher?</string>
<string name="remove_watched_popup_partially_watched_streams">Teilweise angesehene Streams entfernen</string>
<string name="remove_watched">Gesehene entfernen</string>
<string name="remove_watched_popup_title">Gesehene Videos entfernen?</string>
<string name="remove_watched_popup_title">Gesehene Streams entfernen?</string>
<string name="show_original_time_ago_title">Originalzeit vor Elementen anzeigen</string>
<string name="show_original_time_ago_summary">Originaltexte von Diensten werden in Stream-Elementen sichtbar sein</string>
<string name="youtube_restricted_mode_enabled_title">YouTubes „Eingeschränkten Modus“ aktivieren</string>
Expand Down
6 changes: 3 additions & 3 deletions app/src/main/res/values-el/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -525,8 +525,8 @@
</plurals>
<string name="new_seek_duration_toast">Λόγω περιορισμών του ExoPlayer, η διάρκεια αναζήτησης ορίστηκε στα %d δευτερόλεπτα</string>
<string name="remove_watched_popup_partially_watched_streams">Ναι. Και τα μερικώς θεαθέντα βίντεο</string>
<string name="remove_watched_popup_warning">Τα βίντεο που εθεάθησαν πριν και αφού προστέθηκαν στη λίστα αναπαραγωγής θα απομακρυνθούν \nΕίστε σίγουρος; Δεν μπορεί να αναιρεθεί!</string>
<string name="remove_watched_popup_title">Απομάκρυνση θεαθέντων βίντεο;</string>
<string name="remove_watched_popup_warning">Οι ροές που εθεάθησαν πριν και αφού προστέθηκαν στη λίστα αναπαραγωγής θα απομακρυνθούν \nΕίστε σίγουρος;</string>
<string name="remove_watched_popup_title">Απομάκρυνση θεαθέντων ροών;</string>
<string name="remove_watched">Απομάκρυνση όσων θεάθησαν</string>
<string name="app_language_title">Γλώσσα εφαρμογής</string>
<string name="choose_instance_prompt">Επιλογή μιας instance</string>
Expand Down Expand Up @@ -614,7 +614,7 @@
\nΘέλετε να απεγγραφείτε από αυτό το κανάλι;</string>
<string name="feed_load_error_account_info">Αδυναμία φόρτωσης τροφοδοσίας για \'%s\'.</string>
<string name="feed_load_error">Σφάλμα φόρτωσης τροφοδοσίας</string>
<string name="downloads_storage_use_saf_summary_api_29">Από το Android 10 και μετά, μόνο το SAF υποστηρίζεται</string>
<string name="downloads_storage_use_saf_summary_api_29">Από το Android 10 και μετά, μόνο το Πλαίσιο Πρόσβασης Αποθήκευσης υποστηρίζεται</string>
<string name="downloads_storage_ask_summary_no_saf_notice">Θα ερωτηθείτε πού να αποθηκεύσετε κάθε λήψη</string>
<string name="no_dir_yet">Δεν έχει ορισθεί φάκελος λήψεων ακόμα, eπιλέξτε τον προεπιλεγμένο φάκελο τώρα</string>
<string name="metadata_host">Host</string>
Expand Down
4 changes: 2 additions & 2 deletions app/src/main/res/values-et/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -530,9 +530,9 @@
<item quantity="one">%d sekund</item>
<item quantity="other">%d sekundit</item>
</plurals>
<string name="remove_watched_popup_warning">Sellega eemaldame vaadatud videod ja esitusloendisse lisatud videod. \nKas sa oled kindel? Seda tegevust ei saa hiljem tagasi pöörata!</string>
<string name="remove_watched_popup_warning">Sellega eemaldame vaadatud meediavood ja esitusloendisse lisatud sisu. \nKas sa oled kindel?</string>
<string name="remove_watched_popup_partially_watched_streams">Jah, sealhulgas videod, mille vaatmine jäi pooleli</string>
<string name="remove_watched_popup_title">Kas eemaldame vaadatud videod?</string>
<string name="remove_watched_popup_title">Kas eemaldame vaadatud meediavood?</string>
<string name="remove_watched">Eemalda vaadatud videod</string>
<string name="systems_language">Kasuta süsteemi keelt</string>
<string name="app_language_title">Rakenduse keel</string>
Expand Down
2 changes: 1 addition & 1 deletion app/src/main/res/values-eu/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -704,7 +704,7 @@
<string name="metadata_subscribers">Harpidedunak</string>
<string name="unknown_audio_track">Ezezaguna</string>
<string name="volume">Bolumena</string>
<string name="use_exoplayer_decoder_fallback_title">Erabili ExoPlayer-en deskodetzailearen ordezko eginbidea</string>
<string name="use_exoplayer_decoder_fallback_title">Erabili ExoPlayer-en deskodetzailearen ordezko ezaugarria</string>
<string name="none">Bat ere ez</string>
<string name="loading_metadata_title">Metadatuak kargatzen…</string>
<string name="settings_category_exoplayer_summary">Kudeatu ExoPlayer-en ezarpen batzuk. Aldaketa hauek eragina izan dezaten, erreproduzitzailea berrabiarazi behar da</string>
Expand Down
Loading
Loading