mirror of
https://github.com/hexated/cloudstream-extensions-hexated.git
synced 2024-08-15 00:03:22 +00:00
[Sora] added Crunchyroll
This commit is contained in:
parent
bdfda76782
commit
990c0f6f73
3 changed files with 92 additions and 10 deletions
|
@ -1,5 +1,5 @@
|
|||
// use an integer for version numbers
|
||||
version = 54
|
||||
version = 55
|
||||
|
||||
|
||||
cloudstream {
|
||||
|
|
|
@ -1562,6 +1562,51 @@ object SoraExtractor : SoraStream() {
|
|||
|
||||
}
|
||||
|
||||
suspend fun invoCrunchyroll(
|
||||
title: String? = null,
|
||||
epsTitle: String? = null,
|
||||
subtitleCallback: (SubtitleFile) -> Unit,
|
||||
callback: (ExtractorLink) -> Unit
|
||||
) {
|
||||
val id = app.get("$consumetCrunchyrollAPI/$title")
|
||||
.parsedSafe<ConsumetSearchResponse>()?.results?.find {
|
||||
it.title.equals(
|
||||
title,
|
||||
true
|
||||
) && it.type.equals("series")
|
||||
} ?: return
|
||||
|
||||
val detail = app.get("$consumetCrunchyrollAPI/info?id=${id.id}&mediaType=series").text
|
||||
val episodeId = tryParseJson<ConsumetDetails>(detail)?.episodes?.filter {
|
||||
it.title.equals(epsTitle, true) && (it.type == "Subbed" || it.type == "English Dub")
|
||||
}?.map { it.id to it.type } ?: return
|
||||
|
||||
episodeId.apmap { (id, type) ->
|
||||
delay(1000)
|
||||
val json = app.get("$consumetCrunchyrollAPI/watch?episodeId=$id")
|
||||
.parsedSafe<ConsumetSourcesResponse>()
|
||||
|
||||
json?.sources?.map source@{ source ->
|
||||
M3u8Helper.generateM3u8(
|
||||
"Crunchyroll [$type]",
|
||||
source.url ?: return@source null,
|
||||
"",
|
||||
).forEach(callback)
|
||||
}
|
||||
|
||||
json?.subtitles?.map subtitle@{ sub ->
|
||||
subtitleCallback.invoke(
|
||||
SubtitleFile(
|
||||
sub.lang?.replace(Regex("\\[\\S+]"), "")?.trim() ?: "",
|
||||
sub.url ?: return@subtitle null
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
class StreamM4u: XStreamCdn() {
|
||||
|
@ -1662,6 +1707,8 @@ data class ConsumetSourcesResponse(
|
|||
|
||||
data class ConsumetEpisodes(
|
||||
@JsonProperty("id") val id: String? = null,
|
||||
@JsonProperty("type") val type: String? = null,
|
||||
@JsonProperty("title") val title: String? = null,
|
||||
@JsonProperty("number") val number: Int? = null,
|
||||
@JsonProperty("season") val season: Int? = null,
|
||||
)
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package com.hexated
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonProperty
|
||||
import com.hexated.SoraExtractor.invoCrunchyroll
|
||||
import com.hexated.SoraExtractor.invoKisskh
|
||||
import com.hexated.SoraExtractor.invoke123Movie
|
||||
import com.hexated.SoraExtractor.invokeDbgo
|
||||
|
@ -49,11 +50,14 @@ open class SoraStream : TmdbProvider() {
|
|||
/** AUTHOR : Hexated & Sora */
|
||||
companion object {
|
||||
private const val tmdbAPI = "https://api.themoviedb.org/3"
|
||||
private val apiKey = base64DecodeAPI("ZTM=NTg=MjM=MjM=ODc=MzI=OGQ=MmE=Nzk=Nzk=ZjI=NTA=NDY=NDA=MzA=YjA=") // PLEASE DON'T STEAL
|
||||
private val apiKey =
|
||||
base64DecodeAPI("ZTM=NTg=MjM=MjM=ODc=MzI=OGQ=MmE=Nzk=Nzk=ZjI=NTA=NDY=NDA=MzA=YjA=") // PLEASE DON'T STEAL
|
||||
const val tmdb2mal = "https://tmdb2mal.slidemovies.org"
|
||||
const val gdbot = "https://gdbot.xyz"
|
||||
|
||||
private val mainAPI = base64DecodeAPI("cHA=LmE=ZWw=cmM=dmU=aC4=dGM=d2E=eHA=Ly8=czo=dHA=aHQ=")
|
||||
private val mainAPI =
|
||||
base64DecodeAPI("cHA=LmE=ZWw=cmM=dmU=aC4=dGM=d2E=eHA=Ly8=czo=dHA=aHQ=")
|
||||
|
||||
// private var mainServerAPI = base64DecodeAPI("cA==YXA=bC4=Y2U=ZXI=LnY=aWU=b3Y=LW0=cmE=c28=Ly8=czo=dHA=aHQ=")
|
||||
const val twoEmbedAPI = "https://www.2embed.to"
|
||||
const val vidSrcAPI = "https://v2.vidsrc.me"
|
||||
|
@ -72,6 +76,7 @@ open class SoraStream : TmdbProvider() {
|
|||
const val xMovieAPI = "https://xemovies.to"
|
||||
const val consumetFlixhqAPI = "https://api.consumet.org/movies/flixhq"
|
||||
const val consumetZoroAPI = "https://api.consumet.org/anime/zoro"
|
||||
const val consumetCrunchyrollAPI = "https://api.consumet.org/anime/crunchyroll"
|
||||
const val kissKhAPI = "https://kisskh.me"
|
||||
const val lingAPI = "https://ling-online.net"
|
||||
const val uhdmoviesAPI = "https://uhdmovies.site"
|
||||
|
@ -221,7 +226,8 @@ open class SoraStream : TmdbProvider() {
|
|||
orgTitle = orgTitle,
|
||||
isAnime = isAnime,
|
||||
airedYear = year,
|
||||
lastSeason = lastSeason
|
||||
lastSeason = lastSeason,
|
||||
epsTitle = eps.name,
|
||||
).toJson(),
|
||||
name = eps.name,
|
||||
season = eps.seasonNumber,
|
||||
|
@ -342,6 +348,14 @@ open class SoraStream : TmdbProvider() {
|
|||
callback
|
||||
)
|
||||
},
|
||||
{
|
||||
if (res.season != null && res.isAnime) invoCrunchyroll(
|
||||
res.title,
|
||||
res.epsTitle,
|
||||
subtitleCallback,
|
||||
callback
|
||||
)
|
||||
},
|
||||
{
|
||||
if (!res.isAnime) invokeHDMovieBox(res.title, res.season, res.episode, callback)
|
||||
},
|
||||
|
@ -425,13 +439,33 @@ open class SoraStream : TmdbProvider() {
|
|||
invokeFwatayako(res.imdbId, res.season, res.episode, subtitleCallback, callback)
|
||||
},
|
||||
{
|
||||
if(!res.isAnime) invokeGMovies(res.title, res.year, res.season, res.episode, subtitleCallback, callback)
|
||||
if (!res.isAnime) invokeGMovies(
|
||||
res.title,
|
||||
res.year,
|
||||
res.season,
|
||||
res.episode,
|
||||
subtitleCallback,
|
||||
callback
|
||||
)
|
||||
},
|
||||
{
|
||||
if(!res.isAnime) invokeFDMovies(res.title, res.season, res.episode, subtitleCallback, callback)
|
||||
if (!res.isAnime) invokeFDMovies(
|
||||
res.title,
|
||||
res.season,
|
||||
res.episode,
|
||||
subtitleCallback,
|
||||
callback
|
||||
)
|
||||
},
|
||||
{
|
||||
invokeM4uhd(res.title, res.year, res.season, res.episode, subtitleCallback, callback)
|
||||
invokeM4uhd(
|
||||
res.title,
|
||||
res.year,
|
||||
res.season,
|
||||
res.episode,
|
||||
subtitleCallback,
|
||||
callback
|
||||
)
|
||||
},
|
||||
{
|
||||
invokeTvMovies(res.title, res.season, res.episode, subtitleCallback, callback)
|
||||
|
@ -455,6 +489,7 @@ open class SoraStream : TmdbProvider() {
|
|||
val isAnime: Boolean = false,
|
||||
val airedYear: Int? = null,
|
||||
val lastSeason: Int? = null,
|
||||
val epsTitle: String? = null,
|
||||
)
|
||||
|
||||
data class Data(
|
||||
|
|
Loading…
Reference in a new issue