From f57e2ea5afb322df8bac3bb86da840380ee70c55 Mon Sep 17 00:00:00 2001 From: V3u47ZoN Date: Thu, 24 Apr 2025 11:53:03 +0000 Subject: [PATCH] Kickassanime & Hianime: Fix subtitles (#937) * Fix subtitles * Update PlaylistUtils.kt * Update MegaCloudExtractor.kt * Update AniPlay.kt * Update MegaCloudExtractor.kt * Fix regex * Fix subtitles for kickassanime * Update build.gradle * Update build.gradle * Update build.gradle.kts * Update build.gradle.kts * Update build.gradle * Update build.gradle --- .../megacloudextractor/MegaCloudExtractor.kt | 3 ++- .../lib/playlistutils/PlaylistUtils.kt | 27 +++++++++++++++++++ .../animeextension/en/aniplay/AniPlay.kt | 2 +- .../extractors/KickAssAnimeExtractor.kt | 8 +++--- 4 files changed, 35 insertions(+), 5 deletions(-) diff --git a/lib/megacloud-extractor/src/main/java/eu/kanade/tachiyomi/lib/megacloudextractor/MegaCloudExtractor.kt b/lib/megacloud-extractor/src/main/java/eu/kanade/tachiyomi/lib/megacloudextractor/MegaCloudExtractor.kt index eb8ff488..6b4d2fcf 100644 --- a/lib/megacloud-extractor/src/main/java/eu/kanade/tachiyomi/lib/megacloudextractor/MegaCloudExtractor.kt +++ b/lib/megacloud-extractor/src/main/java/eu/kanade/tachiyomi/lib/megacloudextractor/MegaCloudExtractor.kt @@ -47,7 +47,7 @@ class MegaCloudExtractor( private var shouldUpdateKey = false private const val PREF_KEY_KEY = "megacloud_key_" private const val PREF_KEY_DEFAULT = "[[0, 0]]" - + private inline fun runLocked(crossinline block: () -> R) = runBlocking(Dispatchers.IO) { MUTEX.withLock { block() } } @@ -132,6 +132,7 @@ class MegaCloudExtractor( ?.filter { it.kind == "captions" } ?.map { Track(it.file, it.label) } .orEmpty() + .let { playlistUtils.fixSubtitles(it) } return playlistUtils.extractFromHls( masterUrl, videoNameGen = { "$name - $it - $type" }, diff --git a/lib/playlist-utils/src/main/java/eu/kanade/tachiyomi/lib/playlistutils/PlaylistUtils.kt b/lib/playlist-utils/src/main/java/eu/kanade/tachiyomi/lib/playlistutils/PlaylistUtils.kt index f7adb84c..2bf6f1de 100644 --- a/lib/playlist-utils/src/main/java/eu/kanade/tachiyomi/lib/playlistutils/PlaylistUtils.kt +++ b/lib/playlist-utils/src/main/java/eu/kanade/tachiyomi/lib/playlistutils/PlaylistUtils.kt @@ -1,5 +1,6 @@ package eu.kanade.tachiyomi.lib.playlistutils +import android.net.Uri import eu.kanade.tachiyomi.animesource.model.Track import eu.kanade.tachiyomi.animesource.model.Video import eu.kanade.tachiyomi.network.GET @@ -8,6 +9,7 @@ import okhttp3.Headers import okhttp3.HttpUrl.Companion.toHttpUrl import okhttp3.OkHttpClient import okhttp3.internal.commonEmptyHeaders +import java.io.File import kotlin.math.abs class PlaylistUtils(private val client: OkHttpClient, private val headers: Headers = commonEmptyHeaders) { @@ -342,7 +344,32 @@ class PlaylistUtils(private val client: OkHttpClient, private val headers: Heade return "${result}p" } + private fun cleanSubtitleData(matchResult: MatchResult): String { + val lineCount = matchResult.groupValues[1].count { it == '\n' } + return "\n" + " \n".repeat(lineCount - 1) + } + + fun fixSubtitles(subtitleList: List): List { + return subtitleList.mapNotNull { + try { + val subData = client.newCall(GET(it.url)).execute().body.string() + + val file = File.createTempFile("subs", "vtt") + .also(File::deleteOnExit) + + file.writeText(FIX_SUBTITLE_REGEX.replace(subData, ::cleanSubtitleData)) + val uri = Uri.fromFile(file) + + Track(uri.toString(), it.lang) + } catch (_: Exception) { + null + } + } + } + companion object { + private val FIX_SUBTITLE_REGEX = Regex("""${'$'}(\n{2,})(?!(?:\d+:)*\d+(?:\.\d+)?\s-+>\s(?:\d+:)*\d+(?:\.\d+)?)""", RegexOption.MULTILINE) + private const val PLAYLIST_SEPARATOR = "#EXT-X-STREAM-INF:" private val SUBTITLE_REGEX by lazy { Regex("""#EXT-X-MEDIA:TYPE=SUBTITLES.*?NAME="(.*?)".*?URI="(.*?)"""") } 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 d67d4714..ffc65aaa 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 @@ -291,7 +291,7 @@ class AniPlay : AniListAnimeHttpSource(), ConfigurableAnimeSource { return playlistUtils.extractFromHls( playlistUrl = url, videoNameGen = { quality -> "$serverName - $quality - $typeName" }, - subtitleList = subtitles, + subtitleList = playlistUtils.fixSubtitles(subtitles), masterHeadersGen = { baseHeaders: Headers, _: String -> baseHeaders.newBuilder().apply { set("Accept", "*/*") diff --git a/src/en/kickassanime/src/eu/kanade/tachiyomi/animeextension/en/kickassanime/extractors/KickAssAnimeExtractor.kt b/src/en/kickassanime/src/eu/kanade/tachiyomi/animeextension/en/kickassanime/extractors/KickAssAnimeExtractor.kt index 0fc5d08c..d256986b 100644 --- a/src/en/kickassanime/src/eu/kanade/tachiyomi/animeextension/en/kickassanime/extractors/KickAssAnimeExtractor.kt +++ b/src/en/kickassanime/src/eu/kanade/tachiyomi/animeextension/en/kickassanime/extractors/KickAssAnimeExtractor.kt @@ -18,6 +18,8 @@ class KickAssAnimeExtractor( private val json: Json, private val headers: Headers, ) { + private val playlistUtils by lazy { PlaylistUtils(client, headers) } + fun videosFromUrl(url: String, name: String): List