diff --git a/app/proguard-rules.pro b/app/proguard-rules.pro index e3575c65..cde8d2ad 100644 --- a/app/proguard-rules.pro +++ b/app/proguard-rules.pro @@ -47,32 +47,12 @@ # Please add these rules to your existing keep rules in order to suppress warnings. # This is generated automatically by the Android Gradle plugin. -# Ignore warnings from Netty --dontwarn io.netty.** --dontwarn java.lang.management.ManagementFactory --dontwarn java.lang.management.RuntimeMXBean --dontwarn org.apache.log4j.Level --dontwarn org.apache.log4j.Logger --dontwarn org.apache.log4j.Priority --dontwarn org.apache.logging.log4j.Level --dontwarn org.apache.logging.log4j.LogManager --dontwarn org.apache.logging.log4j.Logger --dontwarn org.apache.logging.log4j.message.MessageFactory --dontwarn org.apache.logging.log4j.spi.ExtendedLogger --dontwarn org.apache.logging.log4j.spi.ExtendedLoggerWrapper --dontwarn org.conscrypt.BufferAllocator --dontwarn org.conscrypt.Conscrypt --dontwarn org.conscrypt.HandshakeListener --dontwarn org.eclipse.jetty.npn.NextProtoNego$ClientProvider --dontwarn org.eclipse.jetty.npn.NextProtoNego$Provider --dontwarn org.eclipse.jetty.npn.NextProtoNego$ServerProvider --dontwarn org.eclipse.jetty.npn.NextProtoNego --dontwarn reactor.blockhound.integration.BlockHoundIntegration +-dontwarn sun.misc.Service +-dontwarn sun.misc.ServiceConfigurationError +-dontwarn sun.security.action.GetBooleanAction +-dontwarn sun.security.action.GetIntegerAction +-dontwarn sun.security.action.GetLongAction -# Ktor Server - - --keep class io.ktor.server.config.HoconConfigLoader { *; } # Logback (Custom rules, see https://github.com/krschultz/android-proguard-snippets/blob/master/libraries/proguard-logback-android.pro) @@ -94,52 +74,7 @@ -keepattributes SourceFile,LineNumberTable --keepattributes Signature,InnerClasses -# 保留所有 Netty 类 --keep class io.netty.** { *; } -# 保留 Netty 的内部类 --keep class io.netty.**$* { *; } - -# 保留 Netty 的注解 --keep @interface io.netty.** - -# 保留 Netty 的 native 方法 --keepclasseswithmembernames,includedescriptorclasses class io.netty.** { - native ; -} - -# 保留 Netty 的序列化相关类 --keepclassmembers class io.netty.** implements java.io.Serializable { - static final long serialVersionUID; - private static final java.io.ObjectStreamField[] serialPersistentFields; - private void writeObject(java.io.ObjectOutputStream); - private void readObject(java.io.ObjectInputStream); - java.lang.Object writeReplace(); - java.lang.Object readResolve(); -} - -# 保留 Netty 的 ChannelFuture 相关类 --keep class io.netty.channel.ChannelFuture { *; } --keep class io.netty.util.concurrent.Future { *; } - -# 保留 Netty 的异常类 --keep class io.netty.** extends java.lang.Exception { *; } - -# 保留 Netty 的注解处理器 --keepclassmembers class * extends io.netty.** { - @io.netty.** *; -} - -# 不警告 Netty 相关的类 --dontwarn io.netty.** -# Please add these rules to your existing keep rules in order to suppress warnings. -# This is generated automatically by the Android Gradle plugin. --dontwarn java.beans.BeanInfo --dontwarn java.beans.IntrospectionException --dontwarn java.beans.Introspector --dontwarn java.beans.PropertyDescriptor --dontwarn javax.lang.model.element.Modifier diff --git a/app/src/main/java/com/github/catvod/utils/ProxyServer.kt b/app/src/main/java/com/github/catvod/utils/ProxyServer.kt index 21fce42b..2cad67ee 100644 --- a/app/src/main/java/com/github/catvod/utils/ProxyServer.kt +++ b/app/src/main/java/com/github/catvod/utils/ProxyServer.kt @@ -11,6 +11,9 @@ import kotlinx.coroutines.Job import kotlinx.coroutines.channels.Channel import kotlinx.coroutines.launch import kotlinx.coroutines.withContext +import okhttp3.Headers +import java.io.BufferedOutputStream +import java.io.ByteArrayOutputStream import java.io.OutputStreamWriter import java.net.InetSocketAddress import java.nio.charset.Charset @@ -21,6 +24,7 @@ object ProxyServer { private const val partSize = 1024 * 1024 * 1 private var port = 0 private var httpServer: HttpServer? = null + private val infos = mutableMapOf>>(); fun stop() { httpServer?.stop(1_000) @@ -33,6 +37,8 @@ object ProxyServer { httpServer = HttpServer.create(InetSocketAddress(port), 100); httpServer?.createContext("/") { httpExchange -> run { + httpExchange.sendResponseHeaders(200, "server running ".length.toLong()); + val os = httpExchange.responseBody val writer = OutputStreamWriter(os, Charset.defaultCharset()) writer.write("server running ") @@ -68,8 +74,8 @@ object ProxyServer { httpServer?.stop(1000) } - - SpiderDebug.log("ktorServer start on " + httpServer?.address?.port) + port = httpServer?.address?.port!! + SpiderDebug.log("ktorServer start on " + port) } @@ -78,6 +84,9 @@ object ProxyServer { ) { val channels = List(THREAD_NUM) { Channel() } val outputStream = httpExchange.responseBody + + val bufferedOutputStream = BufferedOutputStream(outputStream) + try { SpiderDebug.log("--proxyMultiThread: THREAD_NUM: $THREAD_NUM") @@ -96,15 +105,24 @@ object ProxyServer { val (startPoint, endPoint) = parseRangePoint( rangeHeader ) + + //缓存response header + var info = infos[url] + if (info == null) { + info = getInfo(url, headers) + infos[url] = info + } + SpiderDebug.log("startPoint: $startPoint; endPoint: $endPoint") - val contentLength = getContentLength(url, headers) + val contentLength = getContentLength(info) SpiderDebug.log("contentLength: $contentLength") val finalEndPoint = if (endPoint == -1L) contentLength - 1 else endPoint httpExchange.responseHeaders.apply { set("Connection", "keep-alive") - set("ContentLength", (finalEndPoint - startPoint + 1).toString()) - set("ContentRange", "bytes $startPoint-$finalEndPoint/$contentLength") + set("Content-Length", (finalEndPoint - startPoint + 1).toString()) + set("Content-Range", "bytes $startPoint-$finalEndPoint/$contentLength") + set("Content-Type", info["Content-Type"]?.get(0)) } httpExchange.sendResponseHeaders(206, 0) @@ -138,23 +156,23 @@ object ProxyServer { val data = channels[index].receive() SpiderDebug.log("Received chunk: ${data.size} bytes") - CoroutineScope(Dispatchers.IO).launch { - outputStream.write(data) - } - } + bufferedOutputStream.write(data) + bufferedOutputStream.flush() + + } } } catch (e: Exception) { SpiderDebug.log("error: ${e.message}") - withContext(Dispatchers.IO) { - outputStream.write("error: ${e.message}".toByteArray()) - } + + outputStream.write("error: ${e.message}".toByteArray()) + } finally { channels.forEach { it.close() } - withContext(Dispatchers.IO) { - outputStream.close() - } + bufferedOutputStream.close() + outputStream.close() + httpExchange.close() } } @@ -185,11 +203,20 @@ object ProxyServer { return start to end } - private fun getContentLength(url: String, headers: Map): Long { - // 实现获取内容长度逻辑 + fun getInfo( + url: String?, headers: Map + ): MutableMap> { + val newHeaders: MutableMap = java.util.HashMap(headers) + newHeaders["Range"] = "bytes=0-" + (1024 * 1024 - 1) + newHeaders["range"] = "bytes=0-" + (1024 * 1024 - 1) val res = OkHttp.newCall(url, headers) res.body()?.close() - return res.headers("Content-Length")[0]?.toLong() ?: 0L + return res.headers().toMultimap() + } + + private fun getContentLength(info: MutableMap>): Long { + // 实现获取内容长度逻辑 + return info["Content-Length"]?.get(0)?.toLong() ?: 0L } private fun getVideoStream( diff --git a/app/src/test/java/com/github/catvod/utils/ProxyVideoTest.java b/app/src/test/java/com/github/catvod/utils/ProxyVideoTest.java index 691d103c..9476e6f1 100644 --- a/app/src/test/java/com/github/catvod/utils/ProxyVideoTest.java +++ b/app/src/test/java/com/github/catvod/utils/ProxyVideoTest.java @@ -6,7 +6,7 @@ import org.robolectric.RobolectricTestRunner; import java.util.HashMap; -//@RunWith(RobolectricTestRunner.class) +@RunWith(RobolectricTestRunner.class) public class ProxyVideoTest { @Test @@ -18,7 +18,7 @@ public class ProxyVideoTest { "http://172.16.1.217:18089/ng-grid/video.mp4", new HashMap<>()); System.out.println(url);*/ ProxyServer.INSTANCE.start(); - System.out.println(ProxyServer.INSTANCE.buildProxyUrl("http://172.16.1.217:18089/ng-grid/video.mp4", new HashMap<>())); + System.out.println(ProxyServer.INSTANCE.buildProxyUrl("https://media.w3.org/2010/05/sintel/trailer.mp4", new HashMap<>())); while (true) { } diff --git a/jar/custom_spider.jar b/jar/custom_spider.jar index 0a12fd44..7ee15743 100644 Binary files a/jar/custom_spider.jar and b/jar/custom_spider.jar differ diff --git a/jar/custom_spider.jar.md5 b/jar/custom_spider.jar.md5 index 4c655aea..03d6f15a 100644 --- a/jar/custom_spider.jar.md5 +++ b/jar/custom_spider.jar.md5 @@ -1 +1 @@ -9013187cddf48a5b4bf4604b07dd534b +2b55efe5a17ba216363ab2bef3b69d05 diff --git a/json/test.json b/json/test.json index 4aae7f90..7f12c99a 100644 --- a/json/test.json +++ b/json/test.json @@ -1,5 +1,5 @@ { - "spider": "https://gh.llkk.cc/https://raw.githubusercontent.com/lushunming/AndroidCatVodSpider/multiThreadNew/jar/custom_spider.jar;md5;8a9fee904fd090f7eb5ec9eb73fc257a", + "spider": "https://gh.llkk.cc/https://raw.githubusercontent.com/lushunming/AndroidCatVodSpider/multiThreadNew/jar/custom_spider.jar;md5;2b55efe5a17ba216363ab2bef3b69d05", "lives": [ { "name": "电视直播",