From 1614891bdcabdc5ceeadc91aed067a961d2bb1e1 Mon Sep 17 00:00:00 2001 From: Dark25 Date: Mon, 6 Jan 2025 01:47:23 +0100 Subject: [PATCH] fix: Aniplay --- src/en/aniplay/build.gradle | 2 +- .../animeextension/en/aniplay/AniPlay.kt | 180 +++++++++++------- .../animeextension/en/aniplay/AniPlayDto.kt | 48 +++-- 3 files changed, 148 insertions(+), 82 deletions(-) diff --git a/src/en/aniplay/build.gradle b/src/en/aniplay/build.gradle index e6dc109ab3..d3638755c5 100644 --- a/src/en/aniplay/build.gradle +++ b/src/en/aniplay/build.gradle @@ -2,7 +2,7 @@ ext { extName = 'AniPlay' extClass = '.AniPlay' themePkg = 'anilist' - overrideVersionCode = 8 + overrideVersionCode = 9 } apply from: "$rootDir/common.gradle" diff --git a/src/en/aniplay/src/eu/kanade/tachiyomi/animeextension/en/aniplay/AniPlay.kt b/src/en/aniplay/src/eu/kanade/tachiyomi/animeextension/en/aniplay/AniPlay.kt index 9dec8ff346..51ce98279e 100644 --- a/src/en/aniplay/src/eu/kanade/tachiyomi/animeextension/en/aniplay/AniPlay.kt +++ b/src/en/aniplay/src/eu/kanade/tachiyomi/animeextension/en/aniplay/AniPlay.kt @@ -17,7 +17,6 @@ import eu.kanade.tachiyomi.lib.playlistutils.PlaylistUtils import eu.kanade.tachiyomi.multisrc.anilist.AniListAnimeHttpSource import eu.kanade.tachiyomi.network.POST import eu.kanade.tachiyomi.util.parallelFlatMap -import eu.kanade.tachiyomi.util.parallelMap import eu.kanade.tachiyomi.util.parseAs import kotlinx.serialization.SerializationException import kotlinx.serialization.encodeToString @@ -183,99 +182,152 @@ class AniPlay : AniListAnimeHttpSource(), ConfigurableAnimeSource { } ?: emptyList() - val headersWithAction = - headers.newBuilder() - // next.js stuff I guess - .add("Next-Action", getHeaderValue(baseHost, NEXT_ACTION_SOURCES_LIST)) - .build() - var timeouts = 0 var maxTimeout = 0 - val episodeDataList = extras.parallelFlatMap { extra -> + val videos = extras.parallelFlatMap { extra -> val languages = mutableListOf("sub").apply { if (extra.hasDub) add("dub") } - languages.parallelMap { language -> - maxTimeout += 1 + languages.parallelFlatMap { language -> val epNum = if (extra.episodeNum == extra.episodeNum.toInt().toFloat()) { - extra.episodeNum.toInt().toString() // If it has no fractional part, convert it to an integer + extra.episodeNum.toInt().toString() } else { - extra.episodeNum.toString() // If it has a fractional part, leave it as a float + extra.episodeNum.toString() } - val requestBody = "[\"$animeId\",\"${extra.source}\",\"${extra.episodeId}\",\"$epNum\",\"$language\"]" - .toRequestBody("application/json".toMediaType()) - val params = mapOf( "host" to extra.source, "ep" to epNum, "type" to language, ) + val builder = Uri.parse("$baseUrl/anime/watch/$animeId").buildUpon() params.map { (k, v) -> builder.appendQueryParameter(k, v); } - val url = builder.build().toString() - try { - val request = POST(url, headersWithAction, requestBody) - val response = client.newCall(request).execute() + val url = builder.build() - val responseString = response.body.string() - val sourcesString = extractSourcesList(responseString) ?: return@parallelMap null - val data = sourcesString.parseAs() + val headersWithAction = + headers.newBuilder() + .add("Next-Action", getHeaderValue(baseHost, NEXT_ACTION_SOURCES_LIST)) + .build() - EpisodeData( - source = extra.source, - language = language, - response = data, - ) + val requestBody = "[\"$animeId\",\"${extra.source}\",\"${extra.episodeId}\",\"$epNum\",\"$language\"]" + .toRequestBody("application/json".toMediaType()) + + val request = POST(url.toString(), headersWithAction, requestBody) + + maxTimeout += 1 + try { + getVideos(extra, language, request) } catch (e: java.net.SocketTimeoutException) { - timeouts += 1 - null + Log.e("AniPlay", "VideoList $url SocketTimeoutException", e) + timeouts++ + emptyList() } catch (e: IOException) { - Log.w("AniPlay", "VideoList $url IOException", e) - timeouts = -999 - null // Return null to be filtered out + Log.e("AniPlay", "VideoList $url IOException", e) + emptyList() } catch (e: Exception) { - Log.w("AniPlay", "VideoList $url Exception", e) - timeouts = -999 - null // Return null to be filtered out + Log.e("AniPlay", "VideoList $url Exception", e) + emptyList() } - }.filterNotNull() // Filter out null values due to errors + } } - if (maxTimeout == timeouts && timeouts != 0) { + if (videos.isEmpty() && timeouts != 0 && maxTimeout == timeouts) { throw Exception("Timed out") } - val videos = episodeDataList.flatMap { episodeData -> - val defaultSource = episodeData.response.sources?.firstOrNull { - it.quality in listOf("default", "auto") - } ?: return@flatMap emptyList() - - val subtitles = episodeData.response.subtitles - ?.filter { it.lang != "Thumbnails" } - ?.map { Track(it.url, it.lang) } - ?: emptyList() - - try { - playlistUtils.extractFromHls( - playlistUrl = defaultSource.url, - videoNameGen = { quality -> - val serverName = getServerName(episodeData.source) - val typeName = when { - subtitles.isNotEmpty() -> "SoftSub" - else -> getTypeName(episodeData.language) - } - "$serverName - $quality - $typeName" - }, - subtitleList = subtitles, + return videos.sort() + } + + private fun getVideos(extra: EpisodeExtra, language: String, request: Request): List