791 lines
27 KiB
Kotlin
791 lines
27 KiB
Kotlin
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.utils.Json
|
|
import com.github.catvod.utils.ProxyServer.buildProxyUrl
|
|
import com.github.catvod.utils.Util
|
|
import com.github.catvod.utils.Util.MEDIA
|
|
import com.google.gson.JsonObject
|
|
import java.util.*
|
|
|
|
object BaiduDrive {
|
|
private val cache = mutableMapOf<String, String>();
|
|
|
|
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",
|
|
"Accept" to "application/json, text/plain, */*",
|
|
"Content-Type" to "application/x-www-form-urlencoded",
|
|
"Origin" to "https://pan.baidu.com",
|
|
"Referer" to "https://pan.baidu.com/"
|
|
)
|
|
|
|
|
|
private val saveDirName = "TVBOX_BD"
|
|
|
|
private var cookies = BaiDuYunHandler.get().token
|
|
|
|
|
|
private val apiHost = "https://pan.baidu.com"
|
|
private val displayName = listOf("BD原画")
|
|
|
|
|
|
fun setCookie(extend: String) {
|
|
if (extend.isEmpty()) return
|
|
cookies = extend
|
|
}
|
|
|
|
fun processShareLinks(urls: List<String>): Pair<List<String>, List<String>> {
|
|
//首先确保cookie不为空
|
|
if (cookies.isEmpty()) {
|
|
BaiDuYunHandler.get().startScan()
|
|
cookies = BaiDuYunHandler.get().token
|
|
}
|
|
if (urls.isEmpty()) return emptyList<String>() to emptyList()
|
|
|
|
|
|
val results = urls.map { url ->
|
|
processSingleLink(url)
|
|
}
|
|
|
|
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 fun processSingleLink(url: String): Pair<List<String>, List<String>>? {
|
|
return try {
|
|
val urlInfo = parseShareUrl(url)
|
|
if (urlInfo.containsKey("error")) return null
|
|
|
|
val tokenInfo = getShareToken(urlInfo)
|
|
if (tokenInfo?.containsKey("error") == true) return null
|
|
|
|
getAllVideos(tokenInfo!!)
|
|
} catch (e: Exception) {
|
|
e.printStackTrace()
|
|
null
|
|
}
|
|
}
|
|
|
|
private fun parseShareUrl(url: String): Map<String, String> {
|
|
var lurl = url
|
|
if ("提取码" in url) lurl = url.replace("提取码:", "?pwd=")
|
|
|
|
if ("/share/" !in url) {
|
|
val response = OkHttp.getLocation(url, headers)
|
|
lurl = response ?: ""
|
|
}
|
|
|
|
val queryParams = parseQueryParams(lurl)
|
|
val finalUrl = if ("/share/" in url) url.replace("share/init?surl=", "s/1") else url
|
|
|
|
return mapOf<String, String>(
|
|
"url" to finalUrl,
|
|
"surl" to (queryParams["surl"]?.firstOrNull() ?: ""),
|
|
"pwd" to (queryParams["pwd"]?.firstOrNull() ?: "")
|
|
)
|
|
}
|
|
|
|
private fun getShareToken(urlInfo: Map<String, String>): Map<String, String>? {
|
|
val params = mapOf(
|
|
"t" to System.currentTimeMillis().toString(), "surl" to (urlInfo["surl"] ?: "")
|
|
)
|
|
|
|
val data = mapOf("pwd" to (urlInfo["pwd"] ?: ""))
|
|
|
|
val response = OkHttp.post(
|
|
"$apiHost/share/verify?t=${params["t"]}&surl=${params["surl"]}", data, headers
|
|
)
|
|
|
|
// if ("error" in response) return response
|
|
val json = Json.safeObject(response.body)
|
|
|
|
|
|
val randsk = json.asJsonObject.get("randsk").asString ?: return mapOf("error" to "获取randsk失败")
|
|
|
|
return mapOf(
|
|
"yurl" to (urlInfo["url"]?.split("s/")?.last()?.split("?")?.first() ?: ""),
|
|
"randsk" to randsk,
|
|
"surl" to (urlInfo["surl"] ?: "")
|
|
)
|
|
}
|
|
|
|
private fun getAllVideos(tokenInfo: Map<String, String>): Pair<List<String>, List<String>> {
|
|
val videos = mutableListOf<String>()
|
|
val avideos = mutableListOf<String>()
|
|
val seenFolders = mutableSetOf<String>()
|
|
val pendingFolders = mutableListOf<Map<String, Any>>()
|
|
|
|
try {
|
|
// 处理根目录
|
|
var currentPage = 1
|
|
var uk = ""
|
|
var shareid = ""
|
|
|
|
while (true) {
|
|
val rootFolder = mutableMapOf(
|
|
"surl" to tokenInfo["surl"]!!,
|
|
"randsk" to tokenInfo["randsk"]!!,
|
|
"page" to currentPage,
|
|
"is_root" to true
|
|
)
|
|
|
|
val rootResult = getFolderContents(rootFolder)
|
|
// if ("error" in rootResult) break
|
|
val data = rootResult?.asJsonObject
|
|
|
|
val items = data?.get("list")?.asJsonArray ?: break
|
|
|
|
if (items.isEmpty) break
|
|
|
|
// 第一页获取uk和shareid
|
|
if (currentPage == 1) {
|
|
uk = data["uk"]?.toString() ?: ""
|
|
shareid = data["share_id"]?.toString() ?: ""
|
|
if (uk.isEmpty() || shareid.isEmpty()) return emptyList<String>() to emptyList()
|
|
}
|
|
|
|
// 处理items
|
|
items.forEach { item ->
|
|
if (item.asJsonObject["isdir"].asInt == 1) {
|
|
val folderPath = "/sharelink$uk-$shareid/${item.asJsonObject["server_filename"].asString}"
|
|
if (folderPath !in seenFolders) {
|
|
seenFolders.add(folderPath)
|
|
pendingFolders.add(
|
|
mapOf(
|
|
"surl" to tokenInfo["surl"]!!,
|
|
"randsk" to tokenInfo["randsk"]!!,
|
|
"uk" to uk,
|
|
"shareid" to shareid,
|
|
"dir" to folderPath,
|
|
"page" to 1
|
|
)
|
|
)
|
|
}
|
|
} else if (isVideoFile(item.asJsonObject["server_filename"].asString ?: "")) {
|
|
addVideo(item.asJsonObject, uk, shareid, tokenInfo, avideos, videos)
|
|
}
|
|
}
|
|
|
|
if (items.size() < 9999) break
|
|
currentPage++
|
|
}
|
|
|
|
// 处理子文件夹
|
|
while (pendingFolders.isNotEmpty()) {
|
|
val currentBatch = pendingFolders.toList()
|
|
pendingFolders.clear()
|
|
|
|
val results = currentBatch.map { folderInfo ->
|
|
getFolderContents(folderInfo)
|
|
}
|
|
|
|
results.forEachIndexed { i, result ->
|
|
val folderInfo = currentBatch[i]
|
|
//if ("error" in result) return@forEachIndexed
|
|
|
|
val items = result?.asJsonObject?.get("list")?.asJsonArray ?: return@forEachIndexed
|
|
|
|
items.forEach { item ->
|
|
if (item.asJsonObject["isdir"].asInt == 1) {
|
|
val folderPath = item.asJsonObject["path"].asString ?: ""
|
|
if (folderPath !in seenFolders) {
|
|
seenFolders.add(folderPath)
|
|
pendingFolders.add(
|
|
mapOf(
|
|
"surl" to tokenInfo["surl"]!!,
|
|
"randsk" to tokenInfo["randsk"]!!,
|
|
"uk" to folderInfo["uk"]!!,
|
|
"shareid" to folderInfo["shareid"]!!,
|
|
"dir" to folderPath,
|
|
"page" to 1
|
|
)
|
|
)
|
|
}
|
|
} else if (isVideoFile(item.asJsonObject["server_filename"].asString ?: "")) {
|
|
addVideo(
|
|
item.asJsonObject,
|
|
folderInfo["uk"]?.toString() ?: "",
|
|
folderInfo["shareid"]?.toString() ?: "",
|
|
tokenInfo,
|
|
avideos,
|
|
videos
|
|
)
|
|
}
|
|
}
|
|
|
|
if (items.size() >= 9999) {
|
|
pendingFolders.add(folderInfo.toMutableMap().apply {
|
|
this["page"] = (this["page"] as Int) + 1
|
|
})
|
|
}
|
|
}
|
|
}
|
|
|
|
return avideos to videos
|
|
} catch (e: Exception) {
|
|
e.printStackTrace()
|
|
return emptyList<String>() to emptyList()
|
|
}
|
|
}
|
|
|
|
private fun isVideoFile(string: String): Boolean {
|
|
|
|
return string.substringAfterLast(".").lowercase(Locale.ROOT) in MEDIA
|
|
}
|
|
|
|
private fun addVideo(
|
|
item: JsonObject,
|
|
uk: String,
|
|
shareid: String,
|
|
tokenInfo: Map<String, String>,
|
|
avideos: MutableList<String>,
|
|
videos: MutableList<String>
|
|
) {
|
|
val sizeStr = formatSize(item["size"].asLong)
|
|
val name = item["server_filename"] ?: ""
|
|
|
|
val originalData = mapOf(
|
|
"uk" to uk,
|
|
"shareid" to shareid,
|
|
"fid" to item["fs_id"],
|
|
"randsk" to tokenInfo["randsk"],
|
|
"pname" to name,
|
|
"qtype" to "original"
|
|
)
|
|
|
|
val previewData = mapOf(
|
|
"uk" to uk,
|
|
"fid" to item["fs_id"],
|
|
"shareid" to shareid,
|
|
"surl" to tokenInfo["yurl"],
|
|
"pname" to name,
|
|
"qtype" to "preview"
|
|
)
|
|
|
|
avideos.add(
|
|
"[$sizeStr]$name$${
|
|
Util.base64Encode(Json.toJson(originalData).toByteArray())
|
|
}"
|
|
)
|
|
videos.add(
|
|
"[$sizeStr]$name$${
|
|
Util.base64Encode(Json.toJson(previewData).toByteArray())
|
|
}"
|
|
)
|
|
}
|
|
|
|
private fun getFolderContents(folderInfo: Map<String, Any>): JsonObject? {
|
|
val params = if (folderInfo.containsKey("dir")) {
|
|
mapOf(
|
|
"uk" to folderInfo["uk"]!!.toString(),
|
|
"shareid" to folderInfo["shareid"]!!.toString(),
|
|
"page" to folderInfo["page"].toString(),
|
|
"num" to "9999",
|
|
"dir" to folderInfo["dir"]!!.toString(),
|
|
"desc" to "0",
|
|
"order" to "name",
|
|
)
|
|
} else {
|
|
mapOf(
|
|
"page" to folderInfo["page"].toString(),
|
|
"num" to "9999",
|
|
"shorturl" to folderInfo["surl"]!!.toString(),
|
|
"root" to "1",
|
|
"desc" to "0",
|
|
"order" to "name",
|
|
)
|
|
}
|
|
|
|
|
|
val tempHeader = headers.toMutableMap()
|
|
tempHeader.put("Cookie", "BDCLND=${folderInfo["randsk"]}")
|
|
val result = OkHttp.string("$apiHost/share/list", params, tempHeader)
|
|
return Json.safeObject(result)
|
|
|
|
}
|
|
|
|
|
|
private fun parseQueryParams(url: String): Map<String, List<String>> {
|
|
val query = url.substringAfter(
|
|
"?"
|
|
).substringBefore('#')
|
|
return query.split('&').associate {
|
|
val (key, value) = it.split('=', limit = 2)
|
|
key to listOf(value)
|
|
}
|
|
}
|
|
|
|
private fun formatSize(bytes: Long): String {
|
|
if (bytes <= 0) return "0 B"
|
|
val units = arrayOf("B", "KB", "MB", "GB", "TB")
|
|
val digitGroups = (Math.log10(bytes.toDouble()) / Math.log10(1024.0)).toInt()
|
|
return "%.1f %s".format(bytes / Math.pow(1024.0, digitGroups.toDouble()), units[digitGroups])
|
|
}
|
|
|
|
|
|
fun getBdUid(): String? {
|
|
if (cache["uid"] != null) {
|
|
return cache["uid"]
|
|
}
|
|
val tempHeader = headers.toMutableMap()
|
|
tempHeader.put("Cookie", cookies)
|
|
try {
|
|
val response = OkHttp.string(
|
|
|
|
"https://mbd.baidu.com/userx/v1/info/get?appname=baiduboxapp&fields=%20%20%20%20%20%20%20%20%5B%22bg_image%22,%22member%22,%22uid%22,%22avatar%22,%20%22avatar_member%22%5D&client&clientfrom&lang=zh-cn&tpl&ttt",
|
|
emptyMap<String, String>(),
|
|
tempHeader
|
|
|
|
)
|
|
|
|
val responseJson = Json.safeObject(response)
|
|
val user = responseJson["data"].asJsonObject
|
|
|
|
val fields = user?.get("fields")?.asJsonObject
|
|
|
|
val uidValue = fields?.get("uid")?.asString
|
|
|
|
if (uidValue != null) {
|
|
cache["uid"] = uidValue
|
|
return uidValue
|
|
} else {
|
|
throw Exception("Failed to retrieve UID from Baidu Drive.")
|
|
}
|
|
} catch (e: Exception) {
|
|
println("获取百度网盘用户ID失败: ${e.message}")
|
|
return ""
|
|
}
|
|
}
|
|
|
|
fun _getSign(videoData: JsonObject): Pair<String, String> {
|
|
val tempHeader = headers.toMutableMap()
|
|
tempHeader.put("Cookie", cookies)
|
|
val response: String? = OkHttp.string(
|
|
"${apiHost}/share/tplconfig", mapOf<String, String>(
|
|
"surl" to videoData["surl"].asString, "fields" to "cfrom_id,Espace_info,card_info,sign,timestamp"
|
|
),
|
|
|
|
tempHeader
|
|
)
|
|
return try {
|
|
val data = Json.safeObject(response)["data"].asJsonObject
|
|
|
|
data["sign"].asString to data["timestamp"].asString
|
|
} catch (_: Exception) {
|
|
"" to ""
|
|
}
|
|
}
|
|
|
|
|
|
fun _getDownloadUrl(videoData: JsonObject): String {
|
|
return try {
|
|
var cookie = ""
|
|
val BDCLND = "BDCLND=" + videoData["randsk"].asString
|
|
// 更新Cookie中的BDCLND值
|
|
if (!this.cookies.contains("BDCLND")) {
|
|
cookie = this.cookies + ";" + BDCLND
|
|
|
|
} else {
|
|
cookie = this.cookies.split(";").joinToString(";") {
|
|
if (it.contains("BDCLND")) {
|
|
BDCLND
|
|
} else {
|
|
it
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
|
|
val transferHeaders = mapOf(
|
|
"User-Agent" to "Android",
|
|
"Connection" to "Keep-Alive",
|
|
"Content-Type" to "application/x-www-form-urlencoded",
|
|
"Accept-Language" to "zh-CN,zh;q=0.8",
|
|
"charset" to "UTF-8",
|
|
"Referer" to "https://pan.baidu.com",
|
|
"Cookie" to cookie
|
|
)
|
|
// 先清空文件夹在创建文件夹
|
|
|
|
_deleteTransferFile("/$saveDirName")
|
|
//创建路径
|
|
createSaveDir()
|
|
|
|
|
|
val data =
|
|
"from=${videoData["uk"].asString}&shareid=${videoData["shareid"].asString}&ondup=newcopy&path=/${saveDirName}&fsidlist=[${videoData["fid"].asString}]"
|
|
|
|
var to = ""
|
|
for (i in 1..30) {
|
|
|
|
|
|
val response =
|
|
OkHttp.post("${apiHost}/share/transfer?${data}", emptyMap<String, String>(), transferHeaders)
|
|
|
|
val result = Json.safeObject(response.body)
|
|
|
|
try {
|
|
to = (result["extra"].asJsonObject)["list"].asJsonArray[0].asJsonObject["to"].asString
|
|
// videoData["to"] = to
|
|
if (to.isNotEmpty()) {
|
|
println("成功转存文件到: $to")
|
|
break
|
|
}
|
|
} catch (e: Exception) {
|
|
println("解析转存响应出错: ${e.message}")
|
|
continue
|
|
}
|
|
}
|
|
|
|
if (to.isEmpty()) {
|
|
println("转存文件失败,无法获取下载链接")
|
|
return ""
|
|
}
|
|
|
|
val mediaInfoHeaders = mapOf(
|
|
|
|
"User-Agent" to "netdisk;1.4.2;22021211RC;android-android;12;JSbridge4.4.0;jointBridge;1.1.0;",
|
|
"Connection" to "Keep-Alive",
|
|
"Accept-Language" to "zh-CN,zh;q=0.8",
|
|
"charset" to "UTF-8",
|
|
"Cookie" to cookie
|
|
).toMutableMap()
|
|
|
|
|
|
val mediaInfoParams = mapOf(
|
|
"type" to "M3U8_FLV_264_480", "path" to "/$to", "clienttype" to "80", "origin" to "dlna"
|
|
)
|
|
|
|
|
|
val mediaInfoResponse: String? = OkHttp.string(
|
|
"${apiHost}/api/mediainfo", mediaInfoParams, mediaInfoHeaders
|
|
)
|
|
val responseJson = Json.safeObject(mediaInfoResponse)
|
|
val info = responseJson["info"].asJsonObject
|
|
val downloadUrl = info["dlink"].asString
|
|
println("获取到下载链接: $downloadUrl")
|
|
downloadUrl
|
|
} catch (e: Exception) {
|
|
println("获取下载链接过程中出错: ${e.message}")
|
|
e.printStackTrace()
|
|
""
|
|
}
|
|
}
|
|
|
|
fun getVideoUrl(videoData: JsonObject, flag: String): Map<String, Any> {
|
|
return try {
|
|
val bdUid = getBdUid()
|
|
println("获取百度网盘用户ID: $bdUid")
|
|
|
|
if (flag.contains("原画")) {
|
|
|
|
var headersApp = mapOf("User-Agent" to "netdisk;P2SP;2.2.91.136;android-android;")
|
|
|
|
var downloadUrl = _getAppDownloadUrl(videoData)
|
|
if (downloadUrl.isEmpty()) {
|
|
|
|
headersApp = mapOf(
|
|
|
|
"User-Agent" to "netdisk;1.4.2;22021211RC;android-android;12;JSbridge4.4.0;jointBridge;1.1.0;"
|
|
)
|
|
|
|
downloadUrl = _getDownloadUrl(videoData)
|
|
}
|
|
if (downloadUrl.isNotEmpty()) {
|
|
|
|
val result = mapOf(
|
|
"parse" to "0", "url" to downloadUrl, "header" to headersApp
|
|
)
|
|
|
|
result
|
|
} else {
|
|
_handleError
|
|
}
|
|
} else {
|
|
val (sign, time) = _getSign(videoData)
|
|
if (sign.isEmpty() || time.isEmpty()) {
|
|
return _handleError
|
|
}
|
|
val plist = _getPlayList(videoData, sign, time)
|
|
val tempHeader = headers.toMutableMap()
|
|
tempHeader.put("Cookie", cookies)
|
|
mapOf(
|
|
"parse" to "0", "url" to plist[0], "header" to tempHeader
|
|
)
|
|
}
|
|
} catch (e: Exception) {
|
|
println("获取播放链接失败: ${e.message}")
|
|
_handleError
|
|
}
|
|
}
|
|
|
|
private fun _getAppDownloadUrl(videoData: JsonObject): String {
|
|
return try {
|
|
val headers = mapOf<String, String>(
|
|
|
|
"User-Agent" to "netdisk;P2SP;2.2.91.136;android-android;",
|
|
"Connection" to "Keep-Alive",
|
|
"Accept-Language" to "zh-CN,zh;q=0.8",
|
|
"charset" to "UTF-8",
|
|
"cookie" to cookies
|
|
)
|
|
val uid = this.getBdUid()
|
|
val t = System.currentTimeMillis()
|
|
val params = mapOf<String, String>(
|
|
"shareid" to videoData["shareid"].asString,
|
|
"uk" to videoData["uk"].asString,
|
|
"fid" to videoData["fid"].asString,
|
|
"sekey" to unquote(videoData["randsk"].asString),
|
|
"origin" to "dlna",
|
|
"devuid" to "73CED981D0F186D12BC18CAE1684FFD5|VSRCQTF6W",
|
|
"clienttype" to "1",
|
|
"channel" to "android_12_zhao_bd-netdisk_1024266h",
|
|
"version" to "11.30.2",
|
|
"time" to t.toString()
|
|
).toMutableMap()
|
|
|
|
val randstr = this.sha1(
|
|
this.sha1(
|
|
Util.findByRegex(
|
|
"BDUSS=(.+?);", cookies, 1
|
|
)
|
|
) + uid + "ebrcUYiuxaZv2XGu7KIYKxUrqfnOfpDF$t${params["devuid"]}11.30.2ae5821440fab5e1a61a025f014bd8972"
|
|
)
|
|
|
|
params.put("rand", randstr)
|
|
|
|
val response = OkHttp.string(
|
|
"${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 list = url["list"] as List<Map<String, Any>>
|
|
val dlink = list[0]["dlink"] as String
|
|
|
|
val pDataResponse = client.get(dlink) {
|
|
headers { this@_getAppDownloadUrl.headers.forEach { name, value -> append(name, value) } }
|
|
cookies?.let { setCookie(it) }
|
|
followRedirects = false
|
|
timeout.socketTimeoutMillis = 10000
|
|
}
|
|
|
|
val pUrl = pDataResponse.headers[HttpHeaders.Location]?.toString()
|
|
pUrl ?: dlink*/
|
|
dlink
|
|
} catch (e: Exception) {
|
|
println("获取下载链接失败: ${e.message}")
|
|
""
|
|
}
|
|
}
|
|
|
|
private fun _getPlayList(videoData: JsonObject, sign: String, time: String): List<String> {
|
|
val hz = getPlayFormatList()
|
|
val plist = mutableListOf<String>()
|
|
|
|
for (quality in hz) {
|
|
val url =
|
|
("${apiHost}/share/streaming?" + "uk=${videoData["uk"].asString}&" + "fid=${videoData["fid"].asString}&" + "sign=$sign&" + "timestamp=$time&" + "shareid=${videoData["shareid"].asString}&" + "type=M3U8_AUTO_${
|
|
quality.replace(
|
|
"P", ""
|
|
)
|
|
}")
|
|
plist.add(url)
|
|
}
|
|
|
|
return plist
|
|
}
|
|
|
|
/**
|
|
* 创建保存目录
|
|
*/
|
|
fun createSaveDir(): Long? {
|
|
var saveDirId: Long? = null
|
|
// 创建保存目录
|
|
if (cookies.isEmpty()) {
|
|
return null
|
|
}
|
|
val tempHeader = headers.toMutableMap()
|
|
tempHeader.put("Cookie", cookies)
|
|
return try {
|
|
val listResp = OkHttp.string(
|
|
"${apiHost}/api/list", mapOf(
|
|
"dir" to "/",
|
|
"order" to "name",
|
|
"desc" to "0",
|
|
"showempty" to "0",
|
|
"web" to "1",
|
|
"app_id" to "250528"
|
|
), tempHeader
|
|
)
|
|
val json = Json.safeObject(listResp)
|
|
|
|
if (json["errno"].asInt != 0) {
|
|
return null
|
|
}
|
|
|
|
val drpyDir = json["list"].asJsonArray.find { item ->
|
|
item.asJsonObject.get("isdir").asInt == 1 && item.asJsonObject.get("server_filename").asString == saveDirName
|
|
|
|
}
|
|
|
|
if (drpyDir != null) {
|
|
saveDirId = drpyDir.asJsonObject.get("fs_id").asLong
|
|
return saveDirId
|
|
}
|
|
|
|
val createResp = OkHttp.post(
|
|
"${apiHost}/api/create?a=commit&bdstoken=${getBdstoken()}&clienttype=0&app_id=250528&web=1&dp-logid=73131200762376420075",
|
|
mapOf(
|
|
"path" to "//$saveDirName",
|
|
"isdir" to "1",
|
|
"block_list" to "[]",
|
|
|
|
),
|
|
tempHeader
|
|
)
|
|
val createJson = Json.safeObject(createResp.body)
|
|
|
|
|
|
|
|
saveDirId = createJson["fs_id"].asLong
|
|
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 {
|
|
return encoded.replace("%([0-9A-Fa-f]{2})".toRegex()) { match ->
|
|
Integer.parseInt(match.groupValues[1], 16).toChar().toString()
|
|
}
|
|
}
|
|
|
|
private fun sha1(input: String): String {
|
|
|
|
return Util.sha1Hex(input)
|
|
}
|
|
|
|
private val _handleError = mapOf(
|
|
"parse" to "1", "msg" to "Error retrieving video URL"
|
|
)
|
|
|
|
|
|
fun getVod(shareUrl: String): Vod {
|
|
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()
|
|
}
|
|
|
|
|
|
}
|