mirror of
				https://github.com/recloudstream/cloudstream.git
				synced 2024-08-15 01:53:11 +00:00 
			
		
		
		
	Added VidEmbed with the help of Arjix :)
This commit is contained in:
		
							parent
							
								
									711397c257
								
							
						
					
					
						commit
						afeb0785a4
					
				
					 7 changed files with 299 additions and 56 deletions
				
			
		|  | @ -1,6 +1,5 @@ | ||||||
| package com.lagradost.cloudstream3 | package com.lagradost.cloudstream3 | ||||||
| 
 | 
 | ||||||
| import android.app.Activity |  | ||||||
| import android.content.Context | import android.content.Context | ||||||
| import androidx.preference.PreferenceManager | import androidx.preference.PreferenceManager | ||||||
| import com.fasterxml.jackson.databind.DeserializationFeature | import com.fasterxml.jackson.databind.DeserializationFeature | ||||||
|  | @ -10,11 +9,10 @@ import com.lagradost.cloudstream3.animeproviders.* | ||||||
| import com.lagradost.cloudstream3.movieproviders.* | import com.lagradost.cloudstream3.movieproviders.* | ||||||
| import com.lagradost.cloudstream3.utils.ExtractorLink | import com.lagradost.cloudstream3.utils.ExtractorLink | ||||||
| import java.util.* | import java.util.* | ||||||
| import kotlin.collections.ArrayList |  | ||||||
| import kotlin.collections.HashSet |  | ||||||
| 
 | 
 | ||||||
| const val USER_AGENT = | const val USER_AGENT = | ||||||
|     "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36" |     "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36" | ||||||
|  | 
 | ||||||
| //val baseHeader = mapOf("User-Agent" to USER_AGENT) | //val baseHeader = mapOf("User-Agent" to USER_AGENT) | ||||||
| val mapper = JsonMapper.builder().addModule(KotlinModule()) | val mapper = JsonMapper.builder().addModule(KotlinModule()) | ||||||
|     .configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false).build()!! |     .configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false).build()!! | ||||||
|  | @ -44,7 +42,8 @@ object APIHolder { | ||||||
|         WatchCartoonOnlineProvider(), |         WatchCartoonOnlineProvider(), | ||||||
|         AllMoviesForYouProvider(), |         AllMoviesForYouProvider(), | ||||||
|         AsiaFlixProvider(), |         AsiaFlixProvider(), | ||||||
|         ThenosProvider() |         ThenosProvider(), | ||||||
|  |         VidEmbedProvider() | ||||||
|     ) |     ) | ||||||
| 
 | 
 | ||||||
|     val restrictedApis = arrayListOf( |     val restrictedApis = arrayListOf( | ||||||
|  |  | ||||||
|  | @ -1,34 +0,0 @@ | ||||||
| package com.lagradost.cloudstream3.extractors |  | ||||||
| 
 |  | ||||||
| import com.lagradost.cloudstream3.utils.ExtractorApi |  | ||||||
| import com.lagradost.cloudstream3.utils.ExtractorLink |  | ||||||
| import com.lagradost.cloudstream3.utils.Qualities |  | ||||||
| import org.jsoup.Jsoup |  | ||||||
| 
 |  | ||||||
| class Shiro : ExtractorApi() { |  | ||||||
|     override val name: String = "Shiro" |  | ||||||
|     override val mainUrl: String = "https://cherry.subsplea.se" |  | ||||||
|     override val requiresReferer = false |  | ||||||
| 
 |  | ||||||
|     override fun getExtractorUrl(id: String): String { |  | ||||||
|         return "$mainUrl/$id" |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     override fun getUrl(url: String, referer: String?): List<ExtractorLink>? { |  | ||||||
|         val headers = mapOf("Referer" to "https://shiro.is/") |  | ||||||
|         val res = khttp.get(url, headers = headers).text |  | ||||||
|         Jsoup.parse(res).select("source").firstOrNull()?.attr("src")?.replace("&", "?")?.let { |  | ||||||
|             return listOf( |  | ||||||
|                 ExtractorLink( |  | ||||||
|                     name, |  | ||||||
|                     name, |  | ||||||
|                     it.replace(" ", "%20"), |  | ||||||
|                     "https://cherry.subsplea.se/", |  | ||||||
|                     // UHD to give top priority |  | ||||||
|                     Qualities.P2160.value |  | ||||||
|                 ) |  | ||||||
|             ) |  | ||||||
|         } |  | ||||||
|         return null |  | ||||||
|     } |  | ||||||
| } |  | ||||||
|  | @ -1,19 +1,29 @@ | ||||||
| package com.lagradost.cloudstream3.extractors | package com.lagradost.cloudstream3.extractors | ||||||
| 
 | 
 | ||||||
|  | import com.lagradost.cloudstream3.mvvm.normalSafeApiCall | ||||||
| import com.lagradost.cloudstream3.pmap | import com.lagradost.cloudstream3.pmap | ||||||
| import com.lagradost.cloudstream3.utils.ExtractorLink | import com.lagradost.cloudstream3.utils.ExtractorLink | ||||||
| import com.lagradost.cloudstream3.utils.extractorApis | import com.lagradost.cloudstream3.utils.extractorApis | ||||||
|  | import com.lagradost.cloudstream3.utils.getQualityFromName | ||||||
| import org.jsoup.Jsoup | import org.jsoup.Jsoup | ||||||
| 
 | 
 | ||||||
| class Vidstream { | /** | ||||||
|  |  * overrideMainUrl is necessary for for other vidstream clones like vidembed.cc | ||||||
|  |  * If they diverge it'd be better to make them separate. | ||||||
|  |  * */ | ||||||
|  | class Vidstream(overrideMainUrl: String? = null) { | ||||||
|     val name: String = "Vidstream" |     val name: String = "Vidstream" | ||||||
|     private val mainUrl: String = "https://gogo-stream.com" |     private val mainUrl: String = overrideMainUrl ?: "https://gogo-stream.com" | ||||||
| 
 | 
 | ||||||
|     private fun getExtractorUrl(id: String): String { |     private fun getExtractorUrl(id: String): String { | ||||||
|         return "$mainUrl/streaming.php?id=$id" |         return "$mainUrl/streaming.php?id=$id" | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     private val normalApis = arrayListOf(Shiro(), MultiQuality()) |     private fun getDownloadUrl(id: String): String { | ||||||
|  |         return "$mainUrl/download?id=$id" | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     private val normalApis = arrayListOf(MultiQuality()) | ||||||
| 
 | 
 | ||||||
|     // https://gogo-stream.com/streaming.php?id=MTE3NDg5 |     // https://gogo-stream.com/streaming.php?id=MTE3NDg5 | ||||||
|     fun getUrl(id: String, isCasting: Boolean = false, callback: (ExtractorLink) -> Unit): Boolean { |     fun getUrl(id: String, isCasting: Boolean = false, callback: (ExtractorLink) -> Unit): Boolean { | ||||||
|  | @ -23,22 +33,47 @@ class Vidstream { | ||||||
|                 val source = api.getSafeUrl(url) |                 val source = api.getSafeUrl(url) | ||||||
|                 source?.forEach { callback.invoke(it) } |                 source?.forEach { callback.invoke(it) } | ||||||
|             } |             } | ||||||
|  |             val extractorUrl = getExtractorUrl(id) | ||||||
| 
 | 
 | ||||||
|             val url = getExtractorUrl(id) |             /** Stolen from GogoanimeProvider.kt extractor */ | ||||||
|             with(khttp.get(url)) { |             normalSafeApiCall { | ||||||
|  |                 val link = getDownloadUrl(id) | ||||||
|  |                 val page = khttp.get(link, headers = mapOf("Referer" to extractorUrl)) | ||||||
|  |                 val pageDoc = Jsoup.parse(page.text) | ||||||
|  |                 val qualityRegex = Regex("(\\d+)P") | ||||||
|  | 
 | ||||||
|  |                 pageDoc.select(".dowload > a[download]").forEach { | ||||||
|  |                     val qual = if (it.text() | ||||||
|  |                             .contains("HDP") | ||||||
|  |                     ) "1080" else qualityRegex.find(it.text())?.destructured?.component1().toString() | ||||||
|  | 
 | ||||||
|  |                     callback.invoke( | ||||||
|  |                         ExtractorLink( | ||||||
|  |                             this.name, | ||||||
|  |                             if (qual == "null") this.name else "${this.name} - " + qual + "p", | ||||||
|  |                             it.attr("href"), | ||||||
|  |                             page.url, | ||||||
|  |                             getQualityFromName(qual), | ||||||
|  |                             it.attr("href").contains(".m3u8") | ||||||
|  |                         ) | ||||||
|  |                     ) | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             with(khttp.get(extractorUrl)) { | ||||||
|                 val document = Jsoup.parse(this.text) |                 val document = Jsoup.parse(this.text) | ||||||
|                 val primaryLinks = document.select("ul.list-server-items > li.linkserver") |                 val primaryLinks = document.select("ul.list-server-items > li.linkserver") | ||||||
|                 //val extractedLinksList: MutableList<ExtractorLink> = mutableListOf() |                 //val extractedLinksList: MutableList<ExtractorLink> = mutableListOf() | ||||||
| 
 | 
 | ||||||
|                 // All vidstream links passed to extractors |                 // All vidstream links passed to extractors | ||||||
|                 primaryLinks.forEach { element -> |                 primaryLinks.distinctBy { it.attr("data-video") }.forEach { element -> | ||||||
|                     val link = element.attr("data-video") |                     val link = element.attr("data-video") | ||||||
|                     //val name = element.text() |                     //val name = element.text() | ||||||
| 
 | 
 | ||||||
|                     // Matches vidstream links with extractors |                     // Matches vidstream links with extractors | ||||||
|                     extractorApis.filter { !it.requiresReferer || !isCasting }.pmap { api -> |                     extractorApis.filter { !it.requiresReferer || !isCasting }.pmap { api -> | ||||||
|                         if (link.startsWith(api.mainUrl)) { |                         if (link.startsWith(api.mainUrl)) { | ||||||
|                             val extractedLinks = api.getSafeUrl(link, url) |                             val extractedLinks = api.getSafeUrl(link, extractorUrl) | ||||||
|                             if (extractedLinks?.isNotEmpty() == true) { |                             if (extractedLinks?.isNotEmpty() == true) { | ||||||
|                                 extractedLinks.forEach { |                                 extractedLinks.forEach { | ||||||
|                                     callback.invoke(it) |                                     callback.invoke(it) | ||||||
|  |  | ||||||
|  | @ -45,6 +45,7 @@ class XStreamCdn : ExtractorApi() { | ||||||
|         val newUrl = url.replace("$mainUrl/v/", "$mainUrl/api/source/") |         val newUrl = url.replace("$mainUrl/v/", "$mainUrl/api/source/") | ||||||
|         val extractedLinksList: MutableList<ExtractorLink> = mutableListOf() |         val extractedLinksList: MutableList<ExtractorLink> = mutableListOf() | ||||||
|         with(khttp.post(newUrl, headers = headers)) { |         with(khttp.post(newUrl, headers = headers)) { | ||||||
|  |             if (this.text == """{"success":false,"data":"Video not found or has been removed"}""") return listOf() | ||||||
|             mapper.readValue<ResponseJson?>(this.text)?.let { |             mapper.readValue<ResponseJson?>(this.text)?.let { | ||||||
|                 if (it.success && it.data != null) { |                 if (it.success && it.data != null) { | ||||||
|                     it.data.forEach { data -> |                     it.data.forEach { data -> | ||||||
|  |  | ||||||
|  | @ -0,0 +1,243 @@ | ||||||
|  | package com.lagradost.cloudstream3.movieproviders | ||||||
|  | 
 | ||||||
|  | import org.jsoup.Jsoup | ||||||
|  | import com.lagradost.cloudstream3.* | ||||||
|  | import com.lagradost.cloudstream3.extractors.Vidstream | ||||||
|  | import com.lagradost.cloudstream3.utils.ExtractorLink | ||||||
|  | import com.lagradost.cloudstream3.utils.getQualityFromName | ||||||
|  | import java.util.* | ||||||
|  | import kotlin.collections.ArrayList | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | class VidEmbedProvider : MainAPI() { | ||||||
|  |     override val mainUrl: String | ||||||
|  |         get() = "https://vidembed.cc" | ||||||
|  |     override val name: String | ||||||
|  |         get() = "VidEmbed" | ||||||
|  |     override val hasQuickSearch: Boolean | ||||||
|  |         get() = false | ||||||
|  |     override val hasMainPage: Boolean | ||||||
|  |         get() = true | ||||||
|  | 
 | ||||||
|  |     private fun fixUrl(url: String): String { | ||||||
|  |         return if (url.startsWith("//")) { | ||||||
|  |             "https:$url" | ||||||
|  |         } else if (url.startsWith("/")) { | ||||||
|  |             "$mainUrl$url" | ||||||
|  |         } else { | ||||||
|  |             url | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     override val supportedTypes: Set<TvType> | ||||||
|  |         get() = setOf(TvType.Anime, TvType.AnimeMovie, TvType.TvSeries, TvType.Movie) | ||||||
|  | 
 | ||||||
|  |     override fun search(query: String): ArrayList<SearchResponse> { | ||||||
|  |         val link = "$mainUrl/search.html?keyword=$query" | ||||||
|  |         val html = khttp.get(link).text | ||||||
|  |         val soup = Jsoup.parse(html) | ||||||
|  | 
 | ||||||
|  |         return ArrayList(soup.select(".listing.items > .video-block").map { li -> | ||||||
|  |             val href = fixUrl(li.selectFirst("a").attr("href")) | ||||||
|  |             val poster = li.selectFirst("img")?.attr("src") | ||||||
|  |             val title = li.selectFirst(".name").text() | ||||||
|  |             val year = li.selectFirst(".date")?.text()?.split("-")?.get(0)?.toIntOrNull() | ||||||
|  | 
 | ||||||
|  |             TvSeriesSearchResponse( | ||||||
|  |                 if (!title.contains("Episode")) title else title.split("Episode")[0].trim(), | ||||||
|  |                 href, | ||||||
|  |                 this.name, | ||||||
|  |                 TvType.TvSeries, | ||||||
|  |                 poster, year, | ||||||
|  |                 null | ||||||
|  |             ) | ||||||
|  |         }) | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     override fun load(url: String): LoadResponse? { | ||||||
|  |         val html = khttp.get(url).text | ||||||
|  |         val soup = Jsoup.parse(html) | ||||||
|  | 
 | ||||||
|  |         var title = soup.selectFirst("h1,h2,h3").text() | ||||||
|  |         title = if (!title.contains("Episode")) title else title.split("Episode")[0].trim() | ||||||
|  | 
 | ||||||
|  |         val description = soup.selectFirst(".post-entry")?.text()?.trim() | ||||||
|  |         var poster: String? = null | ||||||
|  | 
 | ||||||
|  |         val episodes = soup.select(".listing.items.lists > .video-block").withIndex().map { (index, li) -> | ||||||
|  |             val epTitle = if (li.selectFirst(".name") != null) | ||||||
|  |                 if (li.selectFirst(".name").text().contains("Episode")) | ||||||
|  |                     "Episode " + li.selectFirst(".name").text().split("Episode")[1].trim() | ||||||
|  |                 else | ||||||
|  |                     li.selectFirst(".name").text() | ||||||
|  |             else "" | ||||||
|  |             val epThumb = li.selectFirst("img")?.attr("src") | ||||||
|  |             val epDate = li.selectFirst(".meta > .date").text() | ||||||
|  | 
 | ||||||
|  |             if (poster == null) { | ||||||
|  |                 poster = li.selectFirst("img")?.attr("onerror")?.split("=")?.get(1)?.replace(Regex("[';]"), "") | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             val epNum = Regex("""Episode (\d+)""").find(epTitle)?.destructured?.component1()?.toIntOrNull() | ||||||
|  | 
 | ||||||
|  |             TvSeriesEpisode( | ||||||
|  |                 epTitle, | ||||||
|  |                 null, | ||||||
|  |                 epNum, | ||||||
|  |                 fixUrl(li.selectFirst("a").attr("href")), | ||||||
|  |                 epThumb, | ||||||
|  |                 epDate | ||||||
|  |             ) | ||||||
|  |         }.reversed() | ||||||
|  |         val year = if (episodes.isNotEmpty()) episodes.first().date?.split("-")?.get(0)?.toIntOrNull() else null | ||||||
|  | 
 | ||||||
|  |         val tvType = if (episodes.size == 1 && episodes[0].name == title) TvType.Movie else TvType.TvSeries | ||||||
|  | 
 | ||||||
|  |         return when (tvType) { | ||||||
|  |             TvType.TvSeries -> { | ||||||
|  |                 TvSeriesLoadResponse( | ||||||
|  |                     title, | ||||||
|  |                     url, | ||||||
|  |                     this.name, | ||||||
|  |                     tvType, | ||||||
|  |                     episodes, | ||||||
|  |                     poster, | ||||||
|  |                     year, | ||||||
|  |                     description, | ||||||
|  |                     ShowStatus.Ongoing, | ||||||
|  |                     null, | ||||||
|  |                     null | ||||||
|  |                 ) | ||||||
|  |             } | ||||||
|  |             TvType.Movie -> { | ||||||
|  |                 MovieLoadResponse( | ||||||
|  |                     title, | ||||||
|  |                     url, | ||||||
|  |                     this.name, | ||||||
|  |                     tvType, | ||||||
|  |                     episodes[0].data, | ||||||
|  |                     poster, | ||||||
|  |                     year, | ||||||
|  |                     description, | ||||||
|  |                     null, | ||||||
|  |                     null | ||||||
|  |                 ) | ||||||
|  |             } | ||||||
|  |             else -> null | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     override fun getMainPage(): HomePageResponse? { | ||||||
|  |         val urls = listOf( | ||||||
|  |             mainUrl, | ||||||
|  |             "$mainUrl/movies", | ||||||
|  |             "$mainUrl/series", | ||||||
|  |             "$mainUrl/recommended-series", | ||||||
|  |             "$mainUrl/cinema-movies" | ||||||
|  |         ) | ||||||
|  |         val homePageList = ArrayList<HomePageList>() | ||||||
|  |         urls.pmap { url -> | ||||||
|  |             val response = khttp.get(url, timeout = 20.0) | ||||||
|  |             val document = Jsoup.parse(response.text) | ||||||
|  |             document.select("div.main-inner")?.forEach { | ||||||
|  |                 val title = it.select(".widget-title").text().trim() | ||||||
|  |                 val elements = it.select(".video-block").map { | ||||||
|  |                     val link = fixUrl(it.select("a").attr("href")) | ||||||
|  |                     val image = it.select(".picture > img").attr("src") | ||||||
|  |                     val name = it.select("div.name").text().trim() | ||||||
|  |                     val isSeries = (name.contains("Season") || name.contains("Episode")) | ||||||
|  | 
 | ||||||
|  |                     if (isSeries) { | ||||||
|  |                         TvSeriesSearchResponse( | ||||||
|  |                             name, | ||||||
|  |                             link, | ||||||
|  |                             this.name, | ||||||
|  |                             TvType.TvSeries, | ||||||
|  |                             image, | ||||||
|  |                             null, | ||||||
|  |                             null, | ||||||
|  |                         ) | ||||||
|  |                     } else { | ||||||
|  |                         MovieSearchResponse( | ||||||
|  |                             name, | ||||||
|  |                             link, | ||||||
|  |                             this.name, | ||||||
|  |                             TvType.Movie, | ||||||
|  |                             image, | ||||||
|  |                             null, | ||||||
|  |                             null, | ||||||
|  |                         ) | ||||||
|  |                     } | ||||||
|  |                 } | ||||||
|  | 
 | ||||||
|  |                 homePageList.add( | ||||||
|  |                     HomePageList( | ||||||
|  |                         title, elements | ||||||
|  |                     ) | ||||||
|  |                 ) | ||||||
|  | 
 | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |         } | ||||||
|  |         return HomePageResponse(homePageList) | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     override fun loadLinks( | ||||||
|  |         data: String, | ||||||
|  |         isCasting: Boolean, | ||||||
|  |         subtitleCallback: (SubtitleFile) -> Unit, | ||||||
|  |         callback: (ExtractorLink) -> Unit | ||||||
|  |     ): Boolean { | ||||||
|  |         val iframeLink = Jsoup.parse(khttp.get(data).text).selectFirst("iframe")?.attr("src") ?: return false | ||||||
|  |         val vidstreamObject = Vidstream("https://vidembed.cc") | ||||||
|  |         // https://vidembed.cc/streaming.php?id=MzUwNTY2&... -> MzUwNTY2 | ||||||
|  |         val id = Regex("""id=([^&]*)""").find(iframeLink)?.groupValues?.get(1) | ||||||
|  | 
 | ||||||
|  |         if (id != null) { | ||||||
|  |             vidstreamObject.getUrl(id, isCasting, callback) | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         val html = khttp.get(fixUrl(iframeLink)).text | ||||||
|  |         val soup = Jsoup.parse(html) | ||||||
|  | 
 | ||||||
|  |         val servers = soup.select(".list-server-items > .linkserver").mapNotNull { li -> | ||||||
|  |             if (!li?.attr("data-video").isNullOrEmpty()) { | ||||||
|  |                 Pair(li.text(), fixUrl(li.attr("data-video"))) | ||||||
|  |             } else { | ||||||
|  |                 null | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |         servers.forEach { | ||||||
|  |             if (it.first.toLowerCase(Locale.ROOT).trim() == "beta server") { | ||||||
|  |                 // Group 1: link, Group 2: Label | ||||||
|  |                 val sourceRegex = Regex("""sources:[\W\w]*?file:\s*["'](.*?)["'][\W\w]*?label:\s*["'](.*?)["']""") | ||||||
|  |                 val trackRegex = Regex("""tracks:[\W\w]*?file:\s*["'](.*?)["'][\W\w]*?label:\s*["'](.*?)["']""") | ||||||
|  | 
 | ||||||
|  |                 val html = khttp.get(it.second, headers = mapOf("referer" to iframeLink)).text | ||||||
|  |                 sourceRegex.findAll(html).forEach { match -> | ||||||
|  |                     callback.invoke( | ||||||
|  |                         ExtractorLink( | ||||||
|  |                             this.name, | ||||||
|  |                             match.groupValues.getOrNull(2)?.let { "${this.name} $it" } ?: this.name, | ||||||
|  |                             match.groupValues[1], | ||||||
|  |                             it.second, | ||||||
|  |                             getQualityFromName(match.groupValues.getOrNull(2) ?: ""), | ||||||
|  |                             // Kinda risky | ||||||
|  |                             match.groupValues[1].endsWith(".m3u8"), | ||||||
|  |                         ) | ||||||
|  |                     ) | ||||||
|  |                 } | ||||||
|  |                 trackRegex.findAll(html).forEach { match -> | ||||||
|  |                     subtitleCallback.invoke( | ||||||
|  |                         SubtitleFile( | ||||||
|  |                             match.groupValues.getOrNull(2) ?: "Unknown", | ||||||
|  |                             match.groupValues[1] | ||||||
|  |                         ) | ||||||
|  |                     ) | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         return true | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | @ -49,9 +49,9 @@ fun getPacked(string: String): String? { | ||||||
|     return packedRegex.find(string)?.value |     return packedRegex.find(string)?.value | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| fun getAndUnpack(string: String): String? { | fun getAndUnpack(string: String): String { | ||||||
|     val packedText = getPacked(string) |     val packedText = getPacked(string) | ||||||
|     return JsUnpacker(packedText).unpack() |     return JsUnpacker(packedText).unpack() ?: string | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| fun loadExtractor(url: String, referer: String?, callback: (ExtractorLink) -> Unit) { | fun loadExtractor(url: String, referer: String?, callback: (ExtractorLink) -> Unit) { | ||||||
|  | @ -65,7 +65,6 @@ fun loadExtractor(url: String, referer: String?, callback: (ExtractorLink) -> Un | ||||||
| 
 | 
 | ||||||
| val extractorApis: Array<ExtractorApi> = arrayOf( | val extractorApis: Array<ExtractorApi> = arrayOf( | ||||||
|     //AllProvider(), |     //AllProvider(), | ||||||
|     Shiro(), |  | ||||||
|     WcoStream(), |     WcoStream(), | ||||||
|     Mp4Upload(), |     Mp4Upload(), | ||||||
|     StreamTape(), |     StreamTape(), | ||||||
|  |  | ||||||
|  | @ -32,7 +32,7 @@ class JsUnpacker(packedJS: String?) { | ||||||
|         val js = packedJS |         val js = packedJS | ||||||
|         try { |         try { | ||||||
|             var p = |             var p = | ||||||
|                 Pattern.compile("""}\s*\('(.*)',\s*(.*?),\s*(\d+),\s*'(.*?)'\.split\('\|'\)""", Pattern.DOTALL) |                 Pattern.compile("""\}\s*\('(.*)',\s*(.*?),\s*(\d+),\s*'(.*?)'\.split\('\|'\)""", Pattern.DOTALL) | ||||||
|             var m = p.matcher(js) |             var m = p.matcher(js) | ||||||
|             if (m.find() && m.groupCount() == 4) { |             if (m.find() && m.groupCount() == 4) { | ||||||
|                 val payload = m.group(1).replace("\\'", "'") |                 val payload = m.group(1).replace("\\'", "'") | ||||||
|  | @ -72,7 +72,7 @@ class JsUnpacker(packedJS: String?) { | ||||||
|                 return decoded.toString() |                 return decoded.toString() | ||||||
|             } |             } | ||||||
|         } catch (e: Exception) { |         } catch (e: Exception) { | ||||||
|             logError(e) | //            logError(e) | ||||||
|         } |         } | ||||||
|         return null |         return null | ||||||
|     } |     } | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue