diff --git a/SoraStream/build.gradle.kts b/SoraStream/build.gradle.kts index 7a874746..b88310a1 100644 --- a/SoraStream/build.gradle.kts +++ b/SoraStream/build.gradle.kts @@ -1,5 +1,5 @@ // use an integer for version numbers -version = 103 +version = 104 cloudstream { diff --git a/SoraStream/src/main/kotlin/com/hexated/SoraExtractor.kt b/SoraStream/src/main/kotlin/com/hexated/SoraExtractor.kt index 67947d5b..790ea7ae 100644 --- a/SoraStream/src/main/kotlin/com/hexated/SoraExtractor.kt +++ b/SoraStream/src/main/kotlin/com/hexated/SoraExtractor.kt @@ -2772,6 +2772,54 @@ object SoraExtractor : SoraStream() { } + //TODO add subtitle + suspend fun invokeWatchOnline( + imdbId: String? = null, + title: String? = null, + year: Int? = null, + season: Int? = null, + episode: Int? = null, + callback: (ExtractorLink) -> Unit, + ) { + val slug = title.createSlug() + val id = imdbId?.removePrefix("tt") + val url = if (season == null) { + "$watchOnlineAPI/movies/view/$id-$slug-$year" + } else { + "$watchOnlineAPI/shows/view/$id-$slug-$year" + } + + val res = app.get(url).document + + val episodeId = if (season == null) { + res.selectFirst("div.movie__buttons-items a")?.attr("data-watch-list-media-id") + } else { + res.selectFirst("ul[data-season-episodes=$season] li[data-episode=$episode]") + ?.attr("data-id-episode") + } ?: return + + val videoUrl = if (season == null) { + "$watchOnlineAPI/api/v1/security/movie-access?id_movie=$episodeId" + } else { + "$watchOnlineAPI/api/v1/security/episode-access?id=$episodeId" + } + + app.get(videoUrl, referer = url) + .parsedSafe()?.streams?.mapKeys { source -> + callback.invoke( + ExtractorLink( + "WatchOnline", + "WatchOnline", + source.value, + "$watchOnlineAPI/", + getQualityFromName(source.key), + true + ) + ) + } + + } + } @@ -3161,4 +3209,8 @@ data class BiliBiliSources( data class BiliBiliSourcesResponse( @JsonProperty("sources") val sources: ArrayList? = arrayListOf(), @JsonProperty("subtitles") val subtitles: ArrayList? = arrayListOf(), +) + +data class WatchOnlineResponse( + @JsonProperty("streams") val streams: HashMap? = null, ) \ No newline at end of file diff --git a/SoraStream/src/main/kotlin/com/hexated/SoraStream.kt b/SoraStream/src/main/kotlin/com/hexated/SoraStream.kt index a2976132..fb7a0595 100644 --- a/SoraStream/src/main/kotlin/com/hexated/SoraStream.kt +++ b/SoraStream/src/main/kotlin/com/hexated/SoraStream.kt @@ -50,6 +50,7 @@ import com.hexated.SoraExtractor.invokeTgarMovies import com.hexated.SoraExtractor.invokeTvMovies import com.hexated.SoraExtractor.invokeUhdmovies import com.hexated.SoraExtractor.invokeVitoenMovies +import com.hexated.SoraExtractor.invokeWatchOnline import com.hexated.SoraExtractor.invokeWatchsomuch import com.lagradost.cloudstream3.extractors.VidSrcExtractor import com.lagradost.cloudstream3.utils.AppUtils.parseJson @@ -120,6 +121,7 @@ open class SoraStream : TmdbProvider() { val gomoviesAPI = base64DecodeAPI("bQ==Y28=ZS4=aW4=bmw=LW8=ZXM=dmk=bW8=Z28=Ly8=czo=dHA=aHQ=") const val ask4MoviesAPI = "https://ask4movie.mx" const val biliBiliAPI = "https://api-vn.kaguya.app/server" + const val watchOnlineAPI = "https://watchonline.ag" // INDEX SITE const val baymoviesAPI = "https://opengatewayindex.pages.dev" // dead const val chillmovies0API = "https://chill.aicirou.workers.dev/0:" // dead @@ -787,6 +789,16 @@ open class SoraStream : TmdbProvider() { { if (!res.isAnime) invokeAsk4Movies(res.title, res.year, res.season, res.episode, subtitleCallback, callback) }, + { + invokeWatchOnline( + res.imdbId, + res.title, + res.airedYear ?: res.year, + res.season, + res.episode, + callback + ) + }, ) return true diff --git a/SoraStream/src/main/kotlin/com/hexated/SoraStreamLite.kt b/SoraStream/src/main/kotlin/com/hexated/SoraStreamLite.kt index 2517f740..86de35c8 100644 --- a/SoraStream/src/main/kotlin/com/hexated/SoraStreamLite.kt +++ b/SoraStream/src/main/kotlin/com/hexated/SoraStreamLite.kt @@ -24,6 +24,7 @@ import com.hexated.SoraExtractor.invokeSoraStreamLite import com.hexated.SoraExtractor.invokeTwoEmbed import com.hexated.SoraExtractor.invokeUniqueStream import com.hexated.SoraExtractor.invokeVidSrc +import com.hexated.SoraExtractor.invokeWatchOnline import com.hexated.SoraExtractor.invokeWatchsomuch import com.hexated.SoraExtractor.invokeXmovies import com.lagradost.cloudstream3.SubtitleFile @@ -222,6 +223,16 @@ class SoraStreamLite : SoraStream() { callback ) }, + { + invokeWatchOnline( + res.imdbId, + res.title, + res.airedYear ?: res.year, + res.season, + res.episode, + callback + ) + }, ) return true