HLS Audio auto download fix, httpClient setTimeout support

This commit is contained in:
Kelvin 2024-08-29 19:52:40 +02:00
commit f3911d8b68
3 changed files with 38 additions and 6 deletions

View file

@ -17,13 +17,14 @@ import okhttp3.WebSocket
import okhttp3.WebSocketListener import okhttp3.WebSocketListener
import java.security.SecureRandom import java.security.SecureRandom
import java.security.cert.X509Certificate import java.security.cert.X509Certificate
import java.time.Duration
import javax.net.ssl.SSLContext import javax.net.ssl.SSLContext
import javax.net.ssl.TrustManager import javax.net.ssl.TrustManager
import javax.net.ssl.X509TrustManager import javax.net.ssl.X509TrustManager
import kotlin.system.measureTimeMillis import kotlin.system.measureTimeMillis
open class ManagedHttpClient { open class ManagedHttpClient {
protected val _builderTemplate: OkHttpClient.Builder; protected var _builderTemplate: OkHttpClient.Builder;
private var client: OkHttpClient; 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" 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<TrustManager>( private val trustAllCerts = arrayOf<TrustManager>(
object: X509TrustManager { object: X509TrustManager {
override fun checkClientTrusted(chain: Array<out X509Certificate>?, authType: String?) { } override fun checkClientTrusted(chain: Array<out X509Certificate>?, authType: String?) { }
@ -62,6 +72,15 @@ open class ManagedHttpClient {
}.build(); }.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 { open fun clone(): ManagedHttpClient {
val clonedClient = ManagedHttpClient(_builderTemplate); val clonedClient = ManagedHttpClient(_builderTemplate);
clonedClient.user_agent = user_agent; clonedClient.user_agent = user_agent;

View file

@ -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.IAudioSource
import com.futo.platformplayer.api.media.models.streams.sources.IAudioUrlSource 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.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.IHLSManifestSource
import com.futo.platformplayer.api.media.models.streams.sources.IVideoSource import com.futo.platformplayer.api.media.models.streams.sources.IVideoSource
import com.futo.platformplayer.api.media.models.streams.sources.IVideoUrlSource import com.futo.platformplayer.api.media.models.streams.sources.IVideoUrlSource
@ -281,14 +282,17 @@ class VideoDownload {
vsource = VideoHelper.selectBestVideoSource(videoSources, targetPixelCount!!.toInt(), arrayOf()) vsource = VideoHelper.selectBestVideoSource(videoSources, targetPixelCount!!.toInt(), arrayOf())
// ?: throw IllegalStateException("Could not find a valid video source for video"); // ?: throw IllegalStateException("Could not find a valid video source for video");
if(vsource == null) if(vsource == null) {
videoSource = null; videoSource = null;
if(original.video.videoSources.size == 0)
requireVideoSource = false;
}
else if(vsource is IVideoUrlSource) else if(vsource is IVideoUrlSource)
videoSource = VideoUrlSource.fromUrlSource(vsource) videoSource = VideoUrlSource.fromUrlSource(vsource)
else if(vsource is JSSource && requiresLiveVideoSource) else if(vsource is JSSource && requiresLiveVideoSource)
videoSourceLive = vsource; videoSourceLive = vsource;
else 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) { if(audioSource == null && targetBitrate != null) {
@ -296,7 +300,7 @@ class VideoDownload {
val video = original.video val video = original.video
if (video is VideoUnMuxedSourceDescriptor) { if (video is VideoUnMuxedSourceDescriptor) {
for (source in video.audioSources) { for (source in video.audioSources) {
if (source is IHLSManifestSource) { if (source is IHLSManifestAudioSource) {
try { try {
val playlistResponse = client.get(source.url) val playlistResponse = client.get(source.url)
if (playlistResponse.isOk) { if (playlistResponse.isOk) {
@ -328,14 +332,17 @@ class VideoDownload {
asource = VideoHelper.selectBestAudioSource(audioSources, arrayOf(), null, targetBitrate) asource = VideoHelper.selectBestAudioSource(audioSources, arrayOf(), null, targetBitrate)
?: if(videoSource != null ) null ?: if(videoSource != null ) null
else throw DownloadException("Could not find a valid video or audio source for download") else throw DownloadException("Could not find a valid video or audio source for download")
if(asource == null) if(asource == null) {
audioSource = null; audioSource = null;
if(!original.video.isUnMuxed || original.video.videoSources.size == 0)
requireVideoSource = false;
}
else if(asource is IAudioUrlSource) else if(asource is IAudioUrlSource)
audioSource = AudioUrlSource.fromUrlSource(asource) audioSource = AudioUrlSource.fromUrlSource(asource)
else if(asource is JSSource && requiresLiveAudioSource) else if(asource is JSSource && requiresLiveAudioSource)
audioSourceLive = asource; audioSourceLive = asource;
else 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) if(!isVideoDownloadReady)

View file

@ -296,6 +296,12 @@ class PackageHttp: V8Package {
if(_client is JSHttpClient) if(_client is JSHttpClient)
_client.doAllowNewCookies = allow; _client.doAllowNewCookies = allow;
} }
@V8Function
fun setTimeout(timeoutMs: Int) {
if(_client is JSHttpClient) {
_client.setTimeout(timeoutMs.toLong());
}
}
@V8Function @V8Function
fun request(method: String, url: String, headers: MutableMap<String, String> = HashMap(), returnType: ReturnType) : IBridgeHttpResponse { fun request(method: String, url: String, headers: MutableMap<String, String> = HashMap(), returnType: ReturnType) : IBridgeHttpResponse {