fix(android): auto buffer size to prevent OOM
This commit is contained in:
@@ -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()
|
||||
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -126,6 +126,8 @@
|
||||
"hardwareDecodingDescription": "가능한 경우 하드웨어 가속을 사용합니다",
|
||||
"bufferSize": "버퍼 크기",
|
||||
"bufferSizeMB": "${size}MB",
|
||||
"bufferSizeAuto": "자동 (권장)",
|
||||
"bufferSizeWarning": "기기 메모리가 ${heap}MB입니다. ${size}MB 버퍼는 재생 문제를 일으킬 수 있습니다.",
|
||||
"subtitleStyling": "자막 스타일",
|
||||
"subtitleStylingDescription": "자막의 외형을 사용자 설정",
|
||||
"smallSkipDuration": "짧은 건너뛰기 시간",
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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',
|
||||
|
||||
@@ -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',
|
||||
|
||||
@@ -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',
|
||||
|
||||
@@ -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',
|
||||
|
||||
@@ -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',
|
||||
|
||||
@@ -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' => '아침',
|
||||
|
||||
@@ -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',
|
||||
|
||||
@@ -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',
|
||||
|
||||
@@ -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' => '上午',
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -126,6 +126,8 @@
|
||||
"hardwareDecodingDescription": "如果可用,使用硬件加速",
|
||||
"bufferSize": "缓冲区大小",
|
||||
"bufferSizeMB": "${size}MB",
|
||||
"bufferSizeAuto": "自动(推荐)",
|
||||
"bufferSizeWarning": "您的设备有 ${heap}MB 内存。${size}MB 的缓冲区可能导致播放问题。",
|
||||
"subtitleStyling": "字幕样式",
|
||||
"subtitleStylingDescription": "调整字幕外观",
|
||||
"smallSkipDuration": "短跳过时长",
|
||||
|
||||
@@ -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<int> getHeapSize() async {
|
||||
try {
|
||||
final result = await _methodChannel.invokeMethod<int>('getHeapSize');
|
||||
return result ?? 0;
|
||||
} catch (e) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/// Get the current player type ('exoplayer' or 'mpv' if fallback is active).
|
||||
Future<String> getPlayerType() async {
|
||||
checkDisposed();
|
||||
|
||||
@@ -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<SettingsScreen> 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<SettingsScreen> 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<SettingsScreen> 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<SettingsScreen> 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(),
|
||||
|
||||
@@ -380,7 +380,6 @@ class VideoPlayerScreenState extends State<VideoPlayerScreen> 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<VideoPlayerScreen> 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));
|
||||
|
||||
@@ -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),
|
||||
]);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user