Skip to content

Commit

Permalink
fix(pt/pobreflix): Fix video extractor + Add more extractors (#2445)
Browse files Browse the repository at this point in the history
  • Loading branch information
Claudemirovsky authored Oct 30, 2023
1 parent 5df1922 commit d688e06
Show file tree
Hide file tree
Showing 6 changed files with 139 additions and 14 deletions.
4 changes: 4 additions & 0 deletions multisrc/overrides/dooplay/pobreflix/additional.gradle
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
dependencies {
implementation(project(":lib-filemoon-extractor"))
implementation(project(":lib-playlist-utils"))
}
40 changes: 30 additions & 10 deletions multisrc/overrides/dooplay/pobreflix/src/Pobreflix.kt
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
package eu.kanade.tachiyomi.animeextension.pt.pobreflix

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.animesource.model.Video
import eu.kanade.tachiyomi.lib.filemoonextractor.FilemoonExtractor
import eu.kanade.tachiyomi.multisrc.dooplay.DooPlay
import eu.kanade.tachiyomi.network.GET
import eu.kanade.tachiyomi.util.asJsoup
Expand All @@ -21,19 +24,36 @@ class Pobreflix : DooPlay(
override fun latestUpdatesRequest(page: Int) = GET("$baseUrl/series/page/$page/", headers)

// ============================ 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> {
val doc = response.use { it.asJsoup() }
return doc.select("div.source-box > a").flatMap {
val data = it.attr("href").toHttpUrl().queryParameter("auth")
?.let { Base64.decode(it, Base64.DEFAULT) }
?.let(::String)
?: return@flatMap emptyList()
val url = data.replace("\\", "").substringAfter("url\":\"").substringBefore('"')
when {
url.contains("painelfx") ->
PainelfxExtractor(client).videosFromUrl(url, headers)
else -> emptyList()
}
runCatching {
val data = it.attr("href").toHttpUrl().queryParameter("auth")
?.let { Base64.decode(it, Base64.DEFAULT) }
?.let(::String)
?: return@flatMap emptyList()
val url = data.replace("\\", "").substringAfter("url\":\"").substringBefore('"')
when {
url.contains("painelfx") ->
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()
}
}
}
Original file line number Diff line number Diff line change
@@ -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"
}
}
Original file line number Diff line number Diff line change
@@ -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>() }
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,12 @@ import okhttp3.Headers
import okhttp3.HttpUrl.Companion.toHttpUrl
import okhttp3.OkHttpClient

class PainelfxExtractor(private val client: OkHttpClient) {
fun videosFromUrl(url: String, headers: Headers): List<Video> {
class PainelfxExtractor(
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 doc = client.newCall(GET(url, docHeaders)).execute().use { it.asJsoup() }
val lang = when (url.substringAfterLast("/")) {
Expand Down Expand Up @@ -61,7 +65,8 @@ class PainelfxExtractor(private val client: OkHttpClient) {
Video(videoUrl, "$lang - $quality", videoUrl, videoHeaders)
}
} else {
emptyList()
val url = decoded.substringAfter("\"url\":\"").substringBefore('"')
genericExtractor(url, lang)
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ class DooPlayGenerator : ThemeSourceGenerator {
SingleLang("Kinoking", "https://kinoking.cc", "de", isNsfw = false, overrideVersionCode = 17),
SingleLang("Multimovies", "https://multimovies.live", "en", isNsfw = false, overrideVersionCode = 12),
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),
)

Expand Down

0 comments on commit d688e06

Please sign in to comment.