fix(ar/Anime4Up): fix episodes not loading/adding more sources (#1824)
This commit is contained in:
@ -5,13 +5,16 @@ ext {
|
|||||||
extName = 'Anime4up'
|
extName = 'Anime4up'
|
||||||
pkgNameSuffix = 'ar.anime4up'
|
pkgNameSuffix = 'ar.anime4up'
|
||||||
extClass = '.Anime4Up'
|
extClass = '.Anime4Up'
|
||||||
extVersionCode = 44
|
extVersionCode = 45
|
||||||
libVersion = '13'
|
libVersion = '13'
|
||||||
}
|
}
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
implementation(project(':lib-streamsb-extractor'))
|
implementation(project(':lib-streamsb-extractor'))
|
||||||
implementation(project(':lib-dood-extractor'))
|
implementation(project(':lib-dood-extractor'))
|
||||||
|
implementation(project(':lib-voe-extractor'))
|
||||||
|
implementation(project(':lib-vidbom-extractor'))
|
||||||
|
implementation(project(':lib-okru-extractor'))
|
||||||
implementation "dev.datlag.jsunpacker:jsunpacker:1.0.1"
|
implementation "dev.datlag.jsunpacker:jsunpacker:1.0.1"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2,11 +2,11 @@ package eu.kanade.tachiyomi.animeextension.ar.anime4up
|
|||||||
|
|
||||||
import android.app.Application
|
import android.app.Application
|
||||||
import android.content.SharedPreferences
|
import android.content.SharedPreferences
|
||||||
import android.util.Log
|
import android.os.Build
|
||||||
|
import androidx.annotation.RequiresApi
|
||||||
import androidx.preference.ListPreference
|
import androidx.preference.ListPreference
|
||||||
import androidx.preference.PreferenceScreen
|
import androidx.preference.PreferenceScreen
|
||||||
import eu.kanade.tachiyomi.animeextension.ar.anime4up.extractors.GdrivePlayerExtractor
|
import eu.kanade.tachiyomi.animeextension.ar.anime4up.extractors.GdrivePlayerExtractor
|
||||||
import eu.kanade.tachiyomi.animeextension.ar.anime4up.extractors.MoshahdaExtractor
|
|
||||||
import eu.kanade.tachiyomi.animeextension.ar.anime4up.extractors.SharedExtractor
|
import eu.kanade.tachiyomi.animeextension.ar.anime4up.extractors.SharedExtractor
|
||||||
import eu.kanade.tachiyomi.animeextension.ar.anime4up.extractors.VidYardExtractor
|
import eu.kanade.tachiyomi.animeextension.ar.anime4up.extractors.VidYardExtractor
|
||||||
import eu.kanade.tachiyomi.animesource.ConfigurableAnimeSource
|
import eu.kanade.tachiyomi.animesource.ConfigurableAnimeSource
|
||||||
@ -17,11 +17,19 @@ import eu.kanade.tachiyomi.animesource.model.SEpisode
|
|||||||
import eu.kanade.tachiyomi.animesource.model.Video
|
import eu.kanade.tachiyomi.animesource.model.Video
|
||||||
import eu.kanade.tachiyomi.animesource.online.ParsedAnimeHttpSource
|
import eu.kanade.tachiyomi.animesource.online.ParsedAnimeHttpSource
|
||||||
import eu.kanade.tachiyomi.lib.doodextractor.DoodExtractor
|
import eu.kanade.tachiyomi.lib.doodextractor.DoodExtractor
|
||||||
|
import eu.kanade.tachiyomi.lib.okruextractor.OkruExtractor
|
||||||
import eu.kanade.tachiyomi.lib.streamsbextractor.StreamSBExtractor
|
import eu.kanade.tachiyomi.lib.streamsbextractor.StreamSBExtractor
|
||||||
|
import eu.kanade.tachiyomi.lib.vidbomextractor.VidBomExtractor
|
||||||
|
import eu.kanade.tachiyomi.lib.voeextractor.VoeExtractor
|
||||||
import eu.kanade.tachiyomi.network.GET
|
import eu.kanade.tachiyomi.network.GET
|
||||||
import eu.kanade.tachiyomi.network.POST
|
|
||||||
import eu.kanade.tachiyomi.util.asJsoup
|
import eu.kanade.tachiyomi.util.asJsoup
|
||||||
import okhttp3.FormBody
|
import kotlinx.coroutines.Dispatchers
|
||||||
|
import kotlinx.coroutines.async
|
||||||
|
import kotlinx.coroutines.awaitAll
|
||||||
|
import kotlinx.coroutines.runBlocking
|
||||||
|
import kotlinx.serialization.json.Json
|
||||||
|
import kotlinx.serialization.json.JsonObject
|
||||||
|
import kotlinx.serialization.json.jsonObject
|
||||||
import okhttp3.Headers
|
import okhttp3.Headers
|
||||||
import okhttp3.HttpUrl.Companion.toHttpUrlOrNull
|
import okhttp3.HttpUrl.Companion.toHttpUrlOrNull
|
||||||
import okhttp3.OkHttpClient
|
import okhttp3.OkHttpClient
|
||||||
@ -32,6 +40,7 @@ import org.jsoup.nodes.Element
|
|||||||
import uy.kohesive.injekt.Injekt
|
import uy.kohesive.injekt.Injekt
|
||||||
import uy.kohesive.injekt.api.get
|
import uy.kohesive.injekt.api.get
|
||||||
import java.lang.Exception
|
import java.lang.Exception
|
||||||
|
import java.util.Base64
|
||||||
|
|
||||||
class Anime4Up : ConfigurableAnimeSource, ParsedAnimeHttpSource() {
|
class Anime4Up : ConfigurableAnimeSource, ParsedAnimeHttpSource() {
|
||||||
|
|
||||||
@ -45,6 +54,10 @@ class Anime4Up : ConfigurableAnimeSource, ParsedAnimeHttpSource() {
|
|||||||
|
|
||||||
override val client: OkHttpClient = network.cloudflareClient
|
override val client: OkHttpClient = network.cloudflareClient
|
||||||
|
|
||||||
|
private val json = Json {
|
||||||
|
ignoreUnknownKeys = true
|
||||||
|
}
|
||||||
|
|
||||||
private val preferences: SharedPreferences by lazy {
|
private val preferences: SharedPreferences by lazy {
|
||||||
Injekt.get<Application>().getSharedPreferences("source_$id", 0x0000)
|
Injekt.get<Application>().getSharedPreferences("source_$id", 0x0000)
|
||||||
}
|
}
|
||||||
@ -98,76 +111,32 @@ class Anime4Up : ConfigurableAnimeSource, ParsedAnimeHttpSource() {
|
|||||||
|
|
||||||
// Video links
|
// Video links
|
||||||
|
|
||||||
|
@RequiresApi(Build.VERSION_CODES.O)
|
||||||
override fun videoListParse(response: Response): List<Video> {
|
override fun videoListParse(response: Response): List<Video> {
|
||||||
val document = response.asJsoup()
|
val base64 = response.asJsoup().select("input[name=wl]").attr("value")
|
||||||
val iframe = document.select("iframe").attr("src")
|
val jHash = String(Base64.getDecoder().decode(base64))
|
||||||
if (iframe.contains("http")) {
|
val parsedJ = json.decodeFromString<JsonObject>(jHash)
|
||||||
val referer = response.request.url.encodedPath
|
val streamLinks = parsedJ["fhd"]!!.jsonObject.entries + parsedJ["hd"]!!.jsonObject.entries + parsedJ["sd"]!!.jsonObject.entries
|
||||||
val newHeaders = Headers.headersOf("referer", baseUrl + referer)
|
return streamLinks.distinctBy { it.key }.parallelMap {
|
||||||
val iframeResponse = client.newCall(GET(iframe, newHeaders))
|
val url = it.value.toString().replace("\"", "")
|
||||||
.execute().asJsoup()
|
runCatching { extractVideos(url) }.getOrElse { emptyList() }
|
||||||
return videosFromElement(iframeResponse.selectFirst(videoListSelector())!!)
|
}.flatten()
|
||||||
} else {
|
|
||||||
val postUrl = document.select("form[method=post]").attr("action")
|
|
||||||
val ur = document.select("input[name=ur]").attr("value")
|
|
||||||
val wl = document.select("input[name=wl]").attr("value")
|
|
||||||
val dl = document.select("input[name=dl]").attr("value")
|
|
||||||
val moshahda = document.select("input[name=moshahda]").attr("value")
|
|
||||||
val submit = document.select("input[name=submit]").attr("value")
|
|
||||||
// POST data
|
|
||||||
val body = FormBody.Builder()
|
|
||||||
.add("dl", "$dl")
|
|
||||||
.add("moshahda", "$moshahda")
|
|
||||||
.add("submit", "$submit")
|
|
||||||
.add("ur", "$ur")
|
|
||||||
.add("wl", "$wl")
|
|
||||||
.build()
|
|
||||||
// Call POST
|
|
||||||
val referer = response.request.url.encodedPath
|
|
||||||
val newHeaders = Headers.headersOf("referer", "$postUrl")
|
|
||||||
val iframeResponse = client.newCall(POST(postUrl, newHeaders, body)).execute().asJsoup()
|
|
||||||
/*val iframe2 = iframe.select("li[data-i=moshahda] a").attr("data-ep-url")
|
|
||||||
val iframeResponse = client.newCall(GET(iframe2, newHeaders))
|
|
||||||
.execute().asJsoup()*/
|
|
||||||
return videosFromElement(iframeResponse)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// override fun videoListSelector() = "script:containsData(m3u8)"
|
private inline fun <A, B> Iterable<A>.parallelMap(crossinline f: suspend (A) -> B): List<B> =
|
||||||
override fun videoListSelector() = "li[data-i] a"
|
runBlocking {
|
||||||
|
map { async(Dispatchers.Default) { f(it) } }.awaitAll()
|
||||||
private fun videosFromElement(element: Element): List<Video> {
|
|
||||||
val videoList = mutableListOf<Video>()
|
|
||||||
val elements = element.select(videoListSelector())
|
|
||||||
for (element in elements) {
|
|
||||||
val location = element.ownerDocument()!!.location()
|
|
||||||
val embedUrl = element.attr("data-ep-url")
|
|
||||||
val qualityy = element.text()
|
|
||||||
Log.i("embedUrl", "$embedUrl")
|
|
||||||
when {
|
|
||||||
embedUrl.contains("moshahda")
|
|
||||||
-> {
|
|
||||||
val headers = headers.newBuilder()
|
|
||||||
.set("referer", "https://gamertak.com/Watch1.php")
|
|
||||||
.build()
|
|
||||||
val videos = MoshahdaExtractor(client).videosFromUrl(embedUrl, headers)
|
|
||||||
videoList.addAll(videos)
|
|
||||||
}
|
}
|
||||||
embedUrl.contains("dood")
|
private fun extractVideos(url: String): List<Video> {
|
||||||
-> {
|
return when {
|
||||||
val video = DoodExtractor(client).videoFromUrl(embedUrl, qualityy)
|
url.contains("shared") -> {
|
||||||
if (video != null) {
|
SharedExtractor(client).videosFromUrl(url)?.let(::listOf)
|
||||||
videoList.add(video)
|
|
||||||
}
|
}
|
||||||
|
url.contains("drive.google") -> {
|
||||||
|
val embedUrlG = "https://gdriveplayer.to/embed2.php?link=$url"
|
||||||
|
GdrivePlayerExtractor(client).videosFromUrl(embedUrlG)
|
||||||
}
|
}
|
||||||
embedUrl.contains("drive.google")
|
url.contains("vidyard") -> {
|
||||||
-> {
|
|
||||||
val embedUrlG = "https://gdriveplayer.to/embed2.php?link=" + embedUrl
|
|
||||||
val videos = GdrivePlayerExtractor(client).videosFromUrl(embedUrlG)
|
|
||||||
videoList.addAll(videos)
|
|
||||||
}
|
|
||||||
embedUrl.contains("vidyard")
|
|
||||||
-> {
|
|
||||||
val headers = headers.newBuilder()
|
val headers = headers.newBuilder()
|
||||||
.set("Referer", "https://play.vidyard.com")
|
.set("Referer", "https://play.vidyard.com")
|
||||||
.set("Accept-Encoding", "gzip, deflate, br")
|
.set("Accept-Encoding", "gzip, deflate, br")
|
||||||
@ -175,36 +144,33 @@ class Anime4Up : ConfigurableAnimeSource, ParsedAnimeHttpSource() {
|
|||||||
.set("TE", "trailers")
|
.set("TE", "trailers")
|
||||||
.set("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:101.0) Gecko/20100101 Firefox/101.0")
|
.set("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:101.0) Gecko/20100101 Firefox/101.0")
|
||||||
.build()
|
.build()
|
||||||
val id = embedUrl.substringAfter("com/").substringBefore("?")
|
val id = url.substringAfter("com/").substringBefore("?")
|
||||||
val vidUrl = "https://play.vidyard.com/player/" + id + ".json"
|
val vidUrl = "https://play.vidyard.com/player/$id.json"
|
||||||
val videos = VidYardExtractor(client).videosFromUrl(vidUrl, headers)
|
VidYardExtractor(client).videosFromUrl(vidUrl, headers)
|
||||||
videoList.addAll(videos)
|
|
||||||
}
|
}
|
||||||
embedUrl.contains("sbembed.com") || embedUrl.contains("sbembed1.com") || embedUrl.contains("sbplay.org") ||
|
url.contains("ok.ru") -> {
|
||||||
embedUrl.contains("sbvideo.net") || embedUrl.contains("streamsb.net") || embedUrl.contains("sbplay.one") ||
|
OkruExtractor(client).videosFromUrl(url)
|
||||||
embedUrl.contains("cloudemb.com") || embedUrl.contains("playersb.com") || embedUrl.contains("tubesb.com") ||
|
}
|
||||||
embedUrl.contains("sbplay1.com") || embedUrl.contains("embedsb.com") || embedUrl.contains("watchsb.com") ||
|
url.contains("voe") -> {
|
||||||
embedUrl.contains("sbplay2.com") || embedUrl.contains("japopav.tv") || embedUrl.contains("viewsb.com") ||
|
VoeExtractor(client).videoFromUrl(url)?.let(::listOf)
|
||||||
embedUrl.contains("sbfast") || embedUrl.contains("sbfull.com") || embedUrl.contains("javplaya.com") ||
|
}
|
||||||
embedUrl.contains("ssbstream.net") || embedUrl.contains("p1ayerjavseen.com") || embedUrl.contains("sbthe.com") ||
|
Regex("(do*d(?:stream)?\\.(?:com?|watch|to|s[ho]|cx|la|w[sf]|pm|re|yt|stream))").containsMatchIn(url) -> {
|
||||||
embedUrl.contains("vidmovie.xyz") || embedUrl.contains("sbspeed.com") || embedUrl.contains("streamsss.net") ||
|
DoodExtractor(client).videoFromUrl(url, "Dood mirror")?.let(::listOf)
|
||||||
embedUrl.contains("sblanh.com") || embedUrl.contains("tvmshow.com") || embedUrl.contains("sbanh.com") ||
|
}
|
||||||
embedUrl.contains("streamovies.xyz")
|
Regex("(?:v[aie]d[bp][aoe]?m|myvii?d|v[aei]{1,2}dshar[er]?)\\.(?:com|net|org|xyz)").containsMatchIn(url) -> {
|
||||||
|
VidBomExtractor(client).videosFromUrl(url)
|
||||||
|
}
|
||||||
|
Regex("(?:view|watch|embed(?:tv)?|tube|player|cloudemb|japopav|javplaya|p1ayerjavseen|gomovizplay|stream(?:ovies)?|vidmovie|javside|aintahalu|finaltayibin|yahlusubh|taeyabathuna|)?s{0,2}b?(?:embed\\d?|play\\d?|video|fast|full|streams{0,3}|the|speed|l?anh|tvmshow|longvu|arslanrocky|chill|rity|hight|brisk|face|lvturbo|net|one|asian|ani|rapid|sonic|lona)?\\.(?:com|net|org|one|tv|xyz|fun|pro|sbs)").containsMatchIn(url)
|
||||||
-> {
|
-> {
|
||||||
val videos = StreamSBExtractor(client).videosFromUrl(embedUrl, headers)
|
StreamSBExtractor(client).videosFromUrl(url, headers)
|
||||||
videoList.addAll(videos)
|
|
||||||
}
|
}
|
||||||
embedUrl.contains("4shared") -> {
|
else -> null
|
||||||
val video = SharedExtractor(client).videoFromUrl(embedUrl, qualityy)
|
} ?: emptyList()
|
||||||
if (video != null) {
|
|
||||||
videoList.add(video)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return videoList
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// override fun videoListSelector() = "script:containsData(m3u8)"
|
||||||
|
override fun videoListSelector() = "li[data-i] a"
|
||||||
|
|
||||||
override fun List<Video>.sort(): List<Video> {
|
override fun List<Video>.sort(): List<Video> {
|
||||||
val quality = preferences.getString("preferred_quality", null)
|
val quality = preferences.getString("preferred_quality", null)
|
||||||
if (quality != null) {
|
if (quality != null) {
|
||||||
|
@ -6,14 +6,10 @@ import eu.kanade.tachiyomi.util.asJsoup
|
|||||||
import okhttp3.OkHttpClient
|
import okhttp3.OkHttpClient
|
||||||
|
|
||||||
class SharedExtractor(private val client: OkHttpClient) {
|
class SharedExtractor(private val client: OkHttpClient) {
|
||||||
fun videoFromUrl(url: String, quality: String): Video? {
|
fun videosFromUrl(url: String, quality: String = "mirror"): Video? {
|
||||||
val document = client.newCall(GET(url)).execute().asJsoup()
|
val document = client.newCall(GET(url)).execute().asJsoup()
|
||||||
val check = document.select("div.error4shared").text()
|
return document.selectFirst("source")?.let {
|
||||||
val videoUrl = document.select("source").attr("src")
|
Video(it.attr("src"), "4Shared: $quality", it.attr("src"))
|
||||||
return if (check.contains("This file is not available any more")) {
|
|
||||||
Video(url, "no 1video", "https")
|
|
||||||
} else {
|
|
||||||
Video(url, quality, videoUrl)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user