Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ The format is a modified version of [Keep a Changelog](https://keepachangelog.co
- `Other` - for technical stuff.

## [Unreleased]
### Added
- Added option to skip broken tracks on download ([@Secozzi](https://github.com/Secozzi)) ([#169](https://github.com/quickdesh/Animiru/pull/169))

## [v0.19.7.7] - 2026-06-24
### Fixed
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,12 @@ object SettingsDownloadScreen : SearchableSettings {
preference = downloadPreferences.downloadOnlyOverWifi,
title = stringResource(MR.strings.connected_to_wifi),
),
// AM -->
Preference.PreferenceItem.SwitchPreference(
preference = downloadPreferences.ignoreBrokenTracks,
title = stringResource(AMMR.strings.pref_download_ignore_broken_tracks),
),
// <-- AM
Preference.PreferenceItem.SliderPreference(
value = parallelSourceLimit,
valueRange = 1..10,
Expand Down
61 changes: 53 additions & 8 deletions app/src/main/java/eu/kanade/tachiyomi/data/download/Downloader.kt
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ import eu.kanade.tachiyomi.animesource.online.AnimeHttpSource
import eu.kanade.tachiyomi.data.download.model.Download
import eu.kanade.tachiyomi.data.library.LibraryUpdateNotifier
import eu.kanade.tachiyomi.data.notification.NotificationHandler
import eu.kanade.tachiyomi.network.NetworkHelper
import eu.kanade.tachiyomi.network.awaitSuccess
import eu.kanade.tachiyomi.ui.player.loader.EpisodeLoader
import eu.kanade.tachiyomi.ui.player.loader.HosterLoader
import eu.kanade.tachiyomi.util.storage.DiskUtil
Expand Down Expand Up @@ -48,6 +50,9 @@ import kotlinx.coroutines.launch
import kotlinx.coroutines.supervisorScope
import kotlinx.coroutines.suspendCancellableCoroutine
import logcat.LogPriority
import okhttp3.Headers
import okhttp3.OkHttpClient
import okhttp3.Request
import tachiyomi.core.common.i18n.stringResource
import tachiyomi.core.common.storage.extension
import tachiyomi.core.common.util.lang.launchIO
Expand All @@ -64,6 +69,7 @@ import tachiyomi.i18n.animiru.AMMR
import tachiyomi.i18n.aniyomi.AYMR
import uy.kohesive.injekt.Injekt
import uy.kohesive.injekt.api.get
import uy.kohesive.injekt.injectLazy
import java.io.BufferedReader
import kotlin.coroutines.resume
import kotlin.coroutines.resumeWithException
Expand Down Expand Up @@ -106,6 +112,12 @@ class Downloader(
val isRunning: Boolean
get() = downloaderJob?.isActive ?: false

// AM -->
val networkService: NetworkHelper by injectLazy()
val client: OkHttpClient
get() = networkService.client
// <-- AM

/**
* Whether the downloader is paused
*/
Expand Down Expand Up @@ -533,7 +545,7 @@ class Downloader(
"${it.first}: ${it.second}\r\n"
}

val ffmpegOptions = getFFmpegOptions(video, headerOptions, ffmpegFilename())
val ffmpegOptions = getFFmpegOptions(video, headers, headerOptions, ffmpegFilename())
val duration = getDuration(video.videoUrl, headerOptions)?.toLong() ?: 0L

val logCallback = LogCallback { log ->
Expand Down Expand Up @@ -574,7 +586,14 @@ class Downloader(
}
}

private fun getFFmpegOptions(video: Video, headerOptions: String, ffmpegFilename: String): Array<String> {
private suspend fun getFFmpegOptions(
video: Video,
// AM -->
headers: Headers,
// <-- AM
headerOptions: String,
ffmpegFilename: String,
): Array<String> {
fun formatInputs(tracks: List<Track>) = tracks.joinToString(" ", postfix = " ") {
buildList {
if (it.url.startsWith("http")) {
Expand All @@ -593,13 +612,19 @@ class Downloader(
"-metadata:s:$type:$i \"title=${track.lang}\""
}.joinToString(" ")

val subtitleInputs = formatInputs(video.subtitleTracks)
val subtitleMaps = formatMaps(video.subtitleTracks, "s")
val subtitleMetadata = formatMetadata(video.subtitleTracks, "s")
// AM -->
val subtitleTracks = filterTracks(video.subtitleTracks, headers)
// <-- AM
val subtitleInputs = formatInputs(subtitleTracks)
val subtitleMaps = formatMaps(subtitleTracks, "s")
val subtitleMetadata = formatMetadata(subtitleTracks, "s")

val audioInputs = formatInputs(video.audioTracks)
val audioMaps = formatMaps(video.audioTracks, "a", video.subtitleTracks.size)
val audioMetadata = formatMetadata(video.audioTracks, "a")
// AM -->
val audioTracks = filterTracks(video.audioTracks, headers)
// <-- AM
val audioInputs = formatInputs(audioTracks)
val audioMaps = formatMaps(audioTracks, "a", subtitleTracks.size)
val audioMetadata = formatMetadata(audioTracks, "a")

val sourceStreamOptions = video.ffmpegStreamArgs.joinToString(" ") { (key, value) ->
"-$key \"$value\""
Expand Down Expand Up @@ -630,6 +655,26 @@ class Downloader(
return FFmpegKitConfig.parseArguments(command)
}

// AM -->
private suspend fun filterTracks(tracks: List<Track>, headers: Headers): List<Track> {
if (!downloadPreferences.ignoreBrokenTracks.get()) return tracks

return tracks.mapNotNull { track ->
try {
val request = Request.Builder()
.url(track.url)
.headers(headers)
.head()
.build()
client.newCall(request).awaitSuccess()
track
} catch (_: Exception) {
null
}
}
}
// <-- AM

private suspend fun getDuration(videoUrl: String, headerOptions: String): Float? {
val durationFile = context.createFileInCacheDir("ffprobe_duration.txt")
val durationFilePath = durationFile.toUri().toFFmpegString(context)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,13 @@ class DownloadPreferences(
true,
)

// AM -->
val ignoreBrokenTracks: Preference<Boolean> = preferenceStore.getBoolean(
"pref_download_ignore_broken_tracks",
false,
)
// <-- AM

// AY -->
val useExternalDownloader: Preference<Boolean> = preferenceStore.getBoolean("use_external_downloader", false)

Expand Down
3 changes: 3 additions & 0 deletions i18n-animiru/src/commonMain/moko-resources/base/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,9 @@
<string name="action_edit_info">Edit info</string>
<string name="custom_entry_info">Custom entry info</string>

<!-- Downloads -->
<string name="pref_download_ignore_broken_tracks">Skip broken external tracks</string>

<!-- Storage overview -->
<string name="pref_storage_overview">Storage overview</string>
<string name="calculating_storage_overview">Calculating storage usage... (%1$s)</string>
Expand Down
Loading