refactor: Make extensions use the FilemoonExtractor shared lib (#1927)
This commit is contained in:
parent
2b3f65062c
commit
70b2b1406e
@ -24,7 +24,9 @@ android {
|
||||
applicationIdSuffix pkgNameSuffix
|
||||
versionCode extVersionCode
|
||||
versionName project.ext.properties.getOrDefault("libVersion", "13") + ".$extVersionCode"
|
||||
setProperty("archivesBaseName", "aniyomi-$pkgNameSuffix-v$versionName")
|
||||
base {
|
||||
archivesBaseName = "aniyomi-$pkgNameSuffix-v$versionName"
|
||||
}
|
||||
def readmes = project.projectDir.listFiles({ File file ->
|
||||
file.name.equals("README.md") ||
|
||||
file.name.equals("CHANGELOG.md")
|
||||
|
@ -1,4 +1,5 @@
|
||||
dependencies {
|
||||
implementation(project(':lib-filemoon-extractor'))
|
||||
implementation(project(':lib-streamsb-extractor'))
|
||||
implementation "dev.datlag.jsunpacker:jsunpacker:1.0.1"
|
||||
}
|
||||
|
@ -2,12 +2,12 @@ package eu.kanade.tachiyomi.animeextension.en.animenosub
|
||||
|
||||
import androidx.preference.ListPreference
|
||||
import androidx.preference.PreferenceScreen
|
||||
import eu.kanade.tachiyomi.animeextension.en.animenosub.extractors.FilemoonExtractor
|
||||
import eu.kanade.tachiyomi.animeextension.en.animenosub.extractors.StreamWishExtractor
|
||||
import eu.kanade.tachiyomi.animeextension.en.animenosub.extractors.VidMolyExtractor
|
||||
import eu.kanade.tachiyomi.animeextension.en.animenosub.extractors.VtubeExtractor
|
||||
import eu.kanade.tachiyomi.animeextension.en.animenosub.extractors.WolfstreamExtractor
|
||||
import eu.kanade.tachiyomi.animesource.model.Video
|
||||
import eu.kanade.tachiyomi.lib.filemoonextractor.FilemoonExtractor
|
||||
import eu.kanade.tachiyomi.lib.streamsbextractor.StreamSBExtractor
|
||||
import eu.kanade.tachiyomi.multisrc.animestream.AnimeStream
|
||||
import org.jsoup.nodes.Element
|
||||
@ -55,7 +55,7 @@ class Animenosub : AnimeStream(
|
||||
WolfstreamExtractor(client).videosFromUrl(url, prefix)
|
||||
}
|
||||
url.contains("filemoon") -> {
|
||||
FilemoonExtractor(client, headers).videosFromUrl(url, prefix)
|
||||
FilemoonExtractor(client).videosFromUrl(url, prefix, headers)
|
||||
}
|
||||
else -> emptyList()
|
||||
}
|
||||
|
@ -1,34 +0,0 @@
|
||||
package eu.kanade.tachiyomi.animeextension.en.animenosub.extractors
|
||||
|
||||
import dev.datlag.jsunpacker.JsUnpacker
|
||||
import eu.kanade.tachiyomi.animesource.model.Video
|
||||
import eu.kanade.tachiyomi.network.GET
|
||||
import eu.kanade.tachiyomi.util.asJsoup
|
||||
import okhttp3.Headers
|
||||
import okhttp3.HttpUrl.Companion.toHttpUrl
|
||||
import okhttp3.OkHttpClient
|
||||
|
||||
class FilemoonExtractor(private val client: OkHttpClient, private val headers: Headers) {
|
||||
fun videosFromUrl(url: String, prefix: String = ""): List<Video> {
|
||||
val jsE = client.newCall(GET(url)).execute().asJsoup().selectFirst("script:containsData(eval)")!!.data()
|
||||
val masterUrl = JsUnpacker.unpackAndCombine(jsE)?.substringAfter("{file:\"")
|
||||
?.substringBefore("\"}") ?: return emptyList()
|
||||
val masterPlaylist = client.newCall(GET(masterUrl)).execute().body.string()
|
||||
val videoList = mutableListOf<Video>()
|
||||
masterPlaylist.substringAfter("#EXT-X-STREAM-INF:").split("#EXT-X-STREAM-INF:")
|
||||
.forEach {
|
||||
val quality = it.substringAfter("RESOLUTION=").substringAfter("x").substringBefore(",") + "p "
|
||||
val videoUrl = it.substringAfter("\n").substringBefore("\n")
|
||||
|
||||
val videoHeaders = headers.newBuilder()
|
||||
.add("Accept", "*/*")
|
||||
.add("Host", videoUrl.toHttpUrl().host)
|
||||
.add("Origin", "https://${url.toHttpUrl().host}")
|
||||
.add("Referer", "https://${url.toHttpUrl().host}/")
|
||||
.build()
|
||||
|
||||
videoList.add(Video(videoUrl, prefix + quality, videoUrl, headers = videoHeaders))
|
||||
}
|
||||
return videoList
|
||||
}
|
||||
}
|
@ -1,4 +1,5 @@
|
||||
dependencies {
|
||||
implementation(project(':lib-filemoon-extractor'))
|
||||
implementation(project(':lib-dood-extractor'))
|
||||
implementation(project(':lib-streamlare-extractor'))
|
||||
implementation(project(':lib-streamsb-extractor'))
|
||||
|
@ -3,10 +3,10 @@ package eu.kanade.tachiyomi.animeextension.de.cinemathek
|
||||
import androidx.preference.ListPreference
|
||||
import androidx.preference.MultiSelectListPreference
|
||||
import androidx.preference.PreferenceScreen
|
||||
import eu.kanade.tachiyomi.animeextension.de.cinemathek.extractors.FilemoonExtractor
|
||||
import eu.kanade.tachiyomi.animeextension.de.cinemathek.extractors.StreamHideExtractor
|
||||
import eu.kanade.tachiyomi.animesource.model.Video
|
||||
import eu.kanade.tachiyomi.lib.doodextractor.DoodExtractor
|
||||
import eu.kanade.tachiyomi.lib.filemoonextractor.FilemoonExtractor
|
||||
import eu.kanade.tachiyomi.lib.streamlareextractor.StreamlareExtractor
|
||||
import eu.kanade.tachiyomi.lib.streamsbextractor.StreamSBExtractor
|
||||
import eu.kanade.tachiyomi.multisrc.dooplay.DooPlay
|
||||
|
@ -1,28 +0,0 @@
|
||||
package eu.kanade.tachiyomi.animeextension.de.cinemathek.extractors
|
||||
|
||||
import dev.datlag.jsunpacker.JsUnpacker
|
||||
import eu.kanade.tachiyomi.animesource.model.Video
|
||||
import eu.kanade.tachiyomi.network.GET
|
||||
import eu.kanade.tachiyomi.util.asJsoup
|
||||
import okhttp3.OkHttpClient
|
||||
|
||||
class FilemoonExtractor(private val client: OkHttpClient) {
|
||||
fun videosFromUrl(url: String): List<Video> {
|
||||
return runCatching {
|
||||
val doc = client.newCall(GET(url)).execute().asJsoup()
|
||||
val jsEval = doc.selectFirst("script:containsData(eval)")!!.data()
|
||||
val masterUrl = JsUnpacker.unpackAndCombine(jsEval)
|
||||
?.substringAfter("{file:\"")
|
||||
?.substringBefore("\"}")
|
||||
?: return emptyList()
|
||||
|
||||
val masterPlaylist = client.newCall(GET(masterUrl)).execute().body.string()
|
||||
val separator = "#EXT-X-STREAM-INF:"
|
||||
masterPlaylist.substringAfter(separator).split(separator).map {
|
||||
val quality = "Filemoon:" + it.substringAfter("RESOLUTION=").substringAfter("x").substringBefore(",") + "p "
|
||||
val videoUrl = it.substringAfter("\n").substringBefore("\n")
|
||||
Video(videoUrl, quality, videoUrl)
|
||||
}
|
||||
}.getOrElse { emptyList() }
|
||||
}
|
||||
}
|
@ -11,6 +11,7 @@ ext {
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation(project(':lib-filemoon-extractor'))
|
||||
implementation(project(':lib-voe-extractor'))
|
||||
}
|
||||
|
||||
|
@ -6,7 +6,6 @@ import androidx.preference.ListPreference
|
||||
import androidx.preference.MultiSelectListPreference
|
||||
import androidx.preference.PreferenceScreen
|
||||
import eu.kanade.tachiyomi.animeextension.de.filmpalast.extractors.EvoloadExtractor
|
||||
import eu.kanade.tachiyomi.animeextension.de.filmpalast.extractors.FilemoonExtractor
|
||||
import eu.kanade.tachiyomi.animeextension.de.filmpalast.extractors.StreamHideVidExtractor
|
||||
import eu.kanade.tachiyomi.animeextension.de.filmpalast.extractors.UpstreamExtractor
|
||||
import eu.kanade.tachiyomi.animesource.ConfigurableAnimeSource
|
||||
@ -15,6 +14,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.filemoonextractor.FilemoonExtractor
|
||||
import eu.kanade.tachiyomi.lib.voeextractor.VoeExtractor
|
||||
import eu.kanade.tachiyomi.network.GET
|
||||
import eu.kanade.tachiyomi.util.asJsoup
|
||||
@ -136,7 +136,7 @@ class FilmPalast : ConfigurableAnimeSource, ParsedAnimeHttpSource() {
|
||||
}
|
||||
|
||||
url.contains("filemoon.sx") && hosterSelection.contains("moon") ->
|
||||
FilemoonExtractor(client).videoFromUrl(url)
|
||||
FilemoonExtractor(client).videosFromUrl(url)
|
||||
url.contains("hide.com") && hosterSelection.contains("hide") ->
|
||||
StreamHideVidExtractor(client).videosFromUrl(url, "StreamHide")
|
||||
url.contains("streamvid.net") && hosterSelection.contains("vid") ->
|
||||
|
@ -1,28 +0,0 @@
|
||||
package eu.kanade.tachiyomi.animeextension.de.filmpalast.extractors
|
||||
|
||||
import eu.kanade.tachiyomi.animesource.model.Video
|
||||
import eu.kanade.tachiyomi.network.GET
|
||||
import eu.kanade.tachiyomi.util.asJsoup
|
||||
import okhttp3.OkHttpClient
|
||||
|
||||
class FilemoonExtractor(private val client: OkHttpClient) {
|
||||
|
||||
fun videoFromUrl(url: String): MutableList<Video>? {
|
||||
try {
|
||||
val jsE = client.newCall(GET(url)).execute().asJsoup().selectFirst("script:containsData(eval)")!!.data()
|
||||
val masterUrl = JsUnpacker(jsE).unpack().toString()
|
||||
.substringAfter("{file:\"").substringBefore("\"}")
|
||||
val masterPlaylist = client.newCall(GET(masterUrl)).execute().body.string()
|
||||
val videoList = mutableListOf<Video>()
|
||||
masterPlaylist.substringAfter("#EXT-X-STREAM-INF:").split("#EXT-X-STREAM-INF:")
|
||||
.forEach {
|
||||
val quality = "Filemoon:" + it.substringAfter("RESOLUTION=").substringAfter("x").substringBefore(",") + "p "
|
||||
val videoUrl = it.substringAfter("\n").substringBefore("\n")
|
||||
videoList.add(Video(videoUrl, quality, videoUrl))
|
||||
}
|
||||
return videoList
|
||||
} catch (e: Exception) {
|
||||
return null
|
||||
}
|
||||
}
|
||||
}
|
@ -11,6 +11,7 @@ ext {
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation(project(':lib-filemoon-extractor'))
|
||||
implementation(project(':lib-streamtape-extractor'))
|
||||
implementation(project(':lib-voe-extractor'))
|
||||
}
|
||||
|
@ -6,7 +6,6 @@ import android.util.Log
|
||||
import androidx.preference.ListPreference
|
||||
import androidx.preference.MultiSelectListPreference
|
||||
import androidx.preference.PreferenceScreen
|
||||
import eu.kanade.tachiyomi.animeextension.de.kool.extractors.FilemoonExtractor
|
||||
import eu.kanade.tachiyomi.animeextension.de.movie4k.extractors.VidozaExtractor
|
||||
import eu.kanade.tachiyomi.animesource.ConfigurableAnimeSource
|
||||
import eu.kanade.tachiyomi.animesource.model.AnimeFilter
|
||||
@ -16,6 +15,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.AnimeHttpSource
|
||||
import eu.kanade.tachiyomi.lib.filemoonextractor.FilemoonExtractor
|
||||
import eu.kanade.tachiyomi.lib.streamtapeextractor.StreamTapeExtractor
|
||||
import eu.kanade.tachiyomi.lib.voeextractor.VoeExtractor
|
||||
import eu.kanade.tachiyomi.network.POST
|
||||
@ -418,10 +418,7 @@ class Kool : ConfigurableAnimeSource, AnimeHttpSource() {
|
||||
}
|
||||
item.jsonObject["url"]!!.jsonPrimitive.content.contains("https://filemoon.sx") && hosterSelection?.contains("fmoon") == true -> {
|
||||
val videoUrl = item.jsonObject["url"]!!.jsonPrimitive.content
|
||||
val videos = FilemoonExtractor(client).videoFromUrl(videoUrl)
|
||||
if (videos != null) {
|
||||
videoList.addAll(videos)
|
||||
}
|
||||
videoList.addAll(FilemoonExtractor(client).videosFromUrl(videoUrl))
|
||||
}
|
||||
response.request.url.toString().contains("kool-cluster/mediahubmx-resolve.json") -> {
|
||||
val videoUrl = item.jsonObject["url"]!!.jsonPrimitive.content
|
||||
|
@ -1,28 +0,0 @@
|
||||
package eu.kanade.tachiyomi.animeextension.de.kool.extractors
|
||||
|
||||
import eu.kanade.tachiyomi.animesource.model.Video
|
||||
import eu.kanade.tachiyomi.network.GET
|
||||
import eu.kanade.tachiyomi.util.asJsoup
|
||||
import okhttp3.OkHttpClient
|
||||
|
||||
class FilemoonExtractor(private val client: OkHttpClient) {
|
||||
|
||||
fun videoFromUrl(url: String): MutableList<Video>? {
|
||||
try {
|
||||
val jsE = client.newCall(GET(url)).execute().asJsoup().selectFirst("script:containsData(eval)")!!.data()
|
||||
val masterUrl = JsUnpacker(jsE).unpack().toString()
|
||||
.substringAfter("{file:\"").substringBefore("\"}")
|
||||
val masterPlaylist = client.newCall(GET(masterUrl)).execute().body.string()
|
||||
val videoList = mutableListOf<Video>()
|
||||
masterPlaylist.substringAfter("#EXT-X-STREAM-INF:").split("#EXT-X-STREAM-INF:")
|
||||
.forEach {
|
||||
val quality = "Filemoon:" + it.substringAfter("RESOLUTION=").substringAfter("x").substringBefore(",") + "p "
|
||||
val videoUrl = it.substringAfter("\n").substringBefore("\n")
|
||||
videoList.add(Video(videoUrl, quality, videoUrl))
|
||||
}
|
||||
return videoList
|
||||
} catch (e: Exception) {
|
||||
return null
|
||||
}
|
||||
}
|
||||
}
|
@ -11,6 +11,7 @@ ext {
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation(project(':lib-filemoon-extractor'))
|
||||
implementation "dev.datlag.jsunpacker:jsunpacker:1.0.1"
|
||||
}
|
||||
|
||||
|
@ -3,7 +3,6 @@ package eu.kanade.tachiyomi.animeextension.en.ask4movie
|
||||
import android.app.Application
|
||||
import android.content.SharedPreferences
|
||||
import androidx.preference.PreferenceScreen
|
||||
import eu.kanade.tachiyomi.animeextension.en.ask4movie.extractors.FilemoonExtractor
|
||||
import eu.kanade.tachiyomi.animesource.ConfigurableAnimeSource
|
||||
import eu.kanade.tachiyomi.animesource.model.AnimeFilter
|
||||
import eu.kanade.tachiyomi.animesource.model.AnimeFilterList
|
||||
@ -12,6 +11,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.filemoonextractor.FilemoonExtractor
|
||||
import eu.kanade.tachiyomi.network.GET
|
||||
import eu.kanade.tachiyomi.util.asJsoup
|
||||
import okhttp3.OkHttpClient
|
||||
@ -172,7 +172,7 @@ class Ask4Movie : ConfigurableAnimeSource, ParsedAnimeHttpSource() {
|
||||
// ============================ Video Links =============================
|
||||
|
||||
override fun fetchVideoList(episode: SEpisode): Observable<List<Video>> {
|
||||
val videoList = FilemoonExtractor(client, headers).videosFromUrl(episode.url)
|
||||
val videoList = FilemoonExtractor(client).videosFromUrl(episode.url, headers = headers)
|
||||
require(videoList.isNotEmpty()) { "Failed to fetch videos" }
|
||||
return Observable.just(videoList)
|
||||
}
|
||||
|
@ -1,77 +0,0 @@
|
||||
package eu.kanade.tachiyomi.animeextension.en.ask4movie.extractors
|
||||
|
||||
import dev.datlag.jsunpacker.JsUnpacker
|
||||
import eu.kanade.tachiyomi.animesource.model.Track
|
||||
import eu.kanade.tachiyomi.animesource.model.Video
|
||||
import eu.kanade.tachiyomi.network.GET
|
||||
import eu.kanade.tachiyomi.util.asJsoup
|
||||
import kotlinx.serialization.Serializable
|
||||
import kotlinx.serialization.json.Json
|
||||
import okhttp3.Headers
|
||||
import okhttp3.HttpUrl.Companion.toHttpUrl
|
||||
import okhttp3.OkHttpClient
|
||||
import okhttp3.Response
|
||||
import uy.kohesive.injekt.injectLazy
|
||||
|
||||
class FilemoonExtractor(private val client: OkHttpClient, private val headers: Headers) {
|
||||
|
||||
private val json: Json by injectLazy()
|
||||
|
||||
fun videosFromUrl(url: String, prefix: String = ""): List<Video> {
|
||||
val subtitleList = mutableListOf<Track>()
|
||||
val subInfoUrl = url.toHttpUrl().queryParameter("sub.info")
|
||||
runCatching {
|
||||
if (subInfoUrl != null) {
|
||||
val subData = client.newCall(GET(subInfoUrl, headers)).execute().parseAs<List<FMoviesSubs>>()
|
||||
subtitleList.addAll(
|
||||
subData.map {
|
||||
Track(it.file, it.label)
|
||||
},
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
val jsE = client.newCall(GET(url)).execute().asJsoup().selectFirst("script:containsData(m3u8)")!!.data()
|
||||
val masterUrl = JsUnpacker.unpackAndCombine(jsE)?.substringAfter("{file:\"")
|
||||
?.substringBefore("\"}") ?: return emptyList()
|
||||
|
||||
val masterPlaylist = client.newCall(GET(masterUrl)).execute().body.string()
|
||||
val videoList = mutableListOf<Video>()
|
||||
|
||||
val subtitleRegex = Regex("""#EXT-X-MEDIA:TYPE=SUBTITLES.*?NAME="(.*?)".*?URI="(.*?)"""")
|
||||
subtitleList.addAll(
|
||||
subtitleRegex.findAll(masterPlaylist).map {
|
||||
Track(
|
||||
it.groupValues[2],
|
||||
it.groupValues[1],
|
||||
)
|
||||
},
|
||||
)
|
||||
|
||||
masterPlaylist.substringAfter("#EXT-X-STREAM-INF:").split("#EXT-X-STREAM-INF:")
|
||||
.forEach {
|
||||
val quality = it.substringAfter("RESOLUTION=").substringAfter("x").substringBefore(",") + "p "
|
||||
val videoUrl = it.substringAfter("\n").substringBefore("\n")
|
||||
|
||||
val videoHeaders = headers.newBuilder()
|
||||
.add("Accept", "*/*")
|
||||
.add("Origin", "https://${url.toHttpUrl().host}")
|
||||
.add("Referer", "https://${url.toHttpUrl().host}/")
|
||||
.build()
|
||||
|
||||
videoList.add(Video(videoUrl, prefix + quality, videoUrl, headers = videoHeaders, subtitleTracks = subtitleList))
|
||||
}
|
||||
return videoList
|
||||
}
|
||||
|
||||
@Serializable
|
||||
data class FMoviesSubs(
|
||||
val file: String,
|
||||
val label: String,
|
||||
)
|
||||
|
||||
private inline fun <reified T> Response.parseAs(): T {
|
||||
val responseBody = use { it.body.string() }
|
||||
return json.decodeFromString(responseBody)
|
||||
}
|
||||
}
|
@ -11,6 +11,7 @@ ext {
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation(project(':lib-filemoon-extractor'))
|
||||
implementation "dev.datlag.jsunpacker:jsunpacker:1.0.1"
|
||||
}
|
||||
|
||||
|
@ -5,7 +5,6 @@ import android.content.SharedPreferences
|
||||
import androidx.preference.ListPreference
|
||||
import androidx.preference.MultiSelectListPreference
|
||||
import androidx.preference.PreferenceScreen
|
||||
import eu.kanade.tachiyomi.animeextension.en.fmovies.extractors.FilemoonExtractor
|
||||
import eu.kanade.tachiyomi.animeextension.en.fmovies.extractors.StreamtapeExtractor
|
||||
import eu.kanade.tachiyomi.animesource.ConfigurableAnimeSource
|
||||
import eu.kanade.tachiyomi.animesource.model.AnimeFilterList
|
||||
@ -15,6 +14,7 @@ import eu.kanade.tachiyomi.animesource.model.SEpisode
|
||||
import eu.kanade.tachiyomi.animesource.model.Track
|
||||
import eu.kanade.tachiyomi.animesource.model.Video
|
||||
import eu.kanade.tachiyomi.animesource.online.ParsedAnimeHttpSource
|
||||
import eu.kanade.tachiyomi.lib.filemoonextractor.FilemoonExtractor
|
||||
import eu.kanade.tachiyomi.network.GET
|
||||
import eu.kanade.tachiyomi.network.asObservableSuccess
|
||||
import eu.kanade.tachiyomi.util.asJsoup
|
||||
@ -266,7 +266,7 @@ class FMovies : ConfigurableAnimeSource, ParsedAnimeHttpSource() {
|
||||
)
|
||||
}
|
||||
"Filemoon" -> {
|
||||
FilemoonExtractor(client, headers).videosFromUrl(decrypted, prefix = "Filemoon - ")
|
||||
FilemoonExtractor(client).videosFromUrl(decrypted, headers = headers)
|
||||
}
|
||||
"Streamtape" -> {
|
||||
StreamtapeExtractor(client, headers).videosFromUrl(decrypted)
|
||||
|
@ -1,77 +0,0 @@
|
||||
package eu.kanade.tachiyomi.animeextension.en.fmovies.extractors
|
||||
|
||||
import dev.datlag.jsunpacker.JsUnpacker
|
||||
import eu.kanade.tachiyomi.animesource.model.Track
|
||||
import eu.kanade.tachiyomi.animesource.model.Video
|
||||
import eu.kanade.tachiyomi.network.GET
|
||||
import eu.kanade.tachiyomi.util.asJsoup
|
||||
import kotlinx.serialization.Serializable
|
||||
import kotlinx.serialization.json.Json
|
||||
import okhttp3.Headers
|
||||
import okhttp3.HttpUrl.Companion.toHttpUrl
|
||||
import okhttp3.OkHttpClient
|
||||
import okhttp3.Response
|
||||
import uy.kohesive.injekt.injectLazy
|
||||
|
||||
class FilemoonExtractor(private val client: OkHttpClient, private val headers: Headers) {
|
||||
|
||||
private val json: Json by injectLazy()
|
||||
|
||||
fun videosFromUrl(url: String, prefix: String = ""): List<Video> {
|
||||
val subtitleList = mutableListOf<Track>()
|
||||
val subInfoUrl = url.toHttpUrl().queryParameter("sub.info")
|
||||
runCatching {
|
||||
if (subInfoUrl != null) {
|
||||
val subData = client.newCall(GET(subInfoUrl, headers)).execute().parseAs<List<FMoviesSubs>>()
|
||||
subtitleList.addAll(
|
||||
subData.map {
|
||||
Track(it.file, it.label)
|
||||
},
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
val jsE = client.newCall(GET(url)).execute().asJsoup().selectFirst("script:containsData(m3u8)")!!.data()
|
||||
val masterUrl = JsUnpacker.unpackAndCombine(jsE)?.substringAfter("{file:\"")
|
||||
?.substringBefore("\"}") ?: return emptyList()
|
||||
|
||||
val masterPlaylist = client.newCall(GET(masterUrl)).execute().body.string()
|
||||
val videoList = mutableListOf<Video>()
|
||||
|
||||
val subtitleRegex = Regex("""#EXT-X-MEDIA:TYPE=SUBTITLES.*?NAME="(.*?)".*?URI="(.*?)"""")
|
||||
subtitleList.addAll(
|
||||
subtitleRegex.findAll(masterPlaylist).map {
|
||||
Track(
|
||||
it.groupValues[2],
|
||||
it.groupValues[1],
|
||||
)
|
||||
},
|
||||
)
|
||||
|
||||
masterPlaylist.substringAfter("#EXT-X-STREAM-INF:").split("#EXT-X-STREAM-INF:")
|
||||
.forEach {
|
||||
val quality = it.substringAfter("RESOLUTION=").substringAfter("x").substringBefore(",") + "p "
|
||||
val videoUrl = it.substringAfter("\n").substringBefore("\n")
|
||||
|
||||
val videoHeaders = headers.newBuilder()
|
||||
.add("Accept", "*/*")
|
||||
.add("Origin", "https://${url.toHttpUrl().host}")
|
||||
.add("Referer", "https://${url.toHttpUrl().host}/")
|
||||
.build()
|
||||
|
||||
videoList.add(Video(videoUrl, prefix + quality, videoUrl, headers = videoHeaders, subtitleTracks = subtitleList))
|
||||
}
|
||||
return videoList
|
||||
}
|
||||
|
||||
@Serializable
|
||||
data class FMoviesSubs(
|
||||
val file: String,
|
||||
val label: String,
|
||||
)
|
||||
|
||||
private inline fun <reified T> Response.parseAs(): T {
|
||||
val responseBody = use { it.body.string() }
|
||||
return json.decodeFromString(responseBody)
|
||||
}
|
||||
}
|
@ -11,6 +11,7 @@ ext {
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation(project(':lib-filemoon-extractor'))
|
||||
implementation(project(':lib-mp4upload-extractor'))
|
||||
implementation (project(':lib-streamtape-extractor'))
|
||||
implementation "dev.datlag.jsunpacker:jsunpacker:1.0.1"
|
||||
|
@ -13,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.filemoonextractor.FilemoonExtractor
|
||||
import eu.kanade.tachiyomi.lib.mp4uploadextractor.Mp4uploadExtractor
|
||||
import eu.kanade.tachiyomi.lib.streamtapeextractor.StreamTapeExtractor
|
||||
import eu.kanade.tachiyomi.network.GET
|
||||
@ -301,9 +302,9 @@ class NineAnime : ConfigurableAnimeSource, ParsedAnimeHttpSource() {
|
||||
)
|
||||
}
|
||||
"filemoon" -> FilemoonExtractor(client)
|
||||
.videoFromUrl(embedLink, "Filemoon - ${server.first}").let {
|
||||
videoList.addAll(it)
|
||||
}
|
||||
.videosFromUrl(embedLink, "Filemoon - ${server.first} ")
|
||||
.also(videoList::addAll)
|
||||
|
||||
"streamtape" -> StreamTapeExtractor(client)
|
||||
.videoFromUrl(embedLink, "StreamTape - ${server.first}")?.let {
|
||||
videoList.add(it)
|
||||
|
@ -1,79 +0,0 @@
|
||||
package eu.kanade.tachiyomi.animeextension.en.nineanime
|
||||
|
||||
import dev.datlag.jsunpacker.JsUnpacker
|
||||
import eu.kanade.tachiyomi.animesource.model.Track
|
||||
import eu.kanade.tachiyomi.animesource.model.Video
|
||||
import eu.kanade.tachiyomi.network.GET
|
||||
import eu.kanade.tachiyomi.util.asJsoup
|
||||
import kotlinx.serialization.Serializable
|
||||
import kotlinx.serialization.decodeFromString
|
||||
import kotlinx.serialization.json.Json
|
||||
import okhttp3.OkHttpClient
|
||||
|
||||
@Serializable
|
||||
data class CaptionElement(
|
||||
val file: String,
|
||||
val label: String,
|
||||
val kind: String,
|
||||
)
|
||||
|
||||
class FilemoonExtractor(private val client: OkHttpClient) {
|
||||
fun videoFromUrl(url: String, prefix: String = "Filemoon"): List<Video> {
|
||||
try {
|
||||
val unpacked = client.newCall(GET(url)).execute().asJsoup().select("script:containsData(eval)").mapNotNull { element ->
|
||||
element?.data()
|
||||
?.let { JsUnpacker.unpackAndCombine(it) }
|
||||
}.first { it.contains("{file:") }
|
||||
|
||||
val subtitleTracks = mutableListOf<Track>()
|
||||
if (unpacked.contains("fetch('")) {
|
||||
val subtitleString = unpacked.substringAfter("fetch('").substringBefore("').")
|
||||
|
||||
try {
|
||||
if (subtitleString.isNotEmpty()) {
|
||||
val subResponse = client.newCall(
|
||||
GET(subtitleString),
|
||||
).execute()
|
||||
|
||||
val subtitles = Json.decodeFromString<List<CaptionElement>>(subResponse.body.string())
|
||||
for (sub in subtitles) {
|
||||
subtitleTracks.add(Track(sub.file, sub.label))
|
||||
}
|
||||
}
|
||||
} catch (_: Error) {}
|
||||
}
|
||||
|
||||
val masterUrl = unpacked.substringAfter("{file:\"").substringBefore("\"}")
|
||||
|
||||
val masterPlaylist = client.newCall(GET(masterUrl)).execute().body.string()
|
||||
|
||||
val videoList = mutableListOf<Video>()
|
||||
|
||||
val subtitleRegex = Regex("""#EXT-X-MEDIA:TYPE=SUBTITLES.*?NAME="(.*?)".*?URI="(.*?)"""")
|
||||
try {
|
||||
subtitleTracks.addAll(
|
||||
subtitleRegex.findAll(masterPlaylist).map {
|
||||
Track(
|
||||
it.groupValues[2],
|
||||
it.groupValues[1],
|
||||
)
|
||||
},
|
||||
)
|
||||
} catch (_: Error) {}
|
||||
|
||||
masterPlaylist.substringAfter("#EXT-X-STREAM-INF:").split("#EXT-X-STREAM-INF:")
|
||||
.forEach {
|
||||
val quality = "$prefix " + it.substringAfter("RESOLUTION=").substringAfter("x").substringBefore(",") + "p "
|
||||
val videoUrl = it.substringAfter("\n").substringBefore("\n")
|
||||
try {
|
||||
videoList.add(Video(videoUrl, quality, videoUrl, subtitleTracks = subtitleTracks))
|
||||
} catch (e: Error) {
|
||||
videoList.add(Video(videoUrl, quality, videoUrl))
|
||||
}
|
||||
}
|
||||
return videoList
|
||||
} catch (e: Exception) {
|
||||
return emptyList()
|
||||
}
|
||||
}
|
||||
}
|
@ -10,6 +10,7 @@ ext {
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation(project(':lib-filemoon-extractor'))
|
||||
implementation(project(':lib-streamtape-extractor'))
|
||||
implementation(project(':lib-okru-extractor'))
|
||||
implementation(project(':lib-streamsb-extractor'))
|
||||
|
@ -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.es.animelatinohd.extractors.FilemoonExtractor
|
||||
import eu.kanade.tachiyomi.animeextension.es.animelatinohd.extractors.SolidFilesExtractor
|
||||
import eu.kanade.tachiyomi.animesource.ConfigurableAnimeSource
|
||||
import eu.kanade.tachiyomi.animesource.model.AnimeFilter
|
||||
@ -15,6 +14,7 @@ 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.doodextractor.DoodExtractor
|
||||
import eu.kanade.tachiyomi.lib.filemoonextractor.FilemoonExtractor
|
||||
import eu.kanade.tachiyomi.lib.okruextractor.OkruExtractor
|
||||
import eu.kanade.tachiyomi.lib.streamsbextractor.StreamSBExtractor
|
||||
import eu.kanade.tachiyomi.lib.streamtapeextractor.StreamTapeExtractor
|
||||
@ -192,9 +192,8 @@ class AnimeLatinoHD : ConfigurableAnimeSource, ParsedAnimeHttpSource() {
|
||||
videoList.addAll(videos)
|
||||
}
|
||||
if (embedUrl.contains("filemoon")) {
|
||||
FilemoonExtractor(client).videoFromUrl(url, language)?.let {
|
||||
videoList.addAll(it)
|
||||
}
|
||||
FilemoonExtractor(client).videosFromUrl(url, language)
|
||||
.also(videoList::addAll)
|
||||
}
|
||||
if (embedUrl.contains("streamtape")) {
|
||||
val video = StreamTapeExtractor(client).videoFromUrl(url, language + "Streamtape")
|
||||
|
@ -1,28 +0,0 @@
|
||||
package eu.kanade.tachiyomi.animeextension.es.animelatinohd.extractors
|
||||
|
||||
import eu.kanade.tachiyomi.animesource.model.Video
|
||||
import eu.kanade.tachiyomi.network.GET
|
||||
import eu.kanade.tachiyomi.util.asJsoup
|
||||
import okhttp3.OkHttpClient
|
||||
|
||||
class FilemoonExtractor(private val client: OkHttpClient) {
|
||||
|
||||
fun videoFromUrl(url: String, prefix: String = ""): MutableList<Video>? {
|
||||
try {
|
||||
val jsE = client.newCall(GET(url)).execute().asJsoup().selectFirst("script:containsData(eval)")!!.data()
|
||||
val masterUrl = JsUnpacker(jsE).unpack().toString()
|
||||
.substringAfter("{file:\"").substringBefore("\"}")
|
||||
val masterPlaylist = client.newCall(GET(masterUrl)).execute().body.string()
|
||||
val videoList = mutableListOf<Video>()
|
||||
masterPlaylist.substringAfter("#EXT-X-STREAM-INF:").split("#EXT-X-STREAM-INF:")
|
||||
.forEach {
|
||||
val quality = "$prefix Filemoon:" + it.substringAfter("RESOLUTION=").substringAfter("x").substringBefore(",") + "p "
|
||||
val videoUrl = it.substringAfter("\n").substringBefore("\n")
|
||||
videoList.add(Video(videoUrl, quality.trim(), videoUrl))
|
||||
}
|
||||
return videoList
|
||||
} catch (e: Exception) {
|
||||
return null
|
||||
}
|
||||
}
|
||||
}
|
@ -10,6 +10,7 @@ ext {
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation(project(':lib-filemoon-extractor'))
|
||||
implementation(project(':lib-streamlare-extractor'))
|
||||
implementation(project(':lib-yourupload-extractor'))
|
||||
implementation(project(':lib-streamtape-extractor'))
|
||||
|
@ -2,13 +2,13 @@ package eu.kanade.tachiyomi.animeextension.es.pelisplushd
|
||||
|
||||
import androidx.preference.ListPreference
|
||||
import androidx.preference.PreferenceScreen
|
||||
import eu.kanade.tachiyomi.animeextension.es.pelisplushd.extractors.FilemoonExtractor
|
||||
import eu.kanade.tachiyomi.animesource.model.AnimeFilter
|
||||
import eu.kanade.tachiyomi.animesource.model.AnimeFilterList
|
||||
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.lib.doodextractor.DoodExtractor
|
||||
import eu.kanade.tachiyomi.lib.filemoonextractor.FilemoonExtractor
|
||||
import eu.kanade.tachiyomi.lib.okruextractor.OkruExtractor
|
||||
import eu.kanade.tachiyomi.lib.streamlareextractor.StreamlareExtractor
|
||||
import eu.kanade.tachiyomi.lib.streamsbextractor.StreamSBExtractor
|
||||
@ -184,9 +184,8 @@ class Pelisplusph(override val name: String, override val baseUrl: String) : Pel
|
||||
VoeExtractor(client).videoFromUrl(url, "$prefix VoeCDN")?.let { videoList.add(it) }
|
||||
}
|
||||
if (embedUrl.contains("filemoon") || embedUrl.contains("moonplayer")) {
|
||||
FilemoonExtractor(client).videoFromUrl(url, prefix)?.let {
|
||||
videoList.addAll(it)
|
||||
}
|
||||
FilemoonExtractor(client).videosFromUrl(url, prefix)
|
||||
.also(videoList::addAll)
|
||||
}
|
||||
if (embedUrl.contains("streamlare")) {
|
||||
videoList.addAll(StreamlareExtractor(client).videosFromUrl(url))
|
||||
|
@ -2,13 +2,13 @@ package eu.kanade.tachiyomi.animeextension.es.pelisplushd
|
||||
|
||||
import androidx.preference.ListPreference
|
||||
import androidx.preference.PreferenceScreen
|
||||
import eu.kanade.tachiyomi.animeextension.es.pelisplushd.extractors.FilemoonExtractor
|
||||
import eu.kanade.tachiyomi.animesource.model.AnimeFilter
|
||||
import eu.kanade.tachiyomi.animesource.model.AnimeFilterList
|
||||
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.lib.doodextractor.DoodExtractor
|
||||
import eu.kanade.tachiyomi.lib.filemoonextractor.FilemoonExtractor
|
||||
import eu.kanade.tachiyomi.lib.okruextractor.OkruExtractor
|
||||
import eu.kanade.tachiyomi.lib.streamlareextractor.StreamlareExtractor
|
||||
import eu.kanade.tachiyomi.lib.streamsbextractor.StreamSBExtractor
|
||||
@ -179,9 +179,8 @@ class Pelisplusto(override val name: String, override val baseUrl: String) : Pel
|
||||
VoeExtractor(client).videoFromUrl(url)?.let { videoList.add(it) }
|
||||
}
|
||||
if (embedUrl.contains("filemoon") || embedUrl.contains("moonplayer")) {
|
||||
FilemoonExtractor(client).videoFromUrl(url, prefix)?.let {
|
||||
videoList.addAll(it)
|
||||
}
|
||||
FilemoonExtractor(client).videosFromUrl(url, prefix)
|
||||
.also(videoList::addAll)
|
||||
}
|
||||
if (embedUrl.contains("streamlare")) {
|
||||
videoList.addAll(StreamlareExtractor(client).videosFromUrl(url))
|
||||
|
@ -1,28 +0,0 @@
|
||||
package eu.kanade.tachiyomi.animeextension.es.pelisplushd.extractors
|
||||
|
||||
import eu.kanade.tachiyomi.animesource.model.Video
|
||||
import eu.kanade.tachiyomi.network.GET
|
||||
import eu.kanade.tachiyomi.util.asJsoup
|
||||
import okhttp3.OkHttpClient
|
||||
|
||||
class FilemoonExtractor(private val client: OkHttpClient) {
|
||||
|
||||
fun videoFromUrl(url: String, prefix: String = ""): MutableList<Video>? {
|
||||
try {
|
||||
val jsE = client.newCall(GET(url)).execute().asJsoup().selectFirst("script:containsData(eval)")!!.data()
|
||||
val masterUrl = JsUnpacker(jsE).unpack().toString()
|
||||
.substringAfter("{file:\"").substringBefore("\"}")
|
||||
val masterPlaylist = client.newCall(GET(masterUrl)).execute().body.string()
|
||||
val videoList = mutableListOf<Video>()
|
||||
masterPlaylist.substringAfter("#EXT-X-STREAM-INF:").split("#EXT-X-STREAM-INF:")
|
||||
.forEach {
|
||||
val quality = "$prefix Filemoon:" + it.substringAfter("RESOLUTION=").substringAfter("x").substringBefore(",") + "p "
|
||||
val videoUrl = it.substringAfter("\n").substringBefore("\n")
|
||||
videoList.add(Video(videoUrl, quality.trim(), videoUrl))
|
||||
}
|
||||
return videoList
|
||||
} catch (e: Exception) {
|
||||
return null
|
||||
}
|
||||
}
|
||||
}
|
@ -11,6 +11,7 @@ ext {
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation(project(':lib-filemoon-extractor'))
|
||||
implementation(project(':lib-streamtape-extractor'))
|
||||
implementation(project(':lib-streamsb-extractor'))
|
||||
implementation(project(':lib-dood-extractor'))
|
||||
|
@ -7,7 +7,6 @@ import androidx.preference.EditTextPreference
|
||||
import androidx.preference.ListPreference
|
||||
import androidx.preference.PreferenceScreen
|
||||
import eu.kanade.tachiyomi.AppInfo
|
||||
import eu.kanade.tachiyomi.animeextension.it.animeworld.extractors.FilemoonExtractor
|
||||
import eu.kanade.tachiyomi.animeextension.it.animeworld.extractors.StreamHideExtractor
|
||||
import eu.kanade.tachiyomi.animesource.ConfigurableAnimeSource
|
||||
import eu.kanade.tachiyomi.animesource.model.AnimeFilter
|
||||
@ -17,6 +16,7 @@ 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.doodextractor.DoodExtractor
|
||||
import eu.kanade.tachiyomi.lib.filemoonextractor.FilemoonExtractor
|
||||
import eu.kanade.tachiyomi.lib.streamsbextractor.StreamSBExtractor
|
||||
import eu.kanade.tachiyomi.lib.streamtapeextractor.StreamTapeExtractor
|
||||
import eu.kanade.tachiyomi.network.GET
|
||||
@ -169,15 +169,15 @@ class ANIMEWORLD : ConfigurableAnimeSource, ParsedAnimeHttpSource() {
|
||||
listOf(Video(url, "AnimeWorld Server", url))
|
||||
}
|
||||
url.contains("https://doo") -> {
|
||||
val video = DoodExtractor(client).videoFromUrl(url, redirect = true)
|
||||
video?.let { listOf(it) }
|
||||
DoodExtractor(client).videoFromUrl(url, redirect = true)
|
||||
?.let(::listOf)
|
||||
}
|
||||
url.contains("streamtape") -> {
|
||||
val video = StreamTapeExtractor(client).videoFromUrl(url.replace("/v/", "/e/"))
|
||||
video?.let { listOf(it) }
|
||||
StreamTapeExtractor(client).videoFromUrl(url.replace("/v/", "/e/"))
|
||||
?.let(::listOf)
|
||||
}
|
||||
url.contains("filemoon") -> {
|
||||
FilemoonExtractor(client, headers).videosFromUrl(url, prefix = "${server.first} - ")
|
||||
FilemoonExtractor(client).videosFromUrl(url, prefix = "${server.first} - ", headers = headers)
|
||||
}
|
||||
server.first.contains("streamhide", true) -> {
|
||||
StreamHideExtractor(client).videosFromUrl(url, headers)
|
||||
|
@ -1,34 +0,0 @@
|
||||
package eu.kanade.tachiyomi.animeextension.it.animeworld.extractors
|
||||
|
||||
import dev.datlag.jsunpacker.JsUnpacker
|
||||
import eu.kanade.tachiyomi.animesource.model.Video
|
||||
import eu.kanade.tachiyomi.network.GET
|
||||
import eu.kanade.tachiyomi.util.asJsoup
|
||||
import okhttp3.Headers
|
||||
import okhttp3.HttpUrl.Companion.toHttpUrl
|
||||
import okhttp3.OkHttpClient
|
||||
|
||||
class FilemoonExtractor(private val client: OkHttpClient, private val headers: Headers) {
|
||||
fun videosFromUrl(url: String, prefix: String = ""): List<Video> {
|
||||
val jsE = client.newCall(GET(url)).execute().asJsoup().selectFirst("script:containsData(eval)")!!.data()
|
||||
val masterUrl = JsUnpacker.unpackAndCombine(jsE)?.substringAfter("{file:\"")
|
||||
?.substringBefore("\"}") ?: return emptyList()
|
||||
val masterPlaylist = client.newCall(GET(masterUrl)).execute().body.string()
|
||||
val videoList = mutableListOf<Video>()
|
||||
masterPlaylist.substringAfter("#EXT-X-STREAM-INF:").split("#EXT-X-STREAM-INF:")
|
||||
.forEach {
|
||||
val quality = "Filemoon:" + it.substringAfter("RESOLUTION=").substringAfter("x").substringBefore(",") + "p "
|
||||
val videoUrl = it.substringAfter("\n").substringBefore("\n")
|
||||
|
||||
val videoHeaders = headers.newBuilder()
|
||||
.add("Accept", "*/*")
|
||||
.add("Host", videoUrl.toHttpUrl().host)
|
||||
.add("Origin", "https://${url.toHttpUrl().host}")
|
||||
.add("Referer", "https://${url.toHttpUrl().host}/")
|
||||
.build()
|
||||
|
||||
videoList.add(Video(videoUrl, prefix + quality, videoUrl, headers = videoHeaders))
|
||||
}
|
||||
return videoList
|
||||
}
|
||||
}
|
@ -12,6 +12,7 @@ ext {
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation(project(':lib-filemoon-extractor'))
|
||||
implementation("dev.datlag.jsunpacker:jsunpacker:1.0.1")
|
||||
}
|
||||
|
||||
|
@ -7,13 +7,13 @@ import eu.kanade.tachiyomi.animeextension.sr.animesrbija.dto.LatestUpdatesDto
|
||||
import eu.kanade.tachiyomi.animeextension.sr.animesrbija.dto.PagePropsDto
|
||||
import eu.kanade.tachiyomi.animeextension.sr.animesrbija.dto.SearchAnimeDto
|
||||
import eu.kanade.tachiyomi.animeextension.sr.animesrbija.dto.SearchPageDto
|
||||
import eu.kanade.tachiyomi.animeextension.sr.animesrbija.extractors.FilemoonExtractor
|
||||
import eu.kanade.tachiyomi.animesource.model.AnimeFilterList
|
||||
import eu.kanade.tachiyomi.animesource.model.AnimesPage
|
||||
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.AnimeHttpSource
|
||||
import eu.kanade.tachiyomi.lib.filemoonextractor.FilemoonExtractor
|
||||
import eu.kanade.tachiyomi.network.GET
|
||||
import eu.kanade.tachiyomi.network.asObservableSuccess
|
||||
import eu.kanade.tachiyomi.util.asJsoup
|
||||
|
@ -1,28 +0,0 @@
|
||||
package eu.kanade.tachiyomi.animeextension.sr.animesrbija.extractors
|
||||
|
||||
import dev.datlag.jsunpacker.JsUnpacker
|
||||
import eu.kanade.tachiyomi.animesource.model.Video
|
||||
import eu.kanade.tachiyomi.network.GET
|
||||
import eu.kanade.tachiyomi.util.asJsoup
|
||||
import okhttp3.OkHttpClient
|
||||
|
||||
class FilemoonExtractor(private val client: OkHttpClient) {
|
||||
fun videosFromUrl(url: String): List<Video> {
|
||||
return runCatching {
|
||||
val doc = client.newCall(GET(url)).execute().asJsoup()
|
||||
val jsEval = doc.selectFirst("script:containsData(eval)")!!.data()
|
||||
val masterUrl = JsUnpacker.unpackAndCombine(jsEval)
|
||||
?.substringAfter("{file:\"")
|
||||
?.substringBefore("\"}")
|
||||
?: return emptyList()
|
||||
|
||||
val masterPlaylist = client.newCall(GET(masterUrl)).execute().body.string()
|
||||
val separator = "#EXT-X-STREAM-INF:"
|
||||
masterPlaylist.substringAfter(separator).split(separator).map {
|
||||
val quality = "Filemoon:" + it.substringAfter("RESOLUTION=").substringAfter("x").substringBefore(",") + "p "
|
||||
val videoUrl = it.substringAfter("\n").substringBefore("\n")
|
||||
Video(videoUrl, quality, videoUrl)
|
||||
}
|
||||
}.getOrElse { emptyList() }
|
||||
}
|
||||
}
|
@ -5,6 +5,7 @@ plugins {
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation(project(':lib-filemoon-extractor'))
|
||||
implementation(project(':lib-mp4upload-extractor'))
|
||||
implementation(project(":lib-cryptoaes"))
|
||||
implementation(project(":lib-synchrony"))
|
||||
|
@ -8,7 +8,6 @@ import androidx.preference.MultiSelectListPreference
|
||||
import androidx.preference.PreferenceScreen
|
||||
import eu.kanade.tachiyomi.animeextension.tr.turkanime.extractors.AlucardExtractor
|
||||
import eu.kanade.tachiyomi.animeextension.tr.turkanime.extractors.EmbedgramExtractor
|
||||
import eu.kanade.tachiyomi.animeextension.tr.turkanime.extractors.FilemoonExtractor
|
||||
import eu.kanade.tachiyomi.animeextension.tr.turkanime.extractors.GoogleDriveExtractor
|
||||
import eu.kanade.tachiyomi.animeextension.tr.turkanime.extractors.MVidooExtractor
|
||||
import eu.kanade.tachiyomi.animeextension.tr.turkanime.extractors.MailRuExtractor
|
||||
@ -29,6 +28,7 @@ import eu.kanade.tachiyomi.animesource.model.Video
|
||||
import eu.kanade.tachiyomi.animesource.online.ParsedAnimeHttpSource
|
||||
import eu.kanade.tachiyomi.lib.cryptoaes.CryptoAES
|
||||
import eu.kanade.tachiyomi.lib.doodextractor.DoodExtractor
|
||||
import eu.kanade.tachiyomi.lib.filemoonextractor.FilemoonExtractor
|
||||
import eu.kanade.tachiyomi.lib.mp4uploadextractor.Mp4uploadExtractor
|
||||
import eu.kanade.tachiyomi.lib.okruextractor.OkruExtractor
|
||||
import eu.kanade.tachiyomi.lib.sendvidextractor.SendvidExtractor
|
||||
@ -268,7 +268,7 @@ class TurkAnime : ConfigurableAnimeSource, ParsedAnimeHttpSource() {
|
||||
videoList.addAll(EmbedgramExtractor(client, headers).videosFromUrl(hosterLink, prefix = "$subber: "))
|
||||
}
|
||||
"FILEMOON" -> {
|
||||
videoList.addAll(FilemoonExtractor(client, headers).videosFromUrl(hosterLink, prefix = "$subber: "))
|
||||
videoList.addAll(FilemoonExtractor(client).videosFromUrl(hosterLink, prefix = "$subber: ", headers = headers))
|
||||
}
|
||||
"GDRIVE" -> {
|
||||
Regex("""[\w-]{28,}""").find(hosterLink)?.groupValues?.get(0)?.let {
|
||||
|
@ -1,34 +0,0 @@
|
||||
package eu.kanade.tachiyomi.animeextension.tr.turkanime.extractors
|
||||
|
||||
import dev.datlag.jsunpacker.JsUnpacker
|
||||
import eu.kanade.tachiyomi.animesource.model.Video
|
||||
import eu.kanade.tachiyomi.network.GET
|
||||
import eu.kanade.tachiyomi.util.asJsoup
|
||||
import okhttp3.Headers
|
||||
import okhttp3.HttpUrl.Companion.toHttpUrl
|
||||
import okhttp3.OkHttpClient
|
||||
|
||||
class FilemoonExtractor(private val client: OkHttpClient, private val headers: Headers) {
|
||||
fun videosFromUrl(url: String, prefix: String = ""): List<Video> {
|
||||
val jsE = client.newCall(GET(url)).execute().asJsoup().selectFirst("script:containsData(eval)")!!.data()
|
||||
val masterUrl = JsUnpacker.unpackAndCombine(jsE)?.substringAfter("{file:\"")
|
||||
?.substringBefore("\"}") ?: return emptyList()
|
||||
val masterPlaylist = client.newCall(GET(masterUrl)).execute().body.string()
|
||||
val videoList = mutableListOf<Video>()
|
||||
masterPlaylist.substringAfter("#EXT-X-STREAM-INF:").split("#EXT-X-STREAM-INF:")
|
||||
.forEach {
|
||||
val quality = "Filemoon:" + it.substringAfter("RESOLUTION=").substringAfter("x").substringBefore(",") + "p "
|
||||
val videoUrl = it.substringAfter("\n").substringBefore("\n")
|
||||
|
||||
val videoHeaders = headers.newBuilder()
|
||||
.add("Accept", "*/*")
|
||||
.add("Host", videoUrl.toHttpUrl().host)
|
||||
.add("Origin", "https://${url.toHttpUrl().host}")
|
||||
.add("Referer", "https://${url.toHttpUrl().host}/")
|
||||
.build()
|
||||
|
||||
videoList.add(Video(videoUrl, prefix + quality, videoUrl, headers = videoHeaders))
|
||||
}
|
||||
return videoList
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user