Liu Song’s Projects


~/Projects/tvbox

git clone https://code.lsong.org/tvbox

Commit

Commit
ae35ea1efc1be03c631afd2a3b97a74951eb4588
Author
FongMi <[email protected]>
Date
2023-10-11 17:05:37 +0800 +0800
Diffstat
 app/src/leanback/java/com/fongmi/android/tv/ui/activity/SettingPlayerActivity.java | 16 
 app/src/leanback/java/com/fongmi/android/tv/ui/custom/dialog/BufferDialog.java | 66 
 app/src/leanback/res/layout/activity_setting_player.xml | 38 
 app/src/leanback/res/layout/dialog_buffer.xml | 58 
 app/src/main/java/com/fongmi/android/tv/Setting.java | 9 
 app/src/main/java/com/fongmi/android/tv/impl/BufferCallback.java | 6 
 app/src/main/java/com/fongmi/android/tv/player/ExoUtil.java | 2 
 app/src/main/res/values-zh-rCN/strings.xml | 2 
 app/src/main/res/values-zh-rTW/strings.xml | 2 
 app/src/main/res/values/strings.xml | 2 
 app/src/mobile/java/com/fongmi/android/tv/ui/custom/dialog/BufferDialog.java | 55 
 app/src/mobile/java/com/fongmi/android/tv/ui/fragment/SettingPlayerFragment.java | 16 
 app/src/mobile/res/layout/dialog_buffer.xml | 20 
 app/src/mobile/res/layout/fragment_setting_player.xml | 36 

Add buffer setting


diff --git a/app/src/leanback/java/com/fongmi/android/tv/ui/activity/SettingPlayerActivity.java b/app/src/leanback/java/com/fongmi/android/tv/ui/activity/SettingPlayerActivity.java
index 3834083dea875c60eff70af9ebfb993982834346..0ce66780a343f67c45c383be9d5724628c72bf2b 100644
--- a/app/src/leanback/java/com/fongmi/android/tv/ui/activity/SettingPlayerActivity.java
+++ b/app/src/leanback/java/com/fongmi/android/tv/ui/activity/SettingPlayerActivity.java
@@ -9,16 +9,18 @@
 import com.fongmi.android.tv.R;
 import com.fongmi.android.tv.Setting;
 import com.fongmi.android.tv.databinding.ActivitySettingPlayerBinding;
+import com.fongmi.android.tv.impl.BufferCallback;
 import com.fongmi.android.tv.impl.SubtitleCallback;
 import com.fongmi.android.tv.impl.UaCallback;
 import com.fongmi.android.tv.player.ExoUtil;
 import com.fongmi.android.tv.player.Players;
 import com.fongmi.android.tv.ui.base.BaseActivity;
+import com.fongmi.android.tv.ui.custom.dialog.BufferDialog;
 import com.fongmi.android.tv.ui.custom.dialog.SubtitleDialog;
 import com.fongmi.android.tv.ui.custom.dialog.UaDialog;
 import com.fongmi.android.tv.utils.ResUtil;
 
