mirror of
https://github.com/TeamNewPipe/NewPipe
synced 2025-05-07 18:04:07 +00:00
Recreate poToken generator if current is broken
This will be tried only once, and afterwards an error will be thrown
This commit is contained in:
parent
0066b322e1
commit
f856bd9306
@ -1,5 +1,7 @@
|
|||||||
package org.schabi.newpipe.util.potoken
|
package org.schabi.newpipe.util.potoken
|
||||||
|
|
||||||
|
import android.os.Handler
|
||||||
|
import android.os.Looper
|
||||||
import android.util.Log
|
import android.util.Log
|
||||||
import org.schabi.newpipe.App
|
import org.schabi.newpipe.App
|
||||||
import org.schabi.newpipe.extractor.NewPipe
|
import org.schabi.newpipe.extractor.NewPipe
|
||||||
@ -22,33 +24,68 @@ object PoTokenProviderImpl : PoTokenProvider {
|
|||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
|
|
||||||
val (poTokenGenerator, visitorData, streamingPot) = synchronized(WebPoTokenGenLock) {
|
return getWebClientPoToken(videoId = videoId, forceRecreate = false)
|
||||||
if (webPoTokenGenerator == null || webPoTokenGenerator!!.isExpired()) {
|
}
|
||||||
webPoTokenGenerator = PoTokenWebView.newPoTokenGenerator(App.getApp()).blockingGet()
|
|
||||||
webPoTokenVisitorData = YoutubeParsingHelper
|
|
||||||
.randomVisitorData(NewPipe.getPreferredContentCountry())
|
|
||||||
|
|
||||||
// The streaming poToken needs to be generated exactly once before generating any
|
/**
|
||||||
// other (player) tokens.
|
* @param forceRecreate whether to force the recreation of [webPoTokenGenerator], to be used in
|
||||||
webPoTokenStreamingPot = webPoTokenGenerator!!
|
* case the current [webPoTokenGenerator] threw an error last time
|
||||||
.generatePoToken(webPoTokenVisitorData!!).blockingGet()
|
* [PoTokenGenerator.generatePoToken] was called
|
||||||
|
*/
|
||||||
|
private fun getWebClientPoToken(videoId: String, forceRecreate: Boolean): PoTokenResult {
|
||||||
|
// just a helper class since Kotlin does not have builtin support for 4-tuples
|
||||||
|
data class Quadruple<T1, T2, T3, T4>(val t1: T1, val t2: T2, val t3: T3, val t4: T4)
|
||||||
|
|
||||||
|
val (poTokenGenerator, visitorData, streamingPot, hasBeenRecreated) =
|
||||||
|
synchronized(WebPoTokenGenLock) {
|
||||||
|
val shouldRecreate = webPoTokenGenerator == null || forceRecreate ||
|
||||||
|
webPoTokenGenerator!!.isExpired()
|
||||||
|
|
||||||
|
if (shouldRecreate) {
|
||||||
|
// close the current webPoTokenGenerator on the main thread
|
||||||
|
webPoTokenGenerator?.let { Handler(Looper.getMainLooper()).post { it.close() } }
|
||||||
|
|
||||||
|
// create a new webPoTokenGenerator
|
||||||
|
webPoTokenGenerator = PoTokenWebView
|
||||||
|
.newPoTokenGenerator(App.getApp()).blockingGet()
|
||||||
|
webPoTokenVisitorData = YoutubeParsingHelper
|
||||||
|
.randomVisitorData(NewPipe.getPreferredContentCountry())
|
||||||
|
|
||||||
|
// The streaming poToken needs to be generated exactly once before generating
|
||||||
|
// any other (player) tokens.
|
||||||
|
webPoTokenStreamingPot = webPoTokenGenerator!!
|
||||||
|
.generatePoToken(webPoTokenVisitorData!!).blockingGet()
|
||||||
|
}
|
||||||
|
|
||||||
|
return@synchronized Quadruple(
|
||||||
|
webPoTokenGenerator!!,
|
||||||
|
webPoTokenVisitorData!!,
|
||||||
|
webPoTokenStreamingPot!!,
|
||||||
|
shouldRecreate
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
val playerPot = try {
|
||||||
|
// Not using synchronized here, since poTokenGenerator would be able to generate
|
||||||
|
// multiple poTokens in parallel if needed. The only important thing is for exactly one
|
||||||
|
// visitorData/streaming poToken to be generated before anything else.
|
||||||
|
poTokenGenerator.generatePoToken(videoId).blockingGet()
|
||||||
|
} catch (throwable: Throwable) {
|
||||||
|
if (hasBeenRecreated) {
|
||||||
|
// the poTokenGenerator has just been recreated (and possibly this is already the
|
||||||
|
// second time we try), so there is likely nothing we can do
|
||||||
|
throw throwable
|
||||||
|
} else {
|
||||||
|
// retry, this time recreating the [webPoTokenGenerator] from scratch;
|
||||||
|
// this might happen for example if NewPipe goes in the background and the WebView
|
||||||
|
// content is lost
|
||||||
|
Log.e(TAG, "Failed to obtain poToken, retrying", throwable)
|
||||||
|
return getWebClientPoToken(videoId = videoId, forceRecreate = true)
|
||||||
}
|
}
|
||||||
return@synchronized Triple(
|
|
||||||
webPoTokenGenerator!!, webPoTokenVisitorData!!, webPoTokenStreamingPot!!
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Not using synchronized here, since poTokenGenerator would be able to generate multiple
|
|
||||||
// poTokens in parallel if needed. The only important thing is for exactly one
|
|
||||||
// visitorData/streaming poToken to be generated before anything else.
|
|
||||||
val playerPot = poTokenGenerator.generatePoToken(videoId).blockingGet()
|
|
||||||
Log.e(TAG, "success($videoId) $playerPot,web.gvs+$streamingPot;visitor_data=$visitorData")
|
Log.e(TAG, "success($videoId) $playerPot,web.gvs+$streamingPot;visitor_data=$visitorData")
|
||||||
|
return PoTokenResult(visitorData, playerPot, streamingPot)
|
||||||
return PoTokenResult(
|
|
||||||
webPoTokenVisitorData!!,
|
|
||||||
playerPot,
|
|
||||||
webPoTokenStreamingPot!!,
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getWebEmbedClientPoToken(videoId: String): PoTokenResult? = null
|
override fun getWebEmbedClientPoToken(videoId: String): PoTokenResult? = null
|
||||||
|
@ -7,6 +7,7 @@ import android.os.Looper
|
|||||||
import android.util.Log
|
import android.util.Log
|
||||||
import android.webkit.JavascriptInterface
|
import android.webkit.JavascriptInterface
|
||||||
import android.webkit.WebView
|
import android.webkit.WebView
|
||||||
|
import androidx.annotation.MainThread
|
||||||
import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers
|
import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers
|
||||||
import io.reactivex.rxjava3.core.Single
|
import io.reactivex.rxjava3.core.Single
|
||||||
import io.reactivex.rxjava3.core.SingleEmitter
|
import io.reactivex.rxjava3.core.SingleEmitter
|
||||||
@ -275,6 +276,7 @@ class PoTokenWebView private constructor(
|
|||||||
/**
|
/**
|
||||||
* Releases all [webView] and [disposables] resources.
|
* Releases all [webView] and [disposables] resources.
|
||||||
*/
|
*/
|
||||||
|
@MainThread
|
||||||
override fun close() {
|
override fun close() {
|
||||||
disposables.dispose()
|
disposables.dispose()
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user