[Sora] added Crunchyroll

This commit is contained in:
hexated 2022-12-14 12:05:18 +07:00
parent bdfda76782
commit 990c0f6f73
3 changed files with 92 additions and 10 deletions

View File

@ -1,5 +1,5 @@
// use an integer for version numbers
version = 54
version = 55
cloudstream {

View File

@ -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,
)

View File

@ -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,12 +50,15 @@ 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 var mainServerAPI = base64DecodeAPI("cA==YXA=bC4=Y2U=ZXI=LnY=aWU=b3Y=LW0=cmE=c28=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"
const val dbgoAPI = "https://dbgo.fun"
@ -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,
@ -343,7 +349,15 @@ open class SoraStream : TmdbProvider() {
)
},
{
if(!res.isAnime) invokeHDMovieBox(res.title, res.season, res.episode, 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)
},
{
invokeSeries9(res.title, res.season, res.episode, subtitleCallback, callback)
@ -411,7 +425,7 @@ open class SoraStream : TmdbProvider() {
)
},
{
if(!res.isAnime) invokeUhdmovies(
if (!res.isAnime) invokeUhdmovies(
res.title,
res.year,
res.season,
@ -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(