feat(all/chineseanime): Add VatchusExtractor (#2331)
This commit is contained in:
@ -1,4 +1,5 @@
|
|||||||
dependencies {
|
dependencies {
|
||||||
implementation(project(":lib-dailymotion-extractor"))
|
implementation(project(":lib-dailymotion-extractor"))
|
||||||
implementation(project(":lib-streamwish-extractor"))
|
implementation(project(":lib-streamwish-extractor"))
|
||||||
}
|
implementation(project(":lib-playlist-utils"))
|
||||||
|
}
|
||||||
|
@ -2,6 +2,7 @@ package eu.kanade.tachiyomi.animeextension.all.chineseanime
|
|||||||
|
|
||||||
import androidx.preference.ListPreference
|
import androidx.preference.ListPreference
|
||||||
import androidx.preference.PreferenceScreen
|
import androidx.preference.PreferenceScreen
|
||||||
|
import eu.kanade.tachiyomi.animeextension.all.chineseanime.extractors.VatchusExtractor
|
||||||
import eu.kanade.tachiyomi.animesource.model.Video
|
import eu.kanade.tachiyomi.animesource.model.Video
|
||||||
import eu.kanade.tachiyomi.lib.dailymotionextractor.DailymotionExtractor
|
import eu.kanade.tachiyomi.lib.dailymotionextractor.DailymotionExtractor
|
||||||
import eu.kanade.tachiyomi.lib.streamwishextractor.StreamWishExtractor
|
import eu.kanade.tachiyomi.lib.streamwishextractor.StreamWishExtractor
|
||||||
@ -23,15 +24,16 @@ class ChineseAnime : AnimeStream(
|
|||||||
override val filtersSelector = "div.filter > ul"
|
override val filtersSelector = "div.filter > ul"
|
||||||
|
|
||||||
// ============================ Video Links =============================
|
// ============================ Video Links =============================
|
||||||
|
private val dailymotionExtractor by lazy { DailymotionExtractor(client, headers) }
|
||||||
|
private val streamwishExtractor by lazy { StreamWishExtractor(client, headers) }
|
||||||
|
private val vatchusExtractor by lazy { VatchusExtractor(client, headers) }
|
||||||
|
|
||||||
override fun getVideoList(url: String, name: String): List<Video> {
|
override fun getVideoList(url: String, name: String): List<Video> {
|
||||||
val prefix = "$name - "
|
val prefix = "$name - "
|
||||||
return when {
|
return when {
|
||||||
url.contains("dailymotion") -> {
|
url.contains("dailymotion") -> dailymotionExtractor.videosFromUrl(url, prefix)
|
||||||
DailymotionExtractor(client, headers).videosFromUrl(url, prefix)
|
url.contains("embedwish") -> streamwishExtractor.videosFromUrl(url, prefix)
|
||||||
}
|
url.contains("vatchus") -> vatchusExtractor.videosFromUrl(url, prefix)
|
||||||
url.contains("embedwish") -> {
|
|
||||||
StreamWishExtractor(client, headers).videosFromUrl(url, prefix)
|
|
||||||
}
|
|
||||||
else -> emptyList()
|
else -> emptyList()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,56 @@
|
|||||||
|
package eu.kanade.tachiyomi.animeextension.all.chineseanime.extractors
|
||||||
|
|
||||||
|
import android.util.Base64
|
||||||
|
import eu.kanade.tachiyomi.animesource.model.Track
|
||||||
|
import eu.kanade.tachiyomi.animesource.model.Video
|
||||||
|
import eu.kanade.tachiyomi.lib.playlistutils.PlaylistUtils
|
||||||
|
import eu.kanade.tachiyomi.network.GET
|
||||||
|
import eu.kanade.tachiyomi.util.asJsoup
|
||||||
|
import okhttp3.Headers
|
||||||
|
import okhttp3.OkHttpClient
|
||||||
|
|
||||||
|
class VatchusExtractor(private val client: OkHttpClient, private val headers: Headers) {
|
||||||
|
private val playlistUtils by lazy { PlaylistUtils(client, headers) }
|
||||||
|
|
||||||
|
fun videosFromUrl(url: String, prefix: String): List<Video> {
|
||||||
|
val doc = client.newCall(GET(url, headers)).execute()
|
||||||
|
.use { it.asJsoup() }
|
||||||
|
|
||||||
|
val script = doc.selectFirst("script:containsData(document.write)")
|
||||||
|
?.data()
|
||||||
|
?: return emptyList()
|
||||||
|
|
||||||
|
val numberList = script.substringAfter(" = [").substringBefore("];")
|
||||||
|
.replace("\"", "")
|
||||||
|
.split(",")
|
||||||
|
.map(String::trim)
|
||||||
|
.filter(String::isNotBlank)
|
||||||
|
.map { String(Base64.decode(it, Base64.DEFAULT)) }
|
||||||
|
.mapNotNull { it.filter(Char::isDigit).toIntOrNull() }
|
||||||
|
|
||||||
|
val offset = numberList.first() - 60
|
||||||
|
val decodedData = numberList.joinToString("") {
|
||||||
|
Char(it - offset).toString()
|
||||||
|
}.trim()
|
||||||
|
|
||||||
|
val playlistUrl = decodedData.substringAfter("file:'").substringBefore("'")
|
||||||
|
val subs = decodedData.substringAfter("tracks:[").substringBefore("]")
|
||||||
|
.split("{")
|
||||||
|
.drop(1)
|
||||||
|
.filter { it.contains(""""kind":"captions"""") }
|
||||||
|
.mapNotNull {
|
||||||
|
val trackUrl = it.substringAfter("file\":\"").substringBefore('"')
|
||||||
|
.takeIf { link -> link.startsWith("http") }
|
||||||
|
?: return@mapNotNull null
|
||||||
|
val language = it.substringAfter("label\":\"").substringBefore('"')
|
||||||
|
Track(trackUrl, language)
|
||||||
|
}
|
||||||
|
|
||||||
|
return playlistUtils.extractFromHls(
|
||||||
|
playlistUrl,
|
||||||
|
url,
|
||||||
|
subtitleList = subs,
|
||||||
|
videoNameGen = { prefix + it },
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
@ -17,7 +17,7 @@ class AnimeStreamGenerator : ThemeSourceGenerator {
|
|||||||
SingleLang("AnimeTitans", "https://animetitans.com", "ar", isNsfw = false, overrideVersionCode = 13),
|
SingleLang("AnimeTitans", "https://animetitans.com", "ar", isNsfw = false, overrideVersionCode = 13),
|
||||||
SingleLang("AnimeXin", "https://animexin.vip", "all", isNsfw = false, overrideVersionCode = 6),
|
SingleLang("AnimeXin", "https://animexin.vip", "all", isNsfw = false, overrideVersionCode = 6),
|
||||||
SingleLang("AsyaAnimeleri", "https://asyaanimeleri.com", "tr", isNsfw = false, overrideVersionCode = 1),
|
SingleLang("AsyaAnimeleri", "https://asyaanimeleri.com", "tr", isNsfw = false, overrideVersionCode = 1),
|
||||||
SingleLang("ChineseAnime", "https://chineseanime.top", "all", isNsfw = false),
|
SingleLang("ChineseAnime", "https://chineseanime.top", "all", isNsfw = false, overrideVersionCode = 1),
|
||||||
SingleLang("desu-online", "https://desu-online.pl", "pl", className = "DesuOnline", isNsfw = false, overrideVersionCode = 3),
|
SingleLang("desu-online", "https://desu-online.pl", "pl", className = "DesuOnline", isNsfw = false, overrideVersionCode = 3),
|
||||||
SingleLang("DonghuaStream", "https://donghuastream.co.in", "en", isNsfw = false),
|
SingleLang("DonghuaStream", "https://donghuastream.co.in", "en", isNsfw = false),
|
||||||
SingleLang("Hstream", "https://hstream.moe", "en", isNsfw = true, overrideVersionCode = 3),
|
SingleLang("Hstream", "https://hstream.moe", "en", isNsfw = true, overrideVersionCode = 3),
|
||||||
|
Reference in New Issue
Block a user