diff --git a/app/src/main/java/eu/kanade/tachiyomi/data/download/anime/AnimeDownloader.kt b/app/src/main/java/eu/kanade/tachiyomi/data/download/anime/AnimeDownloader.kt index 95db64b2c..d72eced03 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/data/download/anime/AnimeDownloader.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/data/download/anime/AnimeDownloader.kt @@ -11,7 +11,6 @@ import com.arthenica.ffmpegkit.FFprobeSession import com.arthenica.ffmpegkit.Level import com.arthenica.ffmpegkit.LogCallback import com.arthenica.ffmpegkit.SessionState -import com.arthenica.ffmpegkit.StatisticsCallback import com.hippo.unifile.UniFile import com.jakewharton.rxrelay.PublishRelay import eu.kanade.domain.items.episode.model.toSEpisode @@ -506,23 +505,20 @@ class AnimeDownloader( } var duration = 0L - var nextLineIsDuration = false val logCallback = LogCallback { log -> - if (nextLineIsDuration) { - parseDuration(log.message)?.let { duration = it } - nextLineIsDuration = false - } - if (log.message == " Duration: ") nextLineIsDuration = true if (log.level <= Level.AV_LOG_WARNING) log.message?.let { logcat { it } } - } - val statisticsCallback = StatisticsCallback { - if (duration > 0L) { - video.progress = (100 * it.time.toLong() / duration).toInt() + if (duration != 0L && log.message.startsWith("frame=")) { + val outTime = log.message + .substringAfter("time=", "") + .substringBefore(" ", "") + .let { parseTimeStringToSeconds(it) } + if (outTime != null && outTime > 0L) video.progress = (100 * outTime / duration).toInt() } } - val session = FFmpegSession.create(ffmpegOptions, {}, logCallback, statisticsCallback) + val session = FFmpegSession.create(ffmpegOptions, {}, logCallback, {}) val inputDuration = getDuration(ffprobeCommand(video.videoUrl!!, headerOptions)) ?: 0F + duration = inputDuration.toLong() FFmpegKitConfig.ffmpegExecute(session) val outputDuration = getDuration(ffprobeCommand(ffmpegFilename(), null)) ?: 0F // allow for slight errors @@ -541,6 +537,27 @@ class AnimeDownloader( } } + private fun parseTimeStringToSeconds(timeString: String): Long? { + val parts = timeString.split(":") + if (parts.size != 3) { + // Invalid format + return null + } + + return try { + val hours = parts[0].toInt() + val minutes = parts[1].toInt() + val secondsAndMilliseconds = parts[2].split(".") + val seconds = secondsAndMilliseconds[0].toInt() + val milliseconds = secondsAndMilliseconds[1].toInt() + + (hours * 3600 + minutes * 60 + seconds + milliseconds / 100.0).toLong() + } catch (e: NumberFormatException) { + // Invalid number format + null + } + } + private fun getFFmpegOptions(video: Video, headerOptions: String, ffmpegFilename: String): Array { val subtitleInputs = video.subtitleTracks.joinToString(" ", postfix = " ") { "-i \"${it.url}\"" diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 561ae232f..16730c66c 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -91,8 +91,8 @@ voyager-transitions = { module = "ca.gosyer:voyager-transitions", version.ref = kotlinter = "org.jmailen.gradle:kotlinter-gradle:3.13.0" -aniyomi-mpv = "com.github.jmir1:aniyomi-mpv-lib:1.8.n" -ffmpeg-kit = "com.github.jmir1:ffmpeg-kit:1.8" +aniyomi-mpv = "com.github.aniyomiorg:aniyomi-mpv-lib:1.10.n" +ffmpeg-kit = "com.github.jmir1:ffmpeg-kit:1.10" arthenica-smartexceptions = "com.arthenica:smart-exception-java:0.1.1" seeker = "io.github.2307vivek:seeker:1.1.1" diff --git a/source-local/src/androidMain/kotlin/tachiyomi/source/local/entries/anime/LocalAnimeSource.kt b/source-local/src/androidMain/kotlin/tachiyomi/source/local/entries/anime/LocalAnimeSource.kt index dc3bd22fc..3b0dad1a8 100644 --- a/source-local/src/androidMain/kotlin/tachiyomi/source/local/entries/anime/LocalAnimeSource.kt +++ b/source-local/src/androidMain/kotlin/tachiyomi/source/local/entries/anime/LocalAnimeSource.kt @@ -200,8 +200,7 @@ actual class LocalAnimeSource( val duration = ffProbe.allLogsAsString.trim().toFloat() val second = duration.toInt() / 2 - val coverFilename = coverPath.toFFmpegString(context) - com.arthenica.ffmpegkit.FFmpegKit.execute("-ss $second -i \"${episodeFilename()}\" -frames 1 -q:v 2 \"$coverFilename\" -y") + com.arthenica.ffmpegkit.FFmpegKit.execute("-ss $second -i \"${episodeFilename()}\" -frames:v 1 -update true \"$coverPath\" -y") if (File(coverPath).exists()) { anime.thumbnail_url = coverPath