-public class SettingPlayerActivity extends BaseActivity implements UaCallback, SubtitleCallback {
+public class SettingPlayerActivity extends BaseActivity implements UaCallback, BufferCallback, SubtitleCallback {
 
     private ActivitySettingPlayerBinding mBinding;
     private String[] http;
@@ -41,8 +43,10 @@     @Override
     protected void initView() {
         mBinding.uaText.setText(Setting.getUa());
         mBinding.tunnelText.setText(getSwitch(Setting.isTunnel()));
+        mBinding.bufferText.setText(String.valueOf(Setting.getBuffer()));
         mBinding.subtitleText.setText(String.valueOf(Setting.getSubtitle()));
         mBinding.http.setVisibility(Players.isExo(Setting.getPlayer()) ? View.VISIBLE : View.GONE);
+        mBinding.buffer.setVisibility(Players.isExo(Setting.getPlayer()) ? View.VISIBLE : View.GONE);
         mBinding.tunnel.setVisibility(Players.isExo(Setting.getPlayer()) ? View.VISIBLE : View.GONE);
         mBinding.flagText.setText((flag = ResUtil.getStringArray(R.array.select_flag))[Setting.getFlag()]);
         mBinding.httpText.setText((http = ResUtil.getStringArray(R.array.select_exo_http))[Setting.getHttp()]);
@@ -53,6 +57,7 @@     protected void initEvent() {
         mBinding.ua.setOnClickListener(this::onUa);
         mBinding.http.setOnClickListener(this::setHttp);
         mBinding.flag.setOnClickListener(this::setFlag);
+        mBinding.buffer.setOnClickListener(this::onBuffer);
         mBinding.tunnel.setOnClickListener(this::setTunnel);
         mBinding.subtitle.setOnClickListener(this::onSubtitle);
     }
@@ -79,6 +84,10 @@         Setting.putTunnel(!Setting.isTunnel());
         mBinding.tunnelText.setText(getSwitch(Setting.isTunnel()));
     }
 
+    private void onBuffer(View view) {
+        BufferDialog.create(this).show();
+    }
+
     private void onSubtitle(View view) {
         SubtitleDialog.create(this).show();
     }
@@ -87,6 +96,11 @@     @Override
     public void setUa(String ua) {
         mBinding.uaText.setText(ua);
         Setting.putUa(ua);
+    }
+
+    @Override
+    public void setBuffer(int minute) {
+        mBinding.bufferText.setText(String.valueOf(minute));
     }
 
     @Override




diff --git a/app/src/leanback/java/com/fongmi/android/tv/ui/custom/dialog/BufferDialog.java b/app/src/leanback/java/com/fongmi/android/tv/ui/custom/dialog/BufferDialog.java
new file mode 100644
index 0000000000000000000000000000000000000000..1070124bb73b89576f58c1e894669d1e5df082e5
--- /dev/null
+++ b/app/src/leanback/java/com/fongmi/android/tv/ui/custom/dialog/BufferDialog.java
@@ -0,0 +1,66 @@
+package com.fongmi.android.tv.ui.custom.dialog;
+
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.WindowManager;
+
+import androidx.appcompat.app.AlertDialog;
+import androidx.fragment.app.FragmentActivity;
+
+import com.fongmi.android.tv.Setting;
+import com.fongmi.android.tv.databinding.DialogBufferBinding;
+import com.fongmi.android.tv.impl.BufferCallback;
+import com.fongmi.android.tv.utils.ResUtil;
+import com.google.android.material.dialog.MaterialAlertDialogBuilder;
+
+public class BufferDialog {
+
+    private final DialogBufferBinding binding;
+    private final BufferCallback callback;
+    private final AlertDialog dialog;
+    private int value;
+
+    public static BufferDialog create(FragmentActivity activity) {
+        return new BufferDialog(activity);
+    }
+
+    public BufferDialog(FragmentActivity activity) {
+        this.callback = (BufferCallback) activity;
+        this.binding = DialogBufferBinding.inflate(LayoutInflater.from(activity));
+        this.dialog = new MaterialAlertDialogBuilder(activity).setView(binding.getRoot()).create();
+    }
+
+    public void show() {
+        initDialog();
+        initView();
+        initEvent();
+    }
+
+    private void initDialog() {
+        WindowManager.LayoutParams params = dialog.getWindow().getAttributes();
+        params.width = (int) (ResUtil.getScreenWidth() * 0.45f);
+        dialog.getWindow().setAttributes(params);
+        dialog.getWindow().setDimAmount(0);
+        dialog.show();
+    }
+
+    private void initView() {
+        binding.slider.setValue(value = Setting.getBuffer());
+    }
+
+    private void initEvent() {
+        binding.positive.setOnClickListener(this::onPositive);
+        binding.negative.setOnClickListener(this::onNegative);
+    }
+
+    private void onPositive(View view) {
+        callback.setBuffer((int) binding.slider.getValue());
+        Setting.putBuffer((int) binding.slider.getValue());
+        dialog.dismiss();
+    }
+
+    private void onNegative(View view) {
+        callback.setBuffer(value);
+        dialog.dismiss();
+    }
+}




diff --git a/app/src/leanback/res/layout/activity_setting_player.xml b/app/src/leanback/res/layout/activity_setting_player.xml
index ebbe32e6dc3f89ee95c47c50a2a4a19fbe596f11..1bc9a07e268c10f3b187a99d681dd90c649ec456 100644
--- a/app/src/leanback/res/layout/activity_setting_player.xml
+++ b/app/src/leanback/res/layout/activity_setting_player.xml
@@ -160,5 +160,43 @@                 android:textSize="18sp"
                 tools:text="OkHttp" />
 
         </LinearLayout>
+
+        <LinearLayout
+            android:id="@+id/buffer"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:layout_marginTop="16dp"
+            android:background="@drawable/selector_item"
+            android:focusable="true"
+            android:focusableInTouchMode="true"
+            android:orientation="horizontal">
+
+            <TextView
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:layout_marginEnd="16dp"
+                android:text="@string/setting_player_buffer"
+                android:textColor="@color/white"
+                android:textSize="18sp" />
+
+            <TextView
+                android:id="@+id/bufferText"
+                android:layout_width="0dp"
+                android:layout_height="wrap_content"
+                android:layout_weight="1"
+                android:gravity="end"
+                android:textColor="@color/white"
+                android:textSize="18sp"
+                tools:text="1" />
+
+            <TextView
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:layout_marginStart="4dp"
+                android:text="@string/minute"
+                android:textColor="@color/white"
+                android:textSize="18sp" />
+
+        </LinearLayout>
     </LinearLayout>
 </androidx.core.widget.NestedScrollView>
\ No newline at end of file




diff --git a/app/src/leanback/res/layout/dialog_buffer.xml b/app/src/leanback/res/layout/dialog_buffer.xml
new file mode 100644
index 0000000000000000000000000000000000000000..d004ab7b01aa9219401e6b39e1d4adbe7b5d9fb7
--- /dev/null
+++ b/app/src/leanback/res/layout/dialog_buffer.xml
@@ -0,0 +1,58 @@
+<?xml version="1.0" encoding="utf-8"?>
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:app="http://schemas.android.com/apk/res-auto"
+    android:layout_width="match_parent"
+    android:layout_height="wrap_content"
+    android:orientation="vertical"
+    android:padding="16dp">
+
+    <com.google.android.material.slider.Slider
+        android:id="@+id/slider"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:layout_marginTop="16dp"
+        android:nextFocusDown="@id/positive"
+        android:stepSize="1"
+        android:valueFrom="1"
+        android:valueTo="120"
+        app:thumbColor="@color/blue_500"
+        app:trackColorActive="@color/blue_500"
+        app:trackColorInactive="@color/blue_50" />
+
+    <LinearLayout
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:layout_marginTop="8dp"
+        android:orientation="horizontal">
+
+        <TextView
+            android:id="@+id/positive"
+            android:layout_width="0dp"
+            android:layout_height="wrap_content"
+            android:layout_marginEnd="16dp"
+            android:layout_weight="1"
+            android:background="@drawable/selector_text"
+            android:focusable="true"
+            android:focusableInTouchMode="true"
+            android:gravity="center"
+            android:singleLine="true"
+            android:text="@string/dialog_positive"
+            android:textColor="@color/white"
+            android:textSize="14sp" />
+
+        <TextView
+            android:id="@+id/negative"
+            android:layout_width="0dp"
+            android:layout_height="wrap_content"
+            android:layout_weight="1"
+            android:background="@drawable/selector_text"
+            android:focusable="true"
+            android:focusableInTouchMode="true"
+            android:gravity="center"
+            android:singleLine="true"
+            android:text="@string/dialog_negative"
+            android:textColor="@color/white"
+            android:textSize="14sp" />
+
+    </LinearLayout>
+</LinearLayout>
\ No newline at end of file




diff --git a/app/src/main/java/com/fongmi/android/tv/Setting.java b/app/src/main/java/com/fongmi/android/tv/Setting.java
index 8bfe3c2ef58974b18e943a6a8f2f404e0cb77e49..7a1465b517652140cfdc3a8653b94393bbf36200 100644
--- a/app/src/main/java/com/fongmi/android/tv/Setting.java
+++ b/app/src/main/java/com/fongmi/android/tv/Setting.java
@@ -215,6 +215,15 @@         Prefers.put("exo_http", http);
     }
 
 package com.fongmi.android.tv;
+        return Prefers.getInt("player_live", getPlayer());
+        return Math.max(Prefers.getInt("exo_buffer"), 1);
+    }
+
+    public static void putBuffer(int buffer) {
+        Prefers.put("exo_buffer", buffer);
+    }
+
+package com.fongmi.android.tv;
     public static String getProxy() {
         return Prefers.getInt("flag");
     }




diff --git a/app/src/main/java/com/fongmi/android/tv/impl/BufferCallback.java b/app/src/main/java/com/fongmi/android/tv/impl/BufferCallback.java
new file mode 100644
index 0000000000000000000000000000000000000000..b3300dae4fc2dd9ea21de0b2fc4661ccd98d3815
--- /dev/null
+++ b/app/src/main/java/com/fongmi/android/tv/impl/BufferCallback.java
@@ -0,0 +1,6 @@
+package com.fongmi.android.tv.impl;
+
+public interface BufferCallback {
+
+    void setBuffer(int minute);
+}




diff --git a/app/src/main/java/com/fongmi/android/tv/player/ExoUtil.java b/app/src/main/java/com/fongmi/android/tv/player/ExoUtil.java
index 5427276cb2c775bbca43924269c07ebde21082da..081162abb0a183b590144543a874d9f7692b97c4 100644
--- a/app/src/main/java/com/fongmi/android/tv/player/ExoUtil.java
+++ b/app/src/main/java/com/fongmi/android/tv/player/ExoUtil.java
@@ -63,7 +63,7 @@     private static DatabaseProvider database;
     private static Cache cache;
 
     public static LoadControl buildLoadControl() {
-        return new DefaultLoadControl();
+        return new DefaultLoadControl.Builder().setBufferDurationsMs(DefaultLoadControl.DEFAULT_MIN_BUFFER_MS, Setting.getBuffer() * 60 * 1000, DefaultLoadControl.DEFAULT_BUFFER_FOR_PLAYBACK_MS, DefaultLoadControl.DEFAULT_BUFFER_FOR_PLAYBACK_AFTER_REBUFFER_MS).build();
     }
 
     public static TrackSelector buildTrackSelector() {




diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index 0485c7a63fcf35cf439c3f67de3f68868a284221..151ade4952d1077180c62ef0dc713bdaa257baa6 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -69,6 +69,7 @@     Player
     <string name="setting_player_ua">User-Agent</string>
     <string name="setting_player_flag">Flag play</string>
     <string name="setting_player_http">HTTP method</string>
+    <string name="setting_player_buffer">Buffer time</string>
     <string name="setting_player_tunnel">Tunnel mode</string>
     <string name="setting_player_subtitle">Subtitle size</string>
     <string name="setting_player_background">Background play</string>
@@ -123,6 +124,7 @@     Close
 
     <!-- UNIT -->
     <string name="all">All</string>
+    <string name="minute">min</string>
 
     <string-array name="select_decode">
         <item>Soft</item>




diff --git a/app/src/main/res/values-zh-rCN/strings.xml b/app/src/main/res/values-zh-rCN/strings.xml
index 054cbb3be7c35856c514fe59854f947a6e5263d5..ff654368c2b20399598d9ca554699146623bf480 100644
--- a/app/src/main/res/values-zh-rCN/strings.xml
+++ b/app/src/main/res/values-zh-rCN/strings.xml
@@ -69,6 +69,7 @@     播放器
     <string name="setting_player_ua">User-Agent</string>
     <string name="setting_player_flag">线路播放</string>
     <string name="setting_player_http">连线方式</string>
+    <string name="setting_player_buffer">缓冲时间</string>
     <string name="setting_player_tunnel">隧道模式</string>
     <string name="setting_player_subtitle">字幕大小</string>
     <string name="setting_player_background">后台播放</string>
@@ -123,6 +124,7 @@     关闭
 
     <!-- UNIT -->
     <string name="all">全部</string>
+    <string name="minute">分钟</string>
 
     <string-array name="select_decode">
         <item>软解</item>




diff --git a/app/src/main/res/values-zh-rTW/strings.xml b/app/src/main/res/values-zh-rTW/strings.xml
index 6d4a4063ab203a6d07e9fd7aeee4cffaea704adf..11e61bc0ef79db6755e2fbe3f68bc59d253137b0 100644
--- a/app/src/main/res/values-zh-rTW/strings.xml
+++ b/app/src/main/res/values-zh-rTW/strings.xml
@@ -69,6 +69,7 @@     播放器
     <string name="setting_player_ua">User-Agent</string>
     <string name="setting_player_flag">線路播放</string>
     <string name="setting_player_http">連線方式</string>
+    <string name="setting_player_buffer">緩衝時間</string>
     <string name="setting_player_tunnel">隧道模式</string>
     <string name="setting_player_subtitle">字幕大小</string>
     <string name="setting_player_background">背景播放</string>
@@ -123,6 +124,7 @@     關閉
 
     <!-- UNIT -->
     <string name="all">全部</string>
+    <string name="minute">分鐘</string>
 
     <string-array name="select_decode">
         <item>軟解</item>




diff --git a/app/src/mobile/java/com/fongmi/android/tv/ui/custom/dialog/BufferDialog.java b/app/src/mobile/java/com/fongmi/android/tv/ui/custom/dialog/BufferDialog.java
new file mode 100644
index 0000000000000000000000000000000000000000..c9865f793d74f857e5ee089e2bd76ff7cc483f2a
--- /dev/null
+++ b/app/src/mobile/java/com/fongmi/android/tv/ui/custom/dialog/BufferDialog.java
@@ -0,0 +1,55 @@
+package com.fongmi.android.tv.ui.custom.dialog;
+
+import android.content.DialogInterface;
+import android.view.LayoutInflater;
+
+import androidx.appcompat.app.AlertDialog;
+import androidx.fragment.app.Fragment;
+
+import com.fongmi.android.tv.R;
+import com.fongmi.android.tv.Setting;
+import com.fongmi.android.tv.databinding.DialogBufferBinding;
+import com.fongmi.android.tv.impl.BufferCallback;
+import com.google.android.material.dialog.MaterialAlertDialogBuilder;
+
+public class BufferDialog {
+
+    private final DialogBufferBinding binding;
+    private final BufferCallback callback;
+    private int value;
+
+    public static BufferDialog create(Fragment fragment) {
+        return new BufferDialog(fragment);
+    }
+
+    public BufferDialog(Fragment fragment) {
+        this.callback = (BufferCallback) fragment;
+        this.binding = DialogBufferBinding.inflate(LayoutInflater.from(fragment.getContext()));
+    }
+
+    public void show() {
+        initDialog();
+        initView();
+    }
+
+    private void initDialog() {
+        AlertDialog dialog = new MaterialAlertDialogBuilder(binding.getRoot().getContext()).setTitle(R.string.setting_player_buffer).setView(binding.getRoot()).setPositiveButton(R.string.dialog_positive, this::onPositive).setNegativeButton(R.string.dialog_negative, this::onNegative).create();
+        dialog.getWindow().setDimAmount(0);
+        dialog.show();
+    }
+
+    private void initView() {
+        binding.slider.setValue(value = Setting.getBuffer());
+    }
+
+    private void onPositive(DialogInterface dialog, int which) {
+        callback.setBuffer((int) binding.slider.getValue());
+        Setting.putBuffer((int) binding.slider.getValue());
+        dialog.dismiss();
+    }
+
+    private void onNegative(DialogInterface dialog, int which) {
+        callback.setBuffer(value);
+        dialog.dismiss();
+    }
+}




diff --git a/app/src/mobile/java/com/fongmi/android/tv/ui/fragment/SettingPlayerFragment.java b/app/src/mobile/java/com/fongmi/android/tv/ui/fragment/SettingPlayerFragment.java
index 21fb005f6673bd5dc9bfd9eb5c9b6d662ccde3ac..4fe6d128dfb85623ec607ee8279060451f3e3e12 100644
--- a/app/src/mobile/java/com/fongmi/android/tv/ui/fragment/SettingPlayerFragment.java
+++ b/app/src/mobile/java/com/fongmi/android/tv/ui/fragment/SettingPlayerFragment.java
@@ -11,17 +11,19 @@
 import com.fongmi.android.tv.R;
 import com.fongmi.android.tv.Setting;
 import com.fongmi.android.tv.databinding.FragmentSettingPlayerBinding;
+import com.fongmi.android.tv.impl.BufferCallback;
 import com.fongmi.android.tv.impl.SubtitleCallback;
 import com.fongmi.android.tv.impl.UaCallback;
 import com.fongmi.android.tv.player.ExoUtil;
 import com.fongmi.android.tv.player.Players;
 import com.fongmi.android.tv.ui.base.BaseFragment;
+import com.fongmi.android.tv.ui.custom.dialog.BufferDialog;
 import com.fongmi.android.tv.ui.custom.dialog.SubtitleDialog;
 import com.fongmi.android.tv.ui.custom.dialog.UaDialog;
 import com.fongmi.android.tv.utils.ResUtil;
 import com.google.android.material.dialog.MaterialAlertDialogBuilder;
 
-public class SettingPlayerFragment extends BaseFragment implements UaCallback, SubtitleCallback {
+public class SettingPlayerFragment extends BaseFragment implements UaCallback, BufferCallback, SubtitleCallback {
 
     private FragmentSettingPlayerBinding mBinding;
     private String[] background;
@@ -45,6 +47,7 @@     @Override
     protected void initView() {
         mBinding.uaText.setText(Setting.getUa());
         mBinding.tunnelText.setText(getSwitch(Setting.isTunnel()));
+        mBinding.bufferText.setText(String.valueOf(Setting.getBuffer()));
         mBinding.subtitleText.setText(String.valueOf(Setting.getSubtitle()));
         mBinding.flagText.setText((flag = ResUtil.getStringArray(R.array.select_flag))[Setting.getFlag()]);
         mBinding.httpText.setText((http = ResUtil.getStringArray(R.array.select_exo_http))[Setting.getHttp()]);
@@ -57,6 +60,7 @@     protected void initEvent() {
         mBinding.ua.setOnClickListener(this::onUa);
         mBinding.http.setOnClickListener(this::setHttp);
         mBinding.flag.setOnClickListener(this::setFlag);
+        mBinding.buffer.setOnClickListener(this::onBuffer);
         mBinding.tunnel.setOnClickListener(this::setTunnel);
         mBinding.subtitle.setOnClickListener(this::onSubtitle);
         mBinding.background.setOnClickListener(this::setBackground);
@@ -64,6 +68,7 @@     }
 
     private void setVisible() {
         mBinding.http.setVisibility(Players.isExo(Setting.getPlayer()) ? View.VISIBLE : View.GONE);
+        mBinding.buffer.setVisibility(Players.isExo(Setting.getPlayer()) ? View.VISIBLE : View.GONE);
         mBinding.tunnel.setVisibility(Players.isExo(Setting.getPlayer()) ? View.VISIBLE : View.GONE);
     }
 
@@ -89,6 +94,10 @@         Setting.putTunnel(!Setting.isTunnel());
         mBinding.tunnelText.setText(getSwitch(Setting.isTunnel()));
     }
 
+    private void onBuffer(View view) {
+        BufferDialog.create(this).show();
+    }
+
     private void onSubtitle(View view) {
         SubtitleDialog.create(this).show();
     }
@@ -105,6 +114,11 @@     @Override
     public void setUa(String ua) {
         mBinding.uaText.setText(ua);
         Setting.putUa(ua);
+    }
+
+    @Override
+    public void setBuffer(int minute) {
+        mBinding.bufferText.setText(String.valueOf(minute));
     }
 
     @Override




diff --git a/app/src/mobile/res/layout/dialog_buffer.xml b/app/src/mobile/res/layout/dialog_buffer.xml
new file mode 100644
index 0000000000000000000000000000000000000000..8d1da7e5409c67d8c7808fd07e05888e51b80a0e
--- /dev/null
+++ b/app/src/mobile/res/layout/dialog_buffer.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="utf-8"?>
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:app="http://schemas.android.com/apk/res-auto"
+    android:layout_width="match_parent"
+    android:layout_height="wrap_content"
+    android:orientation="vertical"
+    android:paddingStart="24dp"
+    android:paddingTop="16dp"
+    android:paddingEnd="24dp">
+
+    <com.google.android.material.slider.Slider
+        android:id="@+id/slider"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:stepSize="1"
+        android:valueFrom="1"
+        android:valueTo="120"
+        app:trackColorInactive="@color/blue_50" />
+
+</LinearLayout>
\ No newline at end of file




diff --git a/app/src/mobile/res/layout/fragment_setting_player.xml b/app/src/mobile/res/layout/fragment_setting_player.xml
index b71a8a25614a5c904170ff26de90343a74be14c7..1296fa2bb53426d73f75a7fb2de5df909a764015 100644
--- a/app/src/mobile/res/layout/fragment_setting_player.xml
+++ b/app/src/mobile/res/layout/fragment_setting_player.xml
@@ -207,6 +207,42 @@                     tools:text="OkHttp" />
 
             </LinearLayout>
 
+            <LinearLayout
+                android:id="@+id/buffer"
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:layout_marginTop="16dp"
+                android:background="@drawable/shape_item"
+                android:orientation="horizontal">
+
+                <TextView
+                    android:layout_width="wrap_content"
+                    android:layout_height="wrap_content"
+                    android:layout_marginEnd="16dp"
+                    android:text="@string/setting_player_buffer"
+                    android:textColor="@color/white"
+                    android:textSize="16sp" />
+
+                <TextView
+                    android:id="@+id/bufferText"
+                    android:layout_width="0dp"
+                    android:layout_height="wrap_content"
+                    android:layout_weight="1"
+                    android:gravity="end"
+                    android:textColor="@color/white"
+                    android:textSize="16sp"
+                    tools:text="1" />
+
+                <TextView
+                    android:layout_width="wrap_content"
+                    android:layout_height="wrap_content"
+                    android:layout_marginStart="4dp"
+                    android:text="@string/minute"
+                    android:textColor="@color/white"
+                    android:textSize="16sp" />
+
+            </LinearLayout>
+
         android:layout_width="match_parent"
     </androidx.core.widget.NestedScrollView>
 </androidx.coordinatorlayout.widget.CoordinatorLayout>
\ No newline at end of file