mirror of
				https://github.com/recloudstream/cloudstream.git
				synced 2024-08-15 01:53:11 +00:00 
			
		
		
		
	Merge remote-tracking branch 'origin/master'
This commit is contained in:
		
						commit
						7294b21a9e
					
				
					 5 changed files with 60 additions and 28 deletions
				
			
		|  | @ -6,6 +6,7 @@ import com.lagradost.cloudstream3.mvvm.normalSafeApiCall | |||
| import com.lagradost.cloudstream3.mvvm.safeApiCall | ||||
| import com.lagradost.cloudstream3.utils.* | ||||
| import org.jsoup.Jsoup | ||||
| import org.jsoup.nodes.Document | ||||
| import java.net.URI | ||||
| import java.util.* | ||||
| import javax.crypto.Cipher | ||||
|  | @ -34,7 +35,7 @@ class GogoanimeProvider : MainAPI() { | |||
|          * */ | ||||
|         private fun getKey(id: String): String? { | ||||
|             return normalSafeApiCall { | ||||
|                  id.map { | ||||
|                 id.map { | ||||
|                     it.code.toString(16) | ||||
|                 }.joinToString("").substring(0, 32) | ||||
|             } | ||||
|  | @ -77,6 +78,7 @@ class GogoanimeProvider : MainAPI() { | |||
|          * @param secretKey secret key for decryption from site, required non-null if isUsingAdaptiveKeys is off | ||||
|          * @param secretDecryptKey secret key to decrypt the response json, required non-null if isUsingAdaptiveKeys is off | ||||
|          * @param isUsingAdaptiveKeys generates keys from IV and ID, see getKey() | ||||
|          * @param isUsingAdaptiveData generate encrypt-ajax data based on $("script[data-name='episode']")[0].dataset.value | ||||
|          * */ | ||||
|         suspend fun extractVidstream( | ||||
|             iframeUrl: String, | ||||
|  | @ -86,7 +88,8 @@ class GogoanimeProvider : MainAPI() { | |||
|             secretKey: String?, | ||||
|             secretDecryptKey: String?, | ||||
|             // This could be removed, but i prefer it verbose | ||||
|             isUsingAdaptiveKeys: Boolean | ||||
|             isUsingAdaptiveKeys: Boolean, | ||||
|             isUsingAdaptiveData: Boolean | ||||
|         ) = safeApiCall { | ||||
|             // https://github.com/saikou-app/saikou/blob/3e756bd8e876ad7a9318b17110526880525a5cd3/app/src/main/java/ani/saikou/anime/source/extractors/GogoCDN.kt | ||||
|             // No Licence on the following code | ||||
|  | @ -98,8 +101,10 @@ class GogoanimeProvider : MainAPI() { | |||
| 
 | ||||
|             val id = Regex("id=([^&]+)").find(iframeUrl)!!.value.removePrefix("id=") | ||||
| 
 | ||||
|             var document: Document? = null | ||||
|             val foundIv = | ||||
|                 iv ?: app.get(iframeUrl).document.select("""div.wrapper[class*=container]""") | ||||
|                 iv ?: app.get(iframeUrl).document.also { document = it } | ||||
|                     .select("""div.wrapper[class*=container]""") | ||||
|                     .attr("class").split("-").lastOrNull() ?: return@safeApiCall | ||||
|             val foundKey = secretKey ?: getKey(base64Decode(id) + foundIv) ?: return@safeApiCall | ||||
|             val foundDecryptKey = secretDecryptKey ?: foundKey | ||||
|  | @ -108,9 +113,19 @@ class GogoanimeProvider : MainAPI() { | |||
|             val mainUrl = "https://" + uri.host | ||||
| 
 | ||||
|             val encryptedId = cryptoHandler(id, foundIv, foundKey) | ||||
|             val encryptRequestData = if (isUsingAdaptiveData) { | ||||
|                 // Only fetch the document if necessary | ||||
|                 val realDocument = document ?: app.get(iframeUrl).document | ||||
|                 val dataEncrypted = realDocument.select("script[data-name='episode']").attr("data-value") | ||||
|                 val headers = cryptoHandler(dataEncrypted, foundIv, foundKey, false) | ||||
|                 "id=$encryptedId&alias=$id&" + headers.substringAfter("&") | ||||
|             } else { | ||||
|                 "id=$encryptedId&alias=$id" | ||||
|             } | ||||
| 
 | ||||
|             val jsonResponse = | ||||
|                 app.get( | ||||
|                     "$mainUrl/encrypt-ajax.php?id=$encryptedId&alias=$id", | ||||
|                     "$mainUrl/encrypt-ajax.php?$encryptRequestData", | ||||
|                     headers = mapOf("X-Requested-With" to "XMLHttpRequest") | ||||
|                 ) | ||||
|             val dataencrypted = | ||||
|  | @ -129,7 +144,7 @@ class GogoanimeProvider : MainAPI() { | |||
|                             source.file, | ||||
|                             mainUrl, | ||||
|                             headers = mapOf("Referer" to "https://gogoplay4.com") | ||||
|                         ).forEach (sourceCallback) | ||||
|                         ).forEach(sourceCallback) | ||||
|                     } | ||||
|                     source.file.contains("vidstreaming") -> { | ||||
|                         sourceCallback.invoke( | ||||
|  | @ -382,9 +397,9 @@ class GogoanimeProvider : MainAPI() { | |||
|                             loadExtractor(data, streamingResponse.url, callback) | ||||
|                         } | ||||
|                 }, { | ||||
|                     val iv = "4968442212618524" | ||||
|                     val secretKey = "34541577475429958244002440089157" | ||||
|                     val secretDecryptKey = "20945647121183498244002440089157" | ||||
|                     val iv = "3134003223491201" | ||||
|                     val secretKey = "37911490979715163134003223491201" | ||||
|                     val secretDecryptKey = "54674138327930866480207815084989" | ||||
|                     extractVidstream( | ||||
|                         iframe, | ||||
|                         this.name, | ||||
|  | @ -392,7 +407,8 @@ class GogoanimeProvider : MainAPI() { | |||
|                         iv, | ||||
|                         secretKey, | ||||
|                         secretDecryptKey, | ||||
|                         false | ||||
|                         isUsingAdaptiveKeys = false, | ||||
|                         isUsingAdaptiveData = true | ||||
|                     ) | ||||
|                 }) | ||||
|             } | ||||
|  |  | |||
|  | @ -1,10 +1,8 @@ | |||
| package com.lagradost.cloudstream3.extractors | ||||
| 
 | ||||
| import com.fasterxml.jackson.annotation.JsonProperty | ||||
| import com.fasterxml.jackson.module.kotlin.readValue | ||||
| import com.lagradost.cloudstream3.apmap | ||||
| import com.lagradost.cloudstream3.app | ||||
| import com.lagradost.cloudstream3.mapper | ||||
| import com.lagradost.cloudstream3.utils.ExtractorApi | ||||
| import com.lagradost.cloudstream3.utils.ExtractorLink | ||||
| import com.lagradost.cloudstream3.utils.M3u8Helper.Companion.generateM3u8 | ||||
|  | @ -48,7 +46,7 @@ class VizcloudDigital : WcoStream() { | |||
| } | ||||
| 
 | ||||
| open class WcoStream : ExtractorApi() { | ||||
|     override var name = "VidStream" //Cause works for animekisa and wco | ||||
|     override var name = "VidStream" // Cause works for animekisa and wco | ||||
|     override var mainUrl = "https://vidstream.pro" | ||||
|     override val requiresReferer = false | ||||
| 
 | ||||
|  | @ -65,8 +63,6 @@ open class WcoStream : ExtractorApi() { | |||
|         val apiLink = "$baseUrl/info/$Id?domain=wcostream.cc&skey=$skey" | ||||
|         val referrer = "$baseUrl/e/$Id?domain=wcostream.cc" | ||||
| 
 | ||||
|         val response = app.get(apiLink, headers = mapOf("Referer" to referrer)).text | ||||
| 
 | ||||
|         data class Sources( | ||||
|             @JsonProperty("file") val file: String, | ||||
|             @JsonProperty("label") val label: String? | ||||
|  | @ -81,14 +77,14 @@ open class WcoStream : ExtractorApi() { | |||
|             @JsonProperty("media") val media: Media | ||||
|         ) | ||||
| 
 | ||||
|         val mapped = response.let { mapper.readValue<WcoResponse>(it) } | ||||
|         val mapped = app.get(apiLink, headers = mapOf("Referer" to referrer)).mapped<WcoResponse>() | ||||
|         val sources = mutableListOf<ExtractorLink>() | ||||
| 
 | ||||
|         if (mapped.success) { | ||||
|             mapped.media.sources.forEach { | ||||
|                 if (mainUrl == "https://vizcloud2.ru" || mainUrl == "https://vizcloud.online") { | ||||
|                     if (it.file.contains("vizcloud2.ru") || it.file.contains("vizcloud.online")) { | ||||
|                         //Had to do this thing 'cause "list.m3u8#.mp4" gives 404 error so no quality is added | ||||
|                         // Had to do this thing 'cause "list.m3u8#.mp4" gives 404 error so no quality is added | ||||
|                         val link1080 = it.file.replace("list.m3u8#.mp4", "H4/v.m3u8") | ||||
|                         val link720 = it.file.replace("list.m3u8#.mp4", "H3/v.m3u8") | ||||
|                         val link480 = it.file.replace("list.m3u8#.mp4", "H2/v.m3u8") | ||||
|  | @ -123,17 +119,26 @@ open class WcoStream : ExtractorApi() { | |||
|                             } | ||||
|                         } | ||||
|                     } | ||||
|                 } | ||||
|                 if (mainUrl == "https://vidstream.pro" || mainUrl == "https://vidstreamz.online" || mainUrl == "https://vizcloud2.online" | ||||
|                     || mainUrl == "https://vizcloud.xyz" || mainUrl == "https://vizcloud.live" || mainUrl == "https://vizcloud.info" | ||||
|                     || mainUrl == "https://mwvn.vizcloud.info" || mainUrl == "https://vizcloud.digital" | ||||
|                 } else if ( | ||||
|                     arrayOf( | ||||
|                         "https://vidstream.pro", | ||||
|                         "https://vidstreamz.online", | ||||
|                         "https://vizcloud2.online", | ||||
|                         "https://vizcloud.xyz", | ||||
|                         "https://vizcloud.live", | ||||
|                         "https://vizcloud.info", | ||||
|                         "https://mwvn.vizcloud.info", | ||||
|                         "https://vizcloud.digital" | ||||
|                     ).contains(mainUrl) | ||||
|                 ) { | ||||
|                     if (it.file.contains("m3u8")) { | ||||
|                         generateM3u8( | ||||
|                             name, | ||||
|                             it.file.replace("#.mp4", ""), | ||||
|                             url, | ||||
|                             headers = mapOf("Referer" to url) | ||||
|                         sources.addAll( | ||||
|                             generateM3u8( | ||||
|                                 name, | ||||
|                                 it.file.replace("#.mp4", ""), | ||||
|                                 url, | ||||
|                                 headers = mapOf("Referer" to url) | ||||
|                             ) | ||||
|                         ) | ||||
|                     } else { | ||||
|                         sources.add( | ||||
|  |  | |||
|  | @ -199,7 +199,10 @@ class DramaSeeProvider : MainAPI() { | |||
|                     url.startsWith("https://asianembed.io") || url.startsWith("https://asianload.io") -> { | ||||
|                         val iv = "9262859232435825" | ||||
|                         val secretKey = "93422192433952489752342908585752" | ||||
|                         extractVidstream(url, this.name, callback, iv, secretKey, secretKey, false) | ||||
|                         extractVidstream(url, this.name, callback, iv, secretKey, secretKey, | ||||
|                             isUsingAdaptiveKeys = false, | ||||
|                             isUsingAdaptiveData = false | ||||
|                         ) | ||||
|                         AsianEmbedHelper.getUrls(url, callback) | ||||
|                     } | ||||
|                     url.startsWith("https://embedsito.com") -> { | ||||
|  |  | |||
|  | @ -69,6 +69,11 @@ open class VidstreamProviderTemplate : MainAPI() { | |||
|     open val secretDecryptKey: String? = null | ||||
|     /** Generated the key from IV and ID */ | ||||
|     open val isUsingAdaptiveKeys: Boolean = false | ||||
|     /** | ||||
|      * Generate data for the encrypt-ajax automatically (only on supported sites) | ||||
|      * See $("script[data-name='episode']")[0].dataset.value | ||||
|      * */ | ||||
|     open val isUsingAdaptiveData: Boolean = false | ||||
| 
 | ||||
| 
 | ||||
| //    // mainUrl is good to have as a holder for the url to make future changes easier. | ||||
|  | @ -255,7 +260,7 @@ open class VidstreamProviderTemplate : MainAPI() { | |||
|         val iframeLink = | ||||
|             Jsoup.parse(app.get(data).text).selectFirst("iframe")?.attr("src") ?: return false | ||||
| 
 | ||||
|         extractVidstream(iframeLink, this.name, callback, iv, secretKey, secretDecryptKey, isUsingAdaptiveKeys) | ||||
|         extractVidstream(iframeLink, this.name, callback, iv, secretKey, secretDecryptKey, isUsingAdaptiveKeys, isUsingAdaptiveData) | ||||
|         // In this case the video player is a vidstream clone and can be handled by the vidstream extractor. | ||||
|         // This case is a both unorthodox and you normally do not call extractors as they detect the url returned and does the rest. | ||||
|         val vidstreamObject = Vidstream(vidstreamExtractorUrl ?: mainUrl) | ||||
|  |  | |||
|  | @ -216,7 +216,10 @@ class WatchAsianProvider : MainAPI() { | |||
|                 url.startsWith("https://asianembed.io") || url.startsWith("https://asianload.io") -> { | ||||
|                     val iv = "9262859232435825" | ||||
|                     val secretKey = "93422192433952489752342908585752" | ||||
|                     extractVidstream(url, this.name, callback, iv, secretKey, secretKey, false) | ||||
|                     extractVidstream(url, this.name, callback, iv, secretKey, secretKey, | ||||
|                         isUsingAdaptiveKeys = false, | ||||
|                         isUsingAdaptiveData = false | ||||
|                     ) | ||||
|                     AsianEmbedHelper.getUrls(url, callback) | ||||
|                 } | ||||
|                 url.startsWith("https://embedsito.com") -> { | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue