Fix Toonitalia + extractors (#1331)

* Update extractors

* Add more streamsb links

* StreamSB fix
This commit is contained in:
Secozzi 2023-02-25 12:20:27 +01:00 committed by GitHub
parent 6a191b0638
commit 5dc5646302
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 15 additions and 151 deletions

View File

@ -8,6 +8,7 @@ import kotlinx.serialization.json.Json
import kotlinx.serialization.json.JsonObject
import kotlinx.serialization.json.jsonObject
import okhttp3.Headers
import okhttp3.HttpUrl.Companion.toHttpUrl
import okhttp3.OkHttpClient
class StreamSBExtractor(private val client: OkHttpClient) {
@ -26,11 +27,13 @@ class StreamSBExtractor(private val client: OkHttpClient) {
// animension, asianload and dramacool uses "common = false"
private fun fixUrl(url: String, common: Boolean): String {
val sbUrl = url.substringBefore("/e/").substringBefore("/embed-")
val id = url.substringAfter("/e/")
val sbUrl = "https://${url.toHttpUrl().host}"
val id = url.substringAfter("${url.toHttpUrl().host}")
.substringAfter("/e/")
.substringAfter("/embed-")
.substringBefore("?")
.substringBefore(".html")
.substringAfter("/")
return if (common) {
val hexBytes = bytesToHex(id.toByteArray())
"$sbUrl/sources51/625a364258615242766475327c7c${hexBytes}7c7c4761574550654f7461566d347c7c73747265616d7362"

View File

@ -8,7 +8,7 @@ import okhttp3.OkHttpClient
class VoeExtractor(private val client: OkHttpClient) {
fun videoFromUrl(url: String, quality: String? = null): Video? {
val document = client.newCall(GET(url)).execute().asJsoup()
val script = document.selectFirst("script:containsData(const sources)")
val script = document.selectFirst("script:containsData(const sources),script:containsData(var sources)")
?.data()
?: return null
val videoUrl = script.substringAfter("hls': '").substringBefore("'")

View File

@ -5,12 +5,13 @@ ext {
extName = 'Toonitalia'
pkgNameSuffix = 'it.toonitalia'
extClass = '.Toonitalia'
extVersionCode = 2
extVersionCode = 3
libVersion = '13'
}
dependencies {
implementation(project(':lib-voe-extractor'))
implementation(project(':lib-streamsb-extractor'))
}
apply from: "$rootDir/common.gradle"

View File

@ -4,7 +4,6 @@ import android.app.Application
import android.content.SharedPreferences
import androidx.preference.ListPreference
import androidx.preference.PreferenceScreen
import eu.kanade.tachiyomi.animeextension.it.toonitalia.extractors.StreamSBExtractor
import eu.kanade.tachiyomi.animeextension.it.toonitalia.extractors.StreamZExtractor
import eu.kanade.tachiyomi.animesource.ConfigurableAnimeSource
import eu.kanade.tachiyomi.animesource.model.AnimeFilter
@ -14,6 +13,7 @@ import eu.kanade.tachiyomi.animesource.model.SAnime
import eu.kanade.tachiyomi.animesource.model.SEpisode
import eu.kanade.tachiyomi.animesource.model.Video
import eu.kanade.tachiyomi.animesource.online.ParsedAnimeHttpSource
import eu.kanade.tachiyomi.lib.streamsbextractor.StreamSBExtractor
import eu.kanade.tachiyomi.lib.voeextractor.VoeExtractor
import eu.kanade.tachiyomi.network.GET
import eu.kanade.tachiyomi.util.asJsoup
@ -345,7 +345,8 @@ class Toonitalia : ConfigurableAnimeSource, ParsedAnimeHttpSource() {
url.contains("sbfast") || url.contains("sbfull.com") || url.contains("javplaya.com") ||
url.contains("ssbstream.net") || url.contains("p1ayerjavseen.com") || url.contains("sbthe.com") ||
url.contains("sbchill.com") || url.contains("sblongvu.com") || url.contains("sbanh.com") ||
url.contains("sblanh.com")
url.contains("sblanh.com") || url.contains("sbhight.com") || url.contains("sbbrisk.com") ||
url.contains("sbspeed.com")
-> {
val videos = StreamSBExtractor(client).videosFromUrl(url, headers, suffix = name, common = false)
videos

View File

@ -1,141 +0,0 @@
package eu.kanade.tachiyomi.animeextension.it.toonitalia.extractors
import eu.kanade.tachiyomi.animesource.model.Video
import eu.kanade.tachiyomi.network.GET
import kotlinx.serialization.decodeFromString
import kotlinx.serialization.json.Json
import kotlinx.serialization.json.JsonObject
import kotlinx.serialization.json.jsonObject
import okhttp3.Headers
import okhttp3.HttpUrl.Companion.toHttpUrl
import okhttp3.OkHttpClient
class StreamSBExtractor(private val client: OkHttpClient) {
protected fun bytesToHex(bytes: ByteArray): String {
val hexArray = "0123456789ABCDEF".toCharArray()
val hexChars = CharArray(bytes.size * 2)
for (j in bytes.indices) {
val v = bytes[j].toInt() and 0xFF
hexChars[j * 2] = hexArray[v ushr 4]
hexChars[j * 2 + 1] = hexArray[v and 0x0F]
}
return String(hexChars)
}
// animension, asianload and dramacool uses "common = false"
private fun fixUrl(url: String, common: Boolean): String {
val sbUrl = url.substringBefore("/e/")
val id = url.substringAfter("/e/")
.substringBefore("?")
.substringBefore(".html")
return if (common) {
val hexBytes = bytesToHex(id.toByteArray())
"$sbUrl/sources48/625a364258615242766475327c7c${hexBytes}7c7c4761574550654f7461566d347c7c73747265616d7362"
} else {
"$sbUrl/sources48/${bytesToHex("||$id||||streamsb".toByteArray())}/"
}
}
private fun asciiToHex(asciiValue: String): String? {
val chars = asciiValue.toCharArray()
val hex = StringBuffer()
for (i in chars.indices) {
hex.append(Integer.toHexString(chars[i].code))
}
return hex.toString()
}
private fun newFixUrl(url: String): String {
val sbUrl = url.substringBefore("/e/")
val id = url.substringAfter("/e/")
.substringBefore("?")
.substringBefore(".html")
val hexBytes = asciiToHex(id.toHttpUrl().encodedPath.substringAfter("/"))
return "$sbUrl/sources50/63556a6137557a4c5a3752427c7c${hexBytes}7c7c644a4c7356504f4d577949537c7c73747265616d7362"
}
fun videosFromUrl(url: String, headers: Headers, prefix: String = "", suffix: String = "", common: Boolean = true): List<Video> {
val newHeaders = headers.newBuilder()
.set("referer", url)
.set("watchsb", "sbstream")
.set("authority", "embedsb.com")
.build()
return try {
val newUrl = client.newCall(GET(url, headers = headers)).execute().request.url
val json = if (newUrl.host != url.toHttpUrl().host) {
val master = newFixUrl(newUrl.toString()).replace(
"""/(\w+)\.html""".toRegex(), ""
)
val newHeaders = headers.newBuilder()
.set("referer", newUrl.toString())
.set("watchsb", "sbstream")
.set("authority", "embedsb.com")
.build()
Json.decodeFromString<JsonObject>(
client.newCall(GET(master, newHeaders))
.execute().body!!.string()
)
} else {
val master = fixUrl(url, common)
Json.decodeFromString<JsonObject>(
client.newCall(GET(master, newHeaders))
.execute().body!!.string()
)
}
val masterUrl = json["stream_data"]!!.jsonObject["file"].toString().trim('"')
val masterPlaylist = client.newCall(GET(masterUrl, newHeaders))
.execute()
.body!!.string()
val separator = "#EXT-X-STREAM-INF"
masterPlaylist.substringAfter(separator).split(separator).map {
val resolution = it.substringAfter("RESOLUTION=")
.substringBefore("\n")
.substringAfter("x")
.substringBefore(",") + "p"
val quality = ("StreamSB:" + resolution).let {
if (prefix.isNotBlank()) "$prefix $it"
else it
}.let {
if (suffix.isNotBlank()) "$it $suffix"
else it
}
val videoUrl = it.substringAfter("\n").substringBefore("\n")
Video(videoUrl, quality, videoUrl, headers = newHeaders)
}
} catch (e: Exception) {
emptyList<Video>()
}
}
fun videosFromDecryptedUrl(realUrl: String, headers: Headers, prefix: String = "", suffix: String = ""): List<Video> {
return try {
val json = Json.decodeFromString<JsonObject>(client.newCall(GET(realUrl, headers)).execute().body!!.string())
val masterUrl = json["stream_data"]!!.jsonObject["file"].toString().trim('"')
val masterPlaylist = client.newCall(GET(masterUrl, headers)).execute().body!!.string()
val separator = "#EXT-X-STREAM-INF"
masterPlaylist.substringAfter(separator).split(separator).map {
val resolution = it.substringAfter("RESOLUTION=")
.substringBefore("\n")
.substringAfter("x")
.substringBefore(",") + "p"
val quality = ("StreamSB:$resolution").let {
if (prefix.isNotBlank()) "$prefix $it"
else it
}.let {
if (suffix.isNotBlank()) "$it $suffix"
else it
}
val videoUrl = it.substringAfter("\n").substringBefore("\n")
Video(videoUrl, quality, videoUrl, headers = headers)
}
} catch (e: Exception) {
emptyList()
}
}
}