Merge pull request #423 from okcaptain/dev

Dev
pull/424/head^2
okcaptain 2 years ago committed by GitHub
commit 1f06045654
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
  1. 2
      app/build.gradle
  2. 26
      app/src/leanback/java/com/fongmi/android/tv/ui/activity/SettingActivity.java
  3. 29
      app/src/leanback/java/com/fongmi/android/tv/ui/activity/SettingCustomActivity.java
  4. 58
      app/src/leanback/res/layout/activity_setting.xml
  5. 95
      app/src/leanback/res/layout/activity_setting_custom.xml
  6. 2
      app/src/leanback/res/layout/adapter_func_horizontal.xml
  7. 9
      app/src/main/java/com/fongmi/android/tv/Setting.java
  8. 5
      app/src/main/java/com/fongmi/android/tv/player/ExoUtil.java
  9. 5
      app/src/main/java/com/fongmi/android/tv/player/IjkUtil.java
  10. 40
      app/src/main/java/com/fongmi/android/tv/utils/M3U8.java
  11. 1
      app/src/main/res/values-zh-rCN/strings.xml
  12. 3
      app/src/main/res/values-zh-rTW/strings.xml
  13. 1
      app/src/main/res/values/strings.xml
  14. 7
      app/src/mobile/java/com/fongmi/android/tv/ui/fragment/SettingCustomFragment.java
  15. 27
      app/src/mobile/res/layout/fragment_setting_custom.xml

@ -11,7 +11,7 @@ android {
minSdk 21
targetSdk 28
versionCode 233
versionName "0510"
versionName "0512"
javaCompileOptions {
annotationProcessorOptions {
arguments = ["room.schemaLocation": "$projectDir/schemas".toString()]

@ -7,9 +7,7 @@ import android.view.View;
import androidx.viewbinding.ViewBinding;
import com.fongmi.android.tv.App;
import com.fongmi.android.tv.BuildConfig;
import com.fongmi.android.tv.R;
import com.fongmi.android.tv.Setting;
import com.fongmi.android.tv.Updater;
import com.fongmi.android.tv.api.config.LiveConfig;
@ -37,12 +35,9 @@ import com.fongmi.android.tv.ui.dialog.ProxyDialog;
import com.fongmi.android.tv.ui.dialog.SiteDialog;
import com.fongmi.android.tv.utils.FileUtil;
import com.fongmi.android.tv.utils.Notify;
import com.fongmi.android.tv.utils.ResUtil;
import com.fongmi.android.tv.utils.UrlUtil;
import com.github.catvod.bean.Doh;
import com.github.catvod.net.OkHttp;
import com.github.catvod.utils.Shell;
import com.google.android.material.dialog.MaterialAlertDialogBuilder;
import com.permissionx.guolindev.PermissionX;
import java.util.ArrayList;
@ -52,7 +47,6 @@ public class SettingActivity extends BaseActivity implements ConfigCallback, Sit
private ActivitySettingBinding mBinding;
private int type;
private String[] configCache;
public static void start(Activity activity) {
activity.startActivity(new Intent(activity, SettingActivity.class));
@ -84,7 +78,6 @@ public class SettingActivity extends BaseActivity implements ConfigCallback, Sit
mBinding.versionText.setText(BuildConfig.VERSION_NAME);
mBinding.proxyText.setText(UrlUtil.scheme(Setting.getProxy()));
mBinding.aboutText.setText(BuildConfig.FLAVOR_mode + "-" + BuildConfig.FLAVOR_api + "-" + BuildConfig.FLAVOR_abi);
mBinding.configCacheText.setText((configCache = ResUtil.getStringArray(R.array.select_config_cache))[Setting.getConfigCache()]);
setCacheText();
}
@ -122,8 +115,7 @@ public class SettingActivity extends BaseActivity implements ConfigCallback, Sit
mBinding.wallRefresh.setOnClickListener(this::setWallRefresh);
mBinding.custom.setOnClickListener(this::onCustom);
mBinding.doh.setOnClickListener(this::setDoh);
mBinding.configCache.setOnClickListener(this::setConfigCache);
mBinding.reset.setOnClickListener(this::onReset);
mBinding.about.setOnClickListener(this::onAbout);
}
@Override
@ -289,20 +281,8 @@ public class SettingActivity extends BaseActivity implements ConfigCallback, Sit
SettingCustomActivity.start(this);
}
private void setConfigCache(View view) {
int index = Setting.getConfigCache();
Setting.putConfigCache(index = index == configCache.length - 1 ? 0 : ++index);
mBinding.configCacheText.setText(configCache[index]);
}
private void onReset(View view) {
new MaterialAlertDialogBuilder(this).setTitle(R.string.dialog_reset_app).setMessage(R.string.dialog_reset_app_data).setNegativeButton(R.string.dialog_negative, null).setPositiveButton(R.string.dialog_positive, (dialog, which) -> reset()).show();
}
private void reset() {
new Thread(() -> {
Shell.exec("pm clear " + App.get().getPackageName());
}).start();
private void onAbout(View view) {
mBinding.aboutText.setText(BuildConfig.FLAVOR_mode + "-" + BuildConfig.FLAVOR_api + "-" + BuildConfig.FLAVOR_abi);
}
private void setDoh(View view) {

@ -18,6 +18,8 @@ import com.fongmi.android.tv.ui.dialog.LanguageDialog;
import com.fongmi.android.tv.ui.dialog.MenuKeyDialog;
import com.fongmi.android.tv.ui.dialog.X5WebViewDialog;
import com.fongmi.android.tv.utils.ResUtil;
import com.github.catvod.utils.Shell;
import com.google.android.material.dialog.MaterialAlertDialogBuilder;
import com.tencent.smtt.sdk.QbSdk;
import java.util.Locale;
@ -31,6 +33,7 @@ public class SettingCustomActivity extends BaseActivity {
private String[] smallWindowBackKey;
private String[] homeUI;
private String[] parseWebview;
private String[] configCache;
@Override
protected ViewBinding getBinding() {
@ -60,8 +63,10 @@ public class SettingCustomActivity extends BaseActivity {
mBinding.aggregatedSearchText.setText(getSwitch(Setting.isAggregatedSearch()));
mBinding.homeUIText.setText((homeUI = ResUtil.getStringArray(R.array.select_home_ui))[Setting.getHomeUI()]);
mBinding.homeHistoryText.setText(getSwitch(Setting.isHomeHistory()));
mBinding.removeAdText.setText(getSwitch(Setting.isRemoveAd()));
mBinding.languageText.setText((ResUtil.getStringArray(R.array.select_language))[Setting.getLanguage()]);
mBinding.parseWebviewText.setText((parseWebview = ResUtil.getStringArray(R.array.select_parse_webview))[Setting.getParseWebView()]);
mBinding.configCacheText.setText((configCache = ResUtil.getStringArray(R.array.select_config_cache))[Setting.getConfigCache()]);
}
@Override
@ -81,8 +86,11 @@ public class SettingCustomActivity extends BaseActivity {
mBinding.homeUI.setOnClickListener(this::setHomeUI);
mBinding.homeButtons.setOnClickListener(this::onHomeButtons);
mBinding.homeHistory.setOnClickListener(this::setHomeHistory);
mBinding.removeAd.setOnClickListener(this::setRemoveAd);
mBinding.setLanguage.setOnClickListener(this::setLanguage);
mBinding.parseWebview.setOnClickListener(this::setParseWebview);
mBinding.configCache.setOnClickListener(this::setConfigCache);
mBinding.reset.setOnClickListener(this::onReset);
}
@ -178,6 +186,11 @@ public class SettingCustomActivity extends BaseActivity {
mBinding.homeHistoryText.setText(getSwitch(Setting.isHomeHistory()));
}
private void setRemoveAd(View view) {
Setting.putRemoveAd(!Setting.isRemoveAd());
mBinding.removeAdText.setText(getSwitch(Setting.isRemoveAd()));
}
private void setLanguage(View view) {
LanguageDialog.create(this).show();
}
@ -194,4 +207,20 @@ public class SettingCustomActivity extends BaseActivity {
if (index == 1 && QbSdk.getTbsVersion(App.get()) <= 0) X5WebViewDialog.create(this).show();
}
private void setConfigCache(View view) {
int index = Setting.getConfigCache();
Setting.putConfigCache(index = index == configCache.length - 1 ? 0 : ++index);
mBinding.configCacheText.setText(configCache[index]);
}
private void onReset(View view) {
new MaterialAlertDialogBuilder(this).setTitle(R.string.dialog_reset_app).setMessage(R.string.dialog_reset_app_data).setNegativeButton(R.string.dialog_negative, null).setPositiveButton(R.string.dialog_positive, (dialog, which) -> reset()).show();
}
private void reset() {
new Thread(() -> {
Shell.exec("pm clear " + App.get().getPackageName());
}).start();
}
}

@ -319,64 +319,6 @@
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:orientation="horizontal">
<LinearLayout
android:id="@+id/configCache"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginEnd="16dp"
android:layout_weight="1"
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_config_cache"
android:textColor="@color/white"
android:textSize="18sp" />
<TextView
android:id="@+id/configCacheText"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="end"
android:textColor="@color/white"
android:textSize="18sp"
tools:text="关闭" />
</LinearLayout>
<LinearLayout
android:id="@+id/reset"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
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_reset"
android:textColor="@color/white"
android:textSize="18sp" />
</LinearLayout>
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"

@ -530,5 +530,100 @@
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:orientation="horizontal">
<LinearLayout
android:id="@+id/configCache"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginEnd="16dp"
android:layout_weight="1"
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_config_cache"
android:textColor="@color/white"
android:textSize="18sp" />
<TextView
android:id="@+id/configCacheText"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="end"
android:textColor="@color/white"
android:textSize="18sp"
tools:text="关闭" />
</LinearLayout>
<LinearLayout
android:id="@+id/reset"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
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_reset"
android:textColor="@color/white"
android:textSize="18sp" />
</LinearLayout>
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:orientation="horizontal">
<LinearLayout
android:id="@+id/removeAd"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
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_remove_ad"
android:textColor="@color/white"
android:textSize="18sp" />
<TextView
android:id="@+id/removeAdText"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="end"
android:textColor="@color/white"
android:textSize="18sp"
tools:text="关闭" />
</LinearLayout>
</LinearLayout>
</LinearLayout>
</androidx.core.widget.NestedScrollView>

@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="136dp"
android:layout_width="132dp"
android:layout_height="68dp"
android:background="@drawable/selector_item"
android:focusable="true"

@ -8,8 +8,6 @@ import com.fongmi.android.tv.player.Players;
import com.fongmi.android.tv.utils.LanguageUtil;
import com.github.catvod.utils.Prefers;
import java.util.Locale;
public class Setting {
public static String getDoh() {
@ -496,5 +494,12 @@ public class Setting {
return Prefers.getInt("parse_webview", 0);
}
public static boolean isRemoveAd() {
return Prefers.getBoolean("remove_ad", false);
}
public static void putRemoveAd(boolean remove) {
Prefers.put("remove_ad", remove);
}
}

@ -44,13 +44,14 @@ import com.fongmi.android.tv.bean.Channel;
import com.fongmi.android.tv.bean.Drm;
import com.fongmi.android.tv.bean.Result;
import com.fongmi.android.tv.bean.Sub;
import com.fongmi.android.tv.utils.Sniffer;
import com.fongmi.android.tv.server.Server;
import com.fongmi.android.tv.utils.UrlUtil;
import com.github.catvod.net.OkHttp;
import com.github.catvod.utils.Path;
import com.github.catvod.utils.Util;
import com.google.common.net.HttpHeaders;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
@ -140,6 +141,7 @@ public class ExoUtil {
String mimeType = getMimeType(format, errorCode);
if (uri.getUserInfo() != null) headers.put(HttpHeaders.AUTHORIZATION, Util.basic(uri.getUserInfo()));
if (url.contains("***") && url.contains("|||")) return getConcat(headers, url, format, subs, sub, drm, errorCode);
if (url.contains(".m3u8") && Setting.isRemoveAd()) uri = Uri.parse(Server.get().getAddress().concat("/m3u8?url=").concat(URLEncoder.encode(url)));
return new DefaultMediaSourceFactory(getDataSourceFactory(headers), getExtractorsFactory()).createMediaSource(getMediaItem(uri, mimeType, subs, drm));
}
@ -160,7 +162,6 @@ public class ExoUtil {
if (drm != null) builder.setDrmConfiguration(drm.get());
builder.setAllowChunklessPreparation(Players.isHard(Players.EXO));
if (mimeType != null) builder.setMimeType(mimeType);
builder.setAds(Sniffer.getRegex(uri));
return builder.build();
}

@ -2,10 +2,10 @@ package com.fongmi.android.tv.player;
import android.net.Uri;
import com.fongmi.android.tv.Setting;
import com.fongmi.android.tv.bean.Channel;
import com.fongmi.android.tv.bean.Result;
import com.fongmi.android.tv.server.Server;
import com.fongmi.android.tv.utils.Sniffer;
import com.fongmi.android.tv.utils.UrlUtil;
import java.net.URLEncoder;
@ -25,8 +25,7 @@ public class IjkUtil {
public static MediaSource getSource(Map<String, String> headers, String url) {
Uri uri = UrlUtil.uri(url);
boolean m3u8Ad = Sniffer.getRegex(uri).size() > 0;
if (m3u8Ad) uri = Uri.parse(Server.get().getAddress().concat("/m3u8?url=").concat(URLEncoder.encode(uri.toString())));
if (url.contains(".m3u8") && Setting.isRemoveAd()) uri = Uri.parse(Server.get().getAddress().concat("/m3u8?url=").concat(URLEncoder.encode(url)));
return new MediaSource(Players.checkUa(headers), uri);
}
}

@ -1,6 +1,5 @@
package com.fongmi.android.tv.utils;
import android.net.Uri;
import android.text.TextUtils;
import androidx.media3.common.util.UriUtil;
@ -8,8 +7,6 @@ import androidx.media3.common.util.UriUtil;
import com.github.catvod.net.OkHttp;
import com.google.common.net.HttpHeaders;
import java.math.BigDecimal;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
@ -18,14 +15,7 @@ import okhttp3.Headers;
import okhttp3.Response;
public class M3U8 {
private static final String TAG_DISCONTINUITY = "#EXT-X-DISCONTINUITY";
private static final String TAG_MEDIA_DURATION = "#EXTINF";
private static final String TAG_ENDLIST = "#EXT-X-ENDLIST";
private static final String TAG_KEY = "#EXT-X-KEY";
private static final Pattern REGEX_X_DISCONTINUITY = Pattern.compile("#EXT-X-DISCONTINUITY[\\s\\S]*?(?=#EXT-X-DISCONTINUITY|$)");
private static final Pattern REGEX_MEDIA_DURATION = Pattern.compile(TAG_MEDIA_DURATION + ":([\\d\\.]+)\\b");
private static final Pattern REGEX_URI = Pattern.compile("URI=\"(.+?)\"");
public static String get(String url, Map<String, String> headers) {
@ -38,31 +28,13 @@ public class M3U8 {
if (matcher.find() && matcher.groupCount() > 1) return get(UriUtil.resolve(url, matcher.group(2)), headers);
StringBuilder sb = new StringBuilder();
for (String line : result.split("\n")) sb.append(shouldResolve(line) ? resolve(url, line) : line).append("\n");
List<String> ads = Sniffer.getRegex(Uri.parse(url));
return clean(sb.toString(), ads);
return clean(sb.toString());
} catch (Throwable ignored) {
return "";
}
}
private static String clean(String line, List<String> ads) {
boolean scan = false;
for (String ad : ads) {
if (ad.contains(TAG_DISCONTINUITY) || ad.contains(TAG_MEDIA_DURATION)) line = line.replaceAll(ad, "");
else if (isDouble(ad)) scan = true;
}
return scan ? scan(line, ads) : line;
}
private static String scan(String line, List<String> ads) {
Matcher m1 = REGEX_X_DISCONTINUITY.matcher(line);
while (m1.find()) {
String group = m1.group();
BigDecimal t = BigDecimal.ZERO;
Matcher m2 = REGEX_MEDIA_DURATION.matcher(group);
while (m2.find()) t = t.add(new BigDecimal(m2.group(1)));
for (String ad : ads) if (t.toString().startsWith(ad)) line = line.replace(group.replace(TAG_ENDLIST, ""), "");
}
private static String clean(String line) {
return line;
}
@ -73,14 +45,6 @@ public class M3U8 {
return builder.build();
}
private static boolean isDouble(String ad) {
try {
return Double.parseDouble(ad) > 0;
} catch (Exception e) {
return false;
}
}
private static boolean shouldResolve(String line) {
return (!line.startsWith("#") && !line.startsWith("http")) || line.startsWith(TAG_KEY);
}

@ -86,6 +86,7 @@
<string name="setting_home_menu_key">首页菜单键</string>
<string name="setting_home_site_lock">首页源锁定</string>
<string name="setting_incognito">无痕模式</string>
<string name="setting_remove_ad">AI去广告</string>
<string name="setting_small_window_back_key">小窗返回键</string>
<string name="setting_home_display_name">首页显示站源</string>
<string name="setting_home_ui">首页UI</string>

@ -86,8 +86,9 @@
<string name="setting_home_menu_key">首頁選單鍵</string>
<string name="setting_home_site_lock">首頁源鎖定</string>
<string name="setting_incognito">無痕模式</string>
<string name="setting_remove_ad">AI去廣告</string>
<string name="setting_small_window_back_key">小窗返回鍵</string>
<string name="setting_home_display_name">首頁示站源</string>
<string name="setting_home_display_name">首頁示站源</string>
<string name="setting_home_ui">首頁UI</string>
<string name="setting_home_buttons">首頁按鈕</string>
<string name="setting_doh">DoH</string>

@ -86,6 +86,7 @@
<string name="setting_home_menu_key">Home menu key</string>
<string name="setting_home_site_lock">Home site lock</string>
<string name="setting_incognito">Incognito mode</string>
<string name="setting_remove_ad">Remove ads</string>
<string name="setting_small_window_back_key">Small window back key</string>
<string name="setting_home_display_name">Home display name</string>
<string name="setting_home_ui">Home ui style</string>

@ -49,6 +49,7 @@ public class SettingCustomFragment extends BaseFragment {
mBinding.incognitoText.setText(getSwitch(Setting.isIncognito()));
mBinding.aggregatedSearchText.setText(getSwitch(Setting.isAggregatedSearch()));
mBinding.homeDisplayNameText.setText(getSwitch(Setting.isHomeDisplayName()));
mBinding.removeAdText.setText(getSwitch(Setting.isRemoveAd()));
mBinding.languageText.setText((lang = ResUtil.getStringArray(R.array.select_language))[Setting.getLanguage()]);
mBinding.configCacheText.setText((configCache = ResUtil.getStringArray(R.array.select_config_cache))[Setting.getConfigCache()]);
}
@ -63,6 +64,7 @@ public class SettingCustomFragment extends BaseFragment {
mBinding.incognito.setOnClickListener(this::setIncognito);
mBinding.aggregatedSearch.setOnClickListener(this::setAggregatedSearch);
mBinding.homeDisplayName.setOnClickListener(this::setHomeDisplayName);
mBinding.removeAd.setOnClickListener(this::setRemoveAd);
mBinding.language.setOnClickListener(this::setLanguage);
mBinding.configCache.setOnClickListener(this::setConfigCache);
mBinding.reset.setOnClickListener(this::onReset);
@ -122,6 +124,11 @@ public class SettingCustomFragment extends BaseFragment {
RefreshEvent.config();
}
private void setRemoveAd(View view) {
Setting.putRemoveAd(!Setting.isRemoveAd());
mBinding.removeAdText.setText(getSwitch(Setting.isRemoveAd()));
}
private void setLanguage(View view) {
new MaterialAlertDialogBuilder(getActivity()).setTitle(R.string.setting_language).setNegativeButton(R.string.dialog_negative, null).setSingleChoiceItems(lang, Setting.getLanguage(), (dialog, which) -> {
mBinding.languageText.setText(lang[which]);

@ -206,6 +206,33 @@
</LinearLayout>
<LinearLayout
android:id="@+id/removeAd"
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_remove_ad"
android:textColor="@color/white"
android:textSize="16sp" />
<TextView
android:id="@+id/removeAdText"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="end"
android:textColor="@color/white"
android:textSize="16sp"
tools:text="Off" />
</LinearLayout>
<LinearLayout
android:id="@+id/language"
android:layout_width="match_parent"

Loading…
Cancel
Save