From 26ff55e0053090b14a4a78a5c25968bf22103ea7 Mon Sep 17 00:00:00 2001 From: edde746 <86283021+edde746@users.noreply.github.com> Date: Mon, 23 Feb 2026 05:41:47 +0100 Subject: [PATCH] fix(android): auto buffer size to prevent OOM --- .../edde746/plezy/exoplayer/ExoPlayerCore.kt | 2 ++ .../edde746/plezy/exoplayer/ExoPlayerPlugin.kt | 6 ++++++ lib/i18n/de.i18n.json | 2 ++ lib/i18n/en.i18n.json | 2 ++ lib/i18n/es.i18n.json | 2 ++ lib/i18n/fr.i18n.json | 2 ++ lib/i18n/it.i18n.json | 2 ++ lib/i18n/ko.i18n.json | 2 ++ lib/i18n/nl.i18n.json | 2 ++ lib/i18n/strings.g.dart | 4 ++-- lib/i18n/strings_de.g.dart | 8 ++++++-- lib/i18n/strings_en.g.dart | 12 ++++++++++-- lib/i18n/strings_es.g.dart | 8 ++++++-- lib/i18n/strings_fr.g.dart | 8 ++++++-- lib/i18n/strings_it.g.dart | 8 ++++++-- lib/i18n/strings_ko.g.dart | 8 ++++++-- lib/i18n/strings_nl.g.dart | 8 ++++++-- lib/i18n/strings_sv.g.dart | 8 ++++++-- lib/i18n/strings_zh.g.dart | 8 ++++++-- lib/i18n/sv.i18n.json | 2 ++ lib/i18n/zh.i18n.json | 2 ++ lib/mpv/player/player_android.dart | 11 +++++++++++ lib/screens/settings/settings_screen.dart | 17 ++++++++++++----- lib/screens/video_player_screen.dart | 6 ++++-- lib/services/settings_service.dart | 11 ++++++++++- 25 files changed, 123 insertions(+), 28 deletions(-) diff --git a/android/app/src/main/kotlin/com/edde746/plezy/exoplayer/ExoPlayerCore.kt b/android/app/src/main/kotlin/com/edde746/plezy/exoplayer/ExoPlayerCore.kt index 31d30a27..76eb73f3 100644 --- a/android/app/src/main/kotlin/com/edde746/plezy/exoplayer/ExoPlayerCore.kt +++ b/android/app/src/main/kotlin/com/edde746/plezy/exoplayer/ExoPlayerCore.kt @@ -344,6 +344,8 @@ class ExoPlayerCore(private val activity: Activity) : Player.Listener { setTargetBufferBytes(bufferSizeBytes) setPrioritizeTimeOverSizeThresholds(false) Log.d(TAG, "Buffer byte limit set to ${bufferSizeBytes / 1024 / 1024}MB") + } else { + Log.d(TAG, "Buffer in auto mode (time-based thresholds)") } }.build() diff --git a/android/app/src/main/kotlin/com/edde746/plezy/exoplayer/ExoPlayerPlugin.kt b/android/app/src/main/kotlin/com/edde746/plezy/exoplayer/ExoPlayerPlugin.kt index 7b7b3d65..80df9668 100644 --- a/android/app/src/main/kotlin/com/edde746/plezy/exoplayer/ExoPlayerPlugin.kt +++ b/android/app/src/main/kotlin/com/edde746/plezy/exoplayer/ExoPlayerPlugin.kt @@ -1,6 +1,8 @@ package com.edde746.plezy.exoplayer import android.app.Activity +import android.app.ActivityManager +import android.content.Context import android.net.Uri import android.util.Log import com.edde746.plezy.mpv.MpvPlayerCore @@ -119,6 +121,10 @@ class ExoPlayerPlugin : FlutterPlugin, MethodChannel.MethodCallHandler, ) "getStats" -> handleGetStats(result) "getPlayerType" -> result.success(if (usingMpvFallback) "mpv" else "exoplayer") + "getHeapSize" -> { + val am = activity?.getSystemService(Context.ACTIVITY_SERVICE) as? ActivityManager + result.success(am?.largeMemoryClass ?: 0) + } "setSubtitleStyle" -> handleSetSubtitleStyle(call, result) "observeProperty" -> handleObserveProperty(call, result) else -> result.notImplemented() diff --git a/lib/i18n/de.i18n.json b/lib/i18n/de.i18n.json index 93d7a148..cc9f255f 100644 --- a/lib/i18n/de.i18n.json +++ b/lib/i18n/de.i18n.json @@ -126,6 +126,8 @@ "hardwareDecodingDescription": "Hardwarebeschleunigung verwenden, sofern verfügbar", "bufferSize": "Puffergröße", "bufferSizeMB": "${size}MB", + "bufferSizeAuto": "Auto (Empfohlen)", + "bufferSizeWarning": "Ihr Gerät hat ${heap}MB Speicher. Ein ${size}MB-Puffer kann Wiedergabeprobleme verursachen.", "subtitleStyling": "Untertitel-Stil", "subtitleStylingDescription": "Aussehen von Untertiteln anpassen", "smallSkipDuration": "Kleine Sprungdauer", diff --git a/lib/i18n/en.i18n.json b/lib/i18n/en.i18n.json index 4210513c..530b5a0c 100644 --- a/lib/i18n/en.i18n.json +++ b/lib/i18n/en.i18n.json @@ -126,6 +126,8 @@ "hardwareDecodingDescription": "Use hardware acceleration when available", "bufferSize": "Buffer Size", "bufferSizeMB": "${size}MB", + "bufferSizeAuto": "Auto (Recommended)", + "bufferSizeWarning": "Your device has ${heap}MB of memory. A ${size}MB buffer may cause playback issues.", "subtitleStyling": "Subtitle Styling", "subtitleStylingDescription": "Customize subtitle appearance", "smallSkipDuration": "Small Skip Duration", diff --git a/lib/i18n/es.i18n.json b/lib/i18n/es.i18n.json index 25f3a4b9..e9742bde 100644 --- a/lib/i18n/es.i18n.json +++ b/lib/i18n/es.i18n.json @@ -126,6 +126,8 @@ "hardwareDecodingDescription": "Usar aceleración por hardware cuando esté disponible", "bufferSize": "Tamaño del Buffer", "bufferSizeMB": "${size}MB", + "bufferSizeAuto": "Auto (Recomendado)", + "bufferSizeWarning": "Tu dispositivo tiene ${heap}MB de memoria. Un búfer de ${size}MB puede causar problemas de reproducción.", "subtitleStyling": "Estilo de Subtítulos", "subtitleStylingDescription": "Personalizar la apariencia de los subtítulos", "smallSkipDuration": "Salto pequeño", diff --git a/lib/i18n/fr.i18n.json b/lib/i18n/fr.i18n.json index afad6935..b0cd23ee 100644 --- a/lib/i18n/fr.i18n.json +++ b/lib/i18n/fr.i18n.json @@ -126,6 +126,8 @@ "hardwareDecodingDescription": "Utilisez l'accélération matérielle lorsqu'elle est disponible.", "bufferSize": "Taille du Buffer", "bufferSizeMB": "${size}MB", + "bufferSizeAuto": "Auto (Recommandé)", + "bufferSizeWarning": "Votre appareil dispose de ${heap}MB de mémoire. Un tampon de ${size}MB peut causer des problèmes de lecture.", "subtitleStyling": "Stylisation des sous-titres", "subtitleStylingDescription": "Personnaliser l'apparence des sous-titres", "smallSkipDuration": "Small Skip Duration", diff --git a/lib/i18n/it.i18n.json b/lib/i18n/it.i18n.json index ae151fbd..53416dad 100644 --- a/lib/i18n/it.i18n.json +++ b/lib/i18n/it.i18n.json @@ -126,6 +126,8 @@ "hardwareDecodingDescription": "Utilizza l'accelerazione hardware quando disponibile", "bufferSize": "Dimensione buffer", "bufferSizeMB": "${size}MB", + "bufferSizeAuto": "Auto (Consigliato)", + "bufferSizeWarning": "Il tuo dispositivo ha ${heap}MB di memoria. Un buffer di ${size}MB potrebbe causare problemi di riproduzione.", "subtitleStyling": "Stile sottotitoli", "subtitleStylingDescription": "Personalizza l'aspetto dei sottotitoli", "smallSkipDuration": "Durata skip breve", diff --git a/lib/i18n/ko.i18n.json b/lib/i18n/ko.i18n.json index 856cd475..45967dd0 100644 --- a/lib/i18n/ko.i18n.json +++ b/lib/i18n/ko.i18n.json @@ -126,6 +126,8 @@ "hardwareDecodingDescription": "가능한 경우 하드웨어 가속을 사용합니다", "bufferSize": "버퍼 크기", "bufferSizeMB": "${size}MB", + "bufferSizeAuto": "자동 (권장)", + "bufferSizeWarning": "기기 메모리가 ${heap}MB입니다. ${size}MB 버퍼는 재생 문제를 일으킬 수 있습니다.", "subtitleStyling": "자막 스타일", "subtitleStylingDescription": "자막의 외형을 사용자 설정", "smallSkipDuration": "짧은 건너뛰기 시간", diff --git a/lib/i18n/nl.i18n.json b/lib/i18n/nl.i18n.json index cc446181..0ffb278a 100644 --- a/lib/i18n/nl.i18n.json +++ b/lib/i18n/nl.i18n.json @@ -126,6 +126,8 @@ "hardwareDecodingDescription": "Gebruik hardware versnelling indien beschikbaar", "bufferSize": "Buffer grootte", "bufferSizeMB": "${size}MB", + "bufferSizeAuto": "Auto (Aanbevolen)", + "bufferSizeWarning": "Je apparaat heeft ${heap}MB geheugen. Een buffer van ${size}MB kan afspeelproblemen veroorzaken.", "subtitleStyling": "Ondertitel opmaak", "subtitleStylingDescription": "Pas ondertitel uiterlijk aan", "smallSkipDuration": "Korte skip duur", diff --git a/lib/i18n/strings.g.dart b/lib/i18n/strings.g.dart index d1dcb9d2..e82d8901 100644 --- a/lib/i18n/strings.g.dart +++ b/lib/i18n/strings.g.dart @@ -4,9 +4,9 @@ /// To regenerate, run: `dart run slang` /// /// Locales: 9 -/// Strings: 7236 (804 per locale) +/// Strings: 7254 (806 per locale) /// -/// Built on 2026-02-22 at 16:11 UTC +/// Built on 2026-02-23 at 04:30 UTC // coverage:ignore-file // ignore_for_file: type=lint, unused_import diff --git a/lib/i18n/strings_de.g.dart b/lib/i18n/strings_de.g.dart index b6b44128..f0a03044 100644 --- a/lib/i18n/strings_de.g.dart +++ b/lib/i18n/strings_de.g.dart @@ -245,6 +245,8 @@ class _TranslationsSettingsDe implements TranslationsSettingsEn { @override String get hardwareDecodingDescription => 'Hardwarebeschleunigung verwenden, sofern verfügbar'; @override String get bufferSize => 'Puffergröße'; @override String bufferSizeMB({required Object size}) => '${size}MB'; + @override String get bufferSizeAuto => 'Auto (Empfohlen)'; + @override String bufferSizeWarning({required Object heap, required Object size}) => 'Ihr Gerät hat ${heap}MB Speicher. Ein ${size}MB-Puffer kann Wiedergabeprobleme verursachen.'; @override String get subtitleStyling => 'Untertitel-Stil'; @override String get subtitleStylingDescription => 'Aussehen von Untertiteln anpassen'; @override String get smallSkipDuration => 'Kleine Sprungdauer'; @@ -1417,6 +1419,8 @@ extension on TranslationsDe { 'settings.hardwareDecodingDescription' => 'Hardwarebeschleunigung verwenden, sofern verfügbar', 'settings.bufferSize' => 'Puffergröße', 'settings.bufferSizeMB' => ({required Object size}) => '${size}MB', + 'settings.bufferSizeAuto' => 'Auto (Empfohlen)', + 'settings.bufferSizeWarning' => ({required Object heap, required Object size}) => 'Ihr Gerät hat ${heap}MB Speicher. Ein ${size}MB-Puffer kann Wiedergabeprobleme verursachen.', 'settings.subtitleStyling' => 'Untertitel-Stil', 'settings.subtitleStylingDescription' => 'Aussehen von Untertiteln anpassen', 'settings.smallSkipDuration' => 'Kleine Sprungdauer', @@ -1811,10 +1815,10 @@ extension on TranslationsDe { 'liveTv.reloadGuide' => 'Programmführer neu laden', 'liveTv.guideReloaded' => 'Programmdaten neu geladen', 'liveTv.allChannels' => 'Alle Kanäle', - 'liveTv.now' => 'Jetzt', - 'liveTv.today' => 'Heute', _ => null, } ?? switch (path) { + 'liveTv.now' => 'Jetzt', + 'liveTv.today' => 'Heute', 'liveTv.midnight' => 'Mitternacht', 'liveTv.overnight' => 'Nacht', 'liveTv.morning' => 'Morgen', diff --git a/lib/i18n/strings_en.g.dart b/lib/i18n/strings_en.g.dart index d6ca04bc..0a58865e 100644 --- a/lib/i18n/strings_en.g.dart +++ b/lib/i18n/strings_en.g.dart @@ -481,6 +481,12 @@ class TranslationsSettingsEn { /// en: '${size}MB' String bufferSizeMB({required Object size}) => '${size}MB'; + /// en: 'Auto (Recommended)' + String get bufferSizeAuto => 'Auto (Recommended)'; + + /// en: 'Your device has ${heap}MB of memory. A ${size}MB buffer may cause playback issues.' + String bufferSizeWarning({required Object heap, required Object size}) => 'Your device has ${heap}MB of memory. A ${size}MB buffer may cause playback issues.'; + /// en: 'Subtitle Styling' String get subtitleStyling => 'Subtitle Styling'; @@ -3032,6 +3038,8 @@ extension on Translations { 'settings.hardwareDecodingDescription' => 'Use hardware acceleration when available', 'settings.bufferSize' => 'Buffer Size', 'settings.bufferSizeMB' => ({required Object size}) => '${size}MB', + 'settings.bufferSizeAuto' => 'Auto (Recommended)', + 'settings.bufferSizeWarning' => ({required Object heap, required Object size}) => 'Your device has ${heap}MB of memory. A ${size}MB buffer may cause playback issues.', 'settings.subtitleStyling' => 'Subtitle Styling', 'settings.subtitleStylingDescription' => 'Customize subtitle appearance', 'settings.smallSkipDuration' => 'Small Skip Duration', @@ -3426,10 +3434,10 @@ extension on Translations { 'liveTv.reloadGuide' => 'Reload Guide', 'liveTv.guideReloaded' => 'Guide data reloaded', 'liveTv.allChannels' => 'All Channels', - 'liveTv.now' => 'Now', - 'liveTv.today' => 'Today', _ => null, } ?? switch (path) { + 'liveTv.now' => 'Now', + 'liveTv.today' => 'Today', 'liveTv.midnight' => 'Midnight', 'liveTv.overnight' => 'Overnight', 'liveTv.morning' => 'Morning', diff --git a/lib/i18n/strings_es.g.dart b/lib/i18n/strings_es.g.dart index 9a95b944..a5ea246b 100644 --- a/lib/i18n/strings_es.g.dart +++ b/lib/i18n/strings_es.g.dart @@ -245,6 +245,8 @@ class _TranslationsSettingsEs implements TranslationsSettingsEn { @override String get hardwareDecodingDescription => 'Usar aceleración por hardware cuando esté disponible'; @override String get bufferSize => 'Tamaño del Buffer'; @override String bufferSizeMB({required Object size}) => '${size}MB'; + @override String get bufferSizeAuto => 'Auto (Recomendado)'; + @override String bufferSizeWarning({required Object heap, required Object size}) => 'Tu dispositivo tiene ${heap}MB de memoria. Un búfer de ${size}MB puede causar problemas de reproducción.'; @override String get subtitleStyling => 'Estilo de Subtítulos'; @override String get subtitleStylingDescription => 'Personalizar la apariencia de los subtítulos'; @override String get smallSkipDuration => 'Salto pequeño'; @@ -1417,6 +1419,8 @@ extension on TranslationsEs { 'settings.hardwareDecodingDescription' => 'Usar aceleración por hardware cuando esté disponible', 'settings.bufferSize' => 'Tamaño del Buffer', 'settings.bufferSizeMB' => ({required Object size}) => '${size}MB', + 'settings.bufferSizeAuto' => 'Auto (Recomendado)', + 'settings.bufferSizeWarning' => ({required Object heap, required Object size}) => 'Tu dispositivo tiene ${heap}MB de memoria. Un búfer de ${size}MB puede causar problemas de reproducción.', 'settings.subtitleStyling' => 'Estilo de Subtítulos', 'settings.subtitleStylingDescription' => 'Personalizar la apariencia de los subtítulos', 'settings.smallSkipDuration' => 'Salto pequeño', @@ -1811,10 +1815,10 @@ extension on TranslationsEs { 'liveTv.reloadGuide' => 'Recargar guía', 'liveTv.guideReloaded' => 'Datos de la guía recargados', 'liveTv.allChannels' => 'Todos los canales', - 'liveTv.now' => 'Ahora', - 'liveTv.today' => 'Hoy', _ => null, } ?? switch (path) { + 'liveTv.now' => 'Ahora', + 'liveTv.today' => 'Hoy', 'liveTv.midnight' => 'Medianoche', 'liveTv.overnight' => 'Madrugada', 'liveTv.morning' => 'Mañana', diff --git a/lib/i18n/strings_fr.g.dart b/lib/i18n/strings_fr.g.dart index 363a18cd..1ab121b0 100644 --- a/lib/i18n/strings_fr.g.dart +++ b/lib/i18n/strings_fr.g.dart @@ -245,6 +245,8 @@ class _TranslationsSettingsFr implements TranslationsSettingsEn { @override String get hardwareDecodingDescription => 'Utilisez l\'accélération matérielle lorsqu\'elle est disponible.'; @override String get bufferSize => 'Taille du Buffer'; @override String bufferSizeMB({required Object size}) => '${size}MB'; + @override String get bufferSizeAuto => 'Auto (Recommandé)'; + @override String bufferSizeWarning({required Object heap, required Object size}) => 'Votre appareil dispose de ${heap}MB de mémoire. Un tampon de ${size}MB peut causer des problèmes de lecture.'; @override String get subtitleStyling => 'Stylisation des sous-titres'; @override String get subtitleStylingDescription => 'Personnaliser l\'apparence des sous-titres'; @override String get smallSkipDuration => 'Small Skip Duration'; @@ -1417,6 +1419,8 @@ extension on TranslationsFr { 'settings.hardwareDecodingDescription' => 'Utilisez l\'accélération matérielle lorsqu\'elle est disponible.', 'settings.bufferSize' => 'Taille du Buffer', 'settings.bufferSizeMB' => ({required Object size}) => '${size}MB', + 'settings.bufferSizeAuto' => 'Auto (Recommandé)', + 'settings.bufferSizeWarning' => ({required Object heap, required Object size}) => 'Votre appareil dispose de ${heap}MB de mémoire. Un tampon de ${size}MB peut causer des problèmes de lecture.', 'settings.subtitleStyling' => 'Stylisation des sous-titres', 'settings.subtitleStylingDescription' => 'Personnaliser l\'apparence des sous-titres', 'settings.smallSkipDuration' => 'Small Skip Duration', @@ -1811,10 +1815,10 @@ extension on TranslationsFr { 'liveTv.reloadGuide' => 'Recharger le guide', 'liveTv.guideReloaded' => 'Données du guide rechargées', 'liveTv.allChannels' => 'Toutes les chaînes', - 'liveTv.now' => 'Maintenant', - 'liveTv.today' => 'Aujourd\'hui', _ => null, } ?? switch (path) { + 'liveTv.now' => 'Maintenant', + 'liveTv.today' => 'Aujourd\'hui', 'liveTv.midnight' => 'Minuit', 'liveTv.overnight' => 'Nuit', 'liveTv.morning' => 'Matin', diff --git a/lib/i18n/strings_it.g.dart b/lib/i18n/strings_it.g.dart index 3f5022c3..c308a2f6 100644 --- a/lib/i18n/strings_it.g.dart +++ b/lib/i18n/strings_it.g.dart @@ -245,6 +245,8 @@ class _TranslationsSettingsIt implements TranslationsSettingsEn { @override String get hardwareDecodingDescription => 'Utilizza l\'accelerazione hardware quando disponibile'; @override String get bufferSize => 'Dimensione buffer'; @override String bufferSizeMB({required Object size}) => '${size}MB'; + @override String get bufferSizeAuto => 'Auto (Consigliato)'; + @override String bufferSizeWarning({required Object heap, required Object size}) => 'Il tuo dispositivo ha ${heap}MB di memoria. Un buffer di ${size}MB potrebbe causare problemi di riproduzione.'; @override String get subtitleStyling => 'Stile sottotitoli'; @override String get subtitleStylingDescription => 'Personalizza l\'aspetto dei sottotitoli'; @override String get smallSkipDuration => 'Durata skip breve'; @@ -1417,6 +1419,8 @@ extension on TranslationsIt { 'settings.hardwareDecodingDescription' => 'Utilizza l\'accelerazione hardware quando disponibile', 'settings.bufferSize' => 'Dimensione buffer', 'settings.bufferSizeMB' => ({required Object size}) => '${size}MB', + 'settings.bufferSizeAuto' => 'Auto (Consigliato)', + 'settings.bufferSizeWarning' => ({required Object heap, required Object size}) => 'Il tuo dispositivo ha ${heap}MB di memoria. Un buffer di ${size}MB potrebbe causare problemi di riproduzione.', 'settings.subtitleStyling' => 'Stile sottotitoli', 'settings.subtitleStylingDescription' => 'Personalizza l\'aspetto dei sottotitoli', 'settings.smallSkipDuration' => 'Durata skip breve', @@ -1811,10 +1815,10 @@ extension on TranslationsIt { 'liveTv.reloadGuide' => 'Ricarica guida', 'liveTv.guideReloaded' => 'Dati della guida ricaricati', 'liveTv.allChannels' => 'Tutti i canali', - 'liveTv.now' => 'Ora', - 'liveTv.today' => 'Oggi', _ => null, } ?? switch (path) { + 'liveTv.now' => 'Ora', + 'liveTv.today' => 'Oggi', 'liveTv.midnight' => 'Mezzanotte', 'liveTv.overnight' => 'Notte', 'liveTv.morning' => 'Mattina', diff --git a/lib/i18n/strings_ko.g.dart b/lib/i18n/strings_ko.g.dart index 9bb6d101..ee8f53ac 100644 --- a/lib/i18n/strings_ko.g.dart +++ b/lib/i18n/strings_ko.g.dart @@ -245,6 +245,8 @@ class _TranslationsSettingsKo implements TranslationsSettingsEn { @override String get hardwareDecodingDescription => '가능한 경우 하드웨어 가속을 사용합니다'; @override String get bufferSize => '버퍼 크기'; @override String bufferSizeMB({required Object size}) => '${size}MB'; + @override String get bufferSizeAuto => '자동 (권장)'; + @override String bufferSizeWarning({required Object heap, required Object size}) => '기기 메모리가 ${heap}MB입니다. ${size}MB 버퍼는 재생 문제를 일으킬 수 있습니다.'; @override String get subtitleStyling => '자막 스타일'; @override String get subtitleStylingDescription => '자막의 외형을 사용자 설정'; @override String get smallSkipDuration => '짧은 건너뛰기 시간'; @@ -1417,6 +1419,8 @@ extension on TranslationsKo { 'settings.hardwareDecodingDescription' => '가능한 경우 하드웨어 가속을 사용합니다', 'settings.bufferSize' => '버퍼 크기', 'settings.bufferSizeMB' => ({required Object size}) => '${size}MB', + 'settings.bufferSizeAuto' => '자동 (권장)', + 'settings.bufferSizeWarning' => ({required Object heap, required Object size}) => '기기 메모리가 ${heap}MB입니다. ${size}MB 버퍼는 재생 문제를 일으킬 수 있습니다.', 'settings.subtitleStyling' => '자막 스타일', 'settings.subtitleStylingDescription' => '자막의 외형을 사용자 설정', 'settings.smallSkipDuration' => '짧은 건너뛰기 시간', @@ -1811,10 +1815,10 @@ extension on TranslationsKo { 'liveTv.reloadGuide' => '편성표 새로고침', 'liveTv.guideReloaded' => '편성표 데이터가 새로고침되었습니다', 'liveTv.allChannels' => '전체 채널', - 'liveTv.now' => '지금', - 'liveTv.today' => '오늘', _ => null, } ?? switch (path) { + 'liveTv.now' => '지금', + 'liveTv.today' => '오늘', 'liveTv.midnight' => '자정', 'liveTv.overnight' => '심야', 'liveTv.morning' => '아침', diff --git a/lib/i18n/strings_nl.g.dart b/lib/i18n/strings_nl.g.dart index 04f62f64..26b3a9e1 100644 --- a/lib/i18n/strings_nl.g.dart +++ b/lib/i18n/strings_nl.g.dart @@ -245,6 +245,8 @@ class _TranslationsSettingsNl implements TranslationsSettingsEn { @override String get hardwareDecodingDescription => 'Gebruik hardware versnelling indien beschikbaar'; @override String get bufferSize => 'Buffer grootte'; @override String bufferSizeMB({required Object size}) => '${size}MB'; + @override String get bufferSizeAuto => 'Auto (Aanbevolen)'; + @override String bufferSizeWarning({required Object heap, required Object size}) => 'Je apparaat heeft ${heap}MB geheugen. Een buffer van ${size}MB kan afspeelproblemen veroorzaken.'; @override String get subtitleStyling => 'Ondertitel opmaak'; @override String get subtitleStylingDescription => 'Pas ondertitel uiterlijk aan'; @override String get smallSkipDuration => 'Korte skip duur'; @@ -1417,6 +1419,8 @@ extension on TranslationsNl { 'settings.hardwareDecodingDescription' => 'Gebruik hardware versnelling indien beschikbaar', 'settings.bufferSize' => 'Buffer grootte', 'settings.bufferSizeMB' => ({required Object size}) => '${size}MB', + 'settings.bufferSizeAuto' => 'Auto (Aanbevolen)', + 'settings.bufferSizeWarning' => ({required Object heap, required Object size}) => 'Je apparaat heeft ${heap}MB geheugen. Een buffer van ${size}MB kan afspeelproblemen veroorzaken.', 'settings.subtitleStyling' => 'Ondertitel opmaak', 'settings.subtitleStylingDescription' => 'Pas ondertitel uiterlijk aan', 'settings.smallSkipDuration' => 'Korte skip duur', @@ -1811,10 +1815,10 @@ extension on TranslationsNl { 'liveTv.reloadGuide' => 'Gids herladen', 'liveTv.guideReloaded' => 'Gidsgegevens herladen', 'liveTv.allChannels' => 'Alle zenders', - 'liveTv.now' => 'Nu', - 'liveTv.today' => 'Vandaag', _ => null, } ?? switch (path) { + 'liveTv.now' => 'Nu', + 'liveTv.today' => 'Vandaag', 'liveTv.midnight' => 'Middernacht', 'liveTv.overnight' => 'Nacht', 'liveTv.morning' => 'Ochtend', diff --git a/lib/i18n/strings_sv.g.dart b/lib/i18n/strings_sv.g.dart index 99cdb232..6b7268ef 100644 --- a/lib/i18n/strings_sv.g.dart +++ b/lib/i18n/strings_sv.g.dart @@ -245,6 +245,8 @@ class _TranslationsSettingsSv implements TranslationsSettingsEn { @override String get hardwareDecodingDescription => 'Använd hårdvaruacceleration när tillgängligt'; @override String get bufferSize => 'Bufferstorlek'; @override String bufferSizeMB({required Object size}) => '${size}MB'; + @override String get bufferSizeAuto => 'Auto (Rekommenderat)'; + @override String bufferSizeWarning({required Object heap, required Object size}) => 'Din enhet har ${heap}MB minne. En buffert på ${size}MB kan orsaka uppspelningsproblem.'; @override String get subtitleStyling => 'Undertext-styling'; @override String get subtitleStylingDescription => 'Anpassa undertextutseende'; @override String get smallSkipDuration => 'Kort hoppvaraktighet'; @@ -1417,6 +1419,8 @@ extension on TranslationsSv { 'settings.hardwareDecodingDescription' => 'Använd hårdvaruacceleration när tillgängligt', 'settings.bufferSize' => 'Bufferstorlek', 'settings.bufferSizeMB' => ({required Object size}) => '${size}MB', + 'settings.bufferSizeAuto' => 'Auto (Rekommenderat)', + 'settings.bufferSizeWarning' => ({required Object heap, required Object size}) => 'Din enhet har ${heap}MB minne. En buffert på ${size}MB kan orsaka uppspelningsproblem.', 'settings.subtitleStyling' => 'Undertext-styling', 'settings.subtitleStylingDescription' => 'Anpassa undertextutseende', 'settings.smallSkipDuration' => 'Kort hoppvaraktighet', @@ -1811,10 +1815,10 @@ extension on TranslationsSv { 'liveTv.reloadGuide' => 'Ladda om programguide', 'liveTv.guideReloaded' => 'Programdata omladdad', 'liveTv.allChannels' => 'Alla kanaler', - 'liveTv.now' => 'Nu', - 'liveTv.today' => 'Idag', _ => null, } ?? switch (path) { + 'liveTv.now' => 'Nu', + 'liveTv.today' => 'Idag', 'liveTv.midnight' => 'Midnatt', 'liveTv.overnight' => 'Natt', 'liveTv.morning' => 'Morgon', diff --git a/lib/i18n/strings_zh.g.dart b/lib/i18n/strings_zh.g.dart index 6f3f1aa2..ee53097e 100644 --- a/lib/i18n/strings_zh.g.dart +++ b/lib/i18n/strings_zh.g.dart @@ -245,6 +245,8 @@ class _TranslationsSettingsZh implements TranslationsSettingsEn { @override String get hardwareDecodingDescription => '如果可用,使用硬件加速'; @override String get bufferSize => '缓冲区大小'; @override String bufferSizeMB({required Object size}) => '${size}MB'; + @override String get bufferSizeAuto => '自动(推荐)'; + @override String bufferSizeWarning({required Object heap, required Object size}) => '您的设备有 ${heap}MB 内存。${size}MB 的缓冲区可能导致播放问题。'; @override String get subtitleStyling => '字幕样式'; @override String get subtitleStylingDescription => '调整字幕外观'; @override String get smallSkipDuration => '短跳过时长'; @@ -1417,6 +1419,8 @@ extension on TranslationsZh { 'settings.hardwareDecodingDescription' => '如果可用,使用硬件加速', 'settings.bufferSize' => '缓冲区大小', 'settings.bufferSizeMB' => ({required Object size}) => '${size}MB', + 'settings.bufferSizeAuto' => '自动(推荐)', + 'settings.bufferSizeWarning' => ({required Object heap, required Object size}) => '您的设备有 ${heap}MB 内存。${size}MB 的缓冲区可能导致播放问题。', 'settings.subtitleStyling' => '字幕样式', 'settings.subtitleStylingDescription' => '调整字幕外观', 'settings.smallSkipDuration' => '短跳过时长', @@ -1811,10 +1815,10 @@ extension on TranslationsZh { 'liveTv.reloadGuide' => '重新加载节目指南', 'liveTv.guideReloaded' => '节目指南已重新加载', 'liveTv.allChannels' => '所有频道', - 'liveTv.now' => '现在', - 'liveTv.today' => '今天', _ => null, } ?? switch (path) { + 'liveTv.now' => '现在', + 'liveTv.today' => '今天', 'liveTv.midnight' => '午夜', 'liveTv.overnight' => '凌晨', 'liveTv.morning' => '上午', diff --git a/lib/i18n/sv.i18n.json b/lib/i18n/sv.i18n.json index 31259987..82759617 100644 --- a/lib/i18n/sv.i18n.json +++ b/lib/i18n/sv.i18n.json @@ -126,6 +126,8 @@ "hardwareDecodingDescription": "Använd hårdvaruacceleration när tillgängligt", "bufferSize": "Bufferstorlek", "bufferSizeMB": "${size}MB", + "bufferSizeAuto": "Auto (Rekommenderat)", + "bufferSizeWarning": "Din enhet har ${heap}MB minne. En buffert på ${size}MB kan orsaka uppspelningsproblem.", "subtitleStyling": "Undertext-styling", "subtitleStylingDescription": "Anpassa undertextutseende", "smallSkipDuration": "Kort hoppvaraktighet", diff --git a/lib/i18n/zh.i18n.json b/lib/i18n/zh.i18n.json index 49fdc8ab..c5dcf7b5 100644 --- a/lib/i18n/zh.i18n.json +++ b/lib/i18n/zh.i18n.json @@ -126,6 +126,8 @@ "hardwareDecodingDescription": "如果可用,使用硬件加速", "bufferSize": "缓冲区大小", "bufferSizeMB": "${size}MB", + "bufferSizeAuto": "自动(推荐)", + "bufferSizeWarning": "您的设备有 ${heap}MB 内存。${size}MB 的缓冲区可能导致播放问题。", "subtitleStyling": "字幕样式", "subtitleStylingDescription": "调整字幕外观", "smallSkipDuration": "短跳过时长", diff --git a/lib/mpv/player/player_android.dart b/lib/mpv/player/player_android.dart index f0788293..98c6c269 100644 --- a/lib/mpv/player/player_android.dart +++ b/lib/mpv/player/player_android.dart @@ -235,6 +235,17 @@ class PlayerAndroid extends PlayerBase { } } + /// Get the device's large heap size in MB (Android only). + /// Returns 0 if unavailable. + static Future getHeapSize() async { + try { + final result = await _methodChannel.invokeMethod('getHeapSize'); + return result ?? 0; + } catch (e) { + return 0; + } + } + /// Get the current player type ('exoplayer' or 'mpv' if fallback is active). Future getPlayerType() async { checkDisposed(); diff --git a/lib/screens/settings/settings_screen.dart b/lib/screens/settings/settings_screen.dart index 85420123..e178786c 100644 --- a/lib/screens/settings/settings_screen.dart +++ b/lib/screens/settings/settings_screen.dart @@ -22,6 +22,7 @@ import '../../providers/settings_provider.dart'; import '../../providers/theme_provider.dart'; import '../../providers/user_profile_provider.dart'; import '../../services/keyboard_shortcuts_service.dart'; +import '../../mpv/player/player_android.dart'; import '../../services/settings_service.dart' as settings; import '../../services/update_service.dart'; import '../../utils/snackbar_helper.dart'; @@ -105,7 +106,7 @@ class _SettingsScreenState extends State with FocusableTab { bool _enableDebugLogging = false; bool _enableHardwareDecoding = true; - int _bufferSize = 128; + int _bufferSize = 0; int _seekTimeSmall = 10; int _seekTimeLarge = 30; int _sleepTimerDuration = 30; @@ -486,7 +487,7 @@ class _SettingsScreenState extends State with FocusableTab { focusNode: _focusTracker.get(_kBufferSize), leading: const AppIcon(Symbols.memory_rounded, fill: 1), title: Text(t.settings.bufferSize), - subtitle: Text(t.settings.bufferSizeMB(size: _bufferSize.toString())), + subtitle: Text(_bufferSize == 0 ? t.settings.bufferSizeAuto : t.settings.bufferSizeMB(size: _bufferSize.toString())), trailing: const AppIcon(Symbols.chevron_right_rounded, fill: 1), onTap: () => _showBufferSizeDialog(), ), @@ -1057,7 +1058,7 @@ class _SettingsScreenState extends State with FocusableTab { } void _showBufferSizeDialog() { - final options = [64, 128, 256, 512, 1024]; + final options = [0, 64, 128, 256, 512, 1024]; showDialog( context: context, @@ -1072,13 +1073,19 @@ class _SettingsScreenState extends State with FocusableTab { _bufferSize == size ? Symbols.radio_button_checked_rounded : Symbols.radio_button_unchecked_rounded, fill: 1, ), - title: Text('${size}MB'), - onTap: () { + title: Text(size == 0 ? t.settings.bufferSizeAuto : '${size}MB'), + onTap: () async { setState(() { _bufferSize = size; _settingsService.setBufferSize(size); }); Navigator.pop(context); + if (Platform.isAndroid && size > 0) { + final heapMB = await PlayerAndroid.getHeapSize(); + if (heapMB > 0 && size > heapMB ~/ 4 && mounted) { + showAppSnackBar(this.context, t.settings.bufferSizeWarning(heap: heapMB.toString(), size: size.toString())); + } + } }, ); }).toList(), diff --git a/lib/screens/video_player_screen.dart b/lib/screens/video_player_screen.dart index dd2bad11..9ee691dc 100644 --- a/lib/screens/video_player_screen.dart +++ b/lib/screens/video_player_screen.dart @@ -380,7 +380,6 @@ class VideoPlayerScreenState extends State with WidgetsBindin // Load buffer size from settings final settingsService = await SettingsService.getInstance(); final bufferSizeMB = settingsService.getBufferSize(); - final bufferSizeBytes = bufferSizeMB * 1024 * 1024; final enableHardwareDecoding = settingsService.getEnableHardwareDecoding(); final debugLoggingEnabled = settingsService.getEnableDebugLogging(); final useExoPlayer = settingsService.getUseExoPlayer(); @@ -389,7 +388,10 @@ class VideoPlayerScreenState extends State with WidgetsBindin player = Player(useExoPlayer: useExoPlayer); await player!.setProperty('sub-ass', 'yes'); // Enable libass - await player!.setProperty('demuxer-max-bytes', bufferSizeBytes.toString()); + if (bufferSizeMB > 0) { + final bufferSizeBytes = bufferSizeMB * 1024 * 1024; + await player!.setProperty('demuxer-max-bytes', bufferSizeBytes.toString()); + } await player!.setProperty('msg-level', debugLoggingEnabled ? 'all=debug' : 'all=error'); await player!.setLogLevel(debugLoggingEnabled ? 'v' : 'warn'); await player!.setProperty('hwdec', _getHwdecValue(enableHardwareDecoding)); diff --git a/lib/services/settings_service.dart b/lib/services/settings_service.dart index 16f5671f..c12c0199 100644 --- a/lib/services/settings_service.dart +++ b/lib/services/settings_service.dart @@ -20,6 +20,7 @@ class SettingsService extends BaseSharedPreferencesService { static const String _keyThemeMode = 'theme_mode'; static const String _keyEnableDebugLogging = 'enable_debug_logging'; static const String _keyBufferSize = 'buffer_size'; + static const String _keyBufferSizeMigratedToAuto = 'buffer_size_migrated_to_auto'; static const String _keyKeyboardShortcuts = 'keyboard_shortcuts'; static const String _keyKeyboardHotkeys = 'keyboard_hotkeys'; static const String _keyEnableHardwareDecoding = 'enable_hardware_decoding'; @@ -121,7 +122,14 @@ class SettingsService extends BaseSharedPreferencesService { } int getBufferSize() { - return prefs.getInt(_keyBufferSize) ?? 128; // Default 128MB + // One-time migration: reset existing users to Auto. + // SharedPreferences updates in-memory cache synchronously, so the + // unawaited disk-flush futures are safe here (idempotent if re-run). + if (prefs.getBool(_keyBufferSizeMigratedToAuto) != true) { + prefs.remove(_keyBufferSize); + prefs.setBool(_keyBufferSizeMigratedToAuto, true); + } + return prefs.getInt(_keyBufferSize) ?? 0; // 0 = Auto } // Hardware Decoding @@ -1182,6 +1190,7 @@ class SettingsService extends BaseSharedPreferencesService { prefs.remove(_keyCustomExternalPlayers), prefs.remove(_keyConfirmExitOnBack), prefs.remove(_keyAmbientLighting), + prefs.remove(_keyBufferSizeMigratedToAuto), ]); }