m3u8 remove ads

okjack
okjack 2 years ago
parent a240a502b3
commit 85cf69b94b
  1. 7
      app/src/leanback/java/com/fongmi/android/tv/ui/activity/SettingCustomActivity.java
  2. 37
      app/src/leanback/res/layout/activity_setting_custom.xml
  3. 9
      app/src/main/java/com/fongmi/android/tv/Setting.java
  4. 5
      app/src/main/java/com/fongmi/android/tv/player/ExoUtil.java
  5. 5
      app/src/main/java/com/fongmi/android/tv/player/IjkUtil.java
  6. 40
      app/src/main/java/com/fongmi/android/tv/utils/M3U8.java
  7. 1
      app/src/main/res/values-zh-rCN/strings.xml
  8. 3
      app/src/main/res/values-zh-rTW/strings.xml
  9. 1
      app/src/main/res/values/strings.xml
  10. 7
      app/src/mobile/java/com/fongmi/android/tv/ui/fragment/SettingCustomFragment.java
  11. 27
      app/src/mobile/res/layout/fragment_setting_custom.xml

@ -63,6 +63,7 @@ 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()]);
@ -85,6 +86,7 @@ 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);
@ -184,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();
}

@ -588,5 +588,42 @@
</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>

@ -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