diff --git a/app/src/main/java/com/videoapp/tv/PlayerActivity.kt b/app/src/main/java/com/videoapp/tv/PlayerActivity.kt index eb6d7a9..8aff822 100644 --- a/app/src/main/java/com/videoapp/tv/PlayerActivity.kt +++ b/app/src/main/java/com/videoapp/tv/PlayerActivity.kt @@ -259,7 +259,12 @@ class PlayerActivity : AppCompatActivity() { } else if (iframeUrl != null) { playWithWebView(iframeUrl) } else { - playWithWebView(ep.playUrl) + val apiUrl = videoExtractor.fetchPlayUrlFromApi(ep.playUrl, config.baseUrl) + if (apiUrl != null) { + playWithExoPlayer(apiUrl) + } else { + playWithWebView(ep.playUrl) + } } } } diff --git a/app/src/main/java/com/videoapp/tv/data/SitePreset.kt b/app/src/main/java/com/videoapp/tv/data/SitePreset.kt index f6507ae..03132ca 100644 --- a/app/src/main/java/com/videoapp/tv/data/SitePreset.kt +++ b/app/src/main/java/com/videoapp/tv/data/SitePreset.kt @@ -47,8 +47,8 @@ data class SitePreset( categorySelector = ".text-muted", dateSelector = "", episodeSelector = "li.list-inline-item a", - sourceSelector = "h2", - sourceEpisodeGroupSelector = "ul.list-unstyled", + sourceSelector = "", + sourceEpisodeGroupSelector = "", iframeSelector = "iframe", videoSelector = "video source, video[src]" ) diff --git a/app/src/main/java/com/videoapp/tv/engine/VideoExtractor.kt b/app/src/main/java/com/videoapp/tv/engine/VideoExtractor.kt index bb7ddb3..7b484f9 100644 --- a/app/src/main/java/com/videoapp/tv/engine/VideoExtractor.kt +++ b/app/src/main/java/com/videoapp/tv/engine/VideoExtractor.kt @@ -3,7 +3,9 @@ package com.videoapp.tv.engine import com.videoapp.tv.data.SiteConfig import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.withContext +import org.json.JSONObject import org.jsoup.Jsoup +import java.net.URL data class Episode( val title: String, @@ -90,4 +92,30 @@ class VideoExtractor { Pair(null, null) } } + + suspend fun fetchPlayUrlFromApi( + playUrl: String, + baseUrl: String + ): String? = withContext(Dispatchers.IO) { + try { + val pattern = Regex("""(\d+)/ep(\d+)""") + val match = pattern.find(playUrl) ?: return@withContext null + val videoId = match.groupValues[1] + val epNum = match.groupValues[2] + val apiUrl = "${baseUrl.trimEnd('/')}/_fetch_p/$videoId/ep$epNum" + val conn = URL(apiUrl).openConnection() + conn.setRequestProperty("User-Agent", "Mozilla/5.0") + conn.setRequestProperty("Referer", playUrl) + conn.connectTimeout = 15000 + conn.readTimeout = 15000 + val json = conn.getInputStream().bufferedReader().use { it.readText() } + val obj = JSONObject(json) + val playcfgs = obj.getJSONArray("playcfgs") + if (playcfgs.length() > 0) { + playcfgs.getJSONObject(0).getString("url") + } else null + } catch (e: Exception) { + null + } + } } diff --git a/icon.png b/icon.png new file mode 100644 index 0000000..d572846 Binary files /dev/null and b/icon.png differ