forked from recloudstream/cloudstream
autoselect subtitles
This commit is contained in:
parent
355aff9d3f
commit
a194cae245
4 changed files with 104 additions and 33 deletions
|
@ -10,7 +10,6 @@ import com.google.android.exoplayer2.database.StandaloneDatabaseProvider
|
||||||
import com.google.android.exoplayer2.source.DefaultMediaSourceFactory
|
import com.google.android.exoplayer2.source.DefaultMediaSourceFactory
|
||||||
import com.google.android.exoplayer2.source.MergingMediaSource
|
import com.google.android.exoplayer2.source.MergingMediaSource
|
||||||
import com.google.android.exoplayer2.source.SingleSampleMediaSource
|
import com.google.android.exoplayer2.source.SingleSampleMediaSource
|
||||||
import com.google.android.exoplayer2.text.Cue
|
|
||||||
import com.google.android.exoplayer2.trackselection.DefaultTrackSelector
|
import com.google.android.exoplayer2.trackselection.DefaultTrackSelector
|
||||||
import com.google.android.exoplayer2.trackselection.TrackSelector
|
import com.google.android.exoplayer2.trackselection.TrackSelector
|
||||||
import com.google.android.exoplayer2.ui.SubtitleView
|
import com.google.android.exoplayer2.ui.SubtitleView
|
||||||
|
@ -152,9 +151,9 @@ class CS3IPlayer : IPlayer {
|
||||||
subtitleHelper.setAllSubtitles(subtitles)
|
subtitleHelper.setAllSubtitles(subtitles)
|
||||||
}
|
}
|
||||||
|
|
||||||
var currentSubtitles : SubtitleData? = null
|
var currentSubtitles: SubtitleData? = null
|
||||||
override fun setPreferredSubtitles(subtitle: SubtitleData?): Boolean {
|
override fun setPreferredSubtitles(subtitle: SubtitleData?): Boolean {
|
||||||
Log.i(TAG,"setPreferredSubtitles init $subtitle")
|
Log.i(TAG, "setPreferredSubtitles init $subtitle")
|
||||||
currentSubtitles = subtitle
|
currentSubtitles = subtitle
|
||||||
return (exoPlayer?.trackSelector as? DefaultTrackSelector?)?.let { trackSelector ->
|
return (exoPlayer?.trackSelector as? DefaultTrackSelector?)?.let { trackSelector ->
|
||||||
val name = subtitle?.name
|
val name = subtitle?.name
|
||||||
|
@ -166,12 +165,12 @@ class CS3IPlayer : IPlayer {
|
||||||
} else {
|
} else {
|
||||||
when (subtitleHelper.subtitleStatus(subtitle)) {
|
when (subtitleHelper.subtitleStatus(subtitle)) {
|
||||||
SubtitleStatus.REQUIRES_RELOAD -> {
|
SubtitleStatus.REQUIRES_RELOAD -> {
|
||||||
Log.i(TAG,"setPreferredSubtitles REQUIRES_RELOAD")
|
Log.i(TAG, "setPreferredSubtitles REQUIRES_RELOAD")
|
||||||
return@let true
|
return@let true
|
||||||
// reloadPlayer(context)
|
// reloadPlayer(context)
|
||||||
}
|
}
|
||||||
SubtitleStatus.IS_ACTIVE -> {
|
SubtitleStatus.IS_ACTIVE -> {
|
||||||
Log.i(TAG,"setPreferredSubtitles IS_ACTIVE")
|
Log.i(TAG, "setPreferredSubtitles IS_ACTIVE")
|
||||||
|
|
||||||
trackSelector.setParameters(
|
trackSelector.setParameters(
|
||||||
trackSelector.buildUponParameters()
|
trackSelector.buildUponParameters()
|
||||||
|
@ -180,7 +179,7 @@ class CS3IPlayer : IPlayer {
|
||||||
}
|
}
|
||||||
SubtitleStatus.NOT_FOUND -> {
|
SubtitleStatus.NOT_FOUND -> {
|
||||||
// not found
|
// not found
|
||||||
Log.i(TAG,"setPreferredSubtitles NOT_FOUND")
|
Log.i(TAG, "setPreferredSubtitles NOT_FOUND")
|
||||||
return@let true
|
return@let true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -194,7 +193,7 @@ class CS3IPlayer : IPlayer {
|
||||||
exoPlayerSelectedTracks.any {
|
exoPlayerSelectedTracks.any {
|
||||||
// The replace is needed as exoplayer translates _ to -
|
// The replace is needed as exoplayer translates _ to -
|
||||||
// Also we prefix the languages with _
|
// Also we prefix the languages with _
|
||||||
it.second && it.first.replace("-", "") .equals(
|
it.second && it.first.replace("-", "").equals(
|
||||||
sub.name.replace("-", ""),
|
sub.name.replace("-", ""),
|
||||||
ignoreCase = true
|
ignoreCase = true
|
||||||
)
|
)
|
||||||
|
@ -509,14 +508,6 @@ class CS3IPlayer : IPlayer {
|
||||||
super.onTracksInfoChanged(tracksInfo)
|
super.onTracksInfoChanged(tracksInfo)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onCues(cues: MutableList<Cue>) {
|
|
||||||
Log.i(TAG, "CUES: ${cues.size}")
|
|
||||||
if(cues.size > 0) {
|
|
||||||
Log.i(TAG, "CUES SAY: ${cues.first().text}")
|
|
||||||
}
|
|
||||||
super.onCues(cues)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onPlayerStateChanged(playWhenReady: Boolean, playbackState: Int) {
|
override fun onPlayerStateChanged(playWhenReady: Boolean, playbackState: Int) {
|
||||||
exoPlayer?.let { exo ->
|
exoPlayer?.let { exo ->
|
||||||
updateIsPlaying?.invoke(
|
updateIsPlaying?.invoke(
|
||||||
|
@ -641,7 +632,8 @@ class CS3IPlayer : IPlayer {
|
||||||
)
|
)
|
||||||
subtitleHelper.setActiveSubtitles(activeSubtitles.toSet())
|
subtitleHelper.setActiveSubtitles(activeSubtitles.toSet())
|
||||||
|
|
||||||
simpleCache = getCache(context, cacheSize)
|
if (simpleCache == null)
|
||||||
|
simpleCache = getCache(context, cacheSize)
|
||||||
|
|
||||||
val cacheFactory = CacheDataSource.Factory().apply {
|
val cacheFactory = CacheDataSource.Factory().apply {
|
||||||
simpleCache?.let { setCache(it) }
|
simpleCache?.let { setCache(it) }
|
||||||
|
|
|
@ -21,10 +21,8 @@ import com.lagradost.cloudstream3.mvvm.normalSafeApiCall
|
||||||
import com.lagradost.cloudstream3.mvvm.observe
|
import com.lagradost.cloudstream3.mvvm.observe
|
||||||
import com.lagradost.cloudstream3.ui.player.PlayerSubtitleHelper.Companion.toSubtitleMimeType
|
import com.lagradost.cloudstream3.ui.player.PlayerSubtitleHelper.Companion.toSubtitleMimeType
|
||||||
import com.lagradost.cloudstream3.ui.result.ResultEpisode
|
import com.lagradost.cloudstream3.ui.result.ResultEpisode
|
||||||
import com.lagradost.cloudstream3.utils.DataStoreHelper
|
import com.lagradost.cloudstream3.ui.subtitles.SubtitlesFragment
|
||||||
import com.lagradost.cloudstream3.utils.ExtractorLink
|
import com.lagradost.cloudstream3.utils.*
|
||||||
import com.lagradost.cloudstream3.utils.ExtractorUri
|
|
||||||
import com.lagradost.cloudstream3.utils.Qualities
|
|
||||||
import com.lagradost.cloudstream3.utils.UIHelper.dismissSafe
|
import com.lagradost.cloudstream3.utils.UIHelper.dismissSafe
|
||||||
import com.lagradost.cloudstream3.utils.UIHelper.hideSystemUI
|
import com.lagradost.cloudstream3.utils.UIHelper.hideSystemUI
|
||||||
import com.lagradost.cloudstream3.utils.UIHelper.popCurrentPage
|
import com.lagradost.cloudstream3.utils.UIHelper.popCurrentPage
|
||||||
|
@ -52,6 +50,8 @@ class GeneratorPlayer : FullScreenPlayer() {
|
||||||
private var isActive: Boolean = false
|
private var isActive: Boolean = false
|
||||||
private var isNextEpisode: Boolean = false // this is used to reset the watch time
|
private var isNextEpisode: Boolean = false // this is used to reset the watch time
|
||||||
|
|
||||||
|
private var preferredAutoSelectSubtitles: String? = null // null means do nothing, "" means none
|
||||||
|
|
||||||
private fun startLoading() {
|
private fun startLoading() {
|
||||||
player.release()
|
player.release()
|
||||||
currentSelectedSubtitles = null
|
currentSelectedSubtitles = null
|
||||||
|
@ -380,6 +380,50 @@ class GeneratorPlayer : FullScreenPlayer() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun autoSelectFromSettings() {
|
||||||
|
// auto select subtitle based of settings
|
||||||
|
val langCode = preferredAutoSelectSubtitles
|
||||||
|
if (!langCode.isNullOrEmpty() && player.getCurrentPreferredSubtitle() == null) {
|
||||||
|
val lang = SubtitleHelper.fromTwoLettersToLanguage(langCode) ?: return
|
||||||
|
|
||||||
|
currentSubs.firstOrNull { sub ->
|
||||||
|
sub.name.startsWith(lang)
|
||||||
|
|| sub.name.trim() == langCode
|
||||||
|
}?.let { sub ->
|
||||||
|
context?.let { ctx ->
|
||||||
|
if (setSubtitles(sub)) {
|
||||||
|
player.reloadPlayer(ctx)
|
||||||
|
player.handleEvent(CSPlayerEvent.Play)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun autoSelectFromDownloads() {
|
||||||
|
if (player.getCurrentPreferredSubtitle() == null) {
|
||||||
|
currentSubs.firstOrNull { sub ->
|
||||||
|
(sub.origin == SubtitleOrigin.DOWNLOADED_FILE || sub.name == context?.getString(
|
||||||
|
R.string.default_subtitles
|
||||||
|
))
|
||||||
|
}?.let { sub ->
|
||||||
|
context?.let { ctx ->
|
||||||
|
if (setSubtitles(sub)) {
|
||||||
|
player.reloadPlayer(ctx)
|
||||||
|
player.handleEvent(CSPlayerEvent.Play)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun autoSelectSubtitles() {
|
||||||
|
normalSafeApiCall {
|
||||||
|
autoSelectFromSettings()
|
||||||
|
autoSelectFromDownloads()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@SuppressLint("SetTextI18n")
|
@SuppressLint("SetTextI18n")
|
||||||
fun setTitle() {
|
fun setTitle() {
|
||||||
var headerName: String? = null
|
var headerName: String? = null
|
||||||
|
@ -445,6 +489,8 @@ class GeneratorPlayer : FullScreenPlayer() {
|
||||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||||
super.onViewCreated(view, savedInstanceState)
|
super.onViewCreated(view, savedInstanceState)
|
||||||
|
|
||||||
|
preferredAutoSelectSubtitles = SubtitlesFragment.getAutoSelectLanguageISO639_1()
|
||||||
|
|
||||||
if (currentSelectedLink == null) {
|
if (currentSelectedLink == null) {
|
||||||
viewModel.loadLinks()
|
viewModel.loadLinks()
|
||||||
}
|
}
|
||||||
|
@ -482,9 +528,11 @@ class GeneratorPlayer : FullScreenPlayer() {
|
||||||
overlay_loading_skip_button?.isVisible = it.isNotEmpty()
|
overlay_loading_skip_button?.isVisible = it.isNotEmpty()
|
||||||
}
|
}
|
||||||
|
|
||||||
observe(viewModel.currentSubs) {
|
observe(viewModel.currentSubs) { set ->
|
||||||
currentSubs = it
|
currentSubs = set
|
||||||
player.setActiveSubtitles(it)
|
player.setActiveSubtitles(set)
|
||||||
|
|
||||||
|
autoSelectSubtitles()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -97,7 +97,7 @@ class PlayerGeneratorViewModel : ViewModel() {
|
||||||
_currentLinks.postValue(currentLinks)
|
_currentLinks.postValue(currentLinks)
|
||||||
}, {
|
}, {
|
||||||
currentSubs.add(it)
|
currentSubs.add(it)
|
||||||
_currentSubs.postValue(currentSubs)
|
// _currentSubs.postValue(currentSubs) // this causes ConcurrentModificationException, so fuck it
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -64,8 +64,15 @@ class SubtitlesFragment : Fragment() {
|
||||||
fun Context.fromSaveToStyle(data: SaveCaptionStyle): CaptionStyleCompat {
|
fun Context.fromSaveToStyle(data: SaveCaptionStyle): CaptionStyleCompat {
|
||||||
val typeface = data.typeface
|
val typeface = data.typeface
|
||||||
return CaptionStyleCompat(
|
return CaptionStyleCompat(
|
||||||
data.foregroundColor, data.backgroundColor, data.windowColor, data.edgeType, data.edgeColor,
|
data.foregroundColor,
|
||||||
if (typeface == null) Typeface.SANS_SERIF else ResourcesCompat.getFont(this, typeface)
|
data.backgroundColor,
|
||||||
|
data.windowColor,
|
||||||
|
data.edgeType,
|
||||||
|
data.edgeColor,
|
||||||
|
if (typeface == null) Typeface.SANS_SERIF else ResourcesCompat.getFont(
|
||||||
|
this,
|
||||||
|
typeface
|
||||||
|
)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -256,11 +263,26 @@ class SubtitlesFragment : Fragment() {
|
||||||
|
|
||||||
subs_edge_type.setOnClickListener { textView ->
|
subs_edge_type.setOnClickListener { textView ->
|
||||||
val edgeTypes = listOf(
|
val edgeTypes = listOf(
|
||||||
Pair(CaptionStyleCompat.EDGE_TYPE_NONE, textView.context.getString(R.string.subtitles_none)),
|
Pair(
|
||||||
Pair(CaptionStyleCompat.EDGE_TYPE_OUTLINE, textView.context.getString(R.string.subtitles_outline)),
|
CaptionStyleCompat.EDGE_TYPE_NONE,
|
||||||
Pair(CaptionStyleCompat.EDGE_TYPE_DEPRESSED, textView.context.getString(R.string.subtitles_depressed)),
|
textView.context.getString(R.string.subtitles_none)
|
||||||
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)),
|
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
|
//showBottomDialog
|
||||||
|
@ -375,7 +397,15 @@ class SubtitlesFragment : Fragment() {
|
||||||
|
|
||||||
subs_auto_select_language.setOnClickListener { textView ->
|
subs_auto_select_language.setOnClickListener { textView ->
|
||||||
val langMap = arrayListOf(
|
val langMap = arrayListOf(
|
||||||
SubtitleHelper.Language639("None", "None", "", "", "", "", ""),
|
SubtitleHelper.Language639(
|
||||||
|
textView.context.getString(R.string.none),
|
||||||
|
textView.context.getString(R.string.none),
|
||||||
|
"",
|
||||||
|
"",
|
||||||
|
"",
|
||||||
|
"",
|
||||||
|
""
|
||||||
|
),
|
||||||
)
|
)
|
||||||
langMap.addAll(SubtitleHelper.languages)
|
langMap.addAll(SubtitleHelper.languages)
|
||||||
|
|
||||||
|
@ -438,7 +468,8 @@ class SubtitlesFragment : Fragment() {
|
||||||
getPixels(TypedValue.COMPLEX_UNIT_SP, 25.0f).toFloat(),
|
getPixels(TypedValue.COMPLEX_UNIT_SP, 25.0f).toFloat(),
|
||||||
Cue.TEXT_SIZE_TYPE_ABSOLUTE
|
Cue.TEXT_SIZE_TYPE_ABSOLUTE
|
||||||
)
|
)
|
||||||
.setText(subtitle_text.context.getString(R.string.subtitles_example_text)).build()
|
.setText(subtitle_text.context.getString(R.string.subtitles_example_text))
|
||||||
|
.build()
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue