diff --git a/app/src/main/java/com/lagradost/cloudstream3/utils/AniSkip.kt b/app/src/main/java/com/lagradost/cloudstream3/utils/AniSkip.kt index 820a01f9f4..bbdadbf3f5 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/utils/AniSkip.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/utils/AniSkip.kt @@ -2,8 +2,10 @@ package com.lagradost.cloudstream3.utils import android.util.Log import androidx.annotation.StringRes +import com.fasterxml.jackson.annotation.JsonProperty import com.fasterxml.jackson.databind.annotation.JsonSerialize import com.lagradost.cloudstream3.* +import com.lagradost.cloudstream3.LoadResponse.Companion.getImdbId import com.lagradost.cloudstream3.LoadResponse.Companion.getMalId import com.lagradost.cloudstream3.mvvm.logError import com.lagradost.cloudstream3.ui.result.ResultEpisode @@ -86,7 +88,57 @@ object EpisodeSkip { out.addAll(list) } } + } else if (data.type == TvType.TvSeries || data.type == TvType.AsianDrama) { + val season = episode.season + val imdbId = data.getImdbId() + + if (season != null && imdbId != null) { + val result = IntroDbSkip.getResult( + imdbId, + season, + episode.episode + ) + + result?.let { res -> + listOfNotNull( + res.intro?.let { + val start = it.startMs ?: return@let null + val end = it.endMs ?: return@let null + SkipStamp( + type = SkipType.Opening, + skipToNextEpisode = hasNextEpisode && + shouldSkipToNextEpisode(end, episodeDurationMs), + startMs = start, + endMs = end + ) + }, + res.recap?.let { + val start = it.startMs ?: return@let null + val end = it.endMs ?: return@let null + SkipStamp( + type = SkipType.Recap, + skipToNextEpisode = hasNextEpisode && + shouldSkipToNextEpisode(end, episodeDurationMs), + startMs = start, + endMs = end + ) + }, + res.outro?.let { + val start = it.startMs ?: return@let null + val end = it.endMs ?: return@let null + SkipStamp( + type = SkipType.Credits, + skipToNextEpisode = hasNextEpisode && + shouldSkipToNextEpisode(end, episodeDurationMs), + startMs = start, + endMs = end + ) + } + ).let { out.addAll(it) } + } + } } + if (out.isNotEmpty()) cachedStamps[episode.id] = out return out @@ -136,4 +188,43 @@ object AniSkip { @JsonSerialize val startTime: Double, @JsonSerialize val endTime: Double ) +} + +object IntroDbSkip { + private const val TAG = "IntroDb" + + suspend fun getResult( + imdbId: String, + season: Int, + episode: Int, + ): IntroDbResponse? { + return try { + val url = + "https://api.introdb.app/segments?imdb_id=$imdbId&season=$season&episode=$episode" + app.get(url).parsed() + } catch (t: Throwable) { + Log.i(TAG, "error = ${t.message}") + logError(t) + null + } + } + + data class IntroDbResponse( + @JsonProperty("imdb_id") val imdbId: String?, + val season: Int?, + val episode: Int?, + val intro: Segment?, + val recap: Segment?, + val outro: Segment?, + ) + + data class Segment( + @JsonProperty("start_sec") val startSec: Double?, + @JsonProperty("end_sec") val endSec: Double?, + @JsonProperty("start_ms") val startMs: Long?, + @JsonProperty("end_ms") val endMs: Long?, + val confidence: Double?, + @JsonProperty("submission_count") val submissionCount: Int?, + @JsonProperty("updated_at") val updatedAt: String?, + ) } \ No newline at end of file