mirror of
https://github.com/FluxaMedia/fluxa.git
synced 2026-07-26 20:02:14 +00:00
Route player HTTP traffic through Cronet for QUIC/connection migration
Adds Cronet (org.chromium.net:cronet-embedded + Google's cronet-okhttp transport adapter) as an OkHttp network interceptor on the player's two HTTP clients (cache pre-warm + main ExoPlayer data source). All existing interceptor logic — header injection, Dolby Vision manifest rewriting, localhost proxy timeouts — is untouched since Cronet only replaces the final transport, not the OkHttp API surface. This mainly benefits direct-URL/debrid streams (real TLS connections), which can now survive network handoffs (wifi<->cellular) and lossy connections without a full reconnect/rebuffer. Torrent-proxied streams stay on loopback where this has no effect either way. Falls back to plain OkHttp transparently if Cronet engine creation fails for any reason (unsupported ABI, native lib issue, etc.) so there's no regression risk.
This commit is contained in:
parent
35f9c67092
commit
ad6d158f43
4 changed files with 39 additions and 0 deletions
|
|
@ -22,6 +22,8 @@ jellyfinMedia3 = "1.9.0+1"
|
|||
mpv = "1.0.0"
|
||||
retrofit = "3.0.0"
|
||||
okhttp = "5.4.0"
|
||||
cronetEmbedded = "143.7445.0"
|
||||
cronetOkhttp = "0.1.1"
|
||||
coil3 = "3.4.0"
|
||||
room = "2.8.4"
|
||||
jna = "5.17.0"
|
||||
|
|
@ -106,6 +108,8 @@ retrofit-gson = { group = "com.squareup.retrofit2", name = "converter-gson
|
|||
okhttp-logging = { group = "com.squareup.okhttp3", name = "logging-interceptor",version.ref = "okhttp" }
|
||||
okhttp-doh = { group = "com.squareup.okhttp3", name = "okhttp-dnsoverhttps",version.ref = "okhttp" }
|
||||
okhttp-mockwebserver= { group = "com.squareup.okhttp3", name = "mockwebserver", version.ref = "okhttp" }
|
||||
cronet-embedded = { group = "org.chromium.net", name = "cronet-embedded", version.ref = "cronetEmbedded" }
|
||||
cronet-okhttp = { group = "com.google.net.cronet", name = "cronet-okhttp", version.ref = "cronetOkhttp" }
|
||||
|
||||
# Coil
|
||||
coil3 = { group = "io.coil-kt.coil3", name = "coil", version.ref = "coil3" }
|
||||
|
|
|
|||
|
|
@ -51,6 +51,8 @@ kotlin {
|
|||
implementation(libs.mpv)
|
||||
implementation(libs.bundles.retrofit)
|
||||
implementation(libs.okhttp.logging)
|
||||
implementation(libs.cronet.embedded)
|
||||
implementation(libs.cronet.okhttp)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,31 @@
|
|||
package com.fluxa.app.player
|
||||
|
||||
import android.content.Context
|
||||
import android.util.Log
|
||||
import com.google.net.cronet.okhttptransport.CronetInterceptor
|
||||
import okhttp3.Interceptor
|
||||
import org.chromium.net.CronetEngine
|
||||
|
||||
private var cronetEngine: CronetEngine? = null
|
||||
private var cronetEngineInitAttempted = false
|
||||
|
||||
private fun sharedCronetEngine(context: Context): CronetEngine? {
|
||||
if (!cronetEngineInitAttempted) {
|
||||
cronetEngineInitAttempted = true
|
||||
cronetEngine = runCatching {
|
||||
CronetEngine.Builder(context.applicationContext)
|
||||
.enableHttp2(true)
|
||||
.enableQuic(true)
|
||||
.enableBrotli(true)
|
||||
.build()
|
||||
}.onFailure {
|
||||
Log.w("CronetTransport", "Cronet engine unavailable, staying on OkHttp", it)
|
||||
}.getOrNull()
|
||||
}
|
||||
return cronetEngine
|
||||
}
|
||||
|
||||
fun cronetTransportInterceptor(context: Context): Interceptor? =
|
||||
sharedCronetEngine(context)?.let { engine ->
|
||||
runCatching { CronetInterceptor.newBuilder(engine).build() }.getOrNull()
|
||||
}
|
||||
|
|
@ -196,6 +196,7 @@ class MediaPlayerController(internal val context: Context, val exoPlayer: ExoPla
|
|||
if (!shouldUsePlayerDiskCache(uri)) return
|
||||
val okHttp = OkHttpClient.Builder()
|
||||
.callTimeout(10, java.util.concurrent.TimeUnit.SECONDS)
|
||||
.apply { cronetTransportInterceptor(context)?.let { addInterceptor(it) } }
|
||||
.build()
|
||||
val upstream = OkHttpDataSource.Factory(okHttp)
|
||||
.setUserAgent(StreamRequestPolicy.DEFAULT_USER_AGENT)
|
||||
|
|
@ -266,6 +267,7 @@ class MediaPlayerController(internal val context: Context, val exoPlayer: ExoPla
|
|||
chain.proceed(chain.request())
|
||||
}
|
||||
}
|
||||
.apply { cronetTransportInterceptor(context)?.let { addInterceptor(it) } }
|
||||
.build()
|
||||
|
||||
val httpDataSourceFactory = OkHttpDataSource.Factory(okHttpClient)
|
||||
|
|
|
|||
Loading…
Reference in a new issue