diff --git a/app/src/main/java/com/lagradost/cloudstream3/ui/player/FullScreenPlayer.kt b/app/src/main/java/com/lagradost/cloudstream3/ui/player/FullScreenPlayer.kt index d90b6043f28..f38a9ab99fd 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/ui/player/FullScreenPlayer.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/ui/player/FullScreenPlayer.kt @@ -102,12 +102,12 @@ open class FullScreenPlayer : AbstractPlayerFragment( private var hideControlsNames = false protected var subtitleDelay set(value) = try { - player.setSubtitleOffset(-value) + player.setSubtitleOffset(value) } catch (e: Exception) { logError(e) } get() = try { - -player.getSubtitleOffset() + player.getSubtitleOffset() } catch (e: Exception) { logError(e) 0L @@ -527,7 +527,7 @@ open class FullScreenPlayer : AbstractPlayerFragment( // Scroll to the first active subtitle val playerPosition = player.getPosition() ?: 0 - val totalPosition = playerPosition - currentOffset + val totalPosition = playerPosition + currentOffset subtitleAdapter?.updateTime(totalPosition) subtitleAdapter?.getLatestActiveItem(totalPosition) @@ -537,11 +537,11 @@ open class FullScreenPlayer : AbstractPlayerFragment( val str = when { time > 0L -> { - txt(R.string.subtitle_offset_extra_hint_later_format, time) + txt(R.string.subtitle_offset_extra_hint_before_format, time) } time < 0L -> { - txt(R.string.subtitle_offset_extra_hint_before_format, -time) + txt(R.string.subtitle_offset_extra_hint_later_format, -time) } else -> { @@ -559,12 +559,12 @@ open class FullScreenPlayer : AbstractPlayerFragment( subtitleOffsetRecyclerview.isVisible = subtitles.isNotEmpty() noSubtitlesLoadedNotice.isVisible = subtitles.isEmpty() - val initialSubtitlePosition = (player.getPosition() ?: 0) - currentOffset + val initialSubtitlePosition = (player.getPosition() ?: 0) + currentOffset subtitleAdapter = SubtitleOffsetItemAdapter(initialSubtitlePosition) { subtitleCue -> val playerPosition = player.getPosition() ?: 0 subtitleOffsetInput.text = Editable.Factory.getInstance() - ?.newEditable((playerPosition - subtitleCue.startTimeMs).toString()) + ?.newEditable((subtitleCue.startTimeMs - playerPosition).toString()) }.apply { submitList(subtitles) } diff --git a/app/src/main/java/com/lagradost/cloudstream3/ui/player/GeneratorPlayer.kt b/app/src/main/java/com/lagradost/cloudstream3/ui/player/GeneratorPlayer.kt index 4495a560262..b05eb3488b7 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/ui/player/GeneratorPlayer.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/ui/player/GeneratorPlayer.kt @@ -47,6 +47,7 @@ import androidx.preference.PreferenceManager import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.RecyclerView import com.lagradost.cloudstream3.APIHolder.getApiFromNameNull +import com.lagradost.cloudstream3.AllLanguagesName import com.lagradost.cloudstream3.CloudStreamApp import com.lagradost.cloudstream3.CloudStreamApp.Companion.setKey import com.lagradost.cloudstream3.CommonActivity.showToast @@ -101,6 +102,7 @@ import com.lagradost.cloudstream3.ui.settings.Globals.isLayout import com.lagradost.cloudstream3.ui.subtitles.SUBTITLE_AUTO_SELECT_KEY import com.lagradost.cloudstream3.ui.subtitles.SubtitlesFragment import com.lagradost.cloudstream3.ui.subtitles.SubtitlesFragment.Companion.getAutoSelectLanguageTagIETF +import com.lagradost.cloudstream3.utils.AppContextUtils.getApiProviderLangSettings import com.lagradost.cloudstream3.utils.AppContextUtils.getShortSeasonText import com.lagradost.cloudstream3.utils.AppContextUtils.html import com.lagradost.cloudstream3.utils.AppContextUtils.sortSubs @@ -112,7 +114,7 @@ import com.lagradost.cloudstream3.utils.ExtractorLink import com.lagradost.cloudstream3.utils.ExtractorLinkType import com.lagradost.cloudstream3.utils.Qualities import com.lagradost.cloudstream3.utils.SingleSelectionHelper.showDialog -import com.lagradost.cloudstream3.utils.SubtitleHelper.fromTagToEnglishLanguageName +import com.lagradost.cloudstream3.utils.SubtitleHelper.fromCodeToLangTagIETF import com.lagradost.cloudstream3.utils.SubtitleHelper.fromTagToLanguageName import com.lagradost.cloudstream3.utils.SubtitleHelper.languages import com.lagradost.cloudstream3.utils.UIHelper.clipboardHelper @@ -1195,20 +1197,29 @@ class GeneratorPlayer : FullScreenPlayer() { ArrayAdapter(ctx, R.layout.sort_bottom_single_choice) subsArrayAdapter.add(ctx.getString(R.string.no_subtitles).html()) + val unknownGroupName = ctx.getString(R.string.subtitles_group_unknown) + val subtitlesWithGroup = currentSubtitles.map { sub -> + (fromTagToLanguageName(sub.getIETF_tag())?.takeIf { it.isNotBlank() } + ?: unknownGroupName) to sub + } + val subtitlesGrouped = - currentSubtitles.groupBy { it.originalName }.map { (key, value) -> + subtitlesWithGroup.groupBy({ it.first }, { it.second }).map { (key, value) -> key to value.sortedBy { it.nameSuffix.toIntOrNull() ?: 0 } }.toMap() val subtitlesGroupedList = subtitlesGrouped.entries.toList() val subtitles = subtitlesGrouped.map { it.key.html() } + val selectedGroup = + subtitlesWithGroup.firstOrNull { it.second == currentSelectedSubtitles }?.first + val subtitleGroupIndexStart = - subtitlesGrouped.keys.indexOf(currentSelectedSubtitles?.originalName) + 1 + subtitlesGrouped.keys.indexOf(selectedGroup) + 1 var subtitleGroupIndex = subtitleGroupIndexStart val subtitleOptionIndexStart = - subtitlesGrouped[currentSelectedSubtitles?.originalName]?.indexOfFirst { it.nameSuffix == currentSelectedSubtitles?.nameSuffix } + subtitlesGrouped[selectedGroup]?.indexOfFirst { it.nameSuffix == currentSelectedSubtitles?.nameSuffix } ?: 0 var subtitleOptionIndex = subtitleOptionIndexStart @@ -1229,19 +1240,30 @@ class GeneratorPlayer : FullScreenPlayer() { fun updateSubtitleOptionList() { subsOptionsArrayAdapter.clear() + val groupSubtitles = subtitlesGroupedList.getOrNull(subtitleGroupIndex - 1)?.value + + val duplicateNames = groupSubtitles.orEmpty() + .groupingBy { it.originalName }.eachCount().filterValues { it > 1 }.keys + val nameIndex = mutableMapOf() + val subtitleOptions = - subtitlesGroupedList - .getOrNull(subtitleGroupIndex - 1)?.value?.map { subtitle -> - val nameSuffix = subtitle.nameSuffix.html() - nameSuffix.ifBlank { - when (subtitle.origin) { - SubtitleOrigin.URL -> txt(R.string.subtitles_from_online) - SubtitleOrigin.DOWNLOADED_FILE -> txt(R.string.downloaded) - SubtitleOrigin.EMBEDDED_IN_VIDEO -> txt(R.string.subtitles_from_embedded) - }.asString(ctx).toSpanned() + groupSubtitles?.map { subtitle -> + val label = if (subtitle.originalName in duplicateNames) { + val suffix = subtitle.nameSuffix.ifBlank { + val next = (nameIndex[subtitle.originalName] ?: 0) + 1 + nameIndex[subtitle.originalName] = next + next.toString() } + "${subtitle.originalName} $suffix" + } else subtitle.originalName + label.html().ifBlank { + when (subtitle.origin) { + SubtitleOrigin.URL -> txt(R.string.subtitles_from_online) + SubtitleOrigin.DOWNLOADED_FILE -> txt(R.string.downloaded) + SubtitleOrigin.EMBEDDED_IN_VIDEO -> txt(R.string.subtitles_from_embedded) + }.asString(ctx).toSpanned() } - ?: emptyList() + } ?: emptyList() // Show nothing if there is nothing to select val shouldHide = subtitleOptions.size < 2 @@ -2264,12 +2286,10 @@ class GeneratorPlayer : FullScreenPlayer() { viewModel.filterSubByLang = settingsManager.getBoolean(getString(R.string.filter_sub_lang_key), false) if (viewModel.filterSubByLang) { - val langFromPrefMedia = settingsManager.getStringSet( - this.getString(R.string.provider_lang_key), mutableSetOf("en") - ) - viewModel.langFilterList = langFromPrefMedia?.mapNotNull { - fromTagToEnglishLanguageName(it)?.lowercase() ?: return@mapNotNull null - } ?: listOf() + viewModel.langFilterList = ctx.getApiProviderLangSettings().map { tag -> + if (tag == AllLanguagesName) tag + else fromCodeToLangTagIETF(tag)?.lowercase() ?: tag.lowercase() + } } // Set up TV clock visibility diff --git a/app/src/main/java/com/lagradost/cloudstream3/ui/player/PlayerGeneratorViewModel.kt b/app/src/main/java/com/lagradost/cloudstream3/ui/player/PlayerGeneratorViewModel.kt index cb8cf8bfff5..0e1e381c88b 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/ui/player/PlayerGeneratorViewModel.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/ui/player/PlayerGeneratorViewModel.kt @@ -5,6 +5,7 @@ import androidx.lifecycle.LiveData import androidx.lifecycle.MutableLiveData import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope +import com.lagradost.cloudstream3.AllLanguagesName import com.lagradost.cloudstream3.LoadResponse import com.lagradost.cloudstream3.mvvm.Resource import com.lagradost.cloudstream3.mvvm.launchSafe @@ -371,13 +372,18 @@ class PlayerGeneratorViewModel : ViewModel() { return true } - /** Only filter out subtitles fetched online */ - if (subtitle.origin != SubtitleOrigin.URL) { + if (langFilterList.contains(AllLanguagesName)) { return true } + if (subtitle.origin == SubtitleOrigin.DOWNLOADED_FILE) { + return true + } + + val subtitleTag = subtitle.getIETF_tag()?.lowercase() ?: return true + return langFilterList.any { lang -> - subtitle.originalName.contains(lang, ignoreCase = true) + subtitleTag == lang || subtitleTag.substringBefore('-') == lang.substringBefore('-') } } diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 87e447ccb69..0ca11df954e 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -488,6 +488,7 @@ Remove closed captions from subtitles Remove bloat from subtitles Filter by preferred media language + Unknown Extras Trailer https://example.com/example.mp4