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
|
applicationIdSuffix pkgNameSuffix
|
||||||
versionCode extVersionCode
|
versionCode extVersionCode
|
||||||
versionName project.ext.properties.getOrDefault("libVersion", "13") + ".$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 ->
|
def readmes = project.projectDir.listFiles({ File file ->
|
||||||
file.name.equals("README.md") ||
|
file.name.equals("README.md") ||
|
||||||
file.name.equals("CHANGELOG.md")
|
file.name.equals("CHANGELOG.md")
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
dependencies {
|
dependencies {
|
||||||
|
implementation(project(':lib-filemoon-extractor'))
|
||||||
implementation(project(':lib-streamsb-extractor'))
|
implementation(project(':lib-streamsb-extractor'))
|
||||||
implementation "dev.datlag.jsunpacker:jsunpacker:1.0.1"
|
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.ListPreference
|
||||||
import androidx.preference.PreferenceScreen
|
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.StreamWishExtractor
|
||||||
import eu.kanade.tachiyomi.animeextension.en.animenosub.extractors.VidMolyExtractor
|
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.VtubeExtractor
|
||||||
import eu.kanade.tachiyomi.animeextension.en.animenosub.extractors.WolfstreamExtractor
|
import eu.kanade.tachiyomi.animeextension.en.animenosub.extractors.WolfstreamExtractor
|
||||||
import eu.kanade.tachiyomi.animesource.model.Video
|
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.lib.streamsbextractor.StreamSBExtractor
|
||||||
import eu.kanade.tachiyomi.multisrc.animestream.AnimeStream
|
import eu.kanade.tachiyomi.multisrc.animestream.AnimeStream
|
||||||
import org.jsoup.nodes.Element
|
import org.jsoup.nodes.Element
|
||||||
@ -55,7 +55,7 @@ class Animenosub : AnimeStream(
|
|||||||
WolfstreamExtractor(client).videosFromUrl(url, prefix)
|
WolfstreamExtractor(client).videosFromUrl(url, prefix)
|
||||||
}
|
}
|
||||||
url.contains("filemoon") -> {
|
url.contains("filemoon") -> {
|
||||||
FilemoonExtractor(client, headers).videosFromUrl(url, prefix)
|
FilemoonExtractor(client).videosFromUrl(url, prefix, headers)
|
||||||
}
|
}
|
||||||
else -> emptyList()
|
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 {
|
dependencies {
|
||||||
|
implementation(project(':lib-filemoon-extractor'))
|
||||||
implementation(project(':lib-dood-extractor'))
|
implementation(project(':lib-dood-extractor'))
|
||||||
implementation(project(':lib-streamlare-extractor'))
|
implementation(project(':lib-streamlare-extractor'))
|
||||||
implementation(project(':lib-streamsb-extractor'))
|
implementation(project(':lib-streamsb-extractor'))
|
||||||
|
@ -3,10 +3,10 @@ package eu.kanade.tachiyomi.animeextension.de.cinemathek
|
|||||||
import androidx.preference.ListPreference
|
import androidx.preference.ListPreference
|
||||||
import androidx.preference.MultiSelectListPreference
|
import androidx.preference.MultiSelectListPreference
|
||||||
import androidx.preference.PreferenceScreen
|
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.animeextension.de.cinemathek.extractors.StreamHideExtractor
|
||||||
import eu.kanade.tachiyomi.animesource.model.Video
|
import eu.kanade.tachiyomi.animesource.model.Video
|
||||||
import eu.kanade.tachiyomi.lib.doodextractor.DoodExtractor
|
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.streamlareextractor.StreamlareExtractor
|
||||||
import eu.kanade.tachiyomi.lib.streamsbextractor.StreamSBExtractor
|
import eu.kanade.tachiyomi.lib.streamsbextractor.StreamSBExtractor
|
||||||
import eu.kanade.tachiyomi.multisrc.dooplay.DooPlay
|
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 {
|
dependencies {
|
||||||
|
implementation(project(':lib-filemoon-extractor'))
|
||||||
implementation(project(':lib-voe-extractor'))
|
implementation(project(':lib-voe-extractor'))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -6,7 +6,6 @@ import androidx.preference.ListPreference
|
|||||||
import androidx.preference.MultiSelectListPreference
|
import androidx.preference.MultiSelectListPreference
|
||||||
import androidx.preference.PreferenceScreen
|
import androidx.preference.PreferenceScreen
|
||||||
import eu.kanade.tachiyomi.animeextension.de.filmpalast.extractors.EvoloadExtractor
|
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.StreamHideVidExtractor
|
||||||
import eu.kanade.tachiyomi.animeextension.de.filmpalast.extractors.UpstreamExtractor
|
import eu.kanade.tachiyomi.animeextension.de.filmpalast.extractors.UpstreamExtractor
|
||||||
import eu.kanade.tachiyomi.animesource.ConfigurableAnimeSource
|
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.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.voeextractor.VoeExtractor
|
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
|
||||||
@ -136,7 +136,7 @@ class FilmPalast : ConfigurableAnimeSource, ParsedAnimeHttpSource() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
url.contains("filemoon.sx") && hosterSelection.contains("moon") ->
|
url.contains("filemoon.sx") && hosterSelection.contains("moon") ->
|
||||||
FilemoonExtractor(client).videoFromUrl(url)
|
FilemoonExtractor(client).videosFromUrl(url)
|
||||||
url.contains("hide.com") && hosterSelection.contains("hide") ->
|
url.contains("hide.com") && hosterSelection.contains("hide") ->
|
||||||
StreamHideVidExtractor(client).videosFromUrl(url, "StreamHide")
|
StreamHideVidExtractor(client).videosFromUrl(url, "StreamHide")
|
||||||
url.contains("streamvid.net") && hosterSelection.contains("vid") ->
|
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 {
|
dependencies {
|
||||||
|
implementation(project(':lib-filemoon-extractor'))
|
||||||
implementation(project(':lib-streamtape-extractor'))
|
implementation(project(':lib-streamtape-extractor'))
|
||||||
implementation(project(':lib-voe-extractor'))
|
implementation(project(':lib-voe-extractor'))
|
||||||
}
|
}
|
||||||
|
@ -6,7 +6,6 @@ import android.util.Log
|
|||||||
import androidx.preference.ListPreference
|
import androidx.preference.ListPreference
|
||||||
import androidx.preference.MultiSelectListPreference
|
import androidx.preference.MultiSelectListPreference
|
||||||
import androidx.preference.PreferenceScreen
|
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.animeextension.de.movie4k.extractors.VidozaExtractor
|
||||||
import eu.kanade.tachiyomi.animesource.ConfigurableAnimeSource
|
import eu.kanade.tachiyomi.animesource.ConfigurableAnimeSource
|
||||||
import eu.kanade.tachiyomi.animesource.model.AnimeFilter
|
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.SEpisode
|
||||||
import eu.kanade.tachiyomi.animesource.model.Video
|
import eu.kanade.tachiyomi.animesource.model.Video
|
||||||
import eu.kanade.tachiyomi.animesource.online.AnimeHttpSource
|
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.streamtapeextractor.StreamTapeExtractor
|
||||||
import eu.kanade.tachiyomi.lib.voeextractor.VoeExtractor
|
import eu.kanade.tachiyomi.lib.voeextractor.VoeExtractor
|
||||||
import eu.kanade.tachiyomi.network.POST
|
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 -> {
|
item.jsonObject["url"]!!.jsonPrimitive.content.contains("https://filemoon.sx") && hosterSelection?.contains("fmoon") == true -> {
|
||||||
val videoUrl = item.jsonObject["url"]!!.jsonPrimitive.content
|
val videoUrl = item.jsonObject["url"]!!.jsonPrimitive.content
|
||||||
val videos = FilemoonExtractor(client).videoFromUrl(videoUrl)
|
videoList.addAll(FilemoonExtractor(client).videosFromUrl(videoUrl))
|
||||||
if (videos != null) {
|
|
||||||
videoList.addAll(videos)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
response.request.url.toString().contains("kool-cluster/mediahubmx-resolve.json") -> {
|
response.request.url.toString().contains("kool-cluster/mediahubmx-resolve.json") -> {
|
||||||
val videoUrl = item.jsonObject["url"]!!.jsonPrimitive.content
|
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 {
|
dependencies {
|
||||||
|
implementation(project(':lib-filemoon-extractor'))
|
||||||
implementation "dev.datlag.jsunpacker:jsunpacker:1.0.1"
|
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.app.Application
|
||||||
import android.content.SharedPreferences
|
import android.content.SharedPreferences
|
||||||
import androidx.preference.PreferenceScreen
|
import androidx.preference.PreferenceScreen
|
||||||
import eu.kanade.tachiyomi.animeextension.en.ask4movie.extractors.FilemoonExtractor
|
|
||||||
import eu.kanade.tachiyomi.animesource.ConfigurableAnimeSource
|
import eu.kanade.tachiyomi.animesource.ConfigurableAnimeSource
|
||||||
import eu.kanade.tachiyomi.animesource.model.AnimeFilter
|
import eu.kanade.tachiyomi.animesource.model.AnimeFilter
|
||||||
import eu.kanade.tachiyomi.animesource.model.AnimeFilterList
|
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.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.network.GET
|
import eu.kanade.tachiyomi.network.GET
|
||||||
import eu.kanade.tachiyomi.util.asJsoup
|
import eu.kanade.tachiyomi.util.asJsoup
|
||||||
import okhttp3.OkHttpClient
|
import okhttp3.OkHttpClient
|
||||||
@ -172,7 +172,7 @@ class Ask4Movie : ConfigurableAnimeSource, ParsedAnimeHttpSource() {
|
|||||||
// ============================ Video Links =============================
|
// ============================ Video Links =============================
|
||||||
|
|
||||||
override fun fetchVideoList(episode: SEpisode): Observable<List<Video>> {
|
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" }
|
require(videoList.isNotEmpty()) { "Failed to fetch videos" }
|
||||||
return Observable.just(videoList)
|
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 {
|
dependencies {
|
||||||
|
implementation(project(':lib-filemoon-extractor'))
|
||||||
implementation "dev.datlag.jsunpacker:jsunpacker:1.0.1"
|
implementation "dev.datlag.jsunpacker:jsunpacker:1.0.1"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5,7 +5,6 @@ import android.content.SharedPreferences
|
|||||||
import androidx.preference.ListPreference
|
import androidx.preference.ListPreference
|
||||||
import androidx.preference.MultiSelectListPreference
|
import androidx.preference.MultiSelectListPreference
|
||||||
import androidx.preference.PreferenceScreen
|
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.animeextension.en.fmovies.extractors.StreamtapeExtractor
|
||||||
import eu.kanade.tachiyomi.animesource.ConfigurableAnimeSource
|
import eu.kanade.tachiyomi.animesource.ConfigurableAnimeSource
|
||||||
import eu.kanade.tachiyomi.animesource.model.AnimeFilterList
|
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.Track
|
||||||
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.network.GET
|
import eu.kanade.tachiyomi.network.GET
|
||||||
import eu.kanade.tachiyomi.network.asObservableSuccess
|
import eu.kanade.tachiyomi.network.asObservableSuccess
|
||||||
import eu.kanade.tachiyomi.util.asJsoup
|
import eu.kanade.tachiyomi.util.asJsoup
|
||||||
@ -266,7 +266,7 @@ class FMovies : ConfigurableAnimeSource, ParsedAnimeHttpSource() {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
"Filemoon" -> {
|
"Filemoon" -> {
|
||||||
FilemoonExtractor(client, headers).videosFromUrl(decrypted, prefix = "Filemoon - ")
|
FilemoonExtractor(client).videosFromUrl(decrypted, headers = headers)
|
||||||
}
|
}
|
||||||
"Streamtape" -> {
|
"Streamtape" -> {
|
||||||
StreamtapeExtractor(client, headers).videosFromUrl(decrypted)
|
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 {
|
dependencies {
|
||||||
|
implementation(project(':lib-filemoon-extractor'))
|
||||||
implementation(project(':lib-mp4upload-extractor'))
|
implementation(project(':lib-mp4upload-extractor'))
|
||||||
implementation (project(':lib-streamtape-extractor'))
|
implementation (project(':lib-streamtape-extractor'))
|
||||||
implementation "dev.datlag.jsunpacker:jsunpacker:1.0.1"
|
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.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.mp4uploadextractor.Mp4uploadExtractor
|
import eu.kanade.tachiyomi.lib.mp4uploadextractor.Mp4uploadExtractor
|
||||||
import eu.kanade.tachiyomi.lib.streamtapeextractor.StreamTapeExtractor
|
import eu.kanade.tachiyomi.lib.streamtapeextractor.StreamTapeExtractor
|
||||||
import eu.kanade.tachiyomi.network.GET
|
import eu.kanade.tachiyomi.network.GET
|
||||||
@ -301,9 +302,9 @@ class NineAnime : ConfigurableAnimeSource, ParsedAnimeHttpSource() {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
"filemoon" -> FilemoonExtractor(client)
|
"filemoon" -> FilemoonExtractor(client)
|
||||||
.videoFromUrl(embedLink, "Filemoon - ${server.first}").let {
|
.videosFromUrl(embedLink, "Filemoon - ${server.first} ")
|
||||||
videoList.addAll(it)
|
.also(videoList::addAll)
|
||||||
}
|
|
||||||
"streamtape" -> StreamTapeExtractor(client)
|
"streamtape" -> StreamTapeExtractor(client)
|
||||||
.videoFromUrl(embedLink, "StreamTape - ${server.first}")?.let {
|
.videoFromUrl(embedLink, "StreamTape - ${server.first}")?.let {
|
||||||
videoList.add(it)
|
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 {
|
dependencies {
|
||||||
|
implementation(project(':lib-filemoon-extractor'))
|
||||||
implementation(project(':lib-streamtape-extractor'))
|
implementation(project(':lib-streamtape-extractor'))
|
||||||
implementation(project(':lib-okru-extractor'))
|
implementation(project(':lib-okru-extractor'))
|
||||||
implementation(project(':lib-streamsb-extractor'))
|
implementation(project(':lib-streamsb-extractor'))
|
||||||
|
@ -4,7 +4,6 @@ import android.app.Application
|
|||||||
import android.content.SharedPreferences
|
import android.content.SharedPreferences
|
||||||
import androidx.preference.ListPreference
|
import androidx.preference.ListPreference
|
||||||
import androidx.preference.PreferenceScreen
|
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.animeextension.es.animelatinohd.extractors.SolidFilesExtractor
|
||||||
import eu.kanade.tachiyomi.animesource.ConfigurableAnimeSource
|
import eu.kanade.tachiyomi.animesource.ConfigurableAnimeSource
|
||||||
import eu.kanade.tachiyomi.animesource.model.AnimeFilter
|
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.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.filemoonextractor.FilemoonExtractor
|
||||||
import eu.kanade.tachiyomi.lib.okruextractor.OkruExtractor
|
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.streamtapeextractor.StreamTapeExtractor
|
import eu.kanade.tachiyomi.lib.streamtapeextractor.StreamTapeExtractor
|
||||||
@ -192,9 +192,8 @@ class AnimeLatinoHD : ConfigurableAnimeSource, ParsedAnimeHttpSource() {
|
|||||||
videoList.addAll(videos)
|
videoList.addAll(videos)
|
||||||
}
|
}
|
||||||
if (embedUrl.contains("filemoon")) {
|
if (embedUrl.contains("filemoon")) {
|
||||||
FilemoonExtractor(client).videoFromUrl(url, language)?.let {
|
FilemoonExtractor(client).videosFromUrl(url, language)
|
||||||
videoList.addAll(it)
|
.also(videoList::addAll)
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if (embedUrl.contains("streamtape")) {
|
if (embedUrl.contains("streamtape")) {
|
||||||
val video = StreamTapeExtractor(client).videoFromUrl(url, language + "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 {
|
dependencies {
|
||||||
|
implementation(project(':lib-filemoon-extractor'))
|
||||||
implementation(project(':lib-streamlare-extractor'))
|
implementation(project(':lib-streamlare-extractor'))
|
||||||
implementation(project(':lib-yourupload-extractor'))
|
implementation(project(':lib-yourupload-extractor'))
|
||||||
implementation(project(':lib-streamtape-extractor'))
|
implementation(project(':lib-streamtape-extractor'))
|
||||||
|
@ -2,13 +2,13 @@ package eu.kanade.tachiyomi.animeextension.es.pelisplushd
|
|||||||
|
|
||||||
import androidx.preference.ListPreference
|
import androidx.preference.ListPreference
|
||||||
import androidx.preference.PreferenceScreen
|
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.AnimeFilter
|
||||||
import eu.kanade.tachiyomi.animesource.model.AnimeFilterList
|
import eu.kanade.tachiyomi.animesource.model.AnimeFilterList
|
||||||
import eu.kanade.tachiyomi.animesource.model.SAnime
|
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.lib.doodextractor.DoodExtractor
|
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.okruextractor.OkruExtractor
|
||||||
import eu.kanade.tachiyomi.lib.streamlareextractor.StreamlareExtractor
|
import eu.kanade.tachiyomi.lib.streamlareextractor.StreamlareExtractor
|
||||||
import eu.kanade.tachiyomi.lib.streamsbextractor.StreamSBExtractor
|
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) }
|
VoeExtractor(client).videoFromUrl(url, "$prefix VoeCDN")?.let { videoList.add(it) }
|
||||||
}
|
}
|
||||||
if (embedUrl.contains("filemoon") || embedUrl.contains("moonplayer")) {
|
if (embedUrl.contains("filemoon") || embedUrl.contains("moonplayer")) {
|
||||||
FilemoonExtractor(client).videoFromUrl(url, prefix)?.let {
|
FilemoonExtractor(client).videosFromUrl(url, prefix)
|
||||||
videoList.addAll(it)
|
.also(videoList::addAll)
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if (embedUrl.contains("streamlare")) {
|
if (embedUrl.contains("streamlare")) {
|
||||||
videoList.addAll(StreamlareExtractor(client).videosFromUrl(url))
|
videoList.addAll(StreamlareExtractor(client).videosFromUrl(url))
|
||||||
|
@ -2,13 +2,13 @@ package eu.kanade.tachiyomi.animeextension.es.pelisplushd
|
|||||||
|
|
||||||
import androidx.preference.ListPreference
|
import androidx.preference.ListPreference
|
||||||
import androidx.preference.PreferenceScreen
|
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.AnimeFilter
|
||||||
import eu.kanade.tachiyomi.animesource.model.AnimeFilterList
|
import eu.kanade.tachiyomi.animesource.model.AnimeFilterList
|
||||||
import eu.kanade.tachiyomi.animesource.model.SAnime
|
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.lib.doodextractor.DoodExtractor
|
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.okruextractor.OkruExtractor
|
||||||
import eu.kanade.tachiyomi.lib.streamlareextractor.StreamlareExtractor
|
import eu.kanade.tachiyomi.lib.streamlareextractor.StreamlareExtractor
|
||||||
import eu.kanade.tachiyomi.lib.streamsbextractor.StreamSBExtractor
|
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) }
|
VoeExtractor(client).videoFromUrl(url)?.let { videoList.add(it) }
|
||||||
}
|
}
|
||||||
if (embedUrl.contains("filemoon") || embedUrl.contains("moonplayer")) {
|
if (embedUrl.contains("filemoon") || embedUrl.contains("moonplayer")) {
|
||||||
FilemoonExtractor(client).videoFromUrl(url, prefix)?.let {
|
FilemoonExtractor(client).videosFromUrl(url, prefix)
|
||||||
videoList.addAll(it)
|
.also(videoList::addAll)
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if (embedUrl.contains("streamlare")) {
|
if (embedUrl.contains("streamlare")) {
|
||||||
videoList.addAll(StreamlareExtractor(client).videosFromUrl(url))
|
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 {
|
dependencies {
|
||||||
|
implementation(project(':lib-filemoon-extractor'))
|
||||||
implementation(project(':lib-streamtape-extractor'))
|
implementation(project(':lib-streamtape-extractor'))
|
||||||
implementation(project(':lib-streamsb-extractor'))
|
implementation(project(':lib-streamsb-extractor'))
|
||||||
implementation(project(':lib-dood-extractor'))
|
implementation(project(':lib-dood-extractor'))
|
||||||
|
@ -7,7 +7,6 @@ import androidx.preference.EditTextPreference
|
|||||||
import androidx.preference.ListPreference
|
import androidx.preference.ListPreference
|
||||||
import androidx.preference.PreferenceScreen
|
import androidx.preference.PreferenceScreen
|
||||||
import eu.kanade.tachiyomi.AppInfo
|
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.animeextension.it.animeworld.extractors.StreamHideExtractor
|
||||||
import eu.kanade.tachiyomi.animesource.ConfigurableAnimeSource
|
import eu.kanade.tachiyomi.animesource.ConfigurableAnimeSource
|
||||||
import eu.kanade.tachiyomi.animesource.model.AnimeFilter
|
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.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.filemoonextractor.FilemoonExtractor
|
||||||
import eu.kanade.tachiyomi.lib.streamsbextractor.StreamSBExtractor
|
import eu.kanade.tachiyomi.lib.streamsbextractor.StreamSBExtractor
|
||||||
import eu.kanade.tachiyomi.lib.streamtapeextractor.StreamTapeExtractor
|
import eu.kanade.tachiyomi.lib.streamtapeextractor.StreamTapeExtractor
|
||||||
import eu.kanade.tachiyomi.network.GET
|
import eu.kanade.tachiyomi.network.GET
|
||||||
@ -169,15 +169,15 @@ class ANIMEWORLD : ConfigurableAnimeSource, ParsedAnimeHttpSource() {
|
|||||||
listOf(Video(url, "AnimeWorld Server", url))
|
listOf(Video(url, "AnimeWorld Server", url))
|
||||||
}
|
}
|
||||||
url.contains("https://doo") -> {
|
url.contains("https://doo") -> {
|
||||||
val video = DoodExtractor(client).videoFromUrl(url, redirect = true)
|
DoodExtractor(client).videoFromUrl(url, redirect = true)
|
||||||
video?.let { listOf(it) }
|
?.let(::listOf)
|
||||||
}
|
}
|
||||||
url.contains("streamtape") -> {
|
url.contains("streamtape") -> {
|
||||||
val video = StreamTapeExtractor(client).videoFromUrl(url.replace("/v/", "/e/"))
|
StreamTapeExtractor(client).videoFromUrl(url.replace("/v/", "/e/"))
|
||||||
video?.let { listOf(it) }
|
?.let(::listOf)
|
||||||
}
|
}
|
||||||
url.contains("filemoon") -> {
|
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) -> {
|
server.first.contains("streamhide", true) -> {
|
||||||
StreamHideExtractor(client).videosFromUrl(url, headers)
|
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 {
|
dependencies {
|
||||||
|
implementation(project(':lib-filemoon-extractor'))
|
||||||
implementation("dev.datlag.jsunpacker:jsunpacker:1.0.1")
|
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.PagePropsDto
|
||||||
import eu.kanade.tachiyomi.animeextension.sr.animesrbija.dto.SearchAnimeDto
|
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.dto.SearchPageDto
|
||||||
import eu.kanade.tachiyomi.animeextension.sr.animesrbija.extractors.FilemoonExtractor
|
|
||||||
import eu.kanade.tachiyomi.animesource.model.AnimeFilterList
|
import eu.kanade.tachiyomi.animesource.model.AnimeFilterList
|
||||||
import eu.kanade.tachiyomi.animesource.model.AnimesPage
|
import eu.kanade.tachiyomi.animesource.model.AnimesPage
|
||||||
import eu.kanade.tachiyomi.animesource.model.SAnime
|
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.AnimeHttpSource
|
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.GET
|
||||||
import eu.kanade.tachiyomi.network.asObservableSuccess
|
import eu.kanade.tachiyomi.network.asObservableSuccess
|
||||||
import eu.kanade.tachiyomi.util.asJsoup
|
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 {
|
dependencies {
|
||||||
|
implementation(project(':lib-filemoon-extractor'))
|
||||||
implementation(project(':lib-mp4upload-extractor'))
|
implementation(project(':lib-mp4upload-extractor'))
|
||||||
implementation(project(":lib-cryptoaes"))
|
implementation(project(":lib-cryptoaes"))
|
||||||
implementation(project(":lib-synchrony"))
|
implementation(project(":lib-synchrony"))
|
||||||
|
@ -8,7 +8,6 @@ import androidx.preference.MultiSelectListPreference
|
|||||||
import androidx.preference.PreferenceScreen
|
import androidx.preference.PreferenceScreen
|
||||||
import eu.kanade.tachiyomi.animeextension.tr.turkanime.extractors.AlucardExtractor
|
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.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.GoogleDriveExtractor
|
||||||
import eu.kanade.tachiyomi.animeextension.tr.turkanime.extractors.MVidooExtractor
|
import eu.kanade.tachiyomi.animeextension.tr.turkanime.extractors.MVidooExtractor
|
||||||
import eu.kanade.tachiyomi.animeextension.tr.turkanime.extractors.MailRuExtractor
|
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.animesource.online.ParsedAnimeHttpSource
|
||||||
import eu.kanade.tachiyomi.lib.cryptoaes.CryptoAES
|
import eu.kanade.tachiyomi.lib.cryptoaes.CryptoAES
|
||||||
import eu.kanade.tachiyomi.lib.doodextractor.DoodExtractor
|
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.mp4uploadextractor.Mp4uploadExtractor
|
||||||
import eu.kanade.tachiyomi.lib.okruextractor.OkruExtractor
|
import eu.kanade.tachiyomi.lib.okruextractor.OkruExtractor
|
||||||
import eu.kanade.tachiyomi.lib.sendvidextractor.SendvidExtractor
|
import eu.kanade.tachiyomi.lib.sendvidextractor.SendvidExtractor
|
||||||
@ -268,7 +268,7 @@ class TurkAnime : ConfigurableAnimeSource, ParsedAnimeHttpSource() {
|
|||||||
videoList.addAll(EmbedgramExtractor(client, headers).videosFromUrl(hosterLink, prefix = "$subber: "))
|
videoList.addAll(EmbedgramExtractor(client, headers).videosFromUrl(hosterLink, prefix = "$subber: "))
|
||||||
}
|
}
|
||||||
"FILEMOON" -> {
|
"FILEMOON" -> {
|
||||||
videoList.addAll(FilemoonExtractor(client, headers).videosFromUrl(hosterLink, prefix = "$subber: "))
|
videoList.addAll(FilemoonExtractor(client).videosFromUrl(hosterLink, prefix = "$subber: ", headers = headers))
|
||||||
}
|
}
|
||||||
"GDRIVE" -> {
|
"GDRIVE" -> {
|
||||||
Regex("""[\w-]{28,}""").find(hosterLink)?.groupValues?.get(0)?.let {
|
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