feat: 添加 TvcatHandler,支持 /_fetch_p/ API 获取播放链接
This commit is contained in:
@@ -0,0 +1,75 @@
|
||||
package com.videoapp.tv.engine.tvcat
|
||||
|
||||
import com.videoapp.tv.data.SiteConfig
|
||||
import com.videoapp.tv.engine.BaseSourceHandler
|
||||
import com.videoapp.tv.engine.Episode
|
||||
import com.videoapp.tv.engine.PlaySource
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.withContext
|
||||
import org.json.JSONObject
|
||||
import org.jsoup.Jsoup
|
||||
import java.net.URL
|
||||
|
||||
class TvcatHandler : BaseSourceHandler(
|
||||
id = "tvcat",
|
||||
displayName = "tvcat (电视猫)",
|
||||
baseUrl = "https://tvcat.cc",
|
||||
config = SiteConfig(
|
||||
baseUrl = "https://tvcat.cc",
|
||||
searchPath = "/search",
|
||||
searchMethod = "GET",
|
||||
keywordParam = "q",
|
||||
resultSelector = "li.col-md-2.col-sm-3.col-4",
|
||||
titleSelector = "a[title]",
|
||||
coverSelector = "img",
|
||||
linkSelector = "a",
|
||||
categorySelector = ".text-muted",
|
||||
dateSelector = "",
|
||||
episodeSelector = "li.list-inline-item a",
|
||||
sourceSelector = "",
|
||||
sourceEpisodeGroupSelector = "",
|
||||
iframeSelector = "iframe",
|
||||
videoSelector = "video source, video[src]"
|
||||
)
|
||||
) {
|
||||
override suspend fun extractVideos(detailUrl: String): List<PlaySource> =
|
||||
withContext(Dispatchers.IO) {
|
||||
val doc = Jsoup.connect(detailUrl).timeout(15000).get()
|
||||
val episodes = doc.select("li.list-inline-item a").mapNotNull { ep ->
|
||||
val title = ep.text().trim()
|
||||
val href = ep.attr("href").trim()
|
||||
if (title.isNotEmpty() && href.isNotEmpty()) {
|
||||
Episode(title, buildFullUrl(href))
|
||||
} else null
|
||||
}
|
||||
if (episodes.isNotEmpty()) {
|
||||
listOf(PlaySource("默认来源", episodes))
|
||||
} else emptyList()
|
||||
}
|
||||
|
||||
override suspend fun resolvePlayUrl(playUrl: String): Pair<String?, String?> =
|
||||
withContext(Dispatchers.IO) {
|
||||
try {
|
||||
val match = Regex("""(\d+)/ep(\d+)""").find(playUrl)
|
||||
if (match != null) {
|
||||
val videoId = match.groupValues[1]
|
||||
val epNum = match.groupValues[2]
|
||||
val apiUrl = "https://tvcat.cc/_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) {
|
||||
val url = playcfgs.getJSONObject(0).getString("url")
|
||||
Pair(url, null)
|
||||
} else Pair(null, null)
|
||||
} else Pair(null, null)
|
||||
} catch (_: Exception) {
|
||||
Pair(null, null)
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user