forked from recloudstream/cloudstream
		
	refactor on m3u8
This commit is contained in:
		
							parent
							
								
									615b81f600
								
							
						
					
					
						commit
						510411a9bc
					
				
					 15 changed files with 189 additions and 249 deletions
				
			
		|  | @ -8,7 +8,7 @@ import com.lagradost.cloudstream3.mvvm.safeApiCall | ||||||
| import com.lagradost.cloudstream3.utils.AppUtils.parseJson | import com.lagradost.cloudstream3.utils.AppUtils.parseJson | ||||||
| import com.lagradost.cloudstream3.utils.ExtractorLink | import com.lagradost.cloudstream3.utils.ExtractorLink | ||||||
| import com.lagradost.cloudstream3.utils.M3u8Helper | import com.lagradost.cloudstream3.utils.M3u8Helper | ||||||
| import com.lagradost.cloudstream3.utils.getQualityFromName | import com.lagradost.cloudstream3.utils.Qualities | ||||||
| import org.jsoup.Jsoup | import org.jsoup.Jsoup | ||||||
| import org.mozilla.javascript.Context | import org.mozilla.javascript.Context | ||||||
| import org.mozilla.javascript.Scriptable | import org.mozilla.javascript.Scriptable | ||||||
|  | @ -22,8 +22,6 @@ class AllAnimeProvider : MainAPI() { | ||||||
|     override val hasQuickSearch = false |     override val hasQuickSearch = false | ||||||
|     override val hasMainPage = true |     override val hasMainPage = true | ||||||
| 
 | 
 | ||||||
|     private val hlsHelper = M3u8Helper() |  | ||||||
| 
 |  | ||||||
|     private fun getStatus(t: String): ShowStatus { |     private fun getStatus(t: String): ShowStatus { | ||||||
|         return when (t) { |         return when (t) { | ||||||
|             "Finished" -> ShowStatus.Completed |             "Finished" -> ShowStatus.Completed | ||||||
|  | @ -125,7 +123,7 @@ class AllAnimeProvider : MainAPI() { | ||||||
|         val ranlink = app.get(random).text |         val ranlink = app.get(random).text | ||||||
|         val jsonran = parseJson<RandomMain>(ranlink) |         val jsonran = parseJson<RandomMain>(ranlink) | ||||||
|         val ranhome = jsonran.data?.queryRandomRecommendation?.map { |         val ranhome = jsonran.data?.queryRandomRecommendation?.map { | ||||||
|             newAnimeSearchResponse(it.name!!,"$mainUrl/anime/${it.Id}", fix = false) { |             newAnimeSearchResponse(it.name!!, "$mainUrl/anime/${it.Id}", fix = false) { | ||||||
|                 this.posterUrl = it.thumbnail |                 this.posterUrl = it.thumbnail | ||||||
|                 this.otherName = it.nativeName |                 this.otherName = it.nativeName | ||||||
|             } |             } | ||||||
|  | @ -319,19 +317,13 @@ class AllAnimeProvider : MainAPI() { | ||||||
|         referer: String, |         referer: String, | ||||||
|         qualityName: String, |         qualityName: String, | ||||||
|     ): List<ExtractorLink> { |     ): List<ExtractorLink> { | ||||||
|         return hlsHelper.m3u8Generation(M3u8Helper.M3u8Stream(m3u8Link, null), true).map { stream -> |         return M3u8Helper.generateM3u8( | ||||||
|             val qualityString = if ((stream.quality ?: 0) == 0) "" else "${stream.quality}p" |  | ||||||
|             ExtractorLink( |  | ||||||
|             this.name, |             this.name, | ||||||
|                 "${this.name} - $qualityName $qualityString", |             m3u8Link, | ||||||
|                 stream.streamUrl, |  | ||||||
|             referer, |             referer, | ||||||
|                 getQualityFromName(stream.quality.toString()), |             name = "${this.name} - $qualityName" | ||||||
|                 true, |  | ||||||
|                 stream.headers |  | ||||||
|         ) |         ) | ||||||
|     } |     } | ||||||
|     } |  | ||||||
| 
 | 
 | ||||||
|     override suspend fun loadLinks( |     override suspend fun loadLinks( | ||||||
|         data: String, |         data: String, | ||||||
|  | @ -366,7 +358,7 @@ class AllAnimeProvider : MainAPI() { | ||||||
|                                     "", |                                     "", | ||||||
|                                     link, |                                     link, | ||||||
|                                     data, |                                     data, | ||||||
|                                     getQualityFromName("1080"), |                                     Qualities.P1080.value, | ||||||
|                                     false |                                     false | ||||||
|                                 ) |                                 ) | ||||||
|                             ) |                             ) | ||||||
|  | @ -396,7 +388,7 @@ class AllAnimeProvider : MainAPI() { | ||||||
|                                         "$apiEndPoint/player?uri=" + (if (URI(server.link).host.isNotEmpty()) server.link else apiEndPoint + URI( |                                         "$apiEndPoint/player?uri=" + (if (URI(server.link).host.isNotEmpty()) server.link else apiEndPoint + URI( | ||||||
|                                             server.link |                                             server.link | ||||||
|                                         ).path), |                                         ).path), | ||||||
|                                         getQualityFromName("1080"), |                                         Qualities.P1080.value, | ||||||
|                                         false |                                         false | ||||||
|                                     ) |                                     ) | ||||||
|                                 ) |                                 ) | ||||||
|  |  | ||||||
|  | @ -124,35 +124,21 @@ class GogoanimeProvider : MainAPI() { | ||||||
|             ) { |             ) { | ||||||
|                 when { |                 when { | ||||||
|                     source.file.contains("m3u8") -> { |                     source.file.contains("m3u8") -> { | ||||||
|                         M3u8Helper().m3u8Generation( |                         M3u8Helper.generateM3u8( | ||||||
|                             M3u8Helper.M3u8Stream( |  | ||||||
|                                 source.file, |  | ||||||
|                                 headers = mapOf("Referer" to "https://gogoplay4.com") |  | ||||||
|                             ), true |  | ||||||
|                         ) |  | ||||||
|                             .map { stream -> |  | ||||||
|                                 val qualityString = |  | ||||||
|                                     if ((stream.quality ?: 0) == 0) "" else "${stream.quality}p" |  | ||||||
|                                 sourceCallback( |  | ||||||
|                                     ExtractorLink( |  | ||||||
|                             mainApiName, |                             mainApiName, | ||||||
|                                         "$mainApiName $qualityString", |                             source.file, | ||||||
|                                         stream.streamUrl, |  | ||||||
|                             mainUrl, |                             mainUrl, | ||||||
|                                         getQualityFromName(stream.quality.toString()), |                             headers = mapOf("Referer" to "https://gogoplay4.com") | ||||||
|                                         true |                         ).forEach (sourceCallback) | ||||||
|                                     ) |  | ||||||
|                                 ) |  | ||||||
|                             } |  | ||||||
|                     } |                     } | ||||||
|                     source.file.contains("vidstreaming") -> { |                     source.file.contains("vidstreaming") -> { | ||||||
|                         sourceCallback.invoke( |                         sourceCallback.invoke( | ||||||
|                             ExtractorLink( |                             ExtractorLink( | ||||||
|                                 mainApiName, |                                 mainApiName, | ||||||
|                                 "$mainApiName ${source.label?.replace("0 P", "0p") ?: ""}", |                                 mainApiName, | ||||||
|                                 source.file, |                                 source.file, | ||||||
|                                 mainUrl, |                                 mainUrl, | ||||||
|                                 getQualityFromName(source.label ?: ""), |                                 getQualityFromName(source.label), | ||||||
|                                 isM3u8 = source.type == "hls" |                                 isM3u8 = source.type == "hls" | ||||||
|                             ) |                             ) | ||||||
|                         ) |                         ) | ||||||
|  | @ -161,10 +147,10 @@ class GogoanimeProvider : MainAPI() { | ||||||
|                         sourceCallback.invoke( |                         sourceCallback.invoke( | ||||||
|                             ExtractorLink( |                             ExtractorLink( | ||||||
|                                 mainApiName, |                                 mainApiName, | ||||||
|                                 "$mainApiName ${source.label?.replace("0 P", "0p") ?: ""}", |                                 mainApiName, | ||||||
|                                 source.file, |                                 source.file, | ||||||
|                                 mainUrl, |                                 mainUrl, | ||||||
|                                 getQualityFromName(source.label ?: ""), |                                 getQualityFromName(source.label), | ||||||
|                                 isM3u8 = source.type == "hls" |                                 isM3u8 = source.type == "hls" | ||||||
|                             ) |                             ) | ||||||
|                         ) |                         ) | ||||||
|  | @ -372,7 +358,7 @@ class GogoanimeProvider : MainAPI() { | ||||||
|                         callback( |                         callback( | ||||||
|                             ExtractorLink( |                             ExtractorLink( | ||||||
|                                 "Gogoanime", |                                 "Gogoanime", | ||||||
|                                 if (qual == "null") "Gogoanime" else "Gogoanime - " + qual + "p", |                                 "Gogoanime", | ||||||
|                                 it.attr("href"), |                                 it.attr("href"), | ||||||
|                                 page.url, |                                 page.url, | ||||||
|                                 getQualityFromName(qual), |                                 getQualityFromName(qual), | ||||||
|  |  | ||||||
|  | @ -150,7 +150,7 @@ class KawaiifuProvider : MainAPI() { | ||||||
|                 callback( |                 callback( | ||||||
|                     ExtractorLink( |                     ExtractorLink( | ||||||
|                         "Kawaiifu", |                         "Kawaiifu", | ||||||
|                         "${it.first} - ${source.second}", |                         it.first, | ||||||
|                         source.first, |                         source.first, | ||||||
|                         "", |                         "", | ||||||
|                         getQualityFromName(source.second), |                         getQualityFromName(source.second), | ||||||
|  |  | ||||||
|  | @ -333,7 +333,7 @@ class TenshiProvider : MainAPI() { | ||||||
|                 sources.addAll(qualities.map { |                 sources.addAll(qualities.map { | ||||||
|                     ExtractorLink( |                     ExtractorLink( | ||||||
|                         this.name, |                         this.name, | ||||||
|                         "${this.name} $release - " + it.size + "p", |                         "${this.name} $release", | ||||||
|                         fixUrl(it.src), |                         fixUrl(it.src), | ||||||
|                         this.mainUrl, |                         this.mainUrl, | ||||||
|                         getQualityFromName("${it.size}"), |                         getQualityFromName("${it.size}"), | ||||||
|  |  | ||||||
|  | @ -1,7 +1,10 @@ | ||||||
| package com.lagradost.cloudstream3.extractors | package com.lagradost.cloudstream3.extractors | ||||||
| 
 | 
 | ||||||
| import com.lagradost.cloudstream3.app | import com.lagradost.cloudstream3.app | ||||||
| import com.lagradost.cloudstream3.utils.* | import com.lagradost.cloudstream3.utils.ExtractorApi | ||||||
|  | import com.lagradost.cloudstream3.utils.ExtractorLink | ||||||
|  | import com.lagradost.cloudstream3.utils.M3u8Helper | ||||||
|  | import com.lagradost.cloudstream3.utils.getQualityFromName | ||||||
| import java.net.URI | import java.net.URI | ||||||
| 
 | 
 | ||||||
| class AsianLoad : ExtractorApi() { | class AsianLoad : ExtractorApi() { | ||||||
|  | @ -17,32 +20,22 @@ class AsianLoad : ExtractorApi() { | ||||||
|                 val extractedUrl = sourceMatch.groupValues[1] |                 val extractedUrl = sourceMatch.groupValues[1] | ||||||
|                 // Trusting this isn't mp4, may fuck up stuff |                 // Trusting this isn't mp4, may fuck up stuff | ||||||
|                 if (URI(extractedUrl).path.endsWith(".m3u8")) { |                 if (URI(extractedUrl).path.endsWith(".m3u8")) { | ||||||
|                     M3u8Helper().m3u8Generation( |                     M3u8Helper.generateM3u8( | ||||||
|                         M3u8Helper.M3u8Stream( |  | ||||||
|                             extractedUrl, |  | ||||||
|                             headers = mapOf("referer" to this.url) |  | ||||||
|                         ), true |  | ||||||
|                     ) |  | ||||||
|                         .forEach { stream -> |  | ||||||
|                             extractedLinksList.add( |  | ||||||
|                                 ExtractorLink( |  | ||||||
|                         name, |                         name, | ||||||
|                                     name = name, |                         extractedUrl, | ||||||
|                                     stream.streamUrl, |  | ||||||
|                         url, |                         url, | ||||||
|                                     getQualityFromName(stream.quality?.toString()), |                         headers = mapOf("referer" to this.url) | ||||||
|                                     true |                     ).forEach { link -> | ||||||
|                                 ) |                         extractedLinksList.add(link) | ||||||
|                             ) |  | ||||||
|                     } |                     } | ||||||
|                 } else if (extractedUrl.endsWith(".mp4")) { |                 } else if (extractedUrl.endsWith(".mp4")) { | ||||||
|                     extractedLinksList.add( |                     extractedLinksList.add( | ||||||
|                         ExtractorLink( |                         ExtractorLink( | ||||||
|                             name, |                             name, | ||||||
|                             "$name ${sourceMatch.groupValues[2]}", |                             name, | ||||||
|                             extractedUrl, |                             extractedUrl, | ||||||
|                             url.replace(" ", "%20"), |                             url.replace(" ", "%20"), | ||||||
|                             Qualities.Unknown.value, |                             getQualityFromName(sourceMatch.groupValues[2]), | ||||||
|                         ) |                         ) | ||||||
|                     ) |                     ) | ||||||
|                 } |                 } | ||||||
|  |  | ||||||
|  | @ -1,14 +1,10 @@ | ||||||
| package com.lagradost.cloudstream3.extractors | package com.lagradost.cloudstream3.extractors | ||||||
| 
 | 
 | ||||||
| import com.lagradost.cloudstream3.apmap |  | ||||||
| import com.lagradost.cloudstream3.app | import com.lagradost.cloudstream3.app | ||||||
| import com.lagradost.cloudstream3.network.WebViewResolver | import com.lagradost.cloudstream3.network.WebViewResolver | ||||||
| import com.lagradost.cloudstream3.utils.ExtractorApi | import com.lagradost.cloudstream3.utils.ExtractorApi | ||||||
| import com.lagradost.cloudstream3.utils.ExtractorLink | import com.lagradost.cloudstream3.utils.ExtractorLink | ||||||
| import com.lagradost.cloudstream3.utils.M3u8Helper | import com.lagradost.cloudstream3.utils.M3u8Helper | ||||||
| import com.lagradost.cloudstream3.utils.getQualityFromName |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| open class GenericM3U8 : ExtractorApi() { | open class GenericM3U8 : ExtractorApi() { | ||||||
|  | @ -23,21 +19,14 @@ open class GenericM3U8 : ExtractorApi() { | ||||||
|             ) |             ) | ||||||
|         ) |         ) | ||||||
|         val sources = mutableListOf<ExtractorLink>() |         val sources = mutableListOf<ExtractorLink>() | ||||||
|         if (response.url.contains("m3u8")) M3u8Helper().m3u8Generation( |         if (response.url.contains("m3u8")) | ||||||
|             M3u8Helper.M3u8Stream( |             M3u8Helper.generateM3u8( | ||||||
|                 response.url, |  | ||||||
|                 headers = response.headers.toMap() |  | ||||||
|             ), true |  | ||||||
|         ) |  | ||||||
|             .map { stream -> |  | ||||||
|                 sources.add( ExtractorLink( |  | ||||||
|                 name, |                 name, | ||||||
|                     name = name, |                 response.url, | ||||||
|                     stream.streamUrl, |  | ||||||
|                 url, |                 url, | ||||||
|                     getQualityFromName(stream.quality?.toString()), |                 headers = response.headers.toMap() | ||||||
|                     true |             ).forEach { link -> | ||||||
|                 )) |                 sources.add(link) | ||||||
|             } |             } | ||||||
|         return sources |         return sources | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  | @ -1,8 +1,9 @@ | ||||||
| package com.lagradost.cloudstream3.extractors | package com.lagradost.cloudstream3.extractors | ||||||
| 
 | 
 | ||||||
| import com.lagradost.cloudstream3.apmap |  | ||||||
| import com.lagradost.cloudstream3.utils.* |  | ||||||
| import com.lagradost.cloudstream3.app | import com.lagradost.cloudstream3.app | ||||||
|  | import com.lagradost.cloudstream3.utils.ExtractorApi | ||||||
|  | import com.lagradost.cloudstream3.utils.ExtractorLink | ||||||
|  | import com.lagradost.cloudstream3.utils.M3u8Helper | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| open class Jawcloud : ExtractorApi() { | open class Jawcloud : ExtractorApi() { | ||||||
|  | @ -14,22 +15,13 @@ open class Jawcloud : ExtractorApi() { | ||||||
|         val doc = app.get(url).document |         val doc = app.get(url).document | ||||||
|         val urlString = doc.select("html body div source").attr("src") |         val urlString = doc.select("html body div source").attr("src") | ||||||
|         val sources = mutableListOf<ExtractorLink>() |         val sources = mutableListOf<ExtractorLink>() | ||||||
|         if (urlString.contains("m3u8"))  M3u8Helper().m3u8Generation( |         if (urlString.contains("m3u8")) | ||||||
|             M3u8Helper.M3u8Stream( |             M3u8Helper.generateM3u8( | ||||||
|                 urlString, |  | ||||||
|                 headers = app.get(url).headers.toMap() |  | ||||||
|             ), true |  | ||||||
|         ) |  | ||||||
|             .map { stream -> |  | ||||||
|                 sources.add(  ExtractorLink( |  | ||||||
|                 name, |                 name, | ||||||
|                     name = name, |                 urlString, | ||||||
|                     stream.streamUrl, |  | ||||||
|                 url, |                 url, | ||||||
|                     getQualityFromName(stream.quality?.toString()), |                 headers = app.get(url).headers.toMap() | ||||||
|                     true |             ).forEach { link -> sources.add(link) } | ||||||
|                 )) |  | ||||||
|             } |  | ||||||
|         return sources |         return sources | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  | @ -8,7 +8,6 @@ import com.lagradost.cloudstream3.utils.AppUtils.parseJson | ||||||
| import com.lagradost.cloudstream3.utils.ExtractorApi | import com.lagradost.cloudstream3.utils.ExtractorApi | ||||||
| import com.lagradost.cloudstream3.utils.ExtractorLink | import com.lagradost.cloudstream3.utils.ExtractorLink | ||||||
| import com.lagradost.cloudstream3.utils.M3u8Helper | import com.lagradost.cloudstream3.utils.M3u8Helper | ||||||
| import com.lagradost.cloudstream3.utils.getQualityFromName |  | ||||||
| 
 | 
 | ||||||
| open class Mcloud : ExtractorApi() { | open class Mcloud : ExtractorApi() { | ||||||
|     override var name = "Mcloud" |     override var name = "Mcloud" | ||||||
|  | @ -56,23 +55,13 @@ open class Mcloud : ExtractorApi() { | ||||||
|         if (mapped.success) |         if (mapped.success) | ||||||
|             mapped.media.sources.apmap { |             mapped.media.sources.apmap { | ||||||
|                 if (it.file.contains("m3u8")) { |                 if (it.file.contains("m3u8")) { | ||||||
|                     M3u8Helper().m3u8Generation( |                     M3u8Helper.generateM3u8( | ||||||
|                         M3u8Helper.M3u8Stream( |  | ||||||
|                             it.file, |  | ||||||
|                             headers = app.get(url).headers.toMap() |  | ||||||
|                         ), true |  | ||||||
|                     ) |  | ||||||
|                         .map { stream -> |  | ||||||
|                             sources.add( |  | ||||||
|                                 ExtractorLink( |  | ||||||
|                         name, |                         name, | ||||||
|                                     name = name, |                         it.file, | ||||||
|                                     stream.streamUrl, |  | ||||||
|                         url, |                         url, | ||||||
|                                     getQualityFromName(stream.quality?.toString()), |                         headers = app.get(url).headers.toMap() | ||||||
|                                     true |                     ).forEach { link -> | ||||||
|                                 ) |                         sources.add(link) | ||||||
|                             ) |  | ||||||
|                     } |                     } | ||||||
|                 } |                 } | ||||||
|             } |             } | ||||||
|  |  | ||||||
|  | @ -1,8 +1,9 @@ | ||||||
| package com.lagradost.cloudstream3.extractors | package com.lagradost.cloudstream3.extractors | ||||||
| 
 | 
 | ||||||
| import com.lagradost.cloudstream3.apmap |  | ||||||
| import com.lagradost.cloudstream3.utils.* |  | ||||||
| import com.lagradost.cloudstream3.app | import com.lagradost.cloudstream3.app | ||||||
|  | import com.lagradost.cloudstream3.utils.ExtractorApi | ||||||
|  | import com.lagradost.cloudstream3.utils.ExtractorLink | ||||||
|  | import com.lagradost.cloudstream3.utils.M3u8Helper | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| open class PlayerVoxzer : ExtractorApi() { | open class PlayerVoxzer : ExtractorApi() { | ||||||
|  | @ -16,21 +17,14 @@ open class PlayerVoxzer : ExtractorApi() { | ||||||
|         val m3u8regex = Regex("((https:|http:)\\/\\/.*\\.m3u8)") |         val m3u8regex = Regex("((https:|http:)\\/\\/.*\\.m3u8)") | ||||||
|         val sources = mutableListOf<ExtractorLink>() |         val sources = mutableListOf<ExtractorLink>() | ||||||
|         val listm3 = m3u8regex.find(urltext)?.value |         val listm3 = m3u8regex.find(urltext)?.value | ||||||
|         if (listm3?.contains("m3u8") == true)  M3u8Helper().m3u8Generation( |         if (listm3?.contains("m3u8") == true) | ||||||
|             M3u8Helper.M3u8Stream( |             M3u8Helper.generateM3u8( | ||||||
|                 listm3, |  | ||||||
|                 headers = app.get(url).headers.toMap() |  | ||||||
|             ), true |  | ||||||
|         ) |  | ||||||
|             .map { stream -> |  | ||||||
|                 sources.add(  ExtractorLink( |  | ||||||
|                 name, |                 name, | ||||||
|                     name = name, |                 listm3, | ||||||
|                     stream.streamUrl, |  | ||||||
|                 url, |                 url, | ||||||
|                     getQualityFromName(stream.quality?.toString()), |                 headers = app.get(url).headers.toMap() | ||||||
|                     true |             ).forEach { link -> | ||||||
|                 )) |                 sources.add(link) | ||||||
|             } |             } | ||||||
|         return sources |         return sources | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  | @ -1,11 +1,11 @@ | ||||||
| package com.lagradost.cloudstream3.extractors | package com.lagradost.cloudstream3.extractors | ||||||
| 
 | 
 | ||||||
| import com.fasterxml.jackson.annotation.JsonProperty | import com.fasterxml.jackson.annotation.JsonProperty | ||||||
| import com.lagradost.cloudstream3.USER_AGENT |  | ||||||
| import com.lagradost.cloudstream3.apmap |  | ||||||
| import com.lagradost.cloudstream3.utils.* |  | ||||||
| import com.lagradost.cloudstream3.app | import com.lagradost.cloudstream3.app | ||||||
| import com.lagradost.cloudstream3.utils.AppUtils.parseJson | import com.lagradost.cloudstream3.utils.AppUtils.parseJson | ||||||
|  | import com.lagradost.cloudstream3.utils.ExtractorApi | ||||||
|  | import com.lagradost.cloudstream3.utils.ExtractorLink | ||||||
|  | import com.lagradost.cloudstream3.utils.M3u8Helper | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| class StreamSB1 : StreamSB() { | class StreamSB1 : StreamSB() { | ||||||
|  | @ -103,23 +103,13 @@ open class StreamSB : ExtractorApi() { | ||||||
|         val mapped = urltext.let { parseJson<Main>(it) } |         val mapped = urltext.let { parseJson<Main>(it) } | ||||||
|         val testurl = app.get(mapped.streamData.file, headers = headers).text |         val testurl = app.get(mapped.streamData.file, headers = headers).text | ||||||
|         // val urlmain = mapped.streamData.file.substringBefore("/hls/") |         // val urlmain = mapped.streamData.file.substringBefore("/hls/") | ||||||
|         if (urltext.contains("m3u8") && testurl.contains("EXTM3U")) return  M3u8Helper().m3u8Generation( |         if (urltext.contains("m3u8") && testurl.contains("EXTM3U")) | ||||||
|             M3u8Helper.M3u8Stream( |             return M3u8Helper.generateM3u8( | ||||||
|                 mapped.streamData.file, |  | ||||||
|                 headers = headers |  | ||||||
|             ), true |  | ||||||
|         ) |  | ||||||
|             .map { stream -> |  | ||||||
|                // val cleanstreamurl = stream.streamUrl.replace(Regex("https://.*/hls/"), "$urlmain/hls/") |  | ||||||
|                 ExtractorLink( |  | ||||||
|                 name, |                 name, | ||||||
|                     name = name, |                 mapped.streamData.file, | ||||||
|                     stream.streamUrl, |  | ||||||
|                 url, |                 url, | ||||||
|                     getQualityFromName(stream.quality?.toString()), |                 headers = headers | ||||||
|                     true |  | ||||||
|             ) |             ) | ||||||
|             } |  | ||||||
|         return null |         return null | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  | @ -4,8 +4,7 @@ import com.lagradost.cloudstream3.app | ||||||
| import com.lagradost.cloudstream3.network.WebViewResolver | import com.lagradost.cloudstream3.network.WebViewResolver | ||||||
| import com.lagradost.cloudstream3.utils.ExtractorApi | import com.lagradost.cloudstream3.utils.ExtractorApi | ||||||
| import com.lagradost.cloudstream3.utils.ExtractorLink | import com.lagradost.cloudstream3.utils.ExtractorLink | ||||||
| import com.lagradost.cloudstream3.utils.M3u8Helper | import com.lagradost.cloudstream3.utils.M3u8Helper.Companion.generateM3u8 | ||||||
| import com.lagradost.cloudstream3.utils.getQualityFromName |  | ||||||
| 
 | 
 | ||||||
| open class WatchSB : ExtractorApi() { | open class WatchSB : ExtractorApi() { | ||||||
|     override var name = "WatchSB" |     override var name = "WatchSB" | ||||||
|  | @ -19,21 +18,6 @@ open class WatchSB : ExtractorApi() { | ||||||
|             ) |             ) | ||||||
|         ) |         ) | ||||||
| 
 | 
 | ||||||
|         return M3u8Helper().m3u8Generation( |         return generateM3u8(name, response.url, url, headers = response.headers.toMap()) | ||||||
|             M3u8Helper.M3u8Stream( |  | ||||||
|                 response.url, |  | ||||||
|                 headers = response.headers.toMap() |  | ||||||
|             ), true |  | ||||||
|         ) |  | ||||||
|             .map { stream -> |  | ||||||
|                 ExtractorLink( |  | ||||||
|                     name, |  | ||||||
|                     name = name, |  | ||||||
|                     stream.streamUrl, |  | ||||||
|                     url, |  | ||||||
|                     getQualityFromName(stream.quality?.toString()), |  | ||||||
|                     true |  | ||||||
|                 ) |  | ||||||
|             } |  | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  | @ -5,11 +5,16 @@ import com.fasterxml.jackson.module.kotlin.readValue | ||||||
| import com.lagradost.cloudstream3.apmap | import com.lagradost.cloudstream3.apmap | ||||||
| import com.lagradost.cloudstream3.app | import com.lagradost.cloudstream3.app | ||||||
| import com.lagradost.cloudstream3.mapper | import com.lagradost.cloudstream3.mapper | ||||||
| import com.lagradost.cloudstream3.utils.* | import com.lagradost.cloudstream3.utils.ExtractorApi | ||||||
|  | import com.lagradost.cloudstream3.utils.ExtractorLink | ||||||
|  | import com.lagradost.cloudstream3.utils.M3u8Helper.Companion.generateM3u8 | ||||||
|  | import com.lagradost.cloudstream3.utils.Qualities | ||||||
|  | import com.lagradost.cloudstream3.utils.getQualityFromName | ||||||
| 
 | 
 | ||||||
| class Vidstreamz : WcoStream() { | class Vidstreamz : WcoStream() { | ||||||
|     override var mainUrl = "https://vidstreamz.online" |     override var mainUrl = "https://vidstreamz.online" | ||||||
| } | } | ||||||
|  | 
 | ||||||
| class Vizcloud : WcoStream() { | class Vizcloud : WcoStream() { | ||||||
|     override var mainUrl = "https://vizcloud2.ru" |     override var mainUrl = "https://vizcloud2.ru" | ||||||
| } | } | ||||||
|  | @ -46,14 +51,16 @@ 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 var mainUrl = "https://vidstream.pro" | ||||||
|     override val requiresReferer = false |     override val requiresReferer = false | ||||||
|     private val hlsHelper = M3u8Helper() |  | ||||||
| 
 | 
 | ||||||
|     override suspend fun getUrl(url: String, referer: String?): List<ExtractorLink> { |     override suspend fun getUrl(url: String, referer: String?): List<ExtractorLink> { | ||||||
|         val baseUrl = url.split("/e/")[0] |         val baseUrl = url.split("/e/")[0] | ||||||
| 
 | 
 | ||||||
|         val html = app.get(url, headers = mapOf("Referer" to "https://wcostream.cc/")).text |         val html = app.get(url, headers = mapOf("Referer" to "https://wcostream.cc/")).text | ||||||
|         val (Id) = (Regex("/e/(.*?)?domain").find(url)?.destructured ?: Regex("""/e/(.*)""").find(url)?.destructured) ?: return emptyList() |         val (Id) = (Regex("/e/(.*?)?domain").find(url)?.destructured ?: Regex("""/e/(.*)""").find( | ||||||
|         val (skey) = Regex("""skey\s=\s['"](.*?)['"];""").find(html)?.destructured ?: return emptyList() |             url | ||||||
|  |         )?.destructured) ?: return emptyList() | ||||||
|  |         val (skey) = Regex("""skey\s=\s['"](.*?)['"];""").find(html)?.destructured | ||||||
|  |             ?: return emptyList() | ||||||
| 
 | 
 | ||||||
|         val apiLink = "$baseUrl/info/$Id?domain=wcostream.cc&skey=$skey" |         val apiLink = "$baseUrl/info/$Id?domain=wcostream.cc&skey=$skey" | ||||||
|         val referrer = "$baseUrl/e/$Id?domain=wcostream.cc" |         val referrer = "$baseUrl/e/$Id?domain=wcostream.cc" | ||||||
|  | @ -82,17 +89,18 @@ open class WcoStream : ExtractorApi() { | ||||||
|                 if (mainUrl == "https://vizcloud2.ru" || mainUrl == "https://vizcloud.online") { |                 if (mainUrl == "https://vizcloud2.ru" || mainUrl == "https://vizcloud.online") { | ||||||
|                     if (it.file.contains("vizcloud2.ru") || it.file.contains("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 link1080 = it.file.replace("list.m3u8#.mp4", "H4/v.m3u8") | ||||||
|                         val link720 = it.file.replace("list.m3u8#.mp4","H3/v.m3u8") |                         val link720 = it.file.replace("list.m3u8#.mp4", "H3/v.m3u8") | ||||||
|                         val link480 = it.file.replace("list.m3u8#.mp4","H2/v.m3u8") |                         val link480 = it.file.replace("list.m3u8#.mp4", "H2/v.m3u8") | ||||||
|                         val link360 = it.file.replace("list.m3u8#.mp4","H1/v.m3u8") |                         val link360 = it.file.replace("list.m3u8#.mp4", "H1/v.m3u8") | ||||||
|                         val linkauto = it.file.replace("#.mp4","") |                         val linkauto = it.file.replace("#.mp4", "") | ||||||
|                         listOf( |                         listOf( | ||||||
|                             link1080, |                             link1080, | ||||||
|                             link720, |                             link720, | ||||||
|                             link480, |                             link480, | ||||||
|                             link360, |                             link360, | ||||||
|                             linkauto).apmap { serverurl -> |                             linkauto | ||||||
|  |                         ).apmap { serverurl -> | ||||||
|                             val testurl = app.get(serverurl, headers = mapOf("Referer" to url)).text |                             val testurl = app.get(serverurl, headers = mapOf("Referer" to url)).text | ||||||
|                             if (testurl.contains("EXTM3")) { |                             if (testurl.contains("EXTM3")) { | ||||||
|                                 val quality = if (serverurl.contains("H4")) "1080p" |                                 val quality = if (serverurl.contains("H4")) "1080p" | ||||||
|  | @ -116,22 +124,15 @@ open class WcoStream : ExtractorApi() { | ||||||
|                 } |                 } | ||||||
|                 if (mainUrl == "https://vidstream.pro" || mainUrl == "https://vidstreamz.online" || mainUrl == "https://vizcloud2.online" |                 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://vizcloud.xyz" || mainUrl == "https://vizcloud.live" || mainUrl == "https://vizcloud.info" | ||||||
|                      || mainUrl == "https://mwvn.vizcloud.info" || mainUrl == "https://vizcloud.digital") { |                     || mainUrl == "https://mwvn.vizcloud.info" || mainUrl == "https://vizcloud.digital" | ||||||
|  |                 ) { | ||||||
|                     if (it.file.contains("m3u8")) { |                     if (it.file.contains("m3u8")) { | ||||||
|                     hlsHelper.m3u8Generation(M3u8Helper.M3u8Stream(it.file.replace("#.mp4",""), null, |                         generateM3u8( | ||||||
|                     headers = mapOf("Referer" to url)), true) |  | ||||||
|                         .forEach { stream -> |  | ||||||
|                             sources.add( |  | ||||||
|                                 ExtractorLink( |  | ||||||
|                             name, |                             name, | ||||||
|                                     name = name, |                             it.file.replace("#.mp4", ""), | ||||||
|                                     stream.streamUrl, |  | ||||||
|                             url, |                             url, | ||||||
|                                     getQualityFromName(stream.quality?.toString()), |                             headers = mapOf("Referer" to url) | ||||||
|                                     true, |  | ||||||
|                         ) |                         ) | ||||||
|                             ) |  | ||||||
|                         } |  | ||||||
|                     } else { |                     } else { | ||||||
|                         sources.add( |                         sources.add( | ||||||
|                             ExtractorLink( |                             ExtractorLink( | ||||||
|  |  | ||||||
|  | @ -2,7 +2,10 @@ package com.lagradost.cloudstream3.extractors | ||||||
| 
 | 
 | ||||||
| import com.lagradost.cloudstream3.apmap | import com.lagradost.cloudstream3.apmap | ||||||
| import com.lagradost.cloudstream3.app | import com.lagradost.cloudstream3.app | ||||||
| import com.lagradost.cloudstream3.utils.* | import com.lagradost.cloudstream3.utils.ExtractorApi | ||||||
|  | import com.lagradost.cloudstream3.utils.ExtractorLink | ||||||
|  | import com.lagradost.cloudstream3.utils.M3u8Helper | ||||||
|  | import com.lagradost.cloudstream3.utils.getAndUnpack | ||||||
| 
 | 
 | ||||||
| class Zplayer: ZplayerV2() { | class Zplayer: ZplayerV2() { | ||||||
|     override var name: String = "Zplayer" |     override var name: String = "Zplayer" | ||||||
|  | @ -37,21 +40,13 @@ open class ZplayerV2 : ExtractorApi() { | ||||||
|                     if (urlm3u8.contains("m3u8")) { |                     if (urlm3u8.contains("m3u8")) { | ||||||
|                         val testurl = app.get(urlm3u8, headers = mapOf("Referer" to url)).text |                         val testurl = app.get(urlm3u8, headers = mapOf("Referer" to url)).text | ||||||
|                         if (testurl.contains("EXTM3U")) { |                         if (testurl.contains("EXTM3U")) { | ||||||
|                             M3u8Helper().m3u8Generation( |                             M3u8Helper.generateM3u8( | ||||||
|                                 M3u8Helper.M3u8Stream( |                                 name, | ||||||
|                                 urlm3u8, |                                 urlm3u8, | ||||||
|                                     headers = mapOf("Referer" to url) |  | ||||||
|                                 ), true |  | ||||||
|                             ) |  | ||||||
|                                 .map { stream -> |  | ||||||
|                                     sources.add(  ExtractorLink( |  | ||||||
|                                         source = name, |  | ||||||
|                                         name = name, |  | ||||||
|                                         stream.streamUrl, |  | ||||||
|                                 url, |                                 url, | ||||||
|                                         getQualityFromName(stream.quality?.toString()), |                                 headers = mapOf("Referer" to url) | ||||||
|                                         true |                             ).forEach { link -> | ||||||
|                                     )) |                                 sources.add(link) | ||||||
|                             } |                             } | ||||||
|                         } |                         } | ||||||
|                     } |                     } | ||||||
|  |  | ||||||
|  | @ -3,7 +3,6 @@ package com.lagradost.cloudstream3.movieproviders | ||||||
| import com.lagradost.cloudstream3.* | import com.lagradost.cloudstream3.* | ||||||
| import com.lagradost.cloudstream3.utils.ExtractorLink | import com.lagradost.cloudstream3.utils.ExtractorLink | ||||||
| import com.lagradost.cloudstream3.utils.M3u8Helper | import com.lagradost.cloudstream3.utils.M3u8Helper | ||||||
| import com.lagradost.cloudstream3.utils.getQualityFromName |  | ||||||
| import com.lagradost.cloudstream3.utils.loadExtractor | import com.lagradost.cloudstream3.utils.loadExtractor | ||||||
| import org.jsoup.Jsoup | import org.jsoup.Jsoup | ||||||
| 
 | 
 | ||||||
|  | @ -204,25 +203,14 @@ open class PelisplusProviderTemplate : MainAPI() { | ||||||
|         val soup = app.get(link).text |         val soup = app.get(link).text | ||||||
|         val m3u8regex = Regex("((https:|http:)\\/\\/.*m3u8.*expiry=(\\d+))") |         val m3u8regex = Regex("((https:|http:)\\/\\/.*m3u8.*expiry=(\\d+))") | ||||||
|         val m3u8 = m3u8regex.find(soup)?.value ?: return false |         val m3u8 = m3u8regex.find(soup)?.value ?: return false | ||||||
|         M3u8Helper().m3u8Generation( | 
 | ||||||
|             M3u8Helper.M3u8Stream( |         M3u8Helper.generateM3u8( | ||||||
|                 m3u8, |  | ||||||
|                 headers = mapOf("Referer" to mainUrl) |  | ||||||
|             ), true |  | ||||||
|         ) |  | ||||||
|             .map { stream -> |  | ||||||
|                 val qualityString = if ((stream.quality ?: 0) == 0) "" else "${stream.quality}p" |  | ||||||
|                 callback( |  | ||||||
|                     ExtractorLink( |  | ||||||
|             name, |             name, | ||||||
|                         "$name $qualityString", |             m3u8, | ||||||
|                         stream.streamUrl, |  | ||||||
|             mainUrl, |             mainUrl, | ||||||
|                         getQualityFromName(stream.quality.toString()), |             headers = mapOf("Referer" to mainUrl) | ||||||
|                         true |         ).forEach (callback) | ||||||
|                     ) | 
 | ||||||
|                 ) |  | ||||||
|             } |  | ||||||
|         return true |         return true | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -10,13 +10,47 @@ import kotlin.math.pow | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| class M3u8Helper { | class M3u8Helper { | ||||||
|  |     companion object { | ||||||
|  |         private val generator = M3u8Helper() | ||||||
|  |         fun generateM3u8( | ||||||
|  |             source: String, | ||||||
|  |             streamUrl: String, | ||||||
|  |             referer: String, | ||||||
|  |             quality: Int? = null, | ||||||
|  |             headers: Map<String, String> = mapOf(), | ||||||
|  |             name: String = source | ||||||
|  |         ): List<ExtractorLink> { | ||||||
|  |             return generator.m3u8Generation( | ||||||
|  |                 M3u8Stream( | ||||||
|  |                     streamUrl = streamUrl, | ||||||
|  |                     quality = quality, | ||||||
|  |                     headers = headers, | ||||||
|  |                 ), true | ||||||
|  |             ) | ||||||
|  |                 .map { stream -> | ||||||
|  |                     ExtractorLink( | ||||||
|  |                         source, | ||||||
|  |                         name = name, | ||||||
|  |                         stream.streamUrl, | ||||||
|  |                         referer, | ||||||
|  |                         stream.quality ?: Qualities.Unknown.value, | ||||||
|  |                         true, | ||||||
|  |                         stream.headers, | ||||||
|  |                     ) | ||||||
|  |                 } | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|     private val ENCRYPTION_DETECTION_REGEX = Regex("#EXT-X-KEY:METHOD=([^,]+),") |     private val ENCRYPTION_DETECTION_REGEX = Regex("#EXT-X-KEY:METHOD=([^,]+),") | ||||||
|     private val ENCRYPTION_URL_IV_REGEX = Regex("#EXT-X-KEY:METHOD=([^,]+),URI=\"([^\"]+)\"(?:,IV=(.*))?") |     private val ENCRYPTION_URL_IV_REGEX = | ||||||
|  |         Regex("#EXT-X-KEY:METHOD=([^,]+),URI=\"([^\"]+)\"(?:,IV=(.*))?") | ||||||
|     private val QUALITY_REGEX = |     private val QUALITY_REGEX = | ||||||
|         Regex("""#EXT-X-STREAM-INF:(?:(?:.*?(?:RESOLUTION=\d+x(\d+)).*?\s+(.*))|(?:.*?\s+(.*)))""") |         Regex("""#EXT-X-STREAM-INF:(?:(?:.*?(?:RESOLUTION=\d+x(\d+)).*?\s+(.*))|(?:.*?\s+(.*)))""") | ||||||
|     private val TS_EXTENSION_REGEX = Regex("""(.*\.ts.*|.*\.jpg.*)""") //.jpg here 'case vizcloud uses .jpg instead of .ts |     private val TS_EXTENSION_REGEX = | ||||||
|  |         Regex("""(.*\.ts.*|.*\.jpg.*)""") //.jpg here 'case vizcloud uses .jpg instead of .ts | ||||||
| 
 | 
 | ||||||
|     fun absoluteExtensionDetermination(url: String): String? { |     private fun absoluteExtensionDetermination(url: String): String? { | ||||||
|         val split = url.split("/") |         val split = url.split("/") | ||||||
|         val gg: String = split[split.size - 1].split("?")[0] |         val gg: String = split[split.size - 1].split("?")[0] | ||||||
|         return if (gg.contains(".")) { |         return if (gg.contains(".")) { | ||||||
|  | @ -40,7 +74,11 @@ class M3u8Helper { | ||||||
|         } |         } | ||||||
|     }.iterator() |     }.iterator() | ||||||
| 
 | 
 | ||||||
|     private fun getDecrypter(secretKey: ByteArray, data: ByteArray, iv: ByteArray = "".toByteArray()): ByteArray { |     private fun getDecrypter( | ||||||
|  |         secretKey: ByteArray, | ||||||
|  |         data: ByteArray, | ||||||
|  |         iv: ByteArray = "".toByteArray() | ||||||
|  |     ): ByteArray { | ||||||
|         val ivKey = if (iv.isEmpty()) defaultIvGen.next() else iv |         val ivKey = if (iv.isEmpty()) defaultIvGen.next() else iv | ||||||
|         val c = Cipher.getInstance("AES/CBC/PKCS5Padding") |         val c = Cipher.getInstance("AES/CBC/PKCS5Padding") | ||||||
|         val skSpec = SecretKeySpec(secretKey, "AES") |         val skSpec = SecretKeySpec(secretKey, "AES") | ||||||
|  | @ -135,7 +173,14 @@ class M3u8Helper { | ||||||
|     ) |     ) | ||||||
| 
 | 
 | ||||||
|     fun hlsYield(qualities: List<M3u8Stream>, startIndex: Int = 0): Iterator<HlsDownloadData> { |     fun hlsYield(qualities: List<M3u8Stream>, startIndex: Int = 0): Iterator<HlsDownloadData> { | ||||||
|         if (qualities.isEmpty()) return listOf(HlsDownloadData(byteArrayOf(), 1, 1, true)).iterator() |         if (qualities.isEmpty()) return listOf( | ||||||
|  |             HlsDownloadData( | ||||||
|  |                 byteArrayOf(), | ||||||
|  |                 1, | ||||||
|  |                 1, | ||||||
|  |                 true | ||||||
|  |             ) | ||||||
|  |         ).iterator() | ||||||
| 
 | 
 | ||||||
|         var selected = selectBest(qualities) |         var selected = selectBest(qualities) | ||||||
|         if (selected == null) { |         if (selected == null) { | ||||||
|  | @ -148,7 +193,8 @@ class M3u8Helper { | ||||||
| 
 | 
 | ||||||
|         val secondSelection = selectBest(streams.ifEmpty { listOf(selected) }) |         val secondSelection = selectBest(streams.ifEmpty { listOf(selected) }) | ||||||
|         if (secondSelection != null) { |         if (secondSelection != null) { | ||||||
|             val m3u8Response = runBlocking {app.get(secondSelection.streamUrl, headers = headers).text} |             val m3u8Response = | ||||||
|  |                 runBlocking { app.get(secondSelection.streamUrl, headers = headers).text } | ||||||
| 
 | 
 | ||||||
|             var encryptionUri: String? |             var encryptionUri: String? | ||||||
|             var encryptionIv = byteArrayOf() |             var encryptionIv = byteArrayOf() | ||||||
|  | @ -166,7 +212,8 @@ class M3u8Helper { | ||||||
|                 } |                 } | ||||||
| 
 | 
 | ||||||
|                 encryptionIv = match.component3().toByteArray() |                 encryptionIv = match.component3().toByteArray() | ||||||
|                 val encryptionKeyResponse = runBlocking { app.get(encryptionUri, headers = headers) } |                 val encryptionKeyResponse = | ||||||
|  |                     runBlocking { app.get(encryptionUri, headers = headers) } | ||||||
|                 encryptionData = encryptionKeyResponse.body?.bytes() ?: byteArrayOf() |                 encryptionData = encryptionKeyResponse.body?.bytes() ?: byteArrayOf() | ||||||
|             } |             } | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue