This commit is contained in:
LagradOst 2021-11-30 18:59:52 +01:00
parent 517e77fdfb
commit 2932768891
9 changed files with 190 additions and 90 deletions

View file

@ -7,7 +7,6 @@ import com.fasterxml.jackson.databind.DeserializationFeature
import com.fasterxml.jackson.databind.json.JsonMapper
import com.fasterxml.jackson.module.kotlin.KotlinModule
import com.lagradost.cloudstream3.animeproviders.*
import com.lagradost.cloudstream3.metaproviders.TmdbProvider
import com.lagradost.cloudstream3.movieproviders.*
import com.lagradost.cloudstream3.utils.ExtractorLink
import java.util.*

View file

@ -920,9 +920,9 @@ class PlayerFragment : Fragment() {
private var resizeMode = 0
private var playbackSpeed = 0f
private var allEpisodes: HashMap<Int, ArrayList<ExtractorLink>> = HashMap()
private var allEpisodesSubs: HashMap<Int, ArrayList<SubtitleFile>> = HashMap()
private var episodes: List<ResultEpisode> = ArrayList()
private var allEpisodes: HashMap<Int, List<ExtractorLink>> = HashMap()
private var allEpisodesSubs: HashMap<Int, HashMap<String, SubtitleFile>> = HashMap()
private var episodes: List<ResultEpisode> = emptyList()
var currentPoster: String? = null
var currentHeaderName: String? = null
var currentIsMovie: Boolean? = null
@ -1138,7 +1138,7 @@ class PlayerFragment : Fragment() {
context?.let { ctx ->
//val isPlaying = exoPlayer.isPlaying
exoPlayer.pause()
val currentSubtitles = activeSubtitles
val currentSubtitles = context?.getSubs()?.map { it.lang } ?: activeSubtitles
val sourceBuilder = AlertDialog.Builder(ctx, R.style.AlertDialogCustomBlack)
.setView(R.layout.player_select_source_and_subs)
@ -1189,8 +1189,8 @@ class PlayerFragment : Fragment() {
}
val startIndexFromMap =
currentSubtitles.map { it.removeSuffix(" ") }
.indexOf(preferredSubtitles.removeSuffix(" ")) + 1
currentSubtitles.map { it.trimEnd() }
.indexOf(preferredSubtitles.trimEnd()) + 1
var subtitleIndex = startIndexFromMap
if (currentSubtitles.isEmpty()) {
@ -1218,13 +1218,27 @@ class PlayerFragment : Fragment() {
}
applyButton.setOnClickListener {
if (this::exoPlayer.isInitialized) playbackPosition = exoPlayer.currentPosition
var init = false
if (sourceIndex != startSource) {
playbackPosition = if (this::exoPlayer.isInitialized) exoPlayer.currentPosition else 0
setMirrorId(sources[sourceIndex].getId())
initPlayer(getCurrentUrl())
init = true
}
if (subtitleIndex != startIndexFromMap) {
setPreferredSubLanguage(if (subtitleIndex <= 0) null else currentSubtitles[subtitleIndex - 1])
if (subtitleIndex <= 0) {
setPreferredSubLanguage(null)
} else {
val langId = currentSubtitles[subtitleIndex - 1].trimEnd()
setPreferredSubLanguage(langId)
if (!activeSubtitles.any { it.trimEnd() == langId }) {
init = true
}
}
}
if (init) {
initPlayer(getCurrentUrl())
}
sourceDialog.dismiss()
}
@ -1253,7 +1267,7 @@ class PlayerFragment : Fragment() {
private fun setPreferredSubLanguage(lang: String?) {
//val textRendererIndex = getRendererIndex(C.TRACK_TYPE_TEXT) ?: return@setOnClickListener
val realLang = if (lang.isNullOrBlank()) "" else lang
val realLang = if (lang.isNullOrBlank()) "" else lang.trimEnd()
preferredSubtitles =
if (realLang.length == 2) SubtitleHelper.fromTwoLettersToLanguage(realLang) ?: realLang else realLang
@ -1268,7 +1282,7 @@ class PlayerFragment : Fragment() {
} else {
trackSelector.setParameters(
trackSelector.buildUponParameters()
.setPreferredTextLanguage(realLang)
.setPreferredTextLanguage("_$realLang")
//.setRendererDisabled(textRendererIndex, false)
)
}
@ -1423,7 +1437,9 @@ class PlayerFragment : Fragment() {
player_media_route_button?.isVisible = !isDownloadedFile
if (savedInstanceState != null) {
currentWindow = savedInstanceState.getInt(STATE_RESUME_WINDOW)
if (playbackPosition <= 0) {
playbackPosition = savedInstanceState.getLong(STATE_RESUME_POSITION)
}
isFullscreen = savedInstanceState.getBoolean(STATE_PLAYER_FULLSCREEN)
isPlayerPlaying = savedInstanceState.getBoolean(STATE_PLAYER_PLAYING)
resizeMode = savedInstanceState.getInt(RESIZE_MODE_KEY)
@ -1479,6 +1495,13 @@ class PlayerFragment : Fragment() {
observeDirectly(viewModel.allEpisodesSubs) { _allEpisodesSubs ->
allEpisodesSubs = _allEpisodesSubs
if (preferredSubtitles != "" && !activeSubtitles.contains(preferredSubtitles) && allEpisodesSubs[getEpisode()?.id]?.containsKey(
preferredSubtitles
) == true
) {
if (this::exoPlayer.isInitialized) playbackPosition = exoPlayer.currentPosition
initPlayer(getCurrentUrl())
}
}
observeDirectly(viewModel.resultResponse) { data ->
@ -1495,6 +1518,8 @@ class PlayerFragment : Fragment() {
is Resource.Failure -> {
//WTF, HOW DID YOU EVEN GET HERE
}
else -> {
}
}
}
}
@ -1685,7 +1710,7 @@ class PlayerFragment : Fragment() {
}
return list
} else {
allEpisodesSubs[getEpisode()?.id]
allEpisodesSubs[getEpisode()?.id]?.values?.toList()?.sortedBy { it.lang }
}
} catch (e: Exception) {
null
@ -1952,13 +1977,13 @@ class PlayerFragment : Fragment() {
val subItemsId = ArrayList<String>()
for (sub in sortSubs(subs)) {
val langId = sub.lang //SubtitleHelper.fromLanguageToTwoLetters(it.lang) ?: it.lang
val langId = sub.lang.trimEnd() //SubtitleHelper.fromLanguageToTwoLetters(it.lang) ?: it.lang
subItemsId.add(langId)
subItems.add(
MediaItem.Subtitle(
Uri.parse(sub.url),
sub.url.toSubtitleMimeType(),
langId,
"_$langId",
C.SELECTION_FLAG_DEFAULT
)
)
@ -2014,6 +2039,7 @@ class PlayerFragment : Fragment() {
databaseProvider
)
}
val cacheFactory = CacheDataSource.Factory().apply {
simpleCache?.let { setCache(it) }
setUpstreamDataSourceFactory(getDataSourceFactory())
@ -2084,7 +2110,6 @@ class PlayerFragment : Fragment() {
player_view?.performClick()
//TODO FIX
video_title?.text = hName +
if (isEpisodeBased)
if (epSeason == null)
@ -2199,7 +2224,7 @@ class PlayerFragment : Fragment() {
}
override fun onPlayerError(error: PlaybackException) {
println("CURRENT URL: " + currentUrl?.url)
println("CURRENT URL ERROR: " + currentUrl?.url)
// Lets pray this doesn't spam Toasts :)
val msg = error.message ?: ""
val errorName = error.errorCodeName

View file

@ -126,7 +126,7 @@ fun Context.buildResultEpisode(
id: Int,
index: Int,
rating: Int?,
descript: String?,
description: String?,
isFiller: Boolean?,
): ResultEpisode {
val posDur = getViewPos(id)
@ -142,7 +142,7 @@ fun Context.buildResultEpisode(
posDur?.position ?: 0,
posDur?.duration ?: 0,
rating,
descript,
description,
isFiller
)
}
@ -167,8 +167,8 @@ class ResultFragment : Fragment() {
private var currentLoadingCount = 0 // THIS IS USED TO PREVENT LATE EVENTS, AFTER DISMISS WAS CLICKED
private val viewModel: ResultViewModel by activityViewModels()
private var allEpisodes: HashMap<Int, ArrayList<ExtractorLink>> = HashMap()
private var allEpisodesSubs: HashMap<Int, ArrayList<SubtitleFile>> = HashMap()
private var allEpisodes: HashMap<Int, List<ExtractorLink>> = HashMap()
private var allEpisodesSubs: HashMap<Int, HashMap<String, SubtitleFile>> = HashMap()
private var currentHeaderName: String? = null
private var currentType: TvType? = null
private var currentEpisodes: List<ResultEpisode>? = null
@ -352,8 +352,8 @@ class ResultFragment : Fragment() {
val index = episodeClick.data.index
val buildInPlayer = true
currentLoadingCount++
var currentLinks: ArrayList<ExtractorLink>? = null
var currentSubs: ArrayList<SubtitleFile>? = null
var currentLinks: List<ExtractorLink>? = null
var currentSubs: HashMap<String, SubtitleFile>? = null
val showTitle =
episodeClick.data.name ?: getString(R.string.episode_name_format).format(
@ -443,7 +443,7 @@ class ResultFragment : Fragment() {
episodeClick.data.index,
eps,
sortUrls(currentLinks ?: return),
currentSubs ?: ArrayList(),
currentSubs?.values?.toList() ?: emptyList(),
startTime = episodeClick.data.getRealPosition(),
startIndex = startIndex
)
@ -673,7 +673,7 @@ class ResultFragment : Fragment() {
}
var text = "#EXTM3U"
if (subs != null) {
for (sub in subs) {
for (sub in subs.values) {
text += "\n#EXT-X-MEDIA:TYPE=SUBTITLES,GROUP-ID=\"subs\",NAME=\"${sub.lang}\",DEFAULT=NO,AUTOSELECT=NO,FORCED=NO,LANGUAGE=\"${sub.lang}\",URI=\"${sub.url}\""
}
}
@ -731,7 +731,7 @@ class ResultFragment : Fragment() {
}
ACTION_DOWNLOAD_EPISODE -> {
startDownload(currentLinks ?: return@main, currentSubs)
startDownload(currentLinks ?: return@main, currentSubs?.values?.toList() ?: emptyList())
}
ACTION_DOWNLOAD_MIRROR -> {
@ -740,7 +740,7 @@ class ResultFragment : Fragment() {
links,//(currentLinks ?: return@main).filter { !it.isM3u8 },
getString(R.string.episode_action_download_mirror)
) { link ->
startDownload(listOf(link), currentSubs)
startDownload(listOf(link), currentSubs?.values?.toList() ?: emptyList())
}
}
}
@ -1064,6 +1064,12 @@ class ResultFragment : Fragment() {
return@setOnLongClickListener true
}
result_download_movie?.setOnLongClickListener {
val card = currentEpisodes?.firstOrNull() ?: return@setOnLongClickListener true
handleAction(EpisodeClickEvent(ACTION_SHOW_OPTIONS, card))
return@setOnLongClickListener true
}
// result_options.setOnClickListener {
// val card = currentEpisodes?.first() ?: return@setOnClickListener
// handleAction(EpisodeClickEvent(ACTION_SHOW_OPTIONS, card))

View file

@ -12,9 +12,8 @@ import com.lagradost.cloudstream3.mvvm.Resource
import com.lagradost.cloudstream3.mvvm.safeApiCall
import com.lagradost.cloudstream3.ui.APIRepository
import com.lagradost.cloudstream3.ui.WatchType
import com.lagradost.cloudstream3.utils.DOWNLOAD_HEADER_CACHE
import com.lagradost.cloudstream3.utils.*
import com.lagradost.cloudstream3.utils.DataStore.setKey
import com.lagradost.cloudstream3.utils.DataStoreHelper
import com.lagradost.cloudstream3.utils.DataStoreHelper.getBookmarkedData
import com.lagradost.cloudstream3.utils.DataStoreHelper.getResultSeason
import com.lagradost.cloudstream3.utils.DataStoreHelper.getResultWatchState
@ -25,9 +24,7 @@ import com.lagradost.cloudstream3.utils.DataStoreHelper.setLastWatched
import com.lagradost.cloudstream3.utils.DataStoreHelper.setResultSeason
import com.lagradost.cloudstream3.utils.DataStoreHelper.setResultWatchState
import com.lagradost.cloudstream3.utils.DataStoreHelper.setViewPos
import com.lagradost.cloudstream3.utils.ExtractorLink
import com.lagradost.cloudstream3.utils.FillerEpisodeCheck.getFillerEpisodes
import com.lagradost.cloudstream3.utils.VideoDownloadHelper
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
@ -133,7 +130,7 @@ class ResultViewModel : ViewModel() {
val seasons = seasonTypes.toList().map { it.first }.sortedBy { it }
seasonSelections.postValue(seasons)
if (seasons.isEmpty()) { // WHAT THE FUCK DID YOU DO????? HOW DID YOU DO THIS
_publicEpisodes.postValue(Resource.Success(ArrayList()))
_publicEpisodes.postValue(Resource.Success(emptyList()))
return
}
@ -415,18 +412,18 @@ class ResultViewModel : ViewModel() {
}
}
private val _allEpisodes: MutableLiveData<HashMap<Int, ArrayList<ExtractorLink>>> =
private val _allEpisodes: MutableLiveData<HashMap<Int, List<ExtractorLink>>> =
MutableLiveData(HashMap()) // LOOKUP BY ID
private val _allEpisodesSubs: MutableLiveData<HashMap<Int, ArrayList<SubtitleFile>>> =
private val _allEpisodesSubs: MutableLiveData<HashMap<Int, HashMap<String, SubtitleFile>>> =
MutableLiveData(HashMap()) // LOOKUP BY ID
val allEpisodes: LiveData<HashMap<Int, ArrayList<ExtractorLink>>> get() = _allEpisodes
val allEpisodesSubs: LiveData<HashMap<Int, ArrayList<SubtitleFile>>> get() = _allEpisodesSubs
val allEpisodes: LiveData<HashMap<Int, List<ExtractorLink>>> get() = _allEpisodes
val allEpisodesSubs: LiveData<HashMap<Int, HashMap<String, SubtitleFile>>> get() = _allEpisodesSubs
private var _apiName: MutableLiveData<String> = MutableLiveData()
val apiName: LiveData<String> get() = _apiName
data class EpisodeData(val links: ArrayList<ExtractorLink>, val subs: ArrayList<SubtitleFile>)
data class EpisodeData(val links: List<ExtractorLink>, val subs: HashMap<String, SubtitleFile>)
fun loadEpisode(
episode: ResultEpisode,
@ -452,11 +449,35 @@ class ResultViewModel : ViewModel() {
_allEpisodes.value?.remove(id)
}
val links = ArrayList<ExtractorLink>()
val subs = ArrayList<SubtitleFile>()
val subs = HashMap<String, SubtitleFile>()
return safeApiCall {
repo?.loadLinks(data, isCasting, { subtitleFile ->
if (!subs.any { it.url == subtitleFile.url }) {
subs.add(subtitleFile)
if (!subs.values.any { it.url == subtitleFile.url }) {
val langTrimmed = subtitleFile.lang.trimEnd()
val langId = if (langTrimmed.length == 2) {
SubtitleHelper.fromTwoLettersToLanguage(langTrimmed) ?: langTrimmed
} else {
langTrimmed
}
var title: String
var count = 0
while (true) {
title = "$langId${if (count == 0) "" else " ${count+1}"}"
count++
if(!subs.containsKey(title)) {
break
}
}
val file =
subtitleFile.copy(
lang = title
)
subs[title] = file
_allEpisodesSubs.value?.set(id, subs)
_allEpisodesSubs.postValue(_allEpisodesSubs.value)
}

View file

@ -41,7 +41,10 @@ object SearchHelper {
activity.loadSearchResult(card, START_ACTION_LOAD_EP, card.id!!)
}
} else {
handleSearchClickCallback(activity, SearchClickCallback(SEARCH_ACTION_LOAD,callback.view,callback.card))
handleSearchClickCallback(
activity,
SearchClickCallback(SEARCH_ACTION_LOAD, callback.view, callback.card)
)
}
}
SEARCH_ACTION_SHOW_METADATA -> {

View file

@ -216,12 +216,19 @@ class SubtitlesFragment : Fragment() {
}
subs_subtitle_elevation.setOnClickListener { textView ->
val suffix = "dp"
val elevationTypes = listOf(
Pair(0, "None"),
Pair(10, "10"),
Pair(20, "20"),
Pair(30, "30"),
Pair(40, "40"),
Pair(0, textView.context.getString(R.string.none)),
Pair(10, "10$suffix"),
Pair(20, "20$suffix"),
Pair(30, "30$suffix"),
Pair(40, "40$suffix"),
Pair(50, "50$suffix"),
Pair(60, "60$suffix"),
Pair(70, "70$suffix"),
Pair(80, "80$suffix"),
Pair(90, "90$suffix"),
Pair(100, "100$suffix"),
)
//showBottomDialog
@ -248,11 +255,11 @@ class SubtitlesFragment : Fragment() {
subs_edge_type.setOnClickListener { textView ->
val edgeTypes = listOf(
Pair(CaptionStyleCompat.EDGE_TYPE_NONE, "None"),
Pair(CaptionStyleCompat.EDGE_TYPE_OUTLINE, "Outline"),
Pair(CaptionStyleCompat.EDGE_TYPE_DEPRESSED, "Depressed"),
Pair(CaptionStyleCompat.EDGE_TYPE_DROP_SHADOW, "Shadow"),
Pair(CaptionStyleCompat.EDGE_TYPE_RAISED, "Raised"),
Pair(CaptionStyleCompat.EDGE_TYPE_NONE, textView.context.getString(R.string.subtitles_none)),
Pair(CaptionStyleCompat.EDGE_TYPE_OUTLINE, textView.context.getString(R.string.subtitles_outline)),
Pair(CaptionStyleCompat.EDGE_TYPE_DEPRESSED, textView.context.getString(R.string.subtitles_depressed)),
Pair(CaptionStyleCompat.EDGE_TYPE_DROP_SHADOW, textView.context.getString(R.string.subtitles_shadow)),
Pair(CaptionStyleCompat.EDGE_TYPE_RAISED, textView.context.getString(R.string.subtitles_raised)),
)
//showBottomDialog
@ -278,7 +285,7 @@ class SubtitlesFragment : Fragment() {
subs_font_size.setOnClickListener { textView ->
val suffix = "sp"
val fontSizes = listOf(
Pair(null, "Normal"),
Pair(null, textView.context.getString(R.string.normal)),
Pair(6f, "6$suffix"),
Pair(8f, "8$suffix"),
Pair(9f, "9$suffix"),
@ -328,7 +335,7 @@ class SubtitlesFragment : Fragment() {
subs_font.setOnClickListener { textView ->
val fontTypes = listOf(
Pair(null, "Normal"),
Pair(null, textView.context.getString(R.string.normal)),
Pair(R.font.trebuchet_ms, "Trebuchet MS"),
Pair(R.font.netflix_sans, "Netflix Sans"),
Pair(R.font.google_sans, "Google Sans"),
@ -430,7 +437,7 @@ class SubtitlesFragment : Fragment() {
getPixels(TypedValue.COMPLEX_UNIT_SP, 25.0f).toFloat(),
Cue.TEXT_SIZE_TYPE_ABSOLUTE
)
.setText("The quick brown fox jumps over the lazy dog").build()
.setText(subtitle_text.context.getString(R.string.subtitles_example_text)).build()
)
)
}

View file

@ -1,8 +1,5 @@
package com.lagradost.cloudstream3.utils
import com.lagradost.cloudstream3.network.get
import com.lagradost.cloudstream3.network.text
import org.jsoup.Jsoup
import java.util.*
object SubtitleHelper {
@ -52,16 +49,22 @@ object SubtitleHelper {
return null
}
private var ISO_639_1Map : HashMap<String, String> = hashMapOf()
private fun initISO6391Map() {
for (lang in languages) {
ISO_639_1Map[lang.ISO_639_1] = lang.languageName
}
}
/** ISO_639_1 -> lang*/
fun fromTwoLettersToLanguage(input: String): String? {
if (input.length != 2) return null
if(ISO_639_1Map.isEmpty()) {
initISO6391Map()
}
val comparison = input.toLowerCase(Locale.ROOT)
for (lang in languages) {
if (lang.ISO_639_1 == comparison) {
return lang.languageName
}
}
return null
return ISO_639_1Map[comparison]
}
/**ISO_639_2_B or ISO_639_2_T or ISO_639_3-> lang*/

View file

@ -213,4 +213,26 @@
<string name="source_error">Källfel</string>
<string name="remote_error">Fjärrfel</string>
<string name="render_error">Renderingsfel</string>
<string name="subtitles_example_text">Flygande bäckasiner söka hwila på mjuka tuvor</string>
<string name="subtitles_shadow">Skugga</string>
<string name="subtitles_outline">Kontur</string>
<string name="subtitles_depressed">Nedsänkt</string>
<string name="subtitles_raised">Upphöjd</string>
<string name="none">Ingen</string>
<string name="normal">Normal</string>
<string name="all">Allt</string>
<string name="max">Min</string>
<string name="min">Max</string>
<string name="add_account">Lägg till konto</string>
<string name="switch_account">Byt konto</string>
<string name="login">Logga in</string>
<string name="logout">Logga ut</string>
<string name="account">konto</string>
<string name="download_path_pref">Nerladdningsplats</string>
<string name="type_re_watching">Kollar om</string>
<string name="automatic">Automatisk</string>
<string name="dns_pref">DNS över HTTPS</string>
<string name="dns_pref_summary">" "</string>
<string name="app_theme_settings">Appens tema</string>
<string name="app_dub_sub_episode_text_format">%s A%d</string>
</resources>

View file

@ -333,5 +333,19 @@
<string name="switch_account">Switch account</string>
<string name="add_account">Add account</string>
<!-- ============ -->
<string name="none">None</string>
<string name="normal">Normal</string>
<string name="all">All</string>
<string name="max">Max</string>
<string name="min">Min</string>
<string name="subtitles_none" translatable="false">@string/none</string>
<string name="subtitles_outline">Outline</string>
<string name="subtitles_depressed">Depressed</string>
<string name="subtitles_shadow">Shadow</string>
<string name="subtitles_raised">Raised</string>
<!--
Example text does not need to be translated and if you do translate include all the letters in the alphabet,
see https://en.wikipedia.org/wiki/The_quick_brown_fox_jumps_over_the_lazy_dog
-->
<string name="subtitles_example_text">The quick brown fox jumps over the lazy dog</string>
</resources>