This commit is contained in:
lushunming 2025-10-14 17:00:57 +08:00
parent b672af3b1d
commit 873e10b31e
10 changed files with 791 additions and 166 deletions

View File

@ -0,0 +1,37 @@
package com.github.catvod.api;
import com.github.catvod.bean.BD.Cache;
import com.github.catvod.bean.yun.User;
import com.github.catvod.utils.Path;
import java.io.File;
public class BaiDuYunHandler {
private final Cache cache;
public File getCache() {
return Path.tv("bd");
}
private BaiDuYunHandler() {
cache = Cache.objectFrom(Path.read(getCache()));
}
private static class Loader {
static volatile BaiDuYunHandler INSTANCE = new BaiDuYunHandler();
}
public static BaiDuYunHandler get() {
return BaiDuYunHandler.Loader.INSTANCE;
}
public String getToken() {
User user = cache.getUser();
return user.getCookie();
//return "cGM6MTg4OTY3ODE2MDE6eTM1Tjd1dG58MXxSQ1N8MTc1NDQ2OTgwNzEyOXxzMlN0T1VEV3lOVmF5V3pNbGFfM2tJbVp1ZmlqSHBqaEhTSzVyNHZqVXNRLmlhV3loSUxHNDFkMUI5N1BqXzhWN0dtVWtKLnBTclhpNGpZU1EuTGZWMTV3MVFoZmNpcEVoZkxUV2tvYjB0bkFTYV9RTUhhaHhveWx6YkdmcEhQdjNCS1lrbnp1LkxaWDdKOE40YkNNRjkzT3piNmx2Y0d3TWdVUkl5b18ubVUt";
}
}

View File

@ -1,18 +1,18 @@
package com.github.catvod.api package com.github.catvod.api
import com.github.catvod.bean.Result
import com.github.catvod.bean.Vod
import com.github.catvod.bean.Vod.VodPlayBuilder
import com.github.catvod.net.OkHttp import com.github.catvod.net.OkHttp
import com.github.catvod.utils.Json import com.github.catvod.utils.Json
import com.github.catvod.utils.ProxyVideo import com.github.catvod.utils.ProxyServer.buildProxyUrl
import com.github.catvod.utils.Util import com.github.catvod.utils.Util
import com.github.catvod.utils.Util.MEDIA import com.github.catvod.utils.Util.MEDIA
import com.google.gson.JsonObject import com.google.gson.JsonObject
import kotlinx.coroutines.async
import kotlinx.coroutines.awaitAll
import kotlinx.coroutines.coroutineScope
import java.security.MessageDigest
import java.util.* import java.util.*
class BaiduDrive { object BaiduDrive {
private val cache = mutableMapOf<String, String>();
private val headers = mapOf( private val headers = mapOf(
"User-Agent" to "Mozilla/5.0 (Linux; Android 12; SM-X800) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/101.0.4951.40 Safari/537.36", "User-Agent" to "Mozilla/5.0 (Linux; Android 12; SM-X800) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/101.0.4951.40 Safari/537.36",
@ -22,41 +22,46 @@ class BaiduDrive {
"Referer" to "https://pan.baidu.com/" "Referer" to "https://pan.baidu.com/"
) )
private val cookies = private val saveDirName = "TVBOX_BD"
"BIDUPSID=D122360716A06862B6689D4FE32053A1; PSTM=1756869077; MAWEBCUID=web_KAGxElHEQyrFImqrzARlkIssFfvhfCLGaXDsxmWKbhxsfEsvhs; PANWEB=1; delPer=0; ZFY=LJHc036:AkCyc1OPqFkXugSCgXnfaMIH:AjDQUOfkXtP4:C; BDRCVFR[uPX25oyLwh6]=mk3SLVN4HKm; BAIDUID_REF=B0FC75130A1A8DF92DC8685381870C9E:FG=1; H_WISE_SIDS_BFESS=110085_656765_660924_665265_666660_667682_662823_668348_668761_668756_669314_667565_669628_669693_669848_669685_669681_670119_670114_670116_670307_669051_670308_670357_670598_669700_670824_669791_669664_670557_667838_669418_663788; MCITY=-276%3A; ZD_ENTRY=baidu; PSINO=5; BDORZ=B490B5EBF6F3CD402E515D22BCDA1598; BDRCVFR[S4-dAuiWMmn]=I67x6TjHwwYf0; BA_HECTOR=a0a1a50hakakah242g25a18kah41801kejiv325; BAIDUID=102896B6EA4554BB74C3F8C78B676C7B:FG=1; BAIDUID_BFESS=102896B6EA4554BB74C3F8C78B676C7B:FG=1; H_WISE_SIDS=60273_63141_64007_64982_65120_65190_65227_65246_65254_65273_65280_65310_65361_65368_65417_65457_65451_65510_65543_65572_65596_65620_65599_65636_65476; H_PS_PSSID=60273_63141_64007_64982_65120_65190_65227_65246_65254_65273_65280_65310_65361_65368_65417_65457_65451_65510_65543_65572_65596_65620_65599_65636_65476; csrfToken=6tn2uwGoOUgn87ZBElHEGjCD; newlogin=1; ppfuid=FOCoIC3q5fKa8fgJnwzbE67EJ49BGJeplOzf+4l4EOvDuu2RXBRv6R3A1AZMa49I27C0gDDLrJyxcIIeAeEhD8JYsoLTpBiaCXhLqvzbzmvy3SeAW17tKgNq/Xx+RgOdb8TWCFe62MVrDTY6lMf2GrfqL8c87KLF2qFER3obJGmVXQmqM6seEAgB/LlOs0+zGEimjy3MrXEpSuItnI4KDwxAMUTOS16BfoXMcd2lpC/ZmOvCi7lsE0/UM0w4HSMVhh7EfifsXEYHtGj52zkQan6UDL686lBL6BHUyL9m3lfGgLbz7OSojK1zRbqBESR5Pdk2R9IA3lxxOVzA+Iw1TWLSgWjlFVG9Xmh1+20oPSbrzvDjYtVPmZ+9/6evcXmhcO1Y58MgLozKnaQIaLfWRFwa8A3ZyTRp/cDxRMhYc97xUSUZS0ReZYJMPG6nCsxNJlhI2UyeJA6QroZFMelR7tnTNS/pLMWceus0e757/UMPmrThfasmhDJrMFcBfoSrAAv3LCf1Y7/fHL3PTSf9vid/u2VLX4h1nBtx8EF07eCMhWVv+2qjbPV7ZhXk3reaWRFEeso3s/Kc9n/UXtUfNU1sHiCdbrCW5yYsuSM9SPGDZsl7FhTAKw7qIu38vFZiq+DRc8Vbf7jOiN9xPe0lOdZHUhGHZ82rL5jTCsILwcRVCndrarbwmu7G154MpYiKmTXZkqV7Alo4QZzicdyMbWvwvmR2/m//YVTM8qeZWgDSHjDmtehgLWM45zARbPujeqU0T92Gmgs89l2htrSKITeYE0TpfIvjPXsgyQghyP8U3sViHT1z07gbfu1XO5QQ/upk1AkHGkWrkbMWm+rpwpdImdyxYIjA1uSy2hfTFv/d3cnXH4nh+maaicAPllDgrppZTr0lDf2Vsiy73L8egP9ck5gsaaSE4obz9V1JGvyp8lNw+IyCN2Gou0efGgcYWqtuH+3KMtXW4uAv+XUaBDreXqEwrDxmyUrecavkqQ9rGRChHnhPuJeIKACPXiVuli9ItRLEkdb1mLxNHAk3uJy88YX/Rf/sKUjR12zxRTDxxJNDJS+Dlsbqu3n4I65ujli/3rQ8Zk1MjmTOsz9+kTqOM4upsnQ6IWq/zeZTItMCgHpQhuhr4ip73honuzoJgge1cqWBFYvpabAPTOERTOP1kmx5SXPARX5uxyJzAiNILBC8zh7fGfNXOWV37O9gEbYklWGnWpu55tg8Y8GaT7BFVDtu1KaJzjx51nTN1+xVI8c7otOFm3py1Y+wrt2CfI5v5JSd2kRNZE7s6bQrA5yMI31SfUDgxDrsd6lPtUU=; XFI=627d86b0-a655-11f0-b1eb-0f9d37032cfb; XFCS=B8C411ADE99EE9C3B29FDF31558D538BB636F205DF4F52FE2E57F1312E01079F; XFT=yvSTf+EcMsgYHnGyS774OLqljjYcjil0ZkCgy1g0Aso=; BDUSS=55b2xxaGRqOTdSNE0xVUltZFRRTWdkLXZ0VWtmT2steWw5OHNYUFVDa1FZUkZwSVFBQUFBJCQAAAAAAAAAAAEAAAB0wRMxMTIzNDWwtMqxtPLL4wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABDU6WgQ1OloWk; BDUSS_BFESS=55b2xxaGRqOTdSNE0xVUltZFRRTWdkLXZ0VWtmT2steWw5OHNYUFVDa1FZUkZwSVFBQUFBJCQAAAAAAAAAAAEAAAB0wRMxMTIzNDWwtMqxtPLL4wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABDU6WgQ1OloWk; STOKEN=987012cdf0b7fd13bbd965b4d1c68f53eac6c0e7d6b4535e6d027f648dd4acae; Hm_lvt_182d6d59474cf78db37e0b2248640ea5=1760154644; Hm_lpvt_182d6d59474cf78db37e0b2248640ea5=1760161311; BDCLND=nGNVyBu9MKpWH7zlTs5oUxFdRQXvai300GnFk9MGb1A%3D; PANPSC=15679126166052069121%3Au9Rut0jYI4qaUfTgVmgBplcS2d9ns3O5C61tf8CKQkineeMhfK4oNnqD0KGUduys6WRWG5ljYM%2BmSRyxE8aegpNZSd%2B1SXYsBm6rqQ5QdYLMOw0WWU7tUSqLe%2F%2Bg%2FDWP4i2i1JdCg%2BQ3uGXWluwqDsVi7NXtJ9t339k3FioH%2FAqA1gqZJvix0rmqJrAOClKcX0r3JWTW68Ah7IX89yGaj0Eyueu6wBwEDZC8PXQ9dy48%2FX4Y2hjenzCvC2qz1EInzo%2F1llKJ4P7gQiGlDEks0p8M%2Flyi7z69BCKhGHn%2Fawh9ff8YI35KVRVksnPVbyr%2FTaFwbj9JM%2FCSsVZaqyA8TA%3D%3D; ndut_fmt=DACA0AD3BE7AF69A4F5690C5C8C96C528423560F2C90164DB3A1486ED8014AB7; ab_sr=1.0.1_Yjg0ZTYxNzc2MjUxNzUyMjMzNWYzNzY0ODA5Y2JhMmMxMjZiNDg2MTcyNjM0NGJiY2NkMzkzMjEzMjM0ZTVhMThlYTU5YzE5M2VkODRiYzFjYTRkY2Q4OGI5OWE3ZjgxMzM4NmRhZTMzNjE2MTc0MWJkYTMyZmE5OWRlNGIyZGI3ZDhkZDU5ZjZmMGNhODFhZWFhZmUzODAwZDVhOGZhMTYyNTgzNjk3OWRlMWNhYjUxYjBmMTQyZDZhMzQ4ZGRh"
private val apiHost = "https://pan.baidu.com"
private val name = "baidu"
private val displayName = listOf("百度原画", "百度转码")
fun canHandle(url: String): Boolean { private var cookies = BaiDuYunHandler.get().token
return "pan.baidu" in url
private val apiHost = "https://pan.baidu.com"
private val displayName = listOf("BD原画")
fun setCookie(extend: String) {
if (extend.isEmpty()) return
cookies = extend
} }
suspend fun processShareLinks(urls: List<String>): Pair<List<String>, List<String>> { fun processShareLinks(urls: List<String>): Pair<List<String>, List<String>> {
if (urls.isEmpty()) return emptyList<String>() to emptyList() if (urls.isEmpty()) return emptyList<String>() to emptyList()
return coroutineScope {
val results = urls.map { url ->
async { processSingleLink(url) }
}.awaitAll()
val names = mutableListOf<String>() val results = urls.map { url ->
val allVideos = mutableListOf<String>() processSingleLink(url)
results.forEach { result ->
if (result != null) {
val (avideos, videos) = result
names.addAll(displayName)
allVideos.add(avideos.joinToString("#"))
allVideos.add(videos.joinToString("#"))
}
}
names to allVideos
} }
val names = mutableListOf<String>()
val allVideos = mutableListOf<String>()
results.forEach { result ->
if (result != null) {
val (avideos, videos) = result
names.addAll(displayName)
allVideos.add(avideos.joinToString("#"))
//allVideos.add(videos.joinToString("#"))
}
}
return names to allVideos
} }
private suspend fun processSingleLink(url: String): Pair<List<String>, List<String>>? { private fun processSingleLink(url: String): Pair<List<String>, List<String>>? {
return try { return try {
val urlInfo = parseShareUrl(url) val urlInfo = parseShareUrl(url)
if (urlInfo.containsKey("error")) return null if (urlInfo.containsKey("error")) return null
@ -71,7 +76,7 @@ class BaiduDrive {
} }
} }
private suspend fun parseShareUrl(url: String): Map<String, String> { private fun parseShareUrl(url: String): Map<String, String> {
var lurl = url var lurl = url
if ("提取码" in url) lurl = url.replace("提取码:", "?pwd=") if ("提取码" in url) lurl = url.replace("提取码:", "?pwd=")
@ -114,7 +119,7 @@ class BaiduDrive {
) )
} }
private suspend fun getAllVideos(tokenInfo: Map<String, String>): Pair<List<String>, List<String>> { private fun getAllVideos(tokenInfo: Map<String, String>): Pair<List<String>, List<String>> {
val videos = mutableListOf<String>() val videos = mutableListOf<String>()
val avideos = mutableListOf<String>() val avideos = mutableListOf<String>()
val seenFolders = mutableSetOf<String>() val seenFolders = mutableSetOf<String>()
@ -181,8 +186,8 @@ class BaiduDrive {
pendingFolders.clear() pendingFolders.clear()
val results = currentBatch.map { folderInfo -> val results = currentBatch.map { folderInfo ->
coroutineScope { async { getFolderContents(folderInfo) } } getFolderContents(folderInfo)
}.awaitAll() }
results.forEachIndexed { i, result -> results.forEachIndexed { i, result ->
val folderInfo = currentBatch[i] val folderInfo = currentBatch[i]
@ -327,9 +332,10 @@ class BaiduDrive {
} }
fun getBdUid(): String? {/* if (Cache.get("baidu:uid") != null) { fun getBdUid(): String? {
return Cache.get("baidu:uid") as? String if (cache["uid"] != null) {
}*/ return cache["uid"]
}
val tempHeader = headers.toMutableMap() val tempHeader = headers.toMutableMap()
tempHeader.put("Cookie", cookies) tempHeader.put("Cookie", cookies)
try { try {
@ -349,7 +355,7 @@ class BaiduDrive {
val uidValue = fields?.get("uid")?.asString val uidValue = fields?.get("uid")?.asString
if (uidValue != null) { if (uidValue != null) {
// Cache.set("baidu:uid", uidValue) cache["uid"] = uidValue
return uidValue return uidValue
} else { } else {
throw Exception("Failed to retrieve UID from Baidu Drive.") throw Exception("Failed to retrieve UID from Baidu Drive.")
@ -360,7 +366,7 @@ class BaiduDrive {
} }
} }
suspend fun _getSign(videoData: JsonObject): Pair<String, String> { fun _getSign(videoData: JsonObject): Pair<String, String> {
val tempHeader = headers.toMutableMap() val tempHeader = headers.toMutableMap()
tempHeader.put("Cookie", cookies) tempHeader.put("Cookie", cookies)
val response: String? = OkHttp.string( val response: String? = OkHttp.string(
@ -380,7 +386,7 @@ class BaiduDrive {
} }
suspend fun _getDownloadUrl(videoData: JsonObject): String { fun _getDownloadUrl(videoData: JsonObject): String {
return try { return try {
var cookie = "" var cookie = ""
val BDCLND = "BDCLND=" + videoData["randsk"].asString val BDCLND = "BDCLND=" + videoData["randsk"].asString
@ -409,10 +415,15 @@ class BaiduDrive {
"Referer" to "https://pan.baidu.com", "Referer" to "https://pan.baidu.com",
"Cookie" to cookie "Cookie" to cookie
) )
// 先清空文件夹在创建文件夹
_deleteTransferFile("/$saveDirName")
//创建路径
createSaveDir()
val data = val data =
"from=${videoData["uk"].asString}&shareid=${videoData["shareid"].asString}&ondup=newcopy&path=/&fsidlist=[${videoData["fid"].asString}]" "from=${videoData["uk"].asString}&shareid=${videoData["shareid"].asString}&ondup=newcopy&path=/${saveDirName}&fsidlist=[${videoData["fid"].asString}]"
var to = "" var to = ""
for (i in 1..30) { for (i in 1..30) {
@ -424,8 +435,8 @@ class BaiduDrive {
val result = Json.safeObject(response.body) val result = Json.safeObject(response.body)
try { try {
to = (result["extra"].asJsonObject)["list"] .asJsonArray[0].asJsonObject["to"].asString to = (result["extra"].asJsonObject)["list"].asJsonArray[0].asJsonObject["to"].asString
// videoData["to"] = to // videoData["to"] = to
if (to.isNotEmpty()) { if (to.isNotEmpty()) {
println("成功转存文件到: $to") println("成功转存文件到: $to")
break break
@ -471,18 +482,18 @@ class BaiduDrive {
} }
} }
suspend fun getVideoUrl(videoData: JsonObject): Map<String, Any> { fun getVideoUrl(videoData: JsonObject, flag: String): Map<String, Any> {
return try { return try {
val bdUid = getBdUid() val bdUid = getBdUid()
println("获取百度网盘用户ID: $bdUid") println("获取百度网盘用户ID: $bdUid")
val plist = mutableListOf<Pair<String, String>>()
if (videoData["qtype"].asString == "original") { if (flag.contains("原画")) {
var app = true
var headersApp = mapOf("User-Agent" to "netdisk;P2SP;2.2.91.136;android-android;") var headersApp = mapOf("User-Agent" to "netdisk;P2SP;2.2.91.136;android-android;")
var downloadUrl = _getAppDownloadUrl(videoData) var downloadUrl = _getAppDownloadUrl(videoData)
if (downloadUrl.isEmpty()) { if (downloadUrl.isEmpty()) {
app = false
headersApp = mapOf( headersApp = mapOf(
"User-Agent" to "netdisk;1.4.2;22021211RC;android-android;12;JSbridge4.4.0;jointBridge;1.1.0;" "User-Agent" to "netdisk;1.4.2;22021211RC;android-android;12;JSbridge4.4.0;jointBridge;1.1.0;"
@ -491,14 +502,11 @@ class BaiduDrive {
downloadUrl = _getDownloadUrl(videoData) downloadUrl = _getDownloadUrl(videoData)
} }
if (downloadUrl.isNotEmpty()) { if (downloadUrl.isNotEmpty()) {
plist.add(Pair("原画", ProxyVideo.buildCommonProxyUrl(downloadUrl, headersApp)))
val result = mapOf( val result = mapOf(
"parse" to 0, "url" to plist, "header" to headersApp.toString() "parse" to "0", "url" to downloadUrl, "header" to headersApp
) )
// 使用线程而不是asyncio任务
Thread {
// _runDeleteInThread(videoData["to"] as? String)
}.start()
result result
} else { } else {
_handleError _handleError
@ -508,12 +516,11 @@ class BaiduDrive {
if (sign.isEmpty() || time.isEmpty()) { if (sign.isEmpty() || time.isEmpty()) {
return _handleError return _handleError
} }
val plist = _getPlayList(videoData, sign, time)/* val headers = Headers.build { val plist = _getPlayList(videoData, sign, time)
append(HttpHeaders.UserAgent, USER_AGENT) val tempHeader = headers.toMutableMap()
append(HttpHeaders.Cookie, dictToCookieStr(cookies)) tempHeader.put("Cookie", cookies)
}*/
mapOf( mapOf(
"parse" to 0, "url" to plist, "header" to headers.toString() "parse" to "0", "url" to plist[0], "header" to tempHeader
) )
} }
} catch (e: Exception) { } catch (e: Exception) {
@ -522,7 +529,7 @@ class BaiduDrive {
} }
} }
private suspend fun _getAppDownloadUrl(videoData: JsonObject): String { private fun _getAppDownloadUrl(videoData: JsonObject): String {
return try { return try {
val headers = mapOf<String, String>( val headers = mapOf<String, String>(
@ -547,15 +554,21 @@ class BaiduDrive {
"time" to t.toString() "time" to t.toString()
).toMutableMap() ).toMutableMap()
val randstr = val randstr = this.sha1(
this.sha1(this.sha1(Util.findByRegex("BDUSS=(.+?);",cookies,1)) + uid + "ebrcUYiuxaZv2XGu7KIYKxUrqfnOfpDF$t${params["devuid"]}11.30.2ae5821440fab5e1a61a025f014bd8972") this.sha1(
Util.findByRegex(
"BDUSS=(.+?);", cookies, 1
)
) + uid + "ebrcUYiuxaZv2XGu7KIYKxUrqfnOfpDF$t${params["devuid"]}11.30.2ae5821440fab5e1a61a025f014bd8972"
)
params.put("rand", sha1(randstr)) params.put("rand", randstr)
val response = OkHttp.string( val response = OkHttp.string(
"${apiHost}/share/list", params, headers "${apiHost}/share/list", params, headers
) )
val json = Json.safeObject(response)
val dlink = json["list"].asJsonArray[0].asJsonObject["dlink"].asString
/* val url = response["data"] as Map<String, Any> /* val url = response["data"] as Map<String, Any>
val list = url["list"] as List<Map<String, Any>> val list = url["list"] as List<Map<String, Any>>
@ -570,104 +583,142 @@ class BaiduDrive {
val pUrl = pDataResponse.headers[HttpHeaders.Location]?.toString() val pUrl = pDataResponse.headers[HttpHeaders.Location]?.toString()
pUrl ?: dlink*/ pUrl ?: dlink*/
"" dlink
} catch (e: Exception) { } catch (e: Exception) {
println("获取下载链接失败: ${e.message}") println("获取下载链接失败: ${e.message}")
"" ""
} }
} }
private fun _getPlayList(videoData: JsonObject, sign: String, time: String): List<Pair<String, String>> { private fun _getPlayList(videoData: JsonObject, sign: String, time: String): List<String> {
val hz = listOf("1080P", "720P", "480P") val hz = getPlayFormatList()
val plist = mutableListOf<Pair<String, String>>() val plist = mutableListOf<String>()
for (quality in hz) { for (quality in hz) {
val url = val url =
("${apiHost}/share/streaming?" + "uk=${videoData["uk"]}&" + "fid=${videoData["fid"]}&" + "sign=$sign&" + "timestamp=$time&" + "shareid=${videoData["shareid"]}&" + "type=M3U8_AUTO_${ ("${apiHost}/share/streaming?" + "uk=${videoData["uk"].asString}&" + "fid=${videoData["fid"].asString}&" + "sign=$sign&" + "timestamp=$time&" + "shareid=${videoData["shareid"].asString}&" + "type=M3U8_AUTO_${
quality.replace( quality.replace(
"P", "" "P", ""
) )
}") }")
plist.add(Pair(quality, url)) plist.add(url)
} }
return plist return plist
}/* }
private suspend fun _deleteTransferFile(filePath: String) { /**
try { * 创建保存目录
val url = "$API_HOST/api/filemanager" */
val params = Parameters.build { fun createSaveDir(): Long? {
append("opera", "delete") var saveDirId: Long? = null
append("clienttype", "1") // 创建保存目录
} if (cookies.isEmpty()) {
val deleteHeaders = Headers.build { return null
append(HttpHeaders.UserAgent, "Android") }
append(HttpHeaders.Connection, CONNECTION) val tempHeader = headers.toMutableMap()
append(HttpHeaders.AcceptEncoding, "br,gzip") tempHeader.put("Cookie", cookies)
append(HttpHeaders.ContentType, ContentType.Application.FormUrlEncoded.toString()) return try {
append(HttpHeaders.AcceptLanguage, ACCEPT_LANGUAGE) val listResp = OkHttp.string(
append("charset", CHARSET) "${apiHost}/api/list", mapOf(
} "dir" to "/",
val data = "filelist=[\"$filePath\"]" "order" to "name",
"desc" to "0",
"showempty" to "0",
"web" to "1",
"app_id" to "250528"
), tempHeader
)
val json = Json.safeObject(listResp)
val response: HttpResponse = client.post(url) { if (json["errno"].asInt != 0) {
parameters(params) return null
headers { this@_deleteTransferFile.deleteHeaders.forEach { name, value -> append(name, value) } } }
cookies?.let { setCookie(it) }
body = data
timeout.socketTimeoutMillis = 10000
}
val result = try { val drpyDir = json["list"].asJsonArray.find { item ->
response.receive<Map<String, Any>>() item.asJsonObject.get("isdir").asInt == 1 && item.asJsonObject.get("server_filename").asString == saveDirName
} catch (e: Exception) {
response.readBytes().decodeToString()
}
println("删除文件响应: $result") }
println("响应状态码: ${response.status.value}")
} catch (e: Exception) {
println("删除文件出错: ${e.message}")
e.printStackTrace()
}
}
private suspend fun _delayedDeleteFile(to: String) { if (drpyDir != null) {
try { saveDirId = drpyDir.asJsonObject.get("fs_id").asLong
println("开始延迟删除文件: $to") return saveDirId
delay(2000) }
println("开始执行删除操作: $to")
withContext(Dispatchers.IO) {
_deleteTransferFile(to)
}
} catch (e: Exception) {
println("延迟删除文件出错: ${e.message}")
}
}
private fun _runDeleteInThread(to: String?) { val createResp = OkHttp.post(
try { "${apiHost}/api/create?a=commit&bdstoken=${getBdstoken()}&clienttype=0&app_id=250528&web=1&dp-logid=73131200762376420075",
println("开始延迟删除文件(线程): $to") mapOf(
Thread.sleep(2000) "path" to "//$saveDirName",
println("开始执行删除操作(线程): $to") "isdir" to "1",
"block_list" to "[]",
runBlocking { ),
_deleteTransferFile(to!!) tempHeader
} )
val createJson = Json.safeObject(createResp.body)
println("删除操作完成: $to")
} catch (e: Exception) {
println("线程中删除文件出错: ${e.message}")
e.printStackTrace()
}
}
private fun dictToCookieStr(cookieDict: Map<String, String>?): String { saveDirId = createJson["fs_id"].asLong
return cookieDict?.map { "${it.key}=${it.value}" }?.joinToString("; ") ?: "" saveDirId
}*/
} catch (e: Exception) {
println("创建保存目录失败: ${e.message}")
null
}
}
fun getBdstoken(): String {
if (cache["bdstoken"] != null) {
return cache["bdstoken"]!!
}
val tempHeader = headers.toMutableMap()
tempHeader.put("Cookie", cookies)
val userInfo = OkHttp.string(
"${apiHost}/api/gettemplatevariable?clienttype=0&app_id=250528&web=1&fields=[\"bdstoken\",\"token\",\"uk\",\"isdocuser\",\"servertime\"]",
mapOf(),
tempHeader
)
val json = Json.safeObject(userInfo)
val bdstoken: String? = json["result"]?.asJsonObject?.get("bdstoken")?.asString
cache["bdstoken"] = bdstoken ?: ""
return bdstoken ?: ""
}
private fun _deleteTransferFile(filePath: String) {
try {
val url =
"$apiHost/api/filemanager?async=2&onnest=fail&opera=delete&bdstoken=${getBdstoken()}&newVerify=1&clienttype=0&app_id=250528&web=1&dp-logid=39292100213290200076"
val params = mapOf(
"filelist" to "[\"$filePath\"]"
)
val headers = mutableMapOf(
"User-Agent" to "Android",
"Connection" to "Keep-Alive",
"Accept-Encoding" to "br,gzip",
"Content-Type" to "application/x-www-form-urlencoded; charset=utf-8",
"Accept-Language" to "zh-CN,zh;q=0.8",
"charset" to "UTF-8",
"Cookie" to cookies,
)
val response = OkHttp.post(url, params, headers)
println("删除文件响应: ${response.body}")
println("响应状态码: ${response.code}")
} catch (e: Exception) {
println("删除文件出错: ${e.message}")
e.printStackTrace()
}
}
private fun unquote(encoded: String): String { private fun unquote(encoded: String): String {
return encoded.replace("%([0-9A-Fa-f]{2})".toRegex()) { match -> return encoded.replace("%([0-9A-Fa-f]{2})".toRegex()) { match ->
@ -676,17 +727,56 @@ class BaiduDrive {
} }
private fun sha1(input: String): String { private fun sha1(input: String): String {
val bytes = MessageDigest.getInstance("SHA-1").digest(input.toByteArray())
return Util.base64Encode(bytes) return Util.sha1Hex(input)
} }
private val _handleError = mapOf( private val _handleError = mapOf(
"parse" to 1, "msg" to "Error retrieving video URL" "parse" to "1", "msg" to "Error retrieving video URL"
) )
private fun threadUrl(url: String, threads: Int): String {
// Implement the logic for threading URL processing here fun getVod(shareUrl: String): Vod {
return url val (froms, urls) = processShareLinks(listOf(shareUrl))
val builder = VodPlayBuilder()
for (i in froms.indices) {
val playUrls = mutableListOf<VodPlayBuilder.PlayUrl>();
for (url in urls[i].split("#")) {
val arr = url.split("$")
val play = VodPlayBuilder.PlayUrl()
play.name = arr[0]
play.url = arr[1]
playUrls.add(play)
}
builder.append(froms[i], playUrls)
}
val buildResult = builder.build();
val vod = Vod()
vod.setVodId(shareUrl)
vod.setVodPic("")
vod.setVodYear("")
vod.setVodName("")
vod.setVodContent("")
vod.setVodPlayFrom(buildResult.vodPlayFrom)
vod.setVodPlayUrl(buildResult.vodPlayUrl)
return vod
}
fun playerContent(json: JsonObject, flag: String): String {
val play = getVideoUrl(json, flag);
val header = play["header"] as Map<String, String>
return Result.get().url(buildProxyUrl(play["url"] as String, header) ).octet().header(header).string();
}
fun getPlayFormatList(): Array<String> {
return listOf("1080P").toTypedArray()
}
fun proxyVideo(params: MutableMap<String, String>): Array<Any> {
return emptyList<Any>().toTypedArray()
} }

View File

@ -0,0 +1,41 @@
package com.github.catvod.bean.BD;
import com.github.catvod.api.BaiDuYunHandler;
import com.github.catvod.api.YunTokenHandler;
import com.github.catvod.bean.yun.User;
import com.github.catvod.spider.Init;
import com.github.catvod.utils.Path;
import com.google.gson.Gson;
import com.google.gson.annotations.SerializedName;
public class Cache {
@SerializedName("user")
private User user;
public static Cache objectFrom(String str) {
Cache item = new Gson().fromJson(str, Cache.class);
return item == null ? new Cache() : item;
}
public User getUser() {
return user == null ? new User("") : user;
}
public void setUser(User user) {
this.user = user;
this.save();
}
public void save() {
Init.execute(() -> Path.write(BaiDuYunHandler.get().getCache(), toString()));
}
@Override
public String toString() {
return new Gson().toJson(this);
}
}

View File

@ -0,0 +1,106 @@
package com.github.catvod.spider
import android.content.Context
import android.text.TextUtils
import com.github.catvod.api.BaiduDrive
import com.github.catvod.api.BaiduDrive.getPlayFormatList
import com.github.catvod.api.BaiduDrive.getVod
import com.github.catvod.api.BaiduDrive.playerContent
import com.github.catvod.api.BaiduDrive.setCookie
import com.github.catvod.bean.Result
import com.github.catvod.bean.Vod
import com.github.catvod.crawler.Spider
import com.github.catvod.crawler.SpiderDebug
import com.github.catvod.utils.Json
import kotlinx.coroutines.runBlocking
import java.util.*
/**
* @author ColaMint & Adam & FongMi
*/
class BaiDuPan : Spider() {
@Throws(Exception::class)
override fun init(context: Context?, extend: String) {
setCookie(extend)
}
/**
* ids share_link
* @param ids
* @return
* @throws Exception
*/
@Throws(Exception::class)
override fun detailContent(ids: MutableList<String>): String? {
var vod: Vod? = null;
runBlocking {
vod = getVod(ids[0])
}
return Result.string(vod);
}
@Throws(Exception::class)
override fun playerContent(flag: String, id: String, vipFlags: MutableList<String?>?): String {
var content = ""
runBlocking {
content = playerContent(Json.safeObject(com.github.catvod.utils.Util.base64Decode(id)), flag)
}
return content
}
/**
* 獲取詳情內容視頻播放來源 shared_link
*
* @param ids share_link 集合
* @param i
* @return 詳情內容視頻播放來源
*/
fun detailContentVodPlayFrom(ids: MutableList<String?>, index: Int): String? {
val playFrom: MutableList<String?> = ArrayList<String?>()
/* if (ids.size() < 2){
return TextUtils.join("$$$", BaiduDrive.get().getPlayFormatList());
}*/
for (i in 1..ids.size) {
playFrom.add("BD原画" + i + index)
/* for (s in getPlayFormatList()) {
playFrom.add(String.format(Locale.getDefault(), "BD" + s + "#%02d%02d", i, index))
}*/
}
return TextUtils.join("$$$", playFrom)
}
/**
* 獲取詳情內容視頻播放地址 share_link
*
* @param ids share_link 集合
* @return 詳情內容視頻播放地址
*/
@Throws(Exception::class)
fun detailContentVodPlayUrl(ids: List<String>): String? {
val playUrl: MutableList<String?> = ArrayList<String?>()
for (id in ids) {
try {
playUrl.add(getVod(id).getVodPlayUrl())
} catch (e: Exception) {
SpiderDebug.log("获取播放地址出错:" + e.message)
}
}
return TextUtils.join("$$$", playUrl)
}
companion object {
@JvmField
var URL_START = "https://pan.baidu.com"
@Throws(Exception::class)
fun proxy(params: MutableMap<String, String>): Array<Any> {
val type = params["type"]
if ("video" == type) return BaiduDrive.proxyVideo(params)
//if ("sub".equals(type)) return AliYun.get().proxySub(params);
return arrayOf<Any>()
}
}
}

View File

@ -23,6 +23,7 @@ public class Cloud extends Spider {
private UC uc = null;*/ private UC uc = null;*/
private TianYi tianYi = null; private TianYi tianYi = null;
private YiDongYun yiDongYun = null; private YiDongYun yiDongYun = null;
private BaiDuPan baiDuPan = null;
@Override @Override
public void init(Context context, String extend) throws Exception { public void init(Context context, String extend) throws Exception {
@ -32,12 +33,14 @@ public class Cloud extends Spider {
ali = new Ali();*/ ali = new Ali();*/
tianYi = new TianYi(); tianYi = new TianYi();
yiDongYun = new YiDongYun(); yiDongYun = new YiDongYun();
baiDuPan = new BaiDuPan();
boolean first = Objects.nonNull(ext); boolean first = Objects.nonNull(ext);
quark.init(context, first && ext.has("cookie") ? ext.get("cookie").getAsString() : ""); quark.init(context, first && ext.has("cookie") ? ext.get("cookie").getAsString() : "");
/* uc.init(context, first && ext.has("uccookie") ? ext.get("uccookie").getAsString() : ""); /* uc.init(context, first && ext.has("uccookie") ? ext.get("uccookie").getAsString() : "");
ali.init(context, first && ext.has("token") ? ext.get("token").getAsString() : "");*/ ali.init(context, first && ext.has("token") ? ext.get("token").getAsString() : "");*/
tianYi.init(context, first && ext.has("tianyicookie") ? ext.get("tianyicookie").getAsString() : ""); tianYi.init(context, first && ext.has("tianyicookie") ? ext.get("tianyicookie").getAsString() : "");
yiDongYun.init(context, ""); yiDongYun.init(context, "");
baiDuPan.init(context, "");
} }
@ -53,6 +56,8 @@ public class Cloud extends Spider {
return tianYi.detailContent(shareUrl); return tianYi.detailContent(shareUrl);
} else if (shareUrl.get(0).contains(YiDongYun.URL_START)) { } else if (shareUrl.get(0).contains(YiDongYun.URL_START)) {
return yiDongYun.detailContent(shareUrl); return yiDongYun.detailContent(shareUrl);
}else if (shareUrl.get(0).contains(BaiDuPan.URL_START)) {
return baiDuPan.detailContent(shareUrl);
} }
return null; return null;
} }
@ -70,6 +75,10 @@ public class Cloud extends Spider {
}/* else { }/* else {
return ali.playerContent(flag, id, vipFlags); return ali.playerContent(flag, id, vipFlags);
}*/ }*/
else if (flag.contains("BD")) {
return baiDuPan.playerContent(flag, id, vipFlags);
}
return flag; return flag;
} }
@ -89,6 +98,9 @@ public class Cloud extends Spider {
} else if (shareLink.contains(YiDongYun.URL_START)) { } else if (shareLink.contains(YiDongYun.URL_START)) {
from.add(yiDongYun.detailContentVodPlayFrom(List.of(shareLink), i)); from.add(yiDongYun.detailContentVodPlayFrom(List.of(shareLink), i));
} }
else if (shareLink.contains(BaiDuPan.URL_START)) {
from.add(baiDuPan.detailContentVodPlayFrom(List.of(shareLink), i));
}
} }
return TextUtils.join("$$$", from); return TextUtils.join("$$$", from);
@ -107,6 +119,8 @@ public class Cloud extends Spider {
urls.add(tianYi.detailContentVodPlayUrl(List.of(shareLink))); urls.add(tianYi.detailContentVodPlayUrl(List.of(shareLink)));
} else if (shareLink.contains(YiDongYun.URL_START)) { } else if (shareLink.contains(YiDongYun.URL_START)) {
urls.add(yiDongYun.detailContentVodPlayUrl(List.of(shareLink))); urls.add(yiDongYun.detailContentVodPlayUrl(List.of(shareLink)));
}else if (shareLink.contains(BaiDuPan.URL_START)) {
urls.add(baiDuPan.detailContentVodPlayUrl(List.of(shareLink)));
} }
} }
return TextUtils.join("$$$", urls); return TextUtils.join("$$$", urls);

View File

@ -0,0 +1,257 @@
package com.github.catvod.spider;
import android.content.Context;
import android.text.TextUtils;
import com.github.catvod.bean.Result;
import com.github.catvod.bean.Vod;
import com.github.catvod.net.OkHttp;
import com.github.catvod.net.OkResult;
import com.github.catvod.utils.Json;
import com.github.catvod.utils.Util;
import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
public class TgSearchBaidu extends Cloud {
private static final String KEY_API_URLS = "api_urls";
private static final String KEY_DOMAIN_MAP = "siteurl";
private static final String KEY_SOURCES = "sources";
private static final int DEFAULT_PAGE_SIZE = 10;
private List<String> apiUrls = new ArrayList<>();
private Map<String, String> domainMap = new HashMap<String, String>() {{
put("alipan", "阿里");
put("aliyundrive", "阿里");
put("quark", "夸克");
put("115cdn", "115");
put("baidu.com", "百度");
put("uc", "UC");
put("189.cn", "天翼");
put("139.com", "移动");
put("123", "123盘");
}};
private Set<String> sources = new HashSet<>();
private String[] extInfos = null;
@Override
public synchronized void init(Context context, String extend) throws Exception {
super.init(context, extend);
this.apiUrls.clear();
if (!TextUtils.isEmpty(extend)) {
try {
if (extend.contains("###")) {
String[] infos = extend.split("###");
this.extInfos = infos;
if (infos.length > 0 && !TextUtils.isEmpty(infos[0])) {
processExtendConfig(infos[0]);
}
} else {
this.extInfos = new String[]{extend};
processExtendConfig(extend);
}
} catch (Exception e) {}
}
this.extInfos = null; // 重置避免内存泄漏
}
private void processExtendConfig(String config) {
try {
// 检查是否为HTTP URL
if (isValidUrl(config)) {
if (!this.apiUrls.contains(config)) {
this.apiUrls.add(config);
}
return;
}
// 尝试JSON格式解析
JsonObject ext = Json.safeObject(config);
// 处理API URLs配置
processApiUrls(ext);
// 处理域名映射配置
processDomainMap(ext);
// 处理来源过滤配置
processSources(ext, true);
} catch (Exception e) {
// 可以添加日志记录
}
}
private void processApiUrls(JsonObject config) {
if (config.has(KEY_API_URLS) && config.get(KEY_API_URLS).isJsonArray()) {
JsonArray urlsArray = config.getAsJsonArray(KEY_API_URLS);
for (JsonElement element : urlsArray) {
if (element != null && element.isJsonPrimitive() && element.getAsJsonPrimitive().isString()) {
String url = element.getAsString();
if (isValidUrl(url) && !this.apiUrls.contains(url)) {
this.apiUrls.add(url);
}
}
}
}
}
private void processDomainMap(JsonObject config) {
if (config.has(KEY_DOMAIN_MAP) && config.get(KEY_DOMAIN_MAP).isJsonObject()) {
JsonObject customDomains = config.getAsJsonObject(KEY_DOMAIN_MAP);
for (Map.Entry<String, JsonElement> entry : customDomains.entrySet()) {
if (entry == null || entry.getValue() == null) continue;
String domain = entry.getKey();
String sourceName = "";
try { sourceName = entry.getValue().getAsString(); } catch (Exception e) { continue; }
if (!TextUtils.isEmpty(domain) && !TextUtils.isEmpty(sourceName) && !domainMap.containsKey(domain)) {
domainMap.put(domain, sourceName);
}
}
}
}
private void processSources(JsonObject config, boolean clearExisting) {
if (config.has(KEY_SOURCES) && config.get(KEY_SOURCES).isJsonArray()) {
if (clearExisting) {
this.sources.clear();
}
JsonArray sourcesArray = config.getAsJsonArray(KEY_SOURCES);
for (JsonElement element : sourcesArray) {
if (element != null && element.isJsonPrimitive() && element.getAsJsonPrimitive().isString()) {
String source = element.getAsString();
if (!TextUtils.isEmpty(source) && !sources.contains(source)) {
sources.add(source);
}
}
}
}
}
private boolean isValidUrl(String url) {
return !TextUtils.isEmpty(url) && (url.startsWith("http://") || url.startsWith("https://"));
}
private Map<String, String> getHeader() {
Map<String, String> header = new HashMap<>();
header.put("User-Agent", Util.CHROME);
return header;
}
@Override
public String searchContent(String key, boolean quick) throws Exception {
if (key == null || key.trim().isEmpty()) {
return Result.error("关键词不能为空");
}
return performSearch(key, 1, DEFAULT_PAGE_SIZE);
}
private String performSearch(String key, int page, int pageSize) throws Exception {
List<Vod> list = new ArrayList<>();
int total = 0;
Map<String, String> params = new HashMap<>();
params.put("kw", key);
params.put("page", String.valueOf(page));
params.put("size", String.valueOf(pageSize));
for (String apiUrl : apiUrls) {
if (!isValidUrl(apiUrl)) continue;
try {
OkResult result = OkHttp.get(apiUrl, params, getHeader());
if (result.getCode() == 500 || TextUtils.isEmpty(result.getBody())) continue;
JsonObject jsonObject = Json.safeObject(result.getBody());
if (!jsonObject.has("code") || jsonObject.get("code").getAsInt() != 0 || !jsonObject.has("data")) continue;
JsonObject data = jsonObject.getAsJsonObject("data");
total = data.has("total") && !data.get("total").isJsonNull() ? data.get("total").getAsInt() : 0;
// 直接检查merged_by_type字段无需三重判断
if (!data.has("merged_by_type") || !data.get("merged_by_type").isJsonObject()) continue;
JsonObject mergedByType = data.getAsJsonObject("merged_by_type");
for (Map.Entry<String, JsonElement> categoryEntry : mergedByType.entrySet()) {
if (!categoryEntry.getValue().isJsonArray()) continue;
JsonArray items = categoryEntry.getValue().getAsJsonArray();
for (JsonElement item : items) {
if (!item.isJsonObject()) continue;
JsonObject entry = item.getAsJsonObject();
String vodUrl = entry.has("url") && !entry.get("url").isJsonNull() ? entry.get("url").getAsString() : "";
if (TextUtils.isEmpty(vodUrl)) continue;
// 获取来源信息并映射
String originalSource = entry.has("source") && !entry.get("source").isJsonNull() ? entry.get("source").getAsString() : "未知来源";
String sourceName = mapSource(vodUrl, originalSource);
// 获取标题
String title = entry.has("note") && !entry.get("note").isJsonNull() ? entry.get("note").getAsString() : "未命名资源";
// 获取图片
String pic = getFirstImage(entry);
// 简化VodPlayBuilder的使用
Vod vod = new Vod("push://" + vodUrl, title, pic, sourceName + " (" + originalSource + ")");
// 由于只有一个播放源直接设置播放信息
vod.setVodPlayFrom(sourceName);
vod.setVodPlayUrl("播放源$" + vodUrl);
// 来源过滤
if (sources.isEmpty() || sources.contains(sourceName)) {
list.add(vod);
}
}
}
int pageCount = total > 0 && pageSize > 0 ? (total + pageSize - 1) / pageSize : 1;
return Result.string(page, pageCount, pageSize, total, list);
} catch (Exception e) {
// 出错时继续尝试下一个API
continue;
}
}
return Result.error("无法连接到任何搜索API");
}
// 提取来源映射逻辑为单独方法
private String mapSource(String vodUrl, String originalSource) {
for (Map.Entry<String, String> domainEntry : domainMap.entrySet()) {
if (vodUrl.contains(domainEntry.getKey())) {
return domainEntry.getValue();
}
}
return originalSource;
}
// 提取图片获取逻辑为单独方法
private String getFirstImage(JsonObject entry) {
if (entry.has("images") && !entry.get("images").isJsonNull() && entry.get("images").isJsonArray()) {
JsonArray images = entry.getAsJsonArray("images");
if (images.size() > 0 && !images.get(0).isJsonNull() && images.get(0).isJsonPrimitive()) {
return images.get(0).getAsString();
}
}
return "";
}
}

View File

@ -120,6 +120,8 @@ public class YunPanBa extends Cloud {
shareLinks.add(element.attr("href").trim()); shareLinks.add(element.attr("href").trim());
} else if (element.attr("href").matches(Util.patternAli)) { } else if (element.attr("href").matches(Util.patternAli)) {
shareLinks.add(element.attr("href").trim()); shareLinks.add(element.attr("href").trim());
} else if (element.attr("href").startsWith(BaiDuPan.URL_START)) {
shareLinks.add(element.attr("href").trim());
} }
} }

View File

@ -0,0 +1,64 @@
import android.app.Application;
import com.github.catvod.spider.BaiDuPan;
import com.github.catvod.spider.Init;
import com.github.catvod.utils.Json;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.JsonObject;
import org.junit.Assert;
import org.junit.runner.RunWith;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.RuntimeEnvironment;
import java.util.ArrayList;
import java.util.Arrays;
@RunWith(RobolectricTestRunner.class)
public class BaiDuPanTest {
private Application mockContext;
private BaiDuPan spider;
@org.junit.Before
public void setUp() throws Exception {
mockContext = RuntimeEnvironment.application;
Init.init(mockContext);
spider = new BaiDuPan();
// spider.init(mockContext, "b-user-id=89ede34e-0efc-e1dd-c997-f16aaa792d0c; _UP_A4A_11_=wb9661c6dfb642f88f73d8e0c7edd398; b-user-id=89ede34e-0efc-e1dd-c997-f16aaa792d0c; ctoken=wla6p3EUOLyn1FSB8IKp1SEW; grey-id=5583e32b-39df-4bf0-f39f-1adf83f604a2; grey-id.sig=p8ReBIMG2BeZu1sYvsuOAZxYbx-MVrsfKEiCv87MsTM; isQuark=true; isQuark.sig=hUgqObykqFom5Y09bll94T1sS9abT1X-4Df_lzgl8nM; _UP_F7E_8D_=ZkyvVHnrBLp1A1NFJIjWi0PwKLOVbxJPcg0RzQPI6KmBtV6ZMgPh38l93pgubgHDQqhaZ2Sfc0qv%2BRantbfg1mWGAUpRMP4RqXP78Wvu%2FCfvkWWGc5NhCTV71tGOIGgDBR3%2Bu6%2Fjj44KlE5biSNDOWW7Bigcz27lvOTidzNw8s%2FWtKAIxWbnCzZn4%2FJMBUub1SIMcW89g57k4mfPmDlCgpZKzxwl6beSfdtZ4RUWXmZOn5v5NkxVKhU4wR0Pq7NklczEGdRq2nIAcu7v22Uw2o%2FxMY0xBdeC9Korm5%2FNHnxl6K%2Bd6FXSoT9a3XIMQO359auZPiZWzrNlZe%2BqnOahXcx7KAhQIRqSOapSmL4ygJor4r5isJhRuDoXy7vJAVuH%2FRDtEJJ8rZTq0BdC23Bz%2B0MrsdgbK%2BiW; _UP_D_=pc; __wpkreporterwid_=3d3f74a7-99b7-4916-3f78-911fc2eb9d87; tfstk=fIoZNxjnbhKwPOu0TWZ4LsaRqirTcudSSmNbnxD0C5VgClMm8xMyB-GsnSu4tjpOflAOmSD-9PNiGl120XrgkVNb1SrqHbJBN3tSBAEYoQOWVUUg9qZ8n1bGGkD3CqGYINKSBABhjnXgp3_Vywz6gSc0Syj3BWf0mr2DLW24eZfiiovEKWefj1q0swq3E82iNEMinMy7SLrcpA4Fh3z_ZAViCfih3PbtdW5N_DuU77AaTijmYRkL2Wq54ENoy5a7ZXxCbok33XzS7QSZgxD-oyoVsdGotql0p2dVu7umC4nLStbiLmParc4FELHrI-c0u2dPVRrs8zoZWKCnIbNZrlHfUCMUz2z8KyXVSlgSFmUojh58OzeqTzgwaGll4YCYKwctDV5coP2LL79eKHxpNTXHmre1kZU32JPWCR_AkP2LL79eLZQY-WeUNdw1.; __pus=2051c82285199d8be553be41dd5a2100AAQ+mmv35G4FDDZ5x+3Mhe2OMbNgweQ1ODbW8zDt9YuP1LQVqHUuAAz9KWLsPjpNtim0AVGHusN4MCosTmbq/khM; __kp=e6604120-6051-11ef-bfe4-c31b6cdd0766; __kps=AATcZArVgS76EPn0FMaV4HEj; __ktd=sii/iz4ePzEaoVirXul7QQ==; __uid=AATcZArVgS76EPn0FMaV4HEj; __itrace_wid=5829b95d-dac1-48d3-bfd5-f60cd9462786; __puus=7da0b96cb710fa1b376934485f977e05AATp/q8/QupT7IiBR1GWqZhxlIRT677smMvoHlLxQA0Lk6CkP0YJBOTl+p9DZgzlMz6w4hPXPgWsokukk8PW7ZfhFfPmv8tKMgLpCGLW+tk57luhNghmSdTeVPkAF59STtyCPBEtiNzNAd/zZJ6qILJDi5ywEBAAAg+gOyWHoLHNUR+QxeHRuQa8g5WWA95J8jebIlrr8rCvI1vjTbtiYktT");
spider.init(mockContext, "BIDUPSID=D122360716A06862B6689D4FE32053A1; PSTM=1756869077; MAWEBCUID=web_KAGxElHEQyrFImqrzARlkIssFfvhfCLGaXDsxmWKbhxsfEsvhs; PANWEB=1; H_WISE_SIDS_BFESS=110085_656765_660924_665265_666660_667682_662823_668348_668761_668756_669314_667565_669628_669693_669848_669685_669681_670119_670114_670116_670307_669051_670308_670357_670598_669700_670824_669791_669664_670557_667838_669418_663788; MCITY=-276%3A; csrfToken=6tn2uwGoOUgn87ZBElHEGjCD; newlogin=1; XFI=627d86b0-a655-11f0-b1eb-0f9d37032cfb; XFCS=B8C411ADE99EE9C3B29FDF31558D538BB636F205DF4F52FE2E57F1312E01079F; XFT=yvSTf+EcMsgYHnGyS774OLqljjYcjil0ZkCgy1g0Aso=; Hm_lvt_182d6d59474cf78db37e0b2248640ea5=1760154644; BDORZ=B490B5EBF6F3CD402E515D22BCDA1598; Hm_lvt_fa0277816200010a74ab7d2895df481b=1760339732; Hm_lpvt_fa0277816200010a74ab7d2895df481b=1760344537; BAIDUID=BFD9E2570D797C8F01BC34C196D7E6B7:FG=1; H_PS_PSSID=60279_63143_64005_64983_65126_65194_65248_65272_65368_65420_65450_65510_65538_65543_65618_65599_65633_65656_65674_65667_65653_65706_65713; BAIDUID_BFESS=BFD9E2570D797C8F01BC34C196D7E6B7:FG=1; delPer=0; PSINO=5; H_WISE_SIDS=60279_63143_64005_64983_65126_65194_65248_65272_65368_65420_65450_65510_65538_65543_65618_65599_65633_65656_65674_65667_65653_65706_65713; BA_HECTOR=ak24050g8ha5ah018l0g2g802ke50i1ker7km25; ZFY=LJHc036:AkCyc1OPqFkXugSCgXnfaMIH:AjDQUOfkXtP4:C; BDCLND=vGxYxxMPQqznqvbjTPyD6CQEOejzkIZgEuuv9D5ctzM%3D; ndut_fmt=C6428C500AB0E62AC4B1CBB9671EF7803530C20D2457081012790E5079FD5D8E; ab_sr=1.0.1_MjFjNTFiYTgwYzAxOWFlOWJmYTRmYjUwYmQwNmJkYTg4NTkxYzA4YTk1YTU0MWIxMDQ1YjgzN2QzZGU4Y2MxMzRlNGQ4M2YxNjJmNzliNWFkMjg0N2U4ZWUzOGRiMzljNzM0MmJmMjc2YzQwYmJhYzdmMWU2NThkYmQ4MjRlODRlZDA0Mjc2ZWE3YmQxNGZiZGE3Yzk1MDU1Njk3NmVlOQ==; ppfuid=FOCoIC3q5fKa8fgJnwzbE67EJ49BGJeplOzf+4l4EOvDuu2RXBRv6R3A1AZMa49I27C0gDDLrJyxcIIeAeEhD8JYsoLTpBiaCXhLqvzbzmvy3SeAW17tKgNq/Xx+RgOdb8TWCFe62MVrDTY6lMf2GrfqL8c87KLF2qFER3obJGmVXQmqM6seEAgB/LlOs0+zGEimjy3MrXEpSuItnI4KDwxAMUTOS16BfoXMcd2lpC/ZmOvCi7lsE0/UM0w4HSMVhh7EfifsXEYHtGj52zkQan6UDL686lBL6BHUyL9m3lfGgLbz7OSojK1zRbqBESR5Pdk2R9IA3lxxOVzA+Iw1TWLSgWjlFVG9Xmh1+20oPSbrzvDjYtVPmZ+9/6evcXmhcO1Y58MgLozKnaQIaLfWRFwa8A3ZyTRp/cDxRMhYc97xUSUZS0ReZYJMPG6nCsxNJlhI2UyeJA6QroZFMelR7tnTNS/pLMWceus0e757/UMPmrThfasmhDJrMFcBfoSrAAv3LCf1Y7/fHL3PTSf9vid/u2VLX4h1nBtx8EF07eCMhWVv+2qjbPV7ZhXk3reaWRFEeso3s/Kc9n/UXtUfNU1sHiCdbrCW5yYsuSM9SPGDZsl7FhTAKw7qIu38vFZiq+DRc8Vbf7jOiN9xPe0lOdZHUhGHZ82rL5jTCsILwcRVCndrarbwmu7G154MpYiKmTXZkqV7Alo4QZzicdyMbWvwvmR2/m//YVTM8qeZWgDSHjDmtehgLWM45zARbPujeqU0T92Gmgs89l2htrSKITeYE0TpfIvjPXsgyQghyP8U3sViHT1z07gbfu1XO5QQ/upk1AkHGkWrkbMWm+rpwpdImdyxYIjA1uSy2hfTFv/d3cnXH4nh+maaicAPllDgrppZTr0lDf2Vsiy73L8egP9ck5gsaaSE4obz9V1JGvyp8lNw+IyCN2Gou0efGgcYWqtuH+3KMtXW4uAv+XUaBDreXqEwrDxmyUrecavkqQ9rGRChHnhPuJeIKACPXiVuli9ItRLEkdb1mLxNHAk3uJy88YX/Rf/sKUjR12zxRTDxxJNDJS+Dlsbqu3n4I65ujli/3rQ8Zk1MjmTOsz9+kTqOM4upsnQ6IWq/zeZTItMCgHpQhuhr4ip73honuzoJgge1cqWBFYvpabAPTOERTOP1kmx5SXPARX5uxyJzAiNILBC8zh7fGfNXOWV37O9gEbYklWGnWpu55tg8Y8GaT7BFVDtu1KaJzjx51nTN1+xVI8c7otOFm3py1Y+wrt2CfI5v5JSd2kRNZE7s6bQrA5yMI31SfUDgxDrsd6lPtUU=; BDUSS=YyTmxnRVJQN2FOeXpOZU5TazhHdX56a1h3NnlsTmVaUlFqTEFKSm43aTNPaFZwSVFBQUFBJCQAAAAAAAAAAAEAAAB0wRMxMTIzNDWwtMqxtPLL4wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAALet7Wi3re1odF; BDUSS_BFESS=YyTmxnRVJQN2FOeXpOZU5TazhHdX56a1h3NnlsTmVaUlFqTEFKSm43aTNPaFZwSVFBQUFBJCQAAAAAAAAAAAEAAAB0wRMxMTIzNDWwtMqxtPLL4wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAALet7Wi3re1odF; STOKEN=7970ecc47cebf55b8bbd63fee5e5e4b612753bceae56d51073b1b69bab616df6; PANPSC=17920541514426231310%3Au9Rut0jYI4omsQqGlPk7plcS2d9ns3O5C61tf8CKQkigT9ngiMB1eA3MPJHnDhkC6WRWG5ljYM%2BmSRyxE8aegpNZSd%2B1SXYsBm6rqQ5QdYLMOw0WWU7tUSqLe%2F%2Bg%2FDWP4i2i1JdCg%2BQ3uGXWluwqDsVi7NXtJ9t339k3FioH%2FAqA1gqZJvix0rmqJrAOClKcX0r3JWTW68Ah7IX89yGaj0Eyueu6wBwEDZC8PXQ9dy48%2FX4Y2hjenzCvC2qz1EInzo%2F1llKJ4P7gQiGlDEks0p8M%2Flyi7z69BCKhGHn%2Fawh9ff8YI35KVRVksnPVbyr%2FTaFwbj9JM%2FCSsVZaqyA8TA%3D%3D; Hm_lpvt_182d6d59474cf78db37e0b2248640ea5=1760406982");
}
@org.junit.Test
public void init() throws Exception {
spider.init(mockContext, "BIDUPSID=D122360716A06862B6689D4FE32053A1; PSTM=1756869077; MAWEBCUID=web_KAGxElHEQyrFImqrzARlkIssFfvhfCLGaXDsxmWKbhxsfEsvhs; PANWEB=1; H_WISE_SIDS_BFESS=110085_656765_660924_665265_666660_667682_662823_668348_668761_668756_669314_667565_669628_669693_669848_669685_669681_670119_670114_670116_670307_669051_670308_670357_670598_669700_670824_669791_669664_670557_667838_669418_663788; MCITY=-276%3A; csrfToken=6tn2uwGoOUgn87ZBElHEGjCD; newlogin=1; XFI=627d86b0-a655-11f0-b1eb-0f9d37032cfb; XFCS=B8C411ADE99EE9C3B29FDF31558D538BB636F205DF4F52FE2E57F1312E01079F; XFT=yvSTf+EcMsgYHnGyS774OLqljjYcjil0ZkCgy1g0Aso=; Hm_lvt_182d6d59474cf78db37e0b2248640ea5=1760154644; BDORZ=B490B5EBF6F3CD402E515D22BCDA1598; Hm_lvt_fa0277816200010a74ab7d2895df481b=1760339732; Hm_lpvt_fa0277816200010a74ab7d2895df481b=1760344537; BAIDUID=BFD9E2570D797C8F01BC34C196D7E6B7:FG=1; H_PS_PSSID=60279_63143_64005_64983_65126_65194_65248_65272_65368_65420_65450_65510_65538_65543_65618_65599_65633_65656_65674_65667_65653_65706_65713; BAIDUID_BFESS=BFD9E2570D797C8F01BC34C196D7E6B7:FG=1; delPer=0; PSINO=5; H_WISE_SIDS=60279_63143_64005_64983_65126_65194_65248_65272_65368_65420_65450_65510_65538_65543_65618_65599_65633_65656_65674_65667_65653_65706_65713; BA_HECTOR=ak24050g8ha5ah018l0g2g802ke50i1ker7km25; ZFY=LJHc036:AkCyc1OPqFkXugSCgXnfaMIH:AjDQUOfkXtP4:C; BDCLND=vGxYxxMPQqznqvbjTPyD6CQEOejzkIZgEuuv9D5ctzM%3D; ndut_fmt=C6428C500AB0E62AC4B1CBB9671EF7803530C20D2457081012790E5079FD5D8E; ab_sr=1.0.1_MjFjNTFiYTgwYzAxOWFlOWJmYTRmYjUwYmQwNmJkYTg4NTkxYzA4YTk1YTU0MWIxMDQ1YjgzN2QzZGU4Y2MxMzRlNGQ4M2YxNjJmNzliNWFkMjg0N2U4ZWUzOGRiMzljNzM0MmJmMjc2YzQwYmJhYzdmMWU2NThkYmQ4MjRlODRlZDA0Mjc2ZWE3YmQxNGZiZGE3Yzk1MDU1Njk3NmVlOQ==; ppfuid=FOCoIC3q5fKa8fgJnwzbE67EJ49BGJeplOzf+4l4EOvDuu2RXBRv6R3A1AZMa49I27C0gDDLrJyxcIIeAeEhD8JYsoLTpBiaCXhLqvzbzmvy3SeAW17tKgNq/Xx+RgOdb8TWCFe62MVrDTY6lMf2GrfqL8c87KLF2qFER3obJGmVXQmqM6seEAgB/LlOs0+zGEimjy3MrXEpSuItnI4KDwxAMUTOS16BfoXMcd2lpC/ZmOvCi7lsE0/UM0w4HSMVhh7EfifsXEYHtGj52zkQan6UDL686lBL6BHUyL9m3lfGgLbz7OSojK1zRbqBESR5Pdk2R9IA3lxxOVzA+Iw1TWLSgWjlFVG9Xmh1+20oPSbrzvDjYtVPmZ+9/6evcXmhcO1Y58MgLozKnaQIaLfWRFwa8A3ZyTRp/cDxRMhYc97xUSUZS0ReZYJMPG6nCsxNJlhI2UyeJA6QroZFMelR7tnTNS/pLMWceus0e757/UMPmrThfasmhDJrMFcBfoSrAAv3LCf1Y7/fHL3PTSf9vid/u2VLX4h1nBtx8EF07eCMhWVv+2qjbPV7ZhXk3reaWRFEeso3s/Kc9n/UXtUfNU1sHiCdbrCW5yYsuSM9SPGDZsl7FhTAKw7qIu38vFZiq+DRc8Vbf7jOiN9xPe0lOdZHUhGHZ82rL5jTCsILwcRVCndrarbwmu7G154MpYiKmTXZkqV7Alo4QZzicdyMbWvwvmR2/m//YVTM8qeZWgDSHjDmtehgLWM45zARbPujeqU0T92Gmgs89l2htrSKITeYE0TpfIvjPXsgyQghyP8U3sViHT1z07gbfu1XO5QQ/upk1AkHGkWrkbMWm+rpwpdImdyxYIjA1uSy2hfTFv/d3cnXH4nh+maaicAPllDgrppZTr0lDf2Vsiy73L8egP9ck5gsaaSE4obz9V1JGvyp8lNw+IyCN2Gou0efGgcYWqtuH+3KMtXW4uAv+XUaBDreXqEwrDxmyUrecavkqQ9rGRChHnhPuJeIKACPXiVuli9ItRLEkdb1mLxNHAk3uJy88YX/Rf/sKUjR12zxRTDxxJNDJS+Dlsbqu3n4I65ujli/3rQ8Zk1MjmTOsz9+kTqOM4upsnQ6IWq/zeZTItMCgHpQhuhr4ip73honuzoJgge1cqWBFYvpabAPTOERTOP1kmx5SXPARX5uxyJzAiNILBC8zh7fGfNXOWV37O9gEbYklWGnWpu55tg8Y8GaT7BFVDtu1KaJzjx51nTN1+xVI8c7otOFm3py1Y+wrt2CfI5v5JSd2kRNZE7s6bQrA5yMI31SfUDgxDrsd6lPtUU=; BDUSS=YyTmxnRVJQN2FOeXpOZU5TazhHdX56a1h3NnlsTmVaUlFqTEFKSm43aTNPaFZwSVFBQUFBJCQAAAAAAAAAAAEAAAB0wRMxMTIzNDWwtMqxtPLL4wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAALet7Wi3re1odF; BDUSS_BFESS=YyTmxnRVJQN2FOeXpOZU5TazhHdX56a1h3NnlsTmVaUlFqTEFKSm43aTNPaFZwSVFBQUFBJCQAAAAAAAAAAAEAAAB0wRMxMTIzNDWwtMqxtPLL4wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAALet7Wi3re1odF; STOKEN=7970ecc47cebf55b8bbd63fee5e5e4b612753bceae56d51073b1b69bab616df6; PANPSC=17920541514426231310%3Au9Rut0jYI4omsQqGlPk7plcS2d9ns3O5C61tf8CKQkigT9ngiMB1eA3MPJHnDhkC6WRWG5ljYM%2BmSRyxE8aegpNZSd%2B1SXYsBm6rqQ5QdYLMOw0WWU7tUSqLe%2F%2Bg%2FDWP4i2i1JdCg%2BQ3uGXWluwqDsVi7NXtJ9t339k3FioH%2FAqA1gqZJvix0rmqJrAOClKcX0r3JWTW68Ah7IX89yGaj0Eyueu6wBwEDZC8PXQ9dy48%2FX4Y2hjenzCvC2qz1EInzo%2F1llKJ4P7gQiGlDEks0p8M%2Flyi7z69BCKhGHn%2Fawh9ff8YI35KVRVksnPVbyr%2FTaFwbj9JM%2FCSsVZaqyA8TA%3D%3D; Hm_lpvt_182d6d59474cf78db37e0b2248640ea5=1760406982");
//Assert.assertFalse(map.getAsJsonArray("list").isEmpty());
}
@org.junit.Test
public void detailContent() throws Exception {
String content = spider.detailContent(Arrays.asList("https://pan.baidu.com/s/1Ov0S6S7rqnyW_S3AondhmQ?pwd=8888"));
System.out.println("detailContent--" + content);
JsonObject map = Json.safeObject(content);
Gson gson = new GsonBuilder().setPrettyPrinting().create();
System.out.println("detailContent--" + gson.toJson(map));
Assert.assertFalse(map.getAsJsonArray("list").isEmpty());
}
@org.junit.Test
public void playerContent() throws Exception {
String content = spider.playerContent("BD原画", "eyJ1ayI6IjExMDMyNzkxMjIzNDEiLCJzaGFyZWlkIjoiMjk1NzE4ODcyOTgiLCJmaWQiOjMxOTM5NTUxMTQyOTU4MCwicmFuZHNrIjoidkd4WXh4TVBRcXpucXZialRQeUQ2Q1FFT2VqemtJWmdFdXV2OUQ1Y3R6TSUzRCIsInBuYW1lIjoiRHJhZ29uIEJhbGwgREFJTUEuUzAxRTAxLjIwMjQuMTA4MHAuQ1IuV0VCLURMLngyNjQuQUFDLm1rdiIsInF0eXBlIjoib3JpZ2luYWwifQ==", new ArrayList<>());
// String content = spider.playerContent("BD转码", "eyJ1ayI6IjExMDMyNzkxMjIzNDEiLCJmaWQiOjMxOTE2ODY2NDUxMzY1Nywic2hhcmVpZCI6IjI5NTcxODg3Mjk4Iiwic3VybCI6IjFPdjBTNlM3cnFueVdfUzNBb25kaG1RIiwicG5hbWUiOiJEcmFnb24gQmFsbCBEQUlNQS5TMDFFMjAuMjAyNC4xMDgwcC5DUi5XRUItREwueDI2NC5BQUMubWt2IiwicXR5cGUiOiJwcmV2aWV3In0=", new ArrayList<>());
System.out.println("playerContent--" + content);
JsonObject map = Json.safeObject(content);
Gson gson = new GsonBuilder().setPrettyPrinting().create();
System.out.println("playerContent--" + gson.toJson(map));
Assert.assertFalse(map.getAsJsonPrimitive("url").getAsString().isEmpty());
while (true) {
Thread.sleep(1000);
}
}
}

View File

@ -2,26 +2,20 @@ package com.github.catvod.api
import com.github.catvod.utils.Json import com.github.catvod.utils.Json
import kotlinx.coroutines.runBlocking import kotlinx.coroutines.runBlocking
import org.junit.Before
import org.junit.Test import org.junit.Test
import org.junit.runner.RunWith import org.junit.runner.RunWith
import org.robolectric.RobolectricTestRunner import org.robolectric.RobolectricTestRunner
@RunWith(RobolectricTestRunner::class) @RunWith(RobolectricTestRunner::class)
class BaiduDriveTest { class BaiduDriveTest {
var yunDrive: BaiduDrive? = null
@Before
fun setUp() {
yunDrive = BaiduDrive()
}
@Test @Test
fun getShareList() { fun getShareList() {
runBlocking { runBlocking {
val reslut = yunDrive?.processShareLinks(listOf("https://pan.baidu.com/s/1f0y60RkYcSsp4EwWolKgJg?pwd=c26q")) val reslut =
BaiduDrive.processShareLinks(listOf("https://pan.baidu.com/s/1Ov0S6S7rqnyW_S3AondhmQ?pwd=8888"))
System.out.println(Json.toJson(reslut)) System.out.println(Json.toJson(reslut))
} }
} }
@ -30,7 +24,7 @@ class BaiduDriveTest {
fun getBdUid() { fun getBdUid() {
runBlocking { runBlocking {
val reslut = yunDrive?.getBdUid() val reslut = BaiduDrive.getBdUid()
System.out.println(reslut) System.out.println(reslut)
} }
} }
@ -41,24 +35,44 @@ class BaiduDriveTest {
com.github.catvod.utils.Util.base64Decode("eyJ1ayI6IjExMDI4NjAxODI4OTgiLCJmaWQiOjE1NTY5Mzk0MDE4MjQ2NCwic2hhcmVpZCI6IjUzNDc0MDY5NzI0Iiwic3VybCI6IjFmMHk2MFJrWWNTc3A0RXdXb2xLZ0pnIiwicG5hbWUiOiIwNeWbveivrS00Sy7pq5jnoIHnjocubXA0IiwicXR5cGUiOiJwcmV2aWV3In0=") com.github.catvod.utils.Util.base64Decode("eyJ1ayI6IjExMDI4NjAxODI4OTgiLCJmaWQiOjE1NTY5Mzk0MDE4MjQ2NCwic2hhcmVpZCI6IjUzNDc0MDY5NzI0Iiwic3VybCI6IjFmMHk2MFJrWWNTc3A0RXdXb2xLZ0pnIiwicG5hbWUiOiIwNeWbveivrS00Sy7pq5jnoIHnjocubXA0IiwicXR5cGUiOiJwcmV2aWV3In0=")
val obj = Json.safeObject(jsonStr) val obj = Json.safeObject(jsonStr)
runBlocking { runBlocking {
val reslut = yunDrive?._getSign(obj) val reslut = BaiduDrive._getSign(obj)
System.out.println(reslut) System.out.println(reslut)
} }
}@Test
fun getVideoUrl() {
/* val jsonStr = }
com.github.catvod.utils.Util.base64Decode("eyJ1ayI6IjExMDI4NjAxODI4OTgiLCJmaWQiOjE1NTY5Mzk0MDE4MjQ2NCwic2hhcmVpZCI6IjUzNDc0MDY5NzI0Iiwic3VybCI6IjFmMHk2MFJrWWNTc3A0RXdXb2xLZ0pnIiwicG5hbWUiOiIwNeWbveivrS00Sy7pq5jnoIHnjocubXA0IiwicXR5cGUiOiJwcmV2aWV3In0=")
@Test
fun getVideoUrl() {/* val jsonStr =
com.github.catvod.utils.Util.base64Decode("eyJ1ayI6IjExMDI4NjAxODI4OTgiLCJmaWQiOjE1NTY5Mzk0MDE4MjQ2NCwic2hhcmVpZCI6IjUzNDc0MDY5NzI0Iiwic3VybCI6IjFmMHk2MFJrWWNTc3A0RXdXb2xLZ0pnIiwicG5hbWUiOiIwNeWbveivrS00Sy7pq5jnoIHnjocubXA0IiwicXR5cGUiOiJwcmV2aWV3In0=")
val obj = Json.safeObject(jsonStr)
runBlocking {
val reslut = yunDrive?.getVideoUrl(obj)
System.out.println(reslut)
}*/
val jsonStr =
com.github.catvod.utils.Util.base64Decode("eyJ1ayI6IjExMDMyNzkxMjIzNDEiLCJzaGFyZWlkIjoiMjk1NzE4ODcyOTgiLCJmaWQiOjMxOTM5NTUxMTQyOTU4MCwicmFuZHNrIjoidkd4WXh4TVBRcXpucXZialRQeUQ2Q1FFT2VqemtJWmdFdXV2OUQ1Y3R6TSUzRCIsInBuYW1lIjoiRHJhZ29uIEJhbGwgREFJTUEuUzAxRTAxLjIwMjQuMTA4MHAuQ1IuV0VCLURMLngyNjQuQUFDLm1rdiIsInF0eXBlIjoib3JpZ2luYWwifQ==")
val obj = Json.safeObject(jsonStr) val obj = Json.safeObject(jsonStr)
runBlocking { runBlocking {
val reslut = yunDrive?.getVideoUrl(obj) val reslut = BaiduDrive.getVideoUrl(obj, "BD原画1")
System.out.println(reslut)
}*/ val jsonStr =
com.github.catvod.utils.Util.base64Decode("eyJ1ayI6IjExMDI4NjAxODI4OTgiLCJzaGFyZWlkIjoiNTM0NzQwNjk3MjQiLCJmaWQiOjgzNDA3NTIyODU4MjM4NywicmFuZHNrIjoibkdOVnlCdTlNS3BXSDd6bFRzNW9VeEZkUlFYdmFpMzAwR25GazlNR2IxQSUzRCIsInBuYW1lIjoiMDEgNEsubXA0IiwicXR5cGUiOiJvcmlnaW5hbCJ9")
val obj = Json.safeObject(jsonStr)
runBlocking {
val reslut = yunDrive?.getVideoUrl(obj)
System.out.println(reslut) System.out.println(reslut)
} }
} }
@Test
fun createSaveDir() {/* val jsonStr =
com.github.catvod.utils.Util.base64Decode("eyJ1ayI6IjExMDI4NjAxODI4OTgiLCJmaWQiOjE1NTY5Mzk0MDE4MjQ2NCwic2hhcmVpZCI6IjUzNDc0MDY5NzI0Iiwic3VybCI6IjFmMHk2MFJrWWNTc3A0RXdXb2xLZ0pnIiwicG5hbWUiOiIwNeWbveivrS00Sy7pq5jnoIHnjocubXA0IiwicXR5cGUiOiJwcmV2aWV3In0=")
val obj = Json.safeObject(jsonStr)
runBlocking {
val reslut = yunDrive?.getVideoUrl(obj)
System.out.println(reslut)
}*/
runBlocking {
val reslut = BaiduDrive.createSaveDir()
System.out.println(reslut)
}
}
} }

View File

@ -1,5 +1,5 @@
{ {
"spider": "https://wget.la/https://raw.githubusercontent.com/lushunming/AndroidCatVodSpider/bd/jar/custom_spider.jar;md5;851711824c28c744517e650d914bf07d", "spider": "https://andoridspidermt.netlify.app/jar/custom_spider.jar;md5;49c24003ea2a52abb468ad7661ae1730",
"lives": [ "lives": [
{ {
"name": "电视直播", "name": "电视直播",