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 8f72cf86b..64a7dd461 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 @@ -44,14 +44,13 @@ 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.server.Server; +import com.fongmi.android.tv.utils.Sniffer; 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; @@ -141,7 +140,6 @@ 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)); } @@ -162,6 +160,7 @@ 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(); } diff --git a/app/src/main/java/com/fongmi/android/tv/player/IjkUtil.java b/app/src/main/java/com/fongmi/android/tv/player/IjkUtil.java index 439675734..4461eb76a 100644 --- a/app/src/main/java/com/fongmi/android/tv/player/IjkUtil.java +++ b/app/src/main/java/com/fongmi/android/tv/player/IjkUtil.java @@ -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,7 +25,8 @@ public class IjkUtil { public static MediaSource getSource(Map headers, String url) { Uri uri = UrlUtil.uri(url); - if (url.contains(".m3u8") && Setting.isRemoveAd()) uri = Uri.parse(Server.get().getAddress().concat("/m3u8?url=").concat(URLEncoder.encode(url))); + boolean m3u8Ad = Sniffer.getRegex(uri).size() > 0; + if (m3u8Ad) uri = Uri.parse(Server.get().getAddress().concat("/m3u8?url=").concat(URLEncoder.encode(uri.toString()))); return new MediaSource(Players.checkUa(headers), uri); } } diff --git a/app/src/main/java/com/fongmi/android/tv/utils/M3U8.java b/app/src/main/java/com/fongmi/android/tv/utils/M3U8.java index 66afb8f90..a45548688 100644 --- a/app/src/main/java/com/fongmi/android/tv/utils/M3U8.java +++ b/app/src/main/java/com/fongmi/android/tv/utils/M3U8.java @@ -1,5 +1,6 @@ package com.fongmi.android.tv.utils; +import android.net.Uri; import android.text.TextUtils; import androidx.media3.common.util.UriUtil; @@ -7,6 +8,8 @@ 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; @@ -15,7 +18,14 @@ 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 headers) { @@ -28,13 +38,31 @@ 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"); - return clean(sb.toString()); + List ads = Sniffer.getRegex(Uri.parse(url)); + return clean(sb.toString(), ads); } catch (Throwable ignored) { return ""; } } - private static String clean(String line) { + private static String clean(String line, List 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 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, ""), ""); + } return line; } @@ -45,6 +73,14 @@ 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); }