fix(pt/pobreflix): Fix video extractor + Add more extractors (#2445)

This commit is contained in:
Claudemirovsky
2023-10-30 09:51:56 -03:00
committed by GitHub
parent 5df1922e37
commit d688e06337
6 changed files with 139 additions and 14 deletions

View File

@ -0,0 +1,4 @@
dependencies {
implementation(project(":lib-filemoon-extractor"))
implementation(project(":lib-playlist-utils"))
}

View File

@ -1,8 +1,11 @@
package eu.kanade.tachiyomi.animeextension.pt.pobreflix package eu.kanade.tachiyomi.animeextension.pt.pobreflix
import android.util.Base64 import android.util.Base64
import eu.kanade.tachiyomi.animeextension.pt.pobreflix.extractors.EplayerExtractor
import eu.kanade.tachiyomi.animeextension.pt.pobreflix.extractors.MyStreamExtractor
import eu.kanade.tachiyomi.animeextension.pt.pobreflix.extractors.PainelfxExtractor import eu.kanade.tachiyomi.animeextension.pt.pobreflix.extractors.PainelfxExtractor
import eu.kanade.tachiyomi.animesource.model.Video import eu.kanade.tachiyomi.animesource.model.Video
import eu.kanade.tachiyomi.lib.filemoonextractor.FilemoonExtractor
import eu.kanade.tachiyomi.multisrc.dooplay.DooPlay import eu.kanade.tachiyomi.multisrc.dooplay.DooPlay
import eu.kanade.tachiyomi.network.GET import eu.kanade.tachiyomi.network.GET
import eu.kanade.tachiyomi.util.asJsoup import eu.kanade.tachiyomi.util.asJsoup
@ -21,9 +24,15 @@ class Pobreflix : DooPlay(
override fun latestUpdatesRequest(page: Int) = GET("$baseUrl/series/page/$page/", headers) override fun latestUpdatesRequest(page: Int) = GET("$baseUrl/series/page/$page/", headers)
// ============================ Video Links ============================= // ============================ Video Links =============================
private val painelfxExtractor by lazy { PainelfxExtractor(client, headers, ::genericExtractor) }
private val eplayerExtractor by lazy { EplayerExtractor(client) }
private val filemoonExtractor by lazy { FilemoonExtractor(client) }
private val mystreamExtractor by lazy { MyStreamExtractor(client, headers) }
override fun videoListParse(response: Response): List<Video> { override fun videoListParse(response: Response): List<Video> {
val doc = response.use { it.asJsoup() } val doc = response.use { it.asJsoup() }
return doc.select("div.source-box > a").flatMap { return doc.select("div.source-box > a").flatMap {
runCatching {
val data = it.attr("href").toHttpUrl().queryParameter("auth") val data = it.attr("href").toHttpUrl().queryParameter("auth")
?.let { Base64.decode(it, Base64.DEFAULT) } ?.let { Base64.decode(it, Base64.DEFAULT) }
?.let(::String) ?.let(::String)
@ -31,9 +40,20 @@ class Pobreflix : DooPlay(
val url = data.replace("\\", "").substringAfter("url\":\"").substringBefore('"') val url = data.replace("\\", "").substringAfter("url\":\"").substringBefore('"')
when { when {
url.contains("painelfx") -> url.contains("painelfx") ->
PainelfxExtractor(client).videosFromUrl(url, headers) painelfxExtractor.videosFromUrl(url)
else -> genericExtractor(url)
}
}.getOrElse { emptyList() }
}
}
private fun genericExtractor(url: String, language: String = ""): List<Video> {
return when {
url.contains("filemoon") -> filemoonExtractor.videosFromUrl(url, headers = headers)
url.contains("watch.brplayer") || url.contains("/watch?v=") ->
mystreamExtractor.videosFromUrl(url, language)
url.contains("embedplayer") -> eplayerExtractor.videosFromUrl(url, language)
else -> emptyList() else -> emptyList()
} }
} }
}
} }

View File

@ -0,0 +1,46 @@
package eu.kanade.tachiyomi.animeextension.pt.pobreflix.extractors
import eu.kanade.tachiyomi.animesource.model.Video
import eu.kanade.tachiyomi.lib.playlistutils.PlaylistUtils
import eu.kanade.tachiyomi.network.POST
import okhttp3.FormBody
import okhttp3.Headers
import okhttp3.OkHttpClient
class EplayerExtractor(private val client: OkHttpClient) {
private val headers by lazy {
Headers.headersOf(
"X-Requested-With",
"XMLHttpRequest",
"Referer",
EPLAYER_HOST,
"Origin",
EPLAYER_HOST,
)
}
private val playlistUtils by lazy { PlaylistUtils(client, headers) }
fun videosFromUrl(url: String, lang: String): List<Video> {
val id = url.substringAfterLast("/")
val postUrl = "$EPLAYER_HOST/player/index.php?data=$id&do=getVideo"
val body = FormBody.Builder()
.add("hash", id)
.add("r", "")
.build()
val masterUrl = client.newCall(POST(postUrl, headers, body = body)).execute().use {
it.body.string()
.substringAfter("videoSource\":\"")
.substringBefore('"')
.replace("\\", "")
}
return playlistUtils.extractFromHls(masterUrl, videoNameGen = { "[$lang] EmbedPlayer - $it" })
}
companion object {
private const val EPLAYER_HOST = "https://embedplayer.online"
}
}

View File

@ -0,0 +1,50 @@
package eu.kanade.tachiyomi.animeextension.pt.pobreflix.extractors
import eu.kanade.tachiyomi.animesource.model.Video
import eu.kanade.tachiyomi.lib.playlistutils.PlaylistUtils
import eu.kanade.tachiyomi.network.GET
import okhttp3.Headers
import okhttp3.OkHttpClient
// From animeworldindia
class MyStreamExtractor(private val client: OkHttpClient, private val headers: Headers) {
private val playlistUtils by lazy { PlaylistUtils(client, headers) }
fun videosFromUrl(url: String, language: String): List<Video> {
val host = url.substringBefore("/watch?")
return runCatching {
val response = client.newCall(GET(url, headers)).execute()
val body = response.use { it.body.string() }
val codePart = body
.substringAfter("sniff(") // Video function
.substringBefore(",[")
val streamCode = codePart
.substringAfterLast(",\"") // our beloved hash
.substringBefore('"')
val id = codePart.substringAfter(",\"").substringBefore('"') // required ID
val streamUrl = "$host/m3u8/$id/$streamCode/master.txt?s=1&cache=1"
val cookie = response.headers.firstOrNull {
it.first.startsWith("set-cookie", true) && it.second.startsWith("PHPSESSID", true)
}?.second?.substringBefore(";") ?: ""
val newHeaders = headers.newBuilder()
.set("cookie", cookie)
.set("accept", "*/*")
.build()
playlistUtils.extractFromHls(
streamUrl,
masterHeaders = newHeaders,
videoHeaders = newHeaders,
videoNameGen = { "[$language] MyStream: $it" },
)
}.getOrElse { emptyList<Video>() }
}
}

View File

@ -9,8 +9,12 @@ import okhttp3.Headers
import okhttp3.HttpUrl.Companion.toHttpUrl import okhttp3.HttpUrl.Companion.toHttpUrl
import okhttp3.OkHttpClient import okhttp3.OkHttpClient
class PainelfxExtractor(private val client: OkHttpClient) { class PainelfxExtractor(
fun videosFromUrl(url: String, headers: Headers): List<Video> { private val client: OkHttpClient,
private val headers: Headers,
private val genericExtractor: (String, String) -> List<Video>,
) {
fun videosFromUrl(url: String): List<Video> {
val docHeaders = headers.newBuilder().set("Referer", "https://gastronomiabrasileira.net/").build() val docHeaders = headers.newBuilder().set("Referer", "https://gastronomiabrasileira.net/").build()
val doc = client.newCall(GET(url, docHeaders)).execute().use { it.asJsoup() } val doc = client.newCall(GET(url, docHeaders)).execute().use { it.asJsoup() }
val lang = when (url.substringAfterLast("/")) { val lang = when (url.substringAfterLast("/")) {
@ -61,7 +65,8 @@ class PainelfxExtractor(private val client: OkHttpClient) {
Video(videoUrl, "$lang - $quality", videoUrl, videoHeaders) Video(videoUrl, "$lang - $quality", videoUrl, videoHeaders)
} }
} else { } else {
emptyList() val url = decoded.substringAfter("\"url\":\"").substringBefore('"')
genericExtractor(url, lang)
} }
} }

View File

@ -25,7 +25,7 @@ class DooPlayGenerator : ThemeSourceGenerator {
SingleLang("Kinoking", "https://kinoking.cc", "de", isNsfw = false, overrideVersionCode = 17), SingleLang("Kinoking", "https://kinoking.cc", "de", isNsfw = false, overrideVersionCode = 17),
SingleLang("Multimovies", "https://multimovies.live", "en", isNsfw = false, overrideVersionCode = 12), SingleLang("Multimovies", "https://multimovies.live", "en", isNsfw = false, overrideVersionCode = 12),
SingleLang("Pi Fansubs", "https://pifansubs.org", "pt-BR", isNsfw = true, overrideVersionCode = 17), SingleLang("Pi Fansubs", "https://pifansubs.org", "pt-BR", isNsfw = true, overrideVersionCode = 17),
SingleLang("Pobreflix", "https://pobreflix.biz", "pt-BR", isNsfw = true, overrideVersionCode = 1), SingleLang("Pobreflix", "https://pobreflix.biz", "pt-BR", isNsfw = true, overrideVersionCode = 2),
SingleLang("UniqueStream", "https://uniquestream.net", "en", isNsfw = false, overrideVersionCode = 2), SingleLang("UniqueStream", "https://uniquestream.net", "en", isNsfw = false, overrideVersionCode = 2),
) )