mirror of
https://github.com/recloudstream/cloudstream.git
synced 2024-08-15 01:53:11 +00:00
fixed: Test Search & VidMoxy, RapidVid extractors (#1219)
This commit is contained in:
parent
63e27c2ea5
commit
30adb1cd9d
13 changed files with 155 additions and 150 deletions
|
@ -4,6 +4,7 @@ import com.lagradost.cloudstream3.*
|
||||||
import com.lagradost.cloudstream3.mvvm.logError
|
import com.lagradost.cloudstream3.mvvm.logError
|
||||||
import kotlinx.coroutines.*
|
import kotlinx.coroutines.*
|
||||||
import org.junit.Assert
|
import org.junit.Assert
|
||||||
|
import kotlin.random.Random
|
||||||
|
|
||||||
object TestingUtils {
|
object TestingUtils {
|
||||||
open class TestResult(val success: Boolean) {
|
open class TestResult(val success: Boolean) {
|
||||||
|
@ -280,8 +281,8 @@ object TestingUtils {
|
||||||
|
|
||||||
// Test Search Results
|
// Test Search Results
|
||||||
val searchQueries =
|
val searchQueries =
|
||||||
// Use the first 3 home page results as queries since they are guaranteed to exist
|
// Use the random 3 home page results as queries since they are guaranteed to exist
|
||||||
(homePageList.take(3).map { it.name } +
|
(homePageList.shuffled(Random).take(3).map { it.name.split(" ").first() } +
|
||||||
// If home page is sparse then use generic search queries
|
// If home page is sparse then use generic search queries
|
||||||
listOf("over", "iron", "guy")).take(3)
|
listOf("over", "iron", "guy")).take(3)
|
||||||
|
|
||||||
|
|
|
@ -12,53 +12,52 @@ open class ContentX : ExtractorApi() {
|
||||||
override val requiresReferer = true
|
override val requiresReferer = true
|
||||||
|
|
||||||
override suspend fun getUrl(url: String, referer: String?, subtitleCallback: (SubtitleFile) -> Unit, callback: (ExtractorLink) -> Unit) {
|
override suspend fun getUrl(url: String, referer: String?, subtitleCallback: (SubtitleFile) -> Unit, callback: (ExtractorLink) -> Unit) {
|
||||||
val ext_ref = referer ?: ""
|
val extRef = referer ?: ""
|
||||||
Log.d("Kekik_${this.name}", "url » ${url}")
|
|
||||||
|
|
||||||
val i_source = app.get(url, referer=ext_ref).text
|
val iSource = app.get(url, referer=extRef).text
|
||||||
val i_extract = Regex("""window\.openPlayer\('([^']+)'""").find(i_source)!!.groups[1]?.value ?: throw ErrorLoadingException("i_extract is null")
|
val iExtract = Regex("""window\.openPlayer\('([^']+)'""").find(iSource)!!.groups[1]?.value ?: throw ErrorLoadingException("iExtract is null")
|
||||||
|
|
||||||
val sub_urls = mutableSetOf<String>()
|
val subUrls = mutableSetOf<String>()
|
||||||
Regex("""\"file\":\"([^\"]+)\",\"label\":\"([^\"]+)\"""").findAll(i_source).forEach {
|
Regex("""\"file\":\"([^\"]+)\",\"label\":\"([^\"]+)\"""").findAll(iSource).forEach {
|
||||||
val (sub_url, sub_lang) = it.destructured
|
val (subUrl, subLang) = it.destructured
|
||||||
|
|
||||||
if (sub_url in sub_urls) { return@forEach }
|
if (subUrl in subUrls) { return@forEach }
|
||||||
sub_urls.add(sub_url)
|
subUrls.add(subUrl)
|
||||||
|
|
||||||
subtitleCallback.invoke(
|
subtitleCallback.invoke(
|
||||||
SubtitleFile(
|
SubtitleFile(
|
||||||
lang = sub_lang.replace("\\u0131", "ı").replace("\\u0130", "İ").replace("\\u00fc", "ü").replace("\\u00e7", "ç"),
|
lang = subLang.replace("\\u0131", "ı").replace("\\u0130", "İ").replace("\\u00fc", "ü").replace("\\u00e7", "ç"),
|
||||||
url = fixUrl(sub_url.replace("\\", ""))
|
url = fixUrl(subUrl.replace("\\", ""))
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
val vid_source = app.get("${mainUrl}/source2.php?v=${i_extract}", referer=ext_ref).text
|
val vidSource = app.get("${mainUrl}/source2.php?v=${iExtract}", referer=extRef).text
|
||||||
val vid_extract = Regex("""file\":\"([^\"]+)""").find(vid_source)!!.groups[1]?.value ?: throw ErrorLoadingException("vid_extract is null")
|
val vidExtract = Regex("""file\":\"([^\"]+)""").find(vidSource)!!.groups[1]?.value ?: throw ErrorLoadingException("vidExtract is null")
|
||||||
val m3u_link = vid_extract.replace("\\", "")
|
val m3uLink = vidExtract.replace("\\", "")
|
||||||
|
|
||||||
callback.invoke(
|
callback.invoke(
|
||||||
ExtractorLink(
|
ExtractorLink(
|
||||||
source = this.name,
|
source = this.name,
|
||||||
name = this.name,
|
name = this.name,
|
||||||
url = m3u_link,
|
url = m3uLink,
|
||||||
referer = url,
|
referer = url,
|
||||||
quality = Qualities.Unknown.value,
|
quality = Qualities.Unknown.value,
|
||||||
isM3u8 = true
|
isM3u8 = true
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
val i_dublaj = Regex(""",\"([^']+)\",\"Türkçe""").find(i_source)!!.groups[1]?.value
|
val iDublaj = Regex(""",\"([^']+)\",\"Türkçe""").find(iSource)!!.groups[1]?.value
|
||||||
if (i_dublaj != null) {
|
if (iDublaj != null) {
|
||||||
val dublaj_source = app.get("${mainUrl}/source2.php?v=${i_dublaj}", referer=ext_ref).text
|
val dublajSource = app.get("${mainUrl}/source2.php?v=${iDublaj}", referer=extRef).text
|
||||||
val dublaj_extract = Regex("""file\":\"([^\"]+)""").find(dublaj_source)!!.groups[1]?.value ?: throw ErrorLoadingException("dublaj_extract is null")
|
val dublajExtract = Regex("""file\":\"([^\"]+)""").find(dublajSource)!!.groups[1]?.value ?: throw ErrorLoadingException("dublajExtract is null")
|
||||||
val dublaj_link = dublaj_extract.replace("\\", "")
|
val dublajLink = dublajExtract.replace("\\", "")
|
||||||
|
|
||||||
callback.invoke(
|
callback.invoke(
|
||||||
ExtractorLink(
|
ExtractorLink(
|
||||||
source = "${this.name} Türkçe Dublaj",
|
source = "${this.name} Türkçe Dublaj",
|
||||||
name = "${this.name} Türkçe Dublaj",
|
name = "${this.name} Türkçe Dublaj",
|
||||||
url = dublaj_link,
|
url = dublajLink,
|
||||||
referer = url,
|
referer = url,
|
||||||
quality = Qualities.Unknown.value,
|
quality = Qualities.Unknown.value,
|
||||||
isM3u8 = true
|
isM3u8 = true
|
||||||
|
|
|
@ -16,24 +16,23 @@ open class HDMomPlayer : ExtractorApi() {
|
||||||
override val requiresReferer = true
|
override val requiresReferer = true
|
||||||
|
|
||||||
override suspend fun getUrl(url: String, referer: String?, subtitleCallback: (SubtitleFile) -> Unit, callback: (ExtractorLink) -> Unit) {
|
override suspend fun getUrl(url: String, referer: String?, subtitleCallback: (SubtitleFile) -> Unit, callback: (ExtractorLink) -> Unit) {
|
||||||
val m3u_link:String?
|
val m3uLink:String?
|
||||||
val ext_ref = referer ?: ""
|
val extRef = referer ?: ""
|
||||||
val i_source = app.get(url, referer=ext_ref).text
|
val iSource = app.get(url, referer=extRef).text
|
||||||
|
|
||||||
val bePlayer = Regex("""bePlayer\('([^']+)',\s*'(\{[^\}]+\})'\);""").find(i_source)?.groupValues
|
val bePlayer = Regex("""bePlayer\('([^']+)',\s*'(\{[^\}]+\})'\);""").find(iSource)?.groupValues
|
||||||
if (bePlayer != null) {
|
if (bePlayer != null) {
|
||||||
val bePlayerPass = bePlayer.get(1)
|
val bePlayerPass = bePlayer.get(1)
|
||||||
val bePlayerData = bePlayer.get(2)
|
val bePlayerData = bePlayer.get(2)
|
||||||
val encrypted = AesHelper.cryptoAESHandler(bePlayerData, bePlayerPass.toByteArray(), false)?.replace("\\", "") ?: throw ErrorLoadingException("failed to decrypt")
|
val encrypted = AesHelper.cryptoAESHandler(bePlayerData, bePlayerPass.toByteArray(), false)?.replace("\\", "") ?: throw ErrorLoadingException("failed to decrypt")
|
||||||
Log.d("Kekik_${this.name}", "encrypted » ${encrypted}")
|
|
||||||
|
|
||||||
m3u_link = Regex("""video_location\":\"([^\"]+)""").find(encrypted)?.groupValues?.get(1)
|
m3uLink = Regex("""video_location\":\"([^\"]+)""").find(encrypted)?.groupValues?.get(1)
|
||||||
} else {
|
} else {
|
||||||
m3u_link = Regex("""file:\"([^\"]+)""").find(i_source)?.groupValues?.get(1)
|
m3uLink = Regex("""file:\"([^\"]+)""").find(iSource)?.groupValues?.get(1)
|
||||||
|
|
||||||
val track_str = Regex("""tracks:\[([^\]]+)""").find(i_source)?.groupValues?.get(1)
|
val trackStr = Regex("""tracks:\[([^\]]+)""").find(iSource)?.groupValues?.get(1)
|
||||||
if (track_str != null) {
|
if (trackStr != null) {
|
||||||
val tracks:List<Track> = jacksonObjectMapper().readValue("[${track_str}]")
|
val tracks:List<Track> = jacksonObjectMapper().readValue("[${trackStr}]")
|
||||||
|
|
||||||
for (track in tracks) {
|
for (track in tracks) {
|
||||||
if (track.file == null || track.label == null) continue
|
if (track.file == null || track.label == null) continue
|
||||||
|
@ -53,7 +52,7 @@ open class HDMomPlayer : ExtractorApi() {
|
||||||
ExtractorLink(
|
ExtractorLink(
|
||||||
source = this.name,
|
source = this.name,
|
||||||
name = this.name,
|
name = this.name,
|
||||||
url = m3u_link ?: throw ErrorLoadingException("m3u link not found"),
|
url = m3uLink ?: throw ErrorLoadingException("m3u link not found"),
|
||||||
referer = url,
|
referer = url,
|
||||||
quality = Qualities.Unknown.value,
|
quality = Qualities.Unknown.value,
|
||||||
isM3u8 = true
|
isM3u8 = true
|
||||||
|
|
|
@ -13,37 +13,36 @@ open class HDPlayerSystem : ExtractorApi() {
|
||||||
override val requiresReferer = true
|
override val requiresReferer = true
|
||||||
|
|
||||||
override suspend fun getUrl(url: String, referer: String?, subtitleCallback: (SubtitleFile) -> Unit, callback: (ExtractorLink) -> Unit) {
|
override suspend fun getUrl(url: String, referer: String?, subtitleCallback: (SubtitleFile) -> Unit, callback: (ExtractorLink) -> Unit) {
|
||||||
val ext_ref = referer ?: ""
|
val extRef = referer ?: ""
|
||||||
val vid_id = if (url.contains("video/")) {
|
val vidId = if (url.contains("video/")) {
|
||||||
url.substringAfter("video/")
|
url.substringAfter("video/")
|
||||||
} else {
|
} else {
|
||||||
url.substringAfter("?data=")
|
url.substringAfter("?data=")
|
||||||
}
|
}
|
||||||
val post_url = "${mainUrl}/player/index.php?data=${vid_id}&do=getVideo"
|
val postUrl = "${mainUrl}/player/index.php?data=${vidId}&do=getVideo"
|
||||||
Log.d("Kekik_${this.name}", "post_url » ${post_url}")
|
|
||||||
|
|
||||||
val response = app.post(
|
val response = app.post(
|
||||||
post_url,
|
postUrl,
|
||||||
data = mapOf(
|
data = mapOf(
|
||||||
"hash" to vid_id,
|
"hash" to vidId,
|
||||||
"r" to ext_ref
|
"r" to extRef
|
||||||
),
|
),
|
||||||
referer = ext_ref,
|
referer = extRef,
|
||||||
headers = mapOf(
|
headers = mapOf(
|
||||||
"Content-Type" to "application/x-www-form-urlencoded; charset=UTF-8",
|
"Content-Type" to "application/x-www-form-urlencoded; charset=UTF-8",
|
||||||
"X-Requested-With" to "XMLHttpRequest"
|
"X-Requested-With" to "XMLHttpRequest"
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
val video_response = response.parsedSafe<SystemResponse>() ?: throw ErrorLoadingException("failed to parse response")
|
val videoResponse = response.parsedSafe<SystemResponse>() ?: throw ErrorLoadingException("failed to parse response")
|
||||||
val m3u_link = video_response.securedLink
|
val m3uLink = videoResponse.securedLink
|
||||||
|
|
||||||
callback.invoke(
|
callback.invoke(
|
||||||
ExtractorLink(
|
ExtractorLink(
|
||||||
source = this.name,
|
source = this.name,
|
||||||
name = this.name,
|
name = this.name,
|
||||||
url = m3u_link,
|
url = m3uLink,
|
||||||
referer = ext_ref,
|
referer = extRef,
|
||||||
quality = Qualities.Unknown.value,
|
quality = Qualities.Unknown.value,
|
||||||
type = INFER_TYPE
|
type = INFER_TYPE
|
||||||
)
|
)
|
||||||
|
|
|
@ -13,28 +13,25 @@ open class MailRu : ExtractorApi() {
|
||||||
override val requiresReferer = false
|
override val requiresReferer = false
|
||||||
|
|
||||||
override suspend fun getUrl(url: String, referer: String?, subtitleCallback: (SubtitleFile) -> Unit, callback: (ExtractorLink) -> Unit) {
|
override suspend fun getUrl(url: String, referer: String?, subtitleCallback: (SubtitleFile) -> Unit, callback: (ExtractorLink) -> Unit) {
|
||||||
val ext_ref = referer ?: ""
|
val extRef = referer ?: ""
|
||||||
Log.d("Kekik_${this.name}", "url » ${url}")
|
|
||||||
|
|
||||||
val vid_id = url.substringAfter("video/embed/").trim()
|
val vidId = url.substringAfter("video/embed/").trim()
|
||||||
val video_req = app.get("${mainUrl}/+/video/meta/${vid_id}", referer=url)
|
val videoReq = app.get("${mainUrl}/+/video/meta/${vidId}", referer=url)
|
||||||
val video_key = video_req.cookies["video_key"].toString()
|
val videoKey = videoReq.cookies["video_key"].toString()
|
||||||
Log.d("Kekik_${this.name}", "video_key » ${video_key}")
|
|
||||||
|
|
||||||
val video_data = AppUtils.tryParseJson<MailRuData>(video_req.text) ?: throw ErrorLoadingException("Video not found")
|
val videoData = AppUtils.tryParseJson<MailRuData>(videoReq.text) ?: throw ErrorLoadingException("Video not found")
|
||||||
|
|
||||||
for (video in video_data.videos) {
|
for (video in videoData.videos) {
|
||||||
Log.d("Kekik_${this.name}", "video » ${video}")
|
|
||||||
|
|
||||||
val video_url = if (video.url.startsWith("//")) "https:${video.url}" else video.url
|
val videoUrl = if (video.url.startsWith("//")) "https:${video.url}" else video.url
|
||||||
|
|
||||||
callback.invoke(
|
callback.invoke(
|
||||||
ExtractorLink(
|
ExtractorLink(
|
||||||
source = this.name,
|
source = this.name,
|
||||||
name = this.name,
|
name = this.name,
|
||||||
url = video_url,
|
url = videoUrl,
|
||||||
referer = url,
|
referer = url,
|
||||||
headers = mapOf("Cookie" to "video_key=${video_key}"),
|
headers = mapOf("Cookie" to "video_key=${videoKey}"),
|
||||||
quality = getQualityFromName(video.key),
|
quality = getQualityFromName(video.key),
|
||||||
isM3u8 = false
|
isM3u8 = false
|
||||||
)
|
)
|
||||||
|
|
|
@ -13,22 +13,20 @@ open class Odnoklassniki : ExtractorApi() {
|
||||||
override val requiresReferer = false
|
override val requiresReferer = false
|
||||||
|
|
||||||
override suspend fun getUrl(url: String, referer: String?, subtitleCallback: (SubtitleFile) -> Unit, callback: (ExtractorLink) -> Unit) {
|
override suspend fun getUrl(url: String, referer: String?, subtitleCallback: (SubtitleFile) -> Unit, callback: (ExtractorLink) -> Unit) {
|
||||||
val ext_ref = referer ?: ""
|
val extRef = referer ?: ""
|
||||||
Log.d("Kekik_${this.name}", "url » ${url}")
|
|
||||||
|
|
||||||
val user_agent = mapOf("User-Agent" to "Mozilla/5.0 (Linux; Android 10; K) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Mobile Safari/537.36")
|
val userAgent = mapOf("User-Agent" to "Mozilla/5.0 (Linux; Android 10; K) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Mobile Safari/537.36")
|
||||||
|
|
||||||
val video_req = app.get(url, headers=user_agent).text.replace("\\"", "\"").replace("\\\\", "\\")
|
val videoReq = app.get(url, headers=userAgent).text.replace("\\"", "\"").replace("\\\\", "\\")
|
||||||
.replace(Regex("\\\\u([0-9A-Fa-f]{4})")) { matchResult ->
|
.replace(Regex("\\\\u([0-9A-Fa-f]{4})")) { matchResult ->
|
||||||
Integer.parseInt(matchResult.groupValues[1], 16).toChar().toString()
|
Integer.parseInt(matchResult.groupValues[1], 16).toChar().toString()
|
||||||
}
|
}
|
||||||
val videos_str = Regex("""\"videos\":(\[[^\]]*\])""").find(video_req)?.groupValues?.get(1) ?: throw ErrorLoadingException("Video not found")
|
val videosStr = Regex("""\"videos\":(\[[^\]]*\])""").find(videoReq)?.groupValues?.get(1) ?: throw ErrorLoadingException("Video not found")
|
||||||
val videos = AppUtils.tryParseJson<List<OkRuVideo>>(videos_str) ?: throw ErrorLoadingException("Video not found")
|
val videos = AppUtils.tryParseJson<List<OkRuVideo>>(videosStr) ?: throw ErrorLoadingException("Video not found")
|
||||||
|
|
||||||
for (video in videos) {
|
for (video in videos) {
|
||||||
Log.d("Kekik_${this.name}", "video » ${video}")
|
|
||||||
|
|
||||||
val video_url = if (video.url.startsWith("//")) "https:${video.url}" else video.url
|
val videoUrl = if (video.url.startsWith("//")) "https:${video.url}" else video.url
|
||||||
|
|
||||||
val quality = video.name.uppercase()
|
val quality = video.name.uppercase()
|
||||||
.replace("MOBILE", "144p")
|
.replace("MOBILE", "144p")
|
||||||
|
@ -44,10 +42,10 @@ open class Odnoklassniki : ExtractorApi() {
|
||||||
ExtractorLink(
|
ExtractorLink(
|
||||||
source = this.name,
|
source = this.name,
|
||||||
name = this.name,
|
name = this.name,
|
||||||
url = video_url,
|
url = videoUrl,
|
||||||
referer = url,
|
referer = url,
|
||||||
quality = getQualityFromName(quality),
|
quality = getQualityFromName(quality),
|
||||||
headers = user_agent,
|
headers = userAgent,
|
||||||
isM3u8 = false
|
isM3u8 = false
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
|
@ -13,39 +13,38 @@ open class PeaceMakerst : ExtractorApi() {
|
||||||
override val requiresReferer = true
|
override val requiresReferer = true
|
||||||
|
|
||||||
override suspend fun getUrl(url: String, referer: String?, subtitleCallback: (SubtitleFile) -> Unit, callback: (ExtractorLink) -> Unit) {
|
override suspend fun getUrl(url: String, referer: String?, subtitleCallback: (SubtitleFile) -> Unit, callback: (ExtractorLink) -> Unit) {
|
||||||
val m3u_link:String?
|
val m3uLink:String?
|
||||||
val ext_ref = referer ?: ""
|
val extRef = referer ?: ""
|
||||||
val post_url = "${url}?do=getVideo"
|
val postUrl = "${url}?do=getVideo"
|
||||||
Log.d("Kekik_${this.name}", "post_url » ${post_url}")
|
|
||||||
|
|
||||||
val response = app.post(
|
val response = app.post(
|
||||||
post_url,
|
postUrl,
|
||||||
data = mapOf(
|
data = mapOf(
|
||||||
"hash" to url.substringAfter("video/"),
|
"hash" to url.substringAfter("video/"),
|
||||||
"r" to ext_ref,
|
"r" to extRef,
|
||||||
"s" to ""
|
"s" to ""
|
||||||
),
|
),
|
||||||
referer = ext_ref,
|
referer = extRef,
|
||||||
headers = mapOf(
|
headers = mapOf(
|
||||||
"Content-Type" to "application/x-www-form-urlencoded; charset=UTF-8",
|
"Content-Type" to "application/x-www-form-urlencoded; charset=UTF-8",
|
||||||
"X-Requested-With" to "XMLHttpRequest"
|
"X-Requested-With" to "XMLHttpRequest"
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
if (response.text.contains("teve2.com.tr\\/embed\\/")) {
|
if (response.text.contains("teve2.com.tr\\/embed\\/")) {
|
||||||
val teve2_id = response.text.substringAfter("teve2.com.tr\\/embed\\/").substringBefore("\"")
|
val teve2Id = response.text.substringAfter("teve2.com.tr\\/embed\\/").substringBefore("\"")
|
||||||
val teve2_response = app.get(
|
val teve2Response = app.get(
|
||||||
"https://www.teve2.com.tr/action/media/${teve2_id}",
|
"https://www.teve2.com.tr/action/media/${teve2Id}",
|
||||||
referer = "https://www.teve2.com.tr/embed/${teve2_id}"
|
referer = "https://www.teve2.com.tr/embed/${teve2Id}"
|
||||||
).parsedSafe<Teve2ApiResponse>() ?: throw ErrorLoadingException("teve2 response is null")
|
).parsedSafe<Teve2ApiResponse>() ?: throw ErrorLoadingException("teve2 response is null")
|
||||||
|
|
||||||
m3u_link = teve2_response.media.link.serviceUrl + "//" + teve2_response.media.link.securePath
|
m3uLink = teve2Response.media.link.serviceUrl + "//" + teve2Response.media.link.securePath
|
||||||
} else {
|
} else {
|
||||||
val video_response = response.parsedSafe<PeaceResponse>() ?: throw ErrorLoadingException("peace response is null")
|
val videoResponse = response.parsedSafe<PeaceResponse>() ?: throw ErrorLoadingException("peace response is null")
|
||||||
val video_sources = video_response.videoSources
|
val videoSources = videoResponse.videoSources
|
||||||
if (video_sources.isNotEmpty()) {
|
if (videoSources.isNotEmpty()) {
|
||||||
m3u_link = video_sources.lastOrNull()?.file
|
m3uLink = videoSources.lastOrNull()?.file
|
||||||
} else {
|
} else {
|
||||||
m3u_link = null
|
m3uLink = null
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -53,8 +52,8 @@ open class PeaceMakerst : ExtractorApi() {
|
||||||
ExtractorLink(
|
ExtractorLink(
|
||||||
source = this.name,
|
source = this.name,
|
||||||
name = this.name,
|
name = this.name,
|
||||||
url = m3u_link ?: throw ErrorLoadingException("m3u link not found"),
|
url = m3uLink ?: throw ErrorLoadingException("m3u link not found"),
|
||||||
referer = ext_ref,
|
referer = extRef,
|
||||||
quality = Qualities.Unknown.value,
|
quality = Qualities.Unknown.value,
|
||||||
type = INFER_TYPE
|
type = INFER_TYPE
|
||||||
)
|
)
|
||||||
|
|
|
@ -12,36 +12,45 @@ open class RapidVid : ExtractorApi() {
|
||||||
override val requiresReferer = true
|
override val requiresReferer = true
|
||||||
|
|
||||||
override suspend fun getUrl(url: String, referer: String?, subtitleCallback: (SubtitleFile) -> Unit, callback: (ExtractorLink) -> Unit) {
|
override suspend fun getUrl(url: String, referer: String?, subtitleCallback: (SubtitleFile) -> Unit, callback: (ExtractorLink) -> Unit) {
|
||||||
val ext_ref = referer ?: ""
|
val extRef = referer ?: ""
|
||||||
val video_req = app.get(url, referer=ext_ref).text
|
val videoReq = app.get(url, referer=extRef).text
|
||||||
|
|
||||||
val sub_urls = mutableSetOf<String>()
|
val subUrls = mutableSetOf<String>()
|
||||||
Regex("""captions\",\"file\":\"([^\"]+)\",\"label\":\"([^\"]+)\"""").findAll(video_req).forEach {
|
Regex("""captions\",\"file\":\"([^\"]+)\",\"label\":\"([^\"]+)\"""").findAll(videoReq).forEach {
|
||||||
val (sub_url, sub_lang) = it.destructured
|
val (subUrl, subLang) = it.destructured
|
||||||
|
|
||||||
if (sub_url in sub_urls) { return@forEach }
|
if (subUrl in subUrls) { return@forEach }
|
||||||
sub_urls.add(sub_url)
|
subUrls.add(subUrl)
|
||||||
|
|
||||||
subtitleCallback.invoke(
|
subtitleCallback.invoke(
|
||||||
SubtitleFile(
|
SubtitleFile(
|
||||||
lang = sub_lang.replace("\\u0131", "ı").replace("\\u0130", "İ").replace("\\u00fc", "ü").replace("\\u00e7", "ç"),
|
lang = subLang.replace("\\u0131", "ı").replace("\\u0130", "İ").replace("\\u00fc", "ü").replace("\\u00e7", "ç"),
|
||||||
url = fixUrl(sub_url.replace("\\", ""))
|
url = fixUrl(subUrl.replace("\\", ""))
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
val extracted_value = Regex("""file": "(.*)",""").find(video_req)?.groupValues?.get(1) ?: throw ErrorLoadingException("File not found")
|
var extractedValue = Regex("""file": "(.*)",""").find(videoReq)?.groupValues?.get(1)
|
||||||
|
var decoded: String? = null
|
||||||
|
|
||||||
val bytes = extracted_value.split("\\x").filter { it.isNotEmpty() }.map { it.toInt(16).toByte() }.toByteArray()
|
if (extractedValue != null) {
|
||||||
val decoded = String(bytes, Charsets.UTF_8)
|
val bytes = extractedValue.split("\\x").filter { it.isNotEmpty() }.map { it.toInt(16).toByte() }.toByteArray()
|
||||||
Log.d("Kekik_${this.name}", "decoded » ${decoded}")
|
decoded = String(bytes, Charsets.UTF_8) ?: throw ErrorLoadingException("File not found")
|
||||||
|
} else {
|
||||||
|
val evalJWSsetup = Regex("""\};\s*(eval\(function[\s\S]*?)var played = \d+;""").find(videoReq)?.groupValues?.get(1) ?: throw ErrorLoadingException("File not found")
|
||||||
|
val JWSsetup = getAndUnpack(getAndUnpack(evalJWSsetup)).replace("\\\\", "\\")
|
||||||
|
extractedValue = Regex("""file":"(.*)","label""").find(JWSsetup)?.groupValues?.get(1)?.replace("\\\\x", "")
|
||||||
|
|
||||||
|
val bytes = extractedValue?.chunked(2)?.map { it.toInt(16).toByte() }?.toByteArray()
|
||||||
|
decoded = bytes?.toString(Charsets.UTF_8) ?: throw ErrorLoadingException("File not found")
|
||||||
|
}
|
||||||
|
|
||||||
callback.invoke(
|
callback.invoke(
|
||||||
ExtractorLink(
|
ExtractorLink(
|
||||||
source = this.name,
|
source = this.name,
|
||||||
name = this.name,
|
name = this.name,
|
||||||
url = decoded,
|
url = decoded,
|
||||||
referer = ext_ref,
|
referer = extRef,
|
||||||
quality = Qualities.Unknown.value,
|
quality = Qualities.Unknown.value,
|
||||||
isM3u8 = true
|
isM3u8 = true
|
||||||
)
|
)
|
||||||
|
|
|
@ -12,18 +12,17 @@ open class SibNet : ExtractorApi() {
|
||||||
override val requiresReferer = true
|
override val requiresReferer = true
|
||||||
|
|
||||||
override suspend fun getUrl(url: String, referer: String?, subtitleCallback: (SubtitleFile) -> Unit, callback: (ExtractorLink) -> Unit) {
|
override suspend fun getUrl(url: String, referer: String?, subtitleCallback: (SubtitleFile) -> Unit, callback: (ExtractorLink) -> Unit) {
|
||||||
val ext_ref = referer ?: ""
|
val extRef = referer ?: ""
|
||||||
val i_source = app.get(url, referer=ext_ref).text
|
val iSource = app.get(url, referer=extRef).text
|
||||||
var m3u_link = Regex("""player.src\(\[\{src: \"([^\"]+)""").find(i_source)?.groupValues?.get(1) ?: throw ErrorLoadingException("m3u link not found")
|
var m3uLink = Regex("""player.src\(\[\{src: \"([^\"]+)""").find(iSource)?.groupValues?.get(1) ?: throw ErrorLoadingException("m3u link not found")
|
||||||
|
|
||||||
m3u_link = "${mainUrl}${m3u_link}"
|
m3uLink = "${mainUrl}${m3uLink}"
|
||||||
Log.d("Kekik_${this.name}", "m3u_link » ${m3u_link}")
|
|
||||||
|
|
||||||
callback.invoke(
|
callback.invoke(
|
||||||
ExtractorLink(
|
ExtractorLink(
|
||||||
source = this.name,
|
source = this.name,
|
||||||
name = this.name,
|
name = this.name,
|
||||||
url = m3u_link,
|
url = m3uLink,
|
||||||
referer = url,
|
referer = url,
|
||||||
quality = Qualities.Unknown.value,
|
quality = Qualities.Unknown.value,
|
||||||
type = INFER_TYPE
|
type = INFER_TYPE
|
||||||
|
|
|
@ -13,13 +13,13 @@ open class TRsTX : ExtractorApi() {
|
||||||
override val requiresReferer = true
|
override val requiresReferer = true
|
||||||
|
|
||||||
override suspend fun getUrl(url: String, referer: String?, subtitleCallback: (SubtitleFile) -> Unit, callback: (ExtractorLink) -> Unit) {
|
override suspend fun getUrl(url: String, referer: String?, subtitleCallback: (SubtitleFile) -> Unit, callback: (ExtractorLink) -> Unit) {
|
||||||
val ext_ref = referer ?: ""
|
val extRef = referer ?: ""
|
||||||
|
|
||||||
val video_req = app.get(url, referer=ext_ref).text
|
val videoReq = app.get(url, referer=extRef).text
|
||||||
|
|
||||||
val file = Regex("""file\":\"([^\"]+)""").find(video_req)?.groupValues?.get(1) ?: throw ErrorLoadingException("File not found")
|
val file = Regex("""file\":\"([^\"]+)""").find(videoReq)?.groupValues?.get(1) ?: throw ErrorLoadingException("File not found")
|
||||||
val postLink = "${mainUrl}/" + file.replace("\\", "")
|
val postLink = "${mainUrl}/" + file.replace("\\", "")
|
||||||
val rawList = app.post(postLink, referer=ext_ref).parsedSafe<List<Any>>() ?: throw ErrorLoadingException("Post link not found")
|
val rawList = app.post(postLink, referer=extRef).parsedSafe<List<Any>>() ?: throw ErrorLoadingException("Post link not found")
|
||||||
|
|
||||||
val postJson: List<TrstxVideoData> = rawList.drop(1).map { item ->
|
val postJson: List<TrstxVideoData> = rawList.drop(1).map { item ->
|
||||||
val mapItem = item as Map<*, *>
|
val mapItem = item as Map<*, *>
|
||||||
|
@ -28,37 +28,35 @@ open class TRsTX : ExtractorApi() {
|
||||||
file = mapItem["file"] as? String
|
file = mapItem["file"] as? String
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
Log.d("Kekik_${this.name}", "postJson » ${postJson}")
|
|
||||||
|
|
||||||
val vid_links = mutableSetOf<String>()
|
val vidLinks = mutableSetOf<String>()
|
||||||
val vid_map = mutableListOf<Map<String, String>>()
|
val vidMap = mutableListOf<Map<String, String>>()
|
||||||
for (item in postJson) {
|
for (item in postJson) {
|
||||||
if (item.file == null || item.title == null) continue
|
if (item.file == null || item.title == null) continue
|
||||||
|
|
||||||
val fileUrl = "${mainUrl}/playlist/" + item.file.substring(1) + ".txt"
|
val fileUrl = "${mainUrl}/playlist/" + item.file.substring(1) + ".txt"
|
||||||
val videoData = app.post(fileUrl, referer=ext_ref).text
|
val videoData = app.post(fileUrl, referer=extRef).text
|
||||||
|
|
||||||
if (videoData in vid_links) { continue }
|
if (videoData in vidLinks) { continue }
|
||||||
vid_links.add(videoData)
|
vidLinks.add(videoData)
|
||||||
|
|
||||||
vid_map.add(mapOf(
|
vidMap.add(mapOf(
|
||||||
"title" to item.title,
|
"title" to item.title,
|
||||||
"videoData" to videoData
|
"videoData" to videoData
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
for (mapEntry in vid_map) {
|
for (mapEntry in vidMap) {
|
||||||
Log.d("Kekik_${this.name}", "mapEntry » ${mapEntry}")
|
|
||||||
val title = mapEntry["title"] ?: continue
|
val title = mapEntry["title"] ?: continue
|
||||||
val m3u_link = mapEntry["videoData"] ?: continue
|
val m3uLink = mapEntry["videoData"] ?: continue
|
||||||
|
|
||||||
callback.invoke(
|
callback.invoke(
|
||||||
ExtractorLink(
|
ExtractorLink(
|
||||||
source = this.name,
|
source = this.name,
|
||||||
name = "${this.name} - ${title}",
|
name = "${this.name} - ${title}",
|
||||||
url = m3u_link,
|
url = m3uLink,
|
||||||
referer = ext_ref,
|
referer = extRef,
|
||||||
quality = Qualities.Unknown.value,
|
quality = Qualities.Unknown.value,
|
||||||
type = INFER_TYPE
|
type = INFER_TYPE
|
||||||
)
|
)
|
||||||
|
|
|
@ -13,12 +13,11 @@ open class TauVideo : ExtractorApi() {
|
||||||
override val requiresReferer = true
|
override val requiresReferer = true
|
||||||
|
|
||||||
override suspend fun getUrl(url: String, referer: String?, subtitleCallback: (SubtitleFile) -> Unit, callback: (ExtractorLink) -> Unit) {
|
override suspend fun getUrl(url: String, referer: String?, subtitleCallback: (SubtitleFile) -> Unit, callback: (ExtractorLink) -> Unit) {
|
||||||
val ext_ref = referer ?: ""
|
val extRef = referer ?: ""
|
||||||
val video_key = url.split("/").last()
|
val videoKey = url.split("/").last()
|
||||||
val video_url = "${mainUrl}/api/video/${video_key}"
|
val videoUrl = "${mainUrl}/api/video/${videoKey}"
|
||||||
Log.d("Kekik_${this.name}", "video_url » ${video_url}")
|
|
||||||
|
|
||||||
val api = app.get(video_url).parsedSafe<TauVideoUrls>() ?: throw ErrorLoadingException("TauVideo")
|
val api = app.get(videoUrl).parsedSafe<TauVideoUrls>() ?: throw ErrorLoadingException("TauVideo")
|
||||||
|
|
||||||
for (video in api.urls) {
|
for (video in api.urls) {
|
||||||
callback.invoke(
|
callback.invoke(
|
||||||
|
@ -26,7 +25,7 @@ open class TauVideo : ExtractorApi() {
|
||||||
source = this.name,
|
source = this.name,
|
||||||
name = this.name,
|
name = this.name,
|
||||||
url = video.url,
|
url = video.url,
|
||||||
referer = ext_ref,
|
referer = extRef,
|
||||||
quality = getQualityFromName(video.label),
|
quality = getQualityFromName(video.label),
|
||||||
type = INFER_TYPE
|
type = INFER_TYPE
|
||||||
)
|
)
|
||||||
|
|
|
@ -12,36 +12,45 @@ open class VidMoxy : ExtractorApi() {
|
||||||
override val requiresReferer = true
|
override val requiresReferer = true
|
||||||
|
|
||||||
override suspend fun getUrl(url: String, referer: String?, subtitleCallback: (SubtitleFile) -> Unit, callback: (ExtractorLink) -> Unit) {
|
override suspend fun getUrl(url: String, referer: String?, subtitleCallback: (SubtitleFile) -> Unit, callback: (ExtractorLink) -> Unit) {
|
||||||
val ext_ref = referer ?: ""
|
val extRef = referer ?: ""
|
||||||
val video_req = app.get(url, referer=ext_ref).text
|
val videoReq = app.get(url, referer=extRef).text
|
||||||
|
|
||||||
val sub_urls = mutableSetOf<String>()
|
val subUrls = mutableSetOf<String>()
|
||||||
Regex("""captions\",\"file\":\"([^\"]+)\",\"label\":\"([^\"]+)\"""").findAll(video_req).forEach {
|
Regex("""captions\",\"file\":\"([^\"]+)\",\"label\":\"([^\"]+)\"""").findAll(videoReq).forEach {
|
||||||
val (sub_url, sub_lang) = it.destructured
|
val (subUrl, subLang) = it.destructured
|
||||||
|
|
||||||
if (sub_url in sub_urls) { return@forEach }
|
if (subUrl in subUrls) { return@forEach }
|
||||||
sub_urls.add(sub_url)
|
subUrls.add(subUrl)
|
||||||
|
|
||||||
subtitleCallback.invoke(
|
subtitleCallback.invoke(
|
||||||
SubtitleFile(
|
SubtitleFile(
|
||||||
lang = sub_lang.replace("\\u0131", "ı").replace("\\u0130", "İ").replace("\\u00fc", "ü").replace("\\u00e7", "ç"),
|
lang = subLang.replace("\\u0131", "ı").replace("\\u0130", "İ").replace("\\u00fc", "ü").replace("\\u00e7", "ç"),
|
||||||
url = fixUrl(sub_url.replace("\\", ""))
|
url = fixUrl(subUrl.replace("\\", ""))
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
val extracted_value = Regex("""file": "(.*)",""").find(video_req)?.groupValues?.get(1) ?: throw ErrorLoadingException("File not found")
|
var extractedValue = Regex("""file": "(.*)",""").find(videoReq)?.groupValues?.get(1)
|
||||||
|
var decoded: String? = null
|
||||||
|
|
||||||
val bytes = extracted_value.split("\\x").filter { it.isNotEmpty() }.map { it.toInt(16).toByte() }.toByteArray()
|
if (extractedValue != null) {
|
||||||
val decoded = String(bytes, Charsets.UTF_8)
|
val bytes = extractedValue.split("\\x").filter { it.isNotEmpty() }.map { it.toInt(16).toByte() }.toByteArray()
|
||||||
Log.d("Kekik_${this.name}", "decoded » ${decoded}")
|
decoded = String(bytes, Charsets.UTF_8) ?: throw ErrorLoadingException("File not found")
|
||||||
|
} else {
|
||||||
|
val evaljwSetup = Regex("""\};\s*(eval\(function[\s\S]*?)var played = \d+;""").find(videoReq)?.groupValues?.get(1) ?: throw ErrorLoadingException("File not found")
|
||||||
|
val jwSetup = getAndUnpack(getAndUnpack(evaljwSetup)).replace("\\\\", "\\")
|
||||||
|
extractedValue = Regex("""file":"(.*)","label""").find(jwSetup)?.groupValues?.get(1)?.replace("\\\\x", "")
|
||||||
|
|
||||||
|
val bytes = extractedValue?.chunked(2)?.map { it.toInt(16).toByte() }?.toByteArray()
|
||||||
|
decoded = bytes?.toString(Charsets.UTF_8) ?: throw ErrorLoadingException("File not found")
|
||||||
|
}
|
||||||
|
|
||||||
callback.invoke(
|
callback.invoke(
|
||||||
ExtractorLink(
|
ExtractorLink(
|
||||||
source = this.name,
|
source = this.name,
|
||||||
name = this.name,
|
name = this.name,
|
||||||
url = decoded,
|
url = decoded,
|
||||||
referer = ext_ref,
|
referer = extRef,
|
||||||
quality = Qualities.Unknown.value,
|
quality = Qualities.Unknown.value,
|
||||||
isM3u8 = true
|
isM3u8 = true
|
||||||
)
|
)
|
||||||
|
|
|
@ -15,14 +15,13 @@ open class VideoSeyred : ExtractorApi() {
|
||||||
override val requiresReferer = true
|
override val requiresReferer = true
|
||||||
|
|
||||||
override suspend fun getUrl(url: String, referer: String?, subtitleCallback: (SubtitleFile) -> Unit, callback: (ExtractorLink) -> Unit) {
|
override suspend fun getUrl(url: String, referer: String?, subtitleCallback: (SubtitleFile) -> Unit, callback: (ExtractorLink) -> Unit) {
|
||||||
val ext_ref = referer ?: ""
|
val extRef = referer ?: ""
|
||||||
val video_id = url.substringAfter("embed/").substringBefore("?")
|
val videoId = url.substringAfter("embed/").substringBefore("?")
|
||||||
val video_url = "${mainUrl}/playlist/${video_id}.json"
|
val videoUrl = "${mainUrl}/playlist/${videoId}.json"
|
||||||
Log.d("Kekik_${this.name}", "video_url » ${video_url}")
|
|
||||||
|
|
||||||
val response_raw = app.get(video_url)
|
val responseRaw = app.get(videoUrl)
|
||||||
val response_list:List<VideoSeyredSource> = jacksonObjectMapper().readValue(response_raw.text) ?: throw ErrorLoadingException("VideoSeyred")
|
val responseList:List<VideoSeyredSource> = jacksonObjectMapper().readValue(responseRaw.text) ?: throw ErrorLoadingException("VideoSeyred")
|
||||||
val response = response_list[0] ?: throw ErrorLoadingException("VideoSeyred")
|
val response = responseList[0] ?: throw ErrorLoadingException("VideoSeyred")
|
||||||
|
|
||||||
for (track in response.tracks) {
|
for (track in response.tracks) {
|
||||||
if (track.label != null && track.kind == "captions") {
|
if (track.label != null && track.kind == "captions") {
|
||||||
|
|
Loading…
Reference in a new issue