fix(src/es): Fix video extraction and fix json parsing (#3140)
This commit is contained in:
parent
0c552ed88e
commit
36b7d06ec7
@ -1,7 +1,7 @@
|
|||||||
ext {
|
ext {
|
||||||
extName = 'Doramasflix'
|
extName = 'Doramasflix'
|
||||||
extClass = '.Doramasflix'
|
extClass = '.Doramasflix'
|
||||||
extVersionCode = 18
|
extVersionCode = 19
|
||||||
}
|
}
|
||||||
|
|
||||||
apply from: "$rootDir/common.gradle"
|
apply from: "$rootDir/common.gradle"
|
||||||
|
@ -2,7 +2,6 @@ package eu.kanade.tachiyomi.animeextension.es.doramasflix
|
|||||||
|
|
||||||
import kotlinx.serialization.SerialName
|
import kotlinx.serialization.SerialName
|
||||||
import kotlinx.serialization.Serializable
|
import kotlinx.serialization.Serializable
|
||||||
import kotlinx.serialization.json.JsonObject
|
|
||||||
|
|
||||||
// -----------------------Season models------------------------//
|
// -----------------------Season models------------------------//
|
||||||
@Serializable
|
@Serializable
|
||||||
@ -27,7 +26,6 @@ data class ListSeason(
|
|||||||
@SerialName("serie_name")
|
@SerialName("serie_name")
|
||||||
val serieName: String?,
|
val serieName: String?,
|
||||||
val poster: String?,
|
val poster: String?,
|
||||||
val backdrop: String?,
|
|
||||||
@SerialName("__typename")
|
@SerialName("__typename")
|
||||||
val typename: String,
|
val typename: String,
|
||||||
)
|
)
|
||||||
@ -53,50 +51,17 @@ data class ListEpisode(
|
|||||||
val serieName: String?,
|
val serieName: String?,
|
||||||
@SerialName("serie_name_es")
|
@SerialName("serie_name_es")
|
||||||
val serieNameEs: String?,
|
val serieNameEs: String?,
|
||||||
@SerialName("serie_id")
|
|
||||||
val serieId: String?,
|
|
||||||
@SerialName("still_path")
|
|
||||||
val stillPath: String?,
|
|
||||||
@SerialName("air_date")
|
@SerialName("air_date")
|
||||||
val airDate: String?,
|
val airDate: String?,
|
||||||
@SerialName("season_number")
|
@SerialName("season_number")
|
||||||
val seasonNumber: Long?,
|
val seasonNumber: Long?,
|
||||||
@SerialName("episode_number")
|
@SerialName("episode_number")
|
||||||
val episodeNumber: Long?,
|
val episodeNumber: Long?,
|
||||||
// val languages: List<Any?>,
|
|
||||||
val poster: String?,
|
val poster: String?,
|
||||||
val backdrop: String?,
|
|
||||||
@SerialName("__typename")
|
@SerialName("__typename")
|
||||||
val typename: String,
|
val typename: String,
|
||||||
)
|
)
|
||||||
|
|
||||||
// -----------------------Details Model------------------------//
|
|
||||||
|
|
||||||
data class DetailsModel(
|
|
||||||
val props: Props,
|
|
||||||
val page: String,
|
|
||||||
val query: Query,
|
|
||||||
val buildId: String,
|
|
||||||
val isFallback: Boolean,
|
|
||||||
val gip: Boolean,
|
|
||||||
)
|
|
||||||
|
|
||||||
data class Props(
|
|
||||||
val pageProps: PageProps,
|
|
||||||
)
|
|
||||||
|
|
||||||
data class PageProps(
|
|
||||||
val deviceType: String,
|
|
||||||
val slug: String,
|
|
||||||
// val apolloClient: Any?,
|
|
||||||
val apolloState: HashMap<String, HashMap<String, JsonObject>>,
|
|
||||||
val ssrComplete: Boolean,
|
|
||||||
)
|
|
||||||
|
|
||||||
data class Query(
|
|
||||||
val slug: String,
|
|
||||||
)
|
|
||||||
|
|
||||||
// -----------------------Pagination Model------------------------//
|
// -----------------------Pagination Model------------------------//
|
||||||
|
|
||||||
@Serializable
|
@Serializable
|
||||||
@ -136,67 +101,16 @@ data class Item(
|
|||||||
@SerialName("name_es")
|
@SerialName("name_es")
|
||||||
val nameEs: String?,
|
val nameEs: String?,
|
||||||
val slug: String,
|
val slug: String,
|
||||||
val cast: List<Cast> = emptyList(),
|
|
||||||
val names: String?,
|
val names: String?,
|
||||||
val overview: String?,
|
val overview: String?,
|
||||||
val languages: List<String> = emptyList(),
|
|
||||||
@SerialName("created_by")
|
|
||||||
val createdBy: List<CreatedBy> = emptyList(),
|
|
||||||
val popularity: Double?,
|
|
||||||
@SerialName("poster_path")
|
@SerialName("poster_path")
|
||||||
val posterPath: String?,
|
val posterPath: String?,
|
||||||
@SerialName("backdrop_path")
|
|
||||||
val backdropPath: String?,
|
|
||||||
@SerialName("first_air_date")
|
|
||||||
val firstAirDate: String?,
|
|
||||||
@SerialName("isTVShow")
|
|
||||||
val isTvshow: Boolean?,
|
|
||||||
val poster: String?,
|
val poster: String?,
|
||||||
val backdrop: String?,
|
|
||||||
val genres: List<Genre> = emptyList(),
|
val genres: List<Genre> = emptyList(),
|
||||||
val networks: List<Network> = emptyList(),
|
|
||||||
@SerialName("__typename")
|
@SerialName("__typename")
|
||||||
val typename: String,
|
val typename: String,
|
||||||
)
|
)
|
||||||
|
|
||||||
@Serializable
|
|
||||||
data class Cast(
|
|
||||||
val adult: Boolean?,
|
|
||||||
val gender: Long?,
|
|
||||||
val id: Long?,
|
|
||||||
@SerialName("known_for_department")
|
|
||||||
val knownForDepartment: String?,
|
|
||||||
val name: String?,
|
|
||||||
@SerialName("original_name")
|
|
||||||
val originalName: String?,
|
|
||||||
val popularity: Double?,
|
|
||||||
@SerialName("profile_path")
|
|
||||||
val profilePath: String?,
|
|
||||||
val character: String?,
|
|
||||||
@SerialName("credit_id")
|
|
||||||
val creditId: String?,
|
|
||||||
val order: Long?,
|
|
||||||
)
|
|
||||||
|
|
||||||
@Serializable
|
|
||||||
data class CreatedBy(
|
|
||||||
val adult: Boolean?,
|
|
||||||
val gender: Long?,
|
|
||||||
val id: Long?,
|
|
||||||
@SerialName("known_for_department")
|
|
||||||
val knownForDepartment: String?,
|
|
||||||
val name: String?,
|
|
||||||
@SerialName("original_name")
|
|
||||||
val originalName: String?,
|
|
||||||
val popularity: Double?,
|
|
||||||
@SerialName("profile_path")
|
|
||||||
val profilePath: String?,
|
|
||||||
@SerialName("credit_id")
|
|
||||||
val creditId: String?,
|
|
||||||
val department: String?,
|
|
||||||
val job: String?,
|
|
||||||
)
|
|
||||||
|
|
||||||
@Serializable
|
@Serializable
|
||||||
data class Genre(
|
data class Genre(
|
||||||
val name: String?,
|
val name: String?,
|
||||||
@ -205,14 +119,6 @@ data class Genre(
|
|||||||
val typename: String?,
|
val typename: String?,
|
||||||
)
|
)
|
||||||
|
|
||||||
@Serializable
|
|
||||||
data class Network(
|
|
||||||
val name: String?,
|
|
||||||
val slug: String?,
|
|
||||||
@SerialName("__typename")
|
|
||||||
val typename: String?,
|
|
||||||
)
|
|
||||||
|
|
||||||
// -----------------------Search Model------------------------//
|
// -----------------------Search Model------------------------//
|
||||||
@Serializable
|
@Serializable
|
||||||
data class SearchModel(
|
data class SearchModel(
|
||||||
@ -241,18 +147,6 @@ data class SearchDorama(
|
|||||||
)
|
)
|
||||||
|
|
||||||
// -------------------------------------------------------
|
// -------------------------------------------------------
|
||||||
@Serializable
|
|
||||||
data class VideoModel(
|
|
||||||
val json: JsonVideo = JsonVideo(),
|
|
||||||
)
|
|
||||||
|
|
||||||
@Serializable
|
|
||||||
data class JsonVideo(
|
|
||||||
val lang: String? = "",
|
|
||||||
val page: String? = "",
|
|
||||||
val link: String? = "",
|
|
||||||
val server: String? = "",
|
|
||||||
)
|
|
||||||
|
|
||||||
@Serializable
|
@Serializable
|
||||||
data class VideoToken(
|
data class VideoToken(
|
||||||
@ -274,7 +168,6 @@ data class TokenModel(
|
|||||||
val isFallback: Boolean? = false,
|
val isFallback: Boolean? = false,
|
||||||
val isExperimentalCompile: Boolean? = false,
|
val isExperimentalCompile: Boolean? = false,
|
||||||
val gssp: Boolean? = false,
|
val gssp: Boolean? = false,
|
||||||
// val scriptLoader: List<Any?>,
|
|
||||||
)
|
)
|
||||||
|
|
||||||
@Serializable
|
@Serializable
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
ext {
|
ext {
|
||||||
extName = 'Jkanime'
|
extName = 'Jkanime'
|
||||||
extClass = '.Jkanime'
|
extClass = '.Jkanime'
|
||||||
extVersionCode = 19
|
extVersionCode = 20
|
||||||
}
|
}
|
||||||
|
|
||||||
apply from: "$rootDir/common.gradle"
|
apply from: "$rootDir/common.gradle"
|
||||||
@ -10,4 +10,8 @@ dependencies {
|
|||||||
implementation(project(':lib:okru-extractor'))
|
implementation(project(':lib:okru-extractor'))
|
||||||
implementation(project(':lib:mixdrop-extractor'))
|
implementation(project(':lib:mixdrop-extractor'))
|
||||||
implementation(project(':lib:streamwish-extractor'))
|
implementation(project(':lib:streamwish-extractor'))
|
||||||
|
implementation(project(':lib:mp4upload-extractor'))
|
||||||
|
implementation(project(':lib:filemoon-extractor'))
|
||||||
|
implementation(project(':lib:streamtape-extractor'))
|
||||||
|
implementation(project(':lib:voe-extractor'))
|
||||||
}
|
}
|
||||||
|
@ -2,6 +2,7 @@ package eu.kanade.tachiyomi.animeextension.es.jkanime
|
|||||||
|
|
||||||
import android.app.Application
|
import android.app.Application
|
||||||
import android.content.SharedPreferences
|
import android.content.SharedPreferences
|
||||||
|
import android.util.Base64
|
||||||
import androidx.preference.ListPreference
|
import androidx.preference.ListPreference
|
||||||
import androidx.preference.PreferenceScreen
|
import androidx.preference.PreferenceScreen
|
||||||
import eu.kanade.tachiyomi.animeextension.es.jkanime.extractors.JkanimeExtractor
|
import eu.kanade.tachiyomi.animeextension.es.jkanime.extractors.JkanimeExtractor
|
||||||
@ -13,11 +14,18 @@ import eu.kanade.tachiyomi.animesource.model.SAnime
|
|||||||
import eu.kanade.tachiyomi.animesource.model.SEpisode
|
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.filemoonextractor.FilemoonExtractor
|
||||||
import eu.kanade.tachiyomi.lib.mixdropextractor.MixDropExtractor
|
import eu.kanade.tachiyomi.lib.mixdropextractor.MixDropExtractor
|
||||||
|
import eu.kanade.tachiyomi.lib.mp4uploadextractor.Mp4uploadExtractor
|
||||||
import eu.kanade.tachiyomi.lib.okruextractor.OkruExtractor
|
import eu.kanade.tachiyomi.lib.okruextractor.OkruExtractor
|
||||||
|
import eu.kanade.tachiyomi.lib.streamtapeextractor.StreamTapeExtractor
|
||||||
import eu.kanade.tachiyomi.lib.streamwishextractor.StreamWishExtractor
|
import eu.kanade.tachiyomi.lib.streamwishextractor.StreamWishExtractor
|
||||||
|
import eu.kanade.tachiyomi.lib.voeextractor.VoeExtractor
|
||||||
import eu.kanade.tachiyomi.network.GET
|
import eu.kanade.tachiyomi.network.GET
|
||||||
import eu.kanade.tachiyomi.util.asJsoup
|
import eu.kanade.tachiyomi.util.asJsoup
|
||||||
|
import eu.kanade.tachiyomi.util.parallelCatchingFlatMapBlocking
|
||||||
|
import eu.kanade.tachiyomi.util.parseAs
|
||||||
|
import kotlinx.serialization.Serializable
|
||||||
import okhttp3.Request
|
import okhttp3.Request
|
||||||
import okhttp3.Response
|
import okhttp3.Response
|
||||||
import org.jsoup.nodes.Document
|
import org.jsoup.nodes.Document
|
||||||
@ -49,13 +57,15 @@ class Jkanime : ConfigurableAnimeSource, ParsedAnimeHttpSource() {
|
|||||||
private val QUALITY_LIST = arrayOf("1080", "720", "480", "360")
|
private val QUALITY_LIST = arrayOf("1080", "720", "480", "360")
|
||||||
|
|
||||||
private const val PREF_SERVER_KEY = "preferred_server"
|
private const val PREF_SERVER_KEY = "preferred_server"
|
||||||
private const val PREF_SERVER_DEFAULT = "Nozomi"
|
private const val PREF_SERVER_DEFAULT = "Voe"
|
||||||
private val SERVER_LIST = arrayOf(
|
private val SERVER_LIST = arrayOf(
|
||||||
"Okru",
|
"Okru",
|
||||||
"Mixdrop",
|
"Mixdrop",
|
||||||
"StreamWish",
|
"StreamWish",
|
||||||
"Xtreme S",
|
"Filemoon",
|
||||||
"HentaiJk",
|
"Mp4Upload",
|
||||||
|
"StreamTape",
|
||||||
|
"Desuka",
|
||||||
"Nozomi",
|
"Nozomi",
|
||||||
"Desu",
|
"Desu",
|
||||||
)
|
)
|
||||||
@ -114,33 +124,74 @@ class Jkanime : ConfigurableAnimeSource, ParsedAnimeHttpSource() {
|
|||||||
|
|
||||||
override fun episodeFromElement(element: Element) = throw UnsupportedOperationException()
|
override fun episodeFromElement(element: Element) = throw UnsupportedOperationException()
|
||||||
|
|
||||||
override fun videoListParse(response: Response): List<Video> {
|
private val languages = arrayOf(
|
||||||
val document = response.asJsoup()
|
Pair("1", "[JAP]"),
|
||||||
val videos = mutableListOf<Video>()
|
Pair("3", "[LAT]"),
|
||||||
document.select("div.col-lg-12.rounded.bg-servers.text-white.p-3.mt-2 a").forEach { it ->
|
Pair("4", "[CHIN]"),
|
||||||
|
)
|
||||||
|
|
||||||
|
private fun String.getLang(): String {
|
||||||
|
return languages.firstOrNull { it.first == this }?.second ?: ""
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun getVideoLinks(document: Document): List<Pair<String, String>> {
|
||||||
|
val servers = mutableListOf<Pair<String, String>>()
|
||||||
|
val scriptServers = document.selectFirst("script:containsData(var video = [];)")?.data() ?: return emptyList()
|
||||||
|
|
||||||
|
val jsServer = scriptServers.substringAfter("var remote = '").substringBefore("'")
|
||||||
|
val jsPath = scriptServers.substringAfter("= remote+'").substringBefore("'")
|
||||||
|
if (jsServer.isNotEmpty() && jsPath.isNotEmpty()) {
|
||||||
|
val jsLinks = client.newCall(GET(jsServer + jsPath)).execute().body.string()
|
||||||
|
.substringAfter("var servers = ").parseAs<Array<JsLinks>>().map {
|
||||||
|
Pair(String(Base64.decode(it.remote, Base64.DEFAULT)), "${it.lang}".getLang())
|
||||||
|
}
|
||||||
|
servers.addAll(jsLinks)
|
||||||
|
}
|
||||||
|
|
||||||
|
val htmlLinks = document.select("div.col-lg-12.rounded.bg-servers.text-white.p-3.mt-2 a").map {
|
||||||
val serverId = it.attr("data-id")
|
val serverId = it.attr("data-id")
|
||||||
val langClass = it.attr("class")
|
val lang = it.attr("class").substringAfter("lg_").substringBefore(" ").getLang()
|
||||||
val lang = if (langClass.contains("lg_3")) "[LAT]" else if (langClass.contains("lg_1")) "[JAP]" else ""
|
val url = scriptServers
|
||||||
val scriptServers = document.selectFirst("script:containsData(var video = [];)")!!
|
.substringAfter("video[$serverId] = '<iframe class=\"player_conte\" src=\"")
|
||||||
val url = scriptServers.data().substringAfter("video[$serverId] = '<iframe class=\"player_conte\" src=\"")
|
|
||||||
.substringBefore("\"")
|
.substringBefore("\"")
|
||||||
.replace("/jkokru.php?u=", "http://ok.ru/videoembed/")
|
.replace("/jkokru.php?u=", "http://ok.ru/videoembed/")
|
||||||
.replace("/jkvmixdrop.php?u=", "https://mixdrop.ag/e/")
|
.replace("/jkvmixdrop.php?u=", "https://mixdrop.ag/e/")
|
||||||
.replace("/jksw.php?u=", "https://sfastwish.com/e/")
|
.replace("/jksw.php?u=", "https://sfastwish.com/e/")
|
||||||
.replace("/jk.php?u=", "$baseUrl/")
|
.replace("/jk.php?u=", "$baseUrl/")
|
||||||
|
Pair(if (url.contains("um2.php") || url.contains("um.php")) baseUrl + url else url, lang)
|
||||||
try {
|
}
|
||||||
when {
|
servers.addAll(htmlLinks)
|
||||||
"ok" in url -> OkruExtractor(client).videosFromUrl(url, "$lang ").forEach { videos.add(it) }
|
return servers
|
||||||
"mixdrop" in url -> MixDropExtractor(client).videosFromUrl(url, prefix = "$lang ").forEach { videos.add(it) }
|
}
|
||||||
"sfastwish" in url -> StreamWishExtractor(client, headers).videosFromUrl(url, prefix = "$lang StreamWish").forEach { videos.add(it) }
|
|
||||||
"stream/jkmedia" in url -> videos.add(Video(url, "$lang Xtreme S", url))
|
/*--------------------------------Video extractors------------------------------------*/
|
||||||
"um2.php" in url -> JkanimeExtractor(client).getNozomiFromUrl(baseUrl + url, "$lang ").let { if (it != null) videos.add(it) }
|
private val okruExtractor by lazy { OkruExtractor(client) }
|
||||||
"um.php" in url -> JkanimeExtractor(client).getDesuFromUrl(baseUrl + url, "$lang ").let { if (it != null) videos.add(it) }
|
private val voeExtractor by lazy { VoeExtractor(client) }
|
||||||
}
|
private val filemoonExtractor by lazy { FilemoonExtractor(client) }
|
||||||
} catch (_: Exception) {}
|
private val streamTapeExtractor by lazy { StreamTapeExtractor(client) }
|
||||||
|
private val mp4uploadExtractor by lazy { Mp4uploadExtractor(client) }
|
||||||
|
private val mixDropExtractor by lazy { MixDropExtractor(client) }
|
||||||
|
private val streamWishExtractor by lazy { StreamWishExtractor(client, headers) }
|
||||||
|
private val jkanimeExtractor by lazy { JkanimeExtractor(client) }
|
||||||
|
|
||||||
|
override fun videoListParse(response: Response): List<Video> {
|
||||||
|
val document = response.asJsoup()
|
||||||
|
return getVideoLinks(document).parallelCatchingFlatMapBlocking { (url, lang) ->
|
||||||
|
when {
|
||||||
|
"ok" in url -> okruExtractor.videosFromUrl(url, "$lang ")
|
||||||
|
"voe" in url -> voeExtractor.videosFromUrl(url, "$lang ")
|
||||||
|
"filemoon" in url || "moonplayer" in url -> filemoonExtractor.videosFromUrl(url, "$lang Filemoon:")
|
||||||
|
"streamtape" in url || "stp" in url || "stape" in url -> listOf(streamTapeExtractor.videoFromUrl(url, quality = "$lang StreamTape")!!)
|
||||||
|
"mp4upload" in url -> mp4uploadExtractor.videosFromUrl(url, prefix = "$lang ", headers = headers)
|
||||||
|
"mixdrop" in url || "mdbekjwqa" in url -> mixDropExtractor.videosFromUrl(url, prefix = "$lang ")
|
||||||
|
"sfastwish" in url || "wishembed" in url || "streamwish" in url || "strwish" in url || "wish" in url
|
||||||
|
-> streamWishExtractor.videosFromUrl(url, videoNameGen = { "$lang StreamWish:$it" })
|
||||||
|
"stream/jkmedia" in url -> jkanimeExtractor.getDesukaFromUrl(url, "$lang ")
|
||||||
|
"um2.php" in url -> jkanimeExtractor.getNozomiFromUrl(url, "$lang ")
|
||||||
|
"um.php" in url -> jkanimeExtractor.getDesuFromUrl(url, "$lang ")
|
||||||
|
else -> emptyList()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return videos
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun videoListSelector() = throw UnsupportedOperationException()
|
override fun videoListSelector() = throw UnsupportedOperationException()
|
||||||
@ -462,4 +513,12 @@ class Jkanime : ConfigurableAnimeSource, ParsedAnimeHttpSource() {
|
|||||||
}
|
}
|
||||||
}.also(screen::addPreference)
|
}.also(screen::addPreference)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Serializable
|
||||||
|
data class JsLinks(
|
||||||
|
val remote: String? = null,
|
||||||
|
val server: String? = null,
|
||||||
|
val lang: Long? = null,
|
||||||
|
val slug: String? = null,
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
@ -4,17 +4,18 @@ import eu.kanade.tachiyomi.animesource.model.Video
|
|||||||
import eu.kanade.tachiyomi.network.GET
|
import eu.kanade.tachiyomi.network.GET
|
||||||
import eu.kanade.tachiyomi.network.POST
|
import eu.kanade.tachiyomi.network.POST
|
||||||
import eu.kanade.tachiyomi.util.asJsoup
|
import eu.kanade.tachiyomi.util.asJsoup
|
||||||
|
import eu.kanade.tachiyomi.util.parseAs
|
||||||
|
import kotlinx.serialization.Serializable
|
||||||
import okhttp3.Headers
|
import okhttp3.Headers
|
||||||
import okhttp3.MediaType.Companion.toMediaTypeOrNull
|
import okhttp3.MediaType.Companion.toMediaTypeOrNull
|
||||||
import okhttp3.OkHttpClient
|
import okhttp3.OkHttpClient
|
||||||
import okhttp3.RequestBody.Companion.toRequestBody
|
import okhttp3.RequestBody.Companion.toRequestBody
|
||||||
import org.json.JSONObject
|
|
||||||
|
|
||||||
class JkanimeExtractor(
|
class JkanimeExtractor(
|
||||||
private val client: OkHttpClient,
|
private val client: OkHttpClient,
|
||||||
) {
|
) {
|
||||||
|
|
||||||
fun getNozomiFromUrl(url: String, prefix: String = ""): Video? {
|
fun getNozomiFromUrl(url: String, prefix: String = ""): List<Video> {
|
||||||
val dataKeyHeaders = Headers.Builder().add("Referer", url).build()
|
val dataKeyHeaders = Headers.Builder().add("Referer", url).build()
|
||||||
val doc = client.newCall(GET(url, dataKeyHeaders)).execute().asJsoup()
|
val doc = client.newCall(GET(url, dataKeyHeaders)).execute().asJsoup()
|
||||||
val dataKey = doc.select("form input[value]").attr("value")
|
val dataKey = doc.select("form input[value]").attr("value")
|
||||||
@ -26,20 +27,40 @@ class JkanimeExtractor(
|
|||||||
|
|
||||||
val nozomiBody = "v=$postKey".toRequestBody("application/x-www-form-urlencoded".toMediaTypeOrNull())
|
val nozomiBody = "v=$postKey".toRequestBody("application/x-www-form-urlencoded".toMediaTypeOrNull())
|
||||||
val nozomiResponse = client.newCall(POST("https://jkanime.net/gsplay/api.php", body = nozomiBody)).execute()
|
val nozomiResponse = client.newCall(POST("https://jkanime.net/gsplay/api.php", body = nozomiBody)).execute()
|
||||||
val nozomiUrl = JSONObject(nozomiResponse.body.string()).getString("file")
|
val nozomiUrl = nozomiResponse.body.string().parseAs<NozomiResponse>().file ?: return emptyList()
|
||||||
if (nozomiResponse.isSuccessful && nozomiUrl.isNotBlank()) {
|
|
||||||
return Video(nozomiUrl, "${prefix}Nozomi", nozomiUrl)
|
return listOf(Video(nozomiUrl, "${prefix}Nozomi", nozomiUrl))
|
||||||
}
|
|
||||||
return null
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fun getDesuFromUrl(url: String, prefix: String = ""): Video? {
|
fun getDesuFromUrl(url: String, prefix: String = ""): List<Video> {
|
||||||
val document = client.newCall(GET(url)).execute()
|
val document = client.newCall(GET(url)).execute()
|
||||||
val script = document.asJsoup().selectFirst("script:containsData(var parts = {)")!!.data()
|
val streamUrl = document.asJsoup()
|
||||||
val streamUrl = script.substringAfter("url: '").substringBefore("'")
|
.selectFirst("script:containsData(var parts = {)")
|
||||||
if (document.isSuccessful && streamUrl.isNotBlank()) {
|
?.data()?.substringAfter("url: '")
|
||||||
return Video(streamUrl, "${prefix}Desu", streamUrl)
|
?.substringBefore("'") ?: return emptyList()
|
||||||
}
|
|
||||||
return null
|
return listOf(Video(streamUrl, "${prefix}Desu", streamUrl))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun getDesukaFromUrl(url: String, prefix: String = ""): List<Video> {
|
||||||
|
val document = client.newCall(GET(url)).execute()
|
||||||
|
val contentType = document.header("Content-Type") ?: ""
|
||||||
|
|
||||||
|
if (contentType.startsWith("video/")) {
|
||||||
|
val realUrl = document.networkResponse.toString()
|
||||||
|
.substringAfter("url=")
|
||||||
|
.substringBefore("}")
|
||||||
|
return listOf(Video(realUrl, "${prefix}Desuka", realUrl))
|
||||||
|
}
|
||||||
|
|
||||||
|
val streamUrl = document.asJsoup()
|
||||||
|
.selectFirst("script:containsData(new DPlayer({)")
|
||||||
|
?.data()?.substringAfter("url: '")
|
||||||
|
?.substringBefore("'") ?: return emptyList()
|
||||||
|
|
||||||
|
return listOf(Video(streamUrl, "${prefix}Desuka", streamUrl))
|
||||||
|
}
|
||||||
|
|
||||||
|
@Serializable
|
||||||
|
data class NozomiResponse(val file: String? = null)
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user