kt携程版本
This commit is contained in:
parent
191d961f84
commit
ad148795a8
|
|
@ -0,0 +1,150 @@
|
||||||
|
package com.github.catvod.utils
|
||||||
|
|
||||||
|
import com.github.catvod.crawler.SpiderDebug
|
||||||
|
import com.github.catvod.net.OkHttp
|
||||||
|
import com.github.catvod.utils.ProxyVideo.generatePart
|
||||||
|
import com.github.catvod.utils.ProxyVideo.getInfo
|
||||||
|
import com.github.catvod.utils.ProxyVideo.getMimeType
|
||||||
|
import com.github.catvod.utils.ProxyVideo.parseRange
|
||||||
|
import com.github.catvod.utils.ProxyVideo.proxy
|
||||||
|
import kotlinx.coroutines.CoroutineScope
|
||||||
|
import kotlinx.coroutines.Dispatchers
|
||||||
|
import kotlinx.coroutines.Job
|
||||||
|
import kotlinx.coroutines.channels.Channel
|
||||||
|
import kotlinx.coroutines.joinAll
|
||||||
|
import kotlinx.coroutines.launch
|
||||||
|
import okhttp3.Response
|
||||||
|
import org.apache.commons.lang3.StringUtils
|
||||||
|
import java.io.InputStream
|
||||||
|
import java.io.SequenceInputStream
|
||||||
|
import java.util.Vector
|
||||||
|
|
||||||
|
object DownloadMT {
|
||||||
|
val THREAD_NUM: Int = Runtime.getRuntime().availableProcessors() * 2
|
||||||
|
|
||||||
|
private val infos = mutableMapOf<String, Array<Any>>();
|
||||||
|
fun proxyMultiThread(url: String, headers: Map<String, String>): Array<out Any?>? {
|
||||||
|
|
||||||
|
|
||||||
|
/* val service = Executors.newFixedThreadPool(THREAD_NUM)
|
||||||
|
SpiderDebug.log("--proxyMultiThread: THREAD_NUM " + THREAD_NUM)*/
|
||||||
|
|
||||||
|
val `in`: SequenceInputStream?
|
||||||
|
try {
|
||||||
|
//缓存,避免每次都请求total等信息
|
||||||
|
|
||||||
|
|
||||||
|
val info = infos[url]
|
||||||
|
if (info == null) {
|
||||||
|
infos.clear()
|
||||||
|
infos[url] = getInfo(url, headers)
|
||||||
|
}
|
||||||
|
|
||||||
|
val code = info?.get(0) as Int
|
||||||
|
if (code != 206) {
|
||||||
|
return proxy(url, headers)
|
||||||
|
}
|
||||||
|
val resHeader = info[3] as MutableMap<String, String>
|
||||||
|
val contentRange =
|
||||||
|
if (StringUtils.isAllBlank(resHeader["Content-Range"])) resHeader["content-range"] else resHeader["Content-Range"]
|
||||||
|
|
||||||
|
SpiderDebug.log("--contentRange:$contentRange")
|
||||||
|
//文件总大小
|
||||||
|
val total = StringUtils.split(contentRange, "/")[1]
|
||||||
|
SpiderDebug.log("--文件总大小:$total")
|
||||||
|
|
||||||
|
//如果文件太小,也不走代理
|
||||||
|
if (total.toLong() < 1024 * 1024 * 100) {
|
||||||
|
return proxy(url, headers)
|
||||||
|
}
|
||||||
|
var range =
|
||||||
|
if (StringUtils.isAllBlank(headers["range"])) headers["Range"] else headers["range"]
|
||||||
|
if (StringUtils.isAllBlank(range)) range = "bytes=0-";
|
||||||
|
SpiderDebug.log("---proxyMultiThread,Range:$range")
|
||||||
|
val rangeObj = parseRange(
|
||||||
|
range!!
|
||||||
|
)
|
||||||
|
//没有range,无需分割
|
||||||
|
|
||||||
|
val partList = generatePart(rangeObj, total)
|
||||||
|
|
||||||
|
// 存储执行结果的List
|
||||||
|
val jobs = mutableListOf<Job>()
|
||||||
|
val channels = List(THREAD_NUM) { Channel<Response>() }
|
||||||
|
for ((index, part) in partList.withIndex()) {
|
||||||
|
|
||||||
|
|
||||||
|
val newRange = "bytes=" + part[0] + "-" + part[1]
|
||||||
|
SpiderDebug.log("下载开始;newRange:$newRange")
|
||||||
|
|
||||||
|
val headerNew: MutableMap<String, String> = HashMap(headers)
|
||||||
|
|
||||||
|
headerNew["range"] = newRange
|
||||||
|
headerNew["Range"] = newRange
|
||||||
|
jobs += CoroutineScope(Dispatchers.IO).launch {
|
||||||
|
downloadRange(url, headerNew)?.let { channels[index].send(it) };
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
val inputStreams: MutableList<InputStream> = ArrayList()
|
||||||
|
CoroutineScope(Dispatchers.Default).launch {
|
||||||
|
repeat(jobs.size) { index ->
|
||||||
|
launch {
|
||||||
|
val response = channels[index].receive()
|
||||||
|
val body = response.body();/* int bytesRead;
|
||||||
|
while ((bytesRead = body.byteStream().read(bytes)) != -1) {
|
||||||
|
out.write(bytes, 0, bytesRead);
|
||||||
|
}*/
|
||||||
|
inputStreams.add(body!!.byteStream())
|
||||||
|
|
||||||
|
|
||||||
|
SpiderDebug.log("---第" + index + "块下载完成" + ";Content-Range:" + response.headers()["Content-Range"])
|
||||||
|
SpiderDebug.log("---第" + index + "块下载完成" + ";content-range:" + response.headers()["content-range"])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// 等待所有下载完成
|
||||||
|
jobs.joinAll()
|
||||||
|
}
|
||||||
|
|
||||||
|
`in` = SequenceInputStream(Vector(inputStreams).elements())
|
||||||
|
|
||||||
|
|
||||||
|
// SpiderDebug.log(" ++proxy res data:" + Json.toJson(response.body()));
|
||||||
|
var contentType: String? = if (StringUtils.isAllBlank(
|
||||||
|
resHeader["Content-Type"]
|
||||||
|
)
|
||||||
|
) resHeader["content-type"] else resHeader["Content-Type"]
|
||||||
|
val contentDisposition: String = resHeader["Content-Disposition"]!!.toString()
|
||||||
|
if (StringUtils.isAllBlank(contentType)&& StringUtils.isNoneBlank(contentDisposition)) {
|
||||||
|
contentType = getMimeType(contentDisposition)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* respHeaders.put("Access-Control-Allow-Credentials", "true");
|
||||||
|
respHeaders.put("Access-Control-Allow-Origin", "*");*/
|
||||||
|
resHeader["Content-Length"] =
|
||||||
|
(partList[THREAD_NUM - 1][1] - partList[0][0] + 1).toString()
|
||||||
|
// respHeaders.put("content-length", String.valueOf(bytes.length));
|
||||||
|
resHeader["Content-Range"] = String.format(
|
||||||
|
"bytes %s-%s/%s", partList[0][0], partList[THREAD_NUM - 1][1], total
|
||||||
|
)
|
||||||
|
// respHeaders.put("content-range", String.format("bytes %s-%s/%s", partList.get(0)[0], partList.get(THREAD_NUM - 1)[1], total));
|
||||||
|
SpiderDebug.log("++proxy res contentType:$contentType")
|
||||||
|
// SpiderDebug.log("++proxy res body:" + response.body());
|
||||||
|
SpiderDebug.log("++proxy res respHeaders:" + Json.toJson(resHeader))
|
||||||
|
return arrayOf(206, contentType, `in`, resHeader)
|
||||||
|
|
||||||
|
} catch (e: Exception) {
|
||||||
|
SpiderDebug.log("proxyMultiThread error:" + e.message)
|
||||||
|
e.printStackTrace()
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private fun downloadRange(
|
||||||
|
url: String, headerNew: MutableMap<String, String>
|
||||||
|
): Response? = OkHttp.newCall(url, headerNew)
|
||||||
|
}
|
||||||
Binary file not shown.
|
|
@ -1 +1 @@
|
||||||
860afdcd1a39fd5c0bcfae2b0652ec7c
|
2d18b21a13a3e7b982f1d1642d975c9b
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
{
|
{
|
||||||
"spider": "https://gh-proxy.com/https://raw.githubusercontent.com/lushunming/AndroidCatVodSpider/multiThreadkt/jar/custom_spider.jar;md5;860afdcd1a39fd5c0bcfae2b0652ec7c",
|
"spider": "https://gh-proxy.com/https://raw.githubusercontent.com/lushunming/AndroidCatVodSpider/multiThreadkt/jar/custom_spider.jar;md5;2d18b21a13a3e7b982f1d1642d975c9b",
|
||||||
"lives": [
|
"lives": [
|
||||||
{
|
{
|
||||||
"name": "电视直播",
|
"name": "电视直播",
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue