From f3911d8b683421775fa05fa90cc2fb2c6b20d580 Mon Sep 17 00:00:00 2001 From: Kelvin Date: Thu, 29 Aug 2024 19:52:40 +0200 Subject: [PATCH] HLS Audio auto download fix, httpClient setTimeout support --- .../api/http/ManagedHttpClient.kt | 21 ++++++++++++++++++- .../platformplayer/downloads/VideoDownload.kt | 17 ++++++++++----- .../engine/packages/PackageHttp.kt | 6 ++++++ 3 files changed, 38 insertions(+), 6 deletions(-) diff --git a/app/src/main/java/com/futo/platformplayer/api/http/ManagedHttpClient.kt b/app/src/main/java/com/futo/platformplayer/api/http/ManagedHttpClient.kt index 5121f41e..0192d6c0 100644 --- a/app/src/main/java/com/futo/platformplayer/api/http/ManagedHttpClient.kt +++ b/app/src/main/java/com/futo/platformplayer/api/http/ManagedHttpClient.kt @@ -17,13 +17,14 @@ import okhttp3.WebSocket import okhttp3.WebSocketListener import java.security.SecureRandom import java.security.cert.X509Certificate +import java.time.Duration import javax.net.ssl.SSLContext import javax.net.ssl.TrustManager import javax.net.ssl.X509TrustManager import kotlin.system.measureTimeMillis open class ManagedHttpClient { - protected val _builderTemplate: OkHttpClient.Builder; + protected var _builderTemplate: OkHttpClient.Builder; private var client: OkHttpClient; @@ -32,6 +33,15 @@ open class ManagedHttpClient { var user_agent = "Mozilla/5.0 (Windows NT 10.0; rv:91.0) Gecko/20100101 Firefox/91.0" + fun setTimeout(timeout: Long) { + rebuildClient { + it.callTimeout(Duration.ofMillis(client.callTimeoutMillis.toLong())) + .writeTimeout(Duration.ofMillis(client.writeTimeoutMillis.toLong())) + .readTimeout(Duration.ofMillis(client.readTimeoutMillis.toLong())) + .connectTimeout(Duration.ofMillis(timeout)); + } + } + private val trustAllCerts = arrayOf( object: X509TrustManager { override fun checkClientTrusted(chain: Array?, authType: String?) { } @@ -62,6 +72,15 @@ open class ManagedHttpClient { }.build(); } + fun rebuildClient(modify: (OkHttpClient.Builder) -> OkHttpClient.Builder) { + _builderTemplate = modify(_builderTemplate); + client = _builderTemplate.addNetworkInterceptor { chain -> + val request = beforeRequest(chain.request()); + val response = afterRequest(chain.proceed(request)); + return@addNetworkInterceptor response; + }.build(); + } + open fun clone(): ManagedHttpClient { val clonedClient = ManagedHttpClient(_builderTemplate); clonedClient.user_agent = user_agent; diff --git a/app/src/main/java/com/futo/platformplayer/downloads/VideoDownload.kt b/app/src/main/java/com/futo/platformplayer/downloads/VideoDownload.kt index 7de33363..2b24ee13 100644 --- a/app/src/main/java/com/futo/platformplayer/downloads/VideoDownload.kt +++ b/app/src/main/java/com/futo/platformplayer/downloads/VideoDownload.kt @@ -13,6 +13,7 @@ import com.futo.platformplayer.api.media.models.streams.sources.AudioUrlSource import com.futo.platformplayer.api.media.models.streams.sources.IAudioSource import com.futo.platformplayer.api.media.models.streams.sources.IAudioUrlSource import com.futo.platformplayer.api.media.models.streams.sources.IDashManifestSource +import com.futo.platformplayer.api.media.models.streams.sources.IHLSManifestAudioSource import com.futo.platformplayer.api.media.models.streams.sources.IHLSManifestSource import com.futo.platformplayer.api.media.models.streams.sources.IVideoSource import com.futo.platformplayer.api.media.models.streams.sources.IVideoUrlSource @@ -281,14 +282,17 @@ class VideoDownload { vsource = VideoHelper.selectBestVideoSource(videoSources, targetPixelCount!!.toInt(), arrayOf()) // ?: throw IllegalStateException("Could not find a valid video source for video"); - if(vsource == null) + if(vsource == null) { videoSource = null; + if(original.video.videoSources.size == 0) + requireVideoSource = false; + } else if(vsource is IVideoUrlSource) videoSource = VideoUrlSource.fromUrlSource(vsource) else if(vsource is JSSource && requiresLiveVideoSource) videoSourceLive = vsource; else - throw DownloadException("Video source is not supported for downloading (yet)", false); + throw DownloadException("Video source is not supported for downloading (yet) [" + vsource?.javaClass?.name + "]", false); } if(audioSource == null && targetBitrate != null) { @@ -296,7 +300,7 @@ class VideoDownload { val video = original.video if (video is VideoUnMuxedSourceDescriptor) { for (source in video.audioSources) { - if (source is IHLSManifestSource) { + if (source is IHLSManifestAudioSource) { try { val playlistResponse = client.get(source.url) if (playlistResponse.isOk) { @@ -328,14 +332,17 @@ class VideoDownload { asource = VideoHelper.selectBestAudioSource(audioSources, arrayOf(), null, targetBitrate) ?: if(videoSource != null ) null else throw DownloadException("Could not find a valid video or audio source for download") - if(asource == null) + if(asource == null) { audioSource = null; + if(!original.video.isUnMuxed || original.video.videoSources.size == 0) + requireVideoSource = false; + } else if(asource is IAudioUrlSource) audioSource = AudioUrlSource.fromUrlSource(asource) else if(asource is JSSource && requiresLiveAudioSource) audioSourceLive = asource; else - throw DownloadException("Audio source is not supported for downloading (yet)", false); + throw DownloadException("Audio source is not supported for downloading (yet) [" + asource?.javaClass?.name + "]", false); } if(!isVideoDownloadReady) diff --git a/app/src/main/java/com/futo/platformplayer/engine/packages/PackageHttp.kt b/app/src/main/java/com/futo/platformplayer/engine/packages/PackageHttp.kt index 4eab03f0..8535aafb 100644 --- a/app/src/main/java/com/futo/platformplayer/engine/packages/PackageHttp.kt +++ b/app/src/main/java/com/futo/platformplayer/engine/packages/PackageHttp.kt @@ -296,6 +296,12 @@ class PackageHttp: V8Package { if(_client is JSHttpClient) _client.doAllowNewCookies = allow; } + @V8Function + fun setTimeout(timeoutMs: Int) { + if(_client is JSHttpClient) { + _client.setTimeout(timeoutMs.toLong()); + } + } @V8Function fun request(method: String, url: String, headers: MutableMap = HashMap(), returnType: ReturnType) : IBridgeHttpResponse {