mirror of
https://github.com/recloudstream/cloudstream.git
synced 2024-08-15 01:53:11 +00:00
chromecast subtitles color + zoro fix
This commit is contained in:
parent
70776ea80d
commit
6da2bf900e
11 changed files with 568 additions and 30 deletions
|
@ -36,7 +36,7 @@ android {
|
||||||
targetSdkVersion 30
|
targetSdkVersion 30
|
||||||
|
|
||||||
versionCode 42
|
versionCode 42
|
||||||
versionName "2.6.11"
|
versionName "2.6.12"
|
||||||
|
|
||||||
resValue "string", "app_version",
|
resValue "string", "app_version",
|
||||||
"${defaultConfig.versionName}${versionNameSuffix ?: ""}"
|
"${defaultConfig.versionName}${versionNameSuffix ?: ""}"
|
||||||
|
|
|
@ -7,6 +7,7 @@ import com.lagradost.cloudstream3.movieproviders.SflixProvider
|
||||||
import com.lagradost.cloudstream3.movieproviders.SflixProvider.Companion.toExtractorLink
|
import com.lagradost.cloudstream3.movieproviders.SflixProvider.Companion.toExtractorLink
|
||||||
import com.lagradost.cloudstream3.movieproviders.SflixProvider.Companion.toSubtitleFile
|
import com.lagradost.cloudstream3.movieproviders.SflixProvider.Companion.toSubtitleFile
|
||||||
import com.lagradost.cloudstream3.network.WebViewResolver
|
import com.lagradost.cloudstream3.network.WebViewResolver
|
||||||
|
import com.lagradost.cloudstream3.utils.AppUtils.parseJson
|
||||||
import com.lagradost.cloudstream3.utils.ExtractorLink
|
import com.lagradost.cloudstream3.utils.ExtractorLink
|
||||||
import com.lagradost.cloudstream3.utils.loadExtractor
|
import com.lagradost.cloudstream3.utils.loadExtractor
|
||||||
import org.jsoup.Jsoup
|
import org.jsoup.Jsoup
|
||||||
|
@ -283,10 +284,10 @@ class ZoroProvider : MainAPI() {
|
||||||
}
|
}
|
||||||
|
|
||||||
private suspend fun getM3u8FromRapidCloud(url: String): String {
|
private suspend fun getM3u8FromRapidCloud(url: String): String {
|
||||||
return Regex("""/(embed-\d+)/(.*?)\?z=""").find(url)?.groupValues?.let {
|
return /*Regex("""/(embed-\d+)/(.*?)\?z=""").find(url)?.groupValues?.let {
|
||||||
val jsonLink = "https://rapid-cloud.ru/ajax/${it[1]}/getSources?id=${it[2]}"
|
val jsonLink = "https://rapid-cloud.ru/ajax/${it[1]}/getSources?id=${it[2]}"
|
||||||
app.get(jsonLink).text
|
app.get(jsonLink).text
|
||||||
} ?: app.get(
|
} ?:*/ app.get(
|
||||||
"$url&autoPlay=1&oa=0",
|
"$url&autoPlay=1&oa=0",
|
||||||
headers = mapOf(
|
headers = mapOf(
|
||||||
"Referer" to "https://zoro.to/",
|
"Referer" to "https://zoro.to/",
|
||||||
|
@ -319,6 +320,7 @@ class ZoroProvider : MainAPI() {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Prevent duplicates
|
// Prevent duplicates
|
||||||
servers.distinctBy { it.second }.apmap {
|
servers.distinctBy { it.second }.apmap {
|
||||||
val link =
|
val link =
|
||||||
|
@ -326,7 +328,7 @@ class ZoroProvider : MainAPI() {
|
||||||
val extractorLink = app.get(
|
val extractorLink = app.get(
|
||||||
link,
|
link,
|
||||||
).mapped<RapidCloudResponse>().link
|
).mapped<RapidCloudResponse>().link
|
||||||
|
//.also { println("AAAAAAAAA: ${it.text}") }
|
||||||
// Loads the links in the appropriate extractor.
|
// Loads the links in the appropriate extractor.
|
||||||
val hasLoadedExtractorLink = loadExtractor(extractorLink, mainUrl, callback)
|
val hasLoadedExtractorLink = loadExtractor(extractorLink, mainUrl, callback)
|
||||||
|
|
||||||
|
@ -342,7 +344,7 @@ class ZoroProvider : MainAPI() {
|
||||||
)
|
)
|
||||||
|
|
||||||
if (response.contains("<html")) return@apmap
|
if (response.contains("<html")) return@apmap
|
||||||
val mapped = mapper.readValue<SflixProvider.SourceObject>(response)
|
val mapped = parseJson<SflixProvider.SourceObject>(response)
|
||||||
|
|
||||||
mapped.tracks?.forEach { track ->
|
mapped.tracks?.forEach { track ->
|
||||||
track?.toSubtitleFile()?.let { subtitleFile ->
|
track?.toSubtitleFile()?.let { subtitleFile ->
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
package com.lagradost.cloudstream3.ui
|
package com.lagradost.cloudstream3.ui
|
||||||
|
|
||||||
import android.graphics.Color
|
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.util.Log
|
import android.util.Log
|
||||||
import android.view.Menu
|
import android.view.Menu
|
||||||
|
@ -15,7 +14,6 @@ import com.google.android.gms.cast.MediaSeekOptions
|
||||||
import com.google.android.gms.cast.MediaStatus.REPEAT_MODE_REPEAT_OFF
|
import com.google.android.gms.cast.MediaStatus.REPEAT_MODE_REPEAT_OFF
|
||||||
import com.google.android.gms.cast.MediaTrack
|
import com.google.android.gms.cast.MediaTrack
|
||||||
import com.google.android.gms.cast.TextTrackStyle
|
import com.google.android.gms.cast.TextTrackStyle
|
||||||
import com.google.android.gms.cast.TextTrackStyle.EDGE_TYPE_OUTLINE
|
|
||||||
import com.google.android.gms.cast.framework.CastButtonFactory
|
import com.google.android.gms.cast.framework.CastButtonFactory
|
||||||
import com.google.android.gms.cast.framework.CastSession
|
import com.google.android.gms.cast.framework.CastSession
|
||||||
import com.google.android.gms.cast.framework.media.RemoteMediaClient
|
import com.google.android.gms.cast.framework.media.RemoteMediaClient
|
||||||
|
@ -29,6 +27,7 @@ import com.lagradost.cloudstream3.sortUrls
|
||||||
import com.lagradost.cloudstream3.ui.player.RepoLinkGenerator
|
import com.lagradost.cloudstream3.ui.player.RepoLinkGenerator
|
||||||
import com.lagradost.cloudstream3.ui.player.SubtitleData
|
import com.lagradost.cloudstream3.ui.player.SubtitleData
|
||||||
import com.lagradost.cloudstream3.ui.result.ResultEpisode
|
import com.lagradost.cloudstream3.ui.result.ResultEpisode
|
||||||
|
import com.lagradost.cloudstream3.ui.subtitles.ChromecastSubtitlesFragment
|
||||||
import com.lagradost.cloudstream3.utils.AppUtils.toJson
|
import com.lagradost.cloudstream3.utils.AppUtils.toJson
|
||||||
import com.lagradost.cloudstream3.utils.CastHelper.awaitLinks
|
import com.lagradost.cloudstream3.utils.CastHelper.awaitLinks
|
||||||
import com.lagradost.cloudstream3.utils.CastHelper.getMediaInfo
|
import com.lagradost.cloudstream3.utils.CastHelper.getMediaInfo
|
||||||
|
@ -146,16 +145,22 @@ class SelectSourceController(val view: ImageView, val activity: ControllerActivi
|
||||||
if (which == 0) {
|
if (which == 0) {
|
||||||
remoteMediaClient?.setActiveMediaTracks(longArrayOf()) // NO SUBS
|
remoteMediaClient?.setActiveMediaTracks(longArrayOf()) // NO SUBS
|
||||||
} else {
|
} else {
|
||||||
val font = TextTrackStyle()
|
ChromecastSubtitlesFragment.getCurrentSavedStyle().apply {
|
||||||
font.fontFamily = "Google Sans" //TODO FONT SETTINGS
|
val font = TextTrackStyle()
|
||||||
font.backgroundColor = 0x00FFFFFF // TRANSPARENT
|
font.fontFamily = fontFamily ?: "Google Sans"
|
||||||
|
fontGenericFamily?.let {
|
||||||
|
font.fontGenericFamily = it
|
||||||
|
}
|
||||||
|
font.windowColor = windowColor
|
||||||
|
font.backgroundColor = backgroundColor
|
||||||
|
|
||||||
font.edgeColor = Color.BLACK
|
font.edgeColor = edgeColor
|
||||||
font.edgeType = EDGE_TYPE_OUTLINE
|
font.edgeType = edgeType
|
||||||
font.foregroundColor = Color.WHITE
|
font.foregroundColor = foregroundColor
|
||||||
font.fontScale = 1.05f
|
font.fontScale = fontScale
|
||||||
|
|
||||||
remoteMediaClient?.setTextTrackStyle(font)
|
remoteMediaClient?.setTextTrackStyle(font)
|
||||||
|
}
|
||||||
|
|
||||||
remoteMediaClient?.setActiveMediaTracks(longArrayOf(subTracks[which - 1].id))
|
remoteMediaClient?.setActiveMediaTracks(longArrayOf(subTracks[which - 1].id))
|
||||||
?.setResultCallback {
|
?.setResultCallback {
|
||||||
|
@ -290,7 +295,7 @@ class SelectSourceController(val view: ImageView, val activity: ControllerActivi
|
||||||
if (isSuccessful == Resource.Success(true)) {
|
if (isSuccessful == Resource.Success(true)) {
|
||||||
if (currentLinks.isNotEmpty()) {
|
if (currentLinks.isNotEmpty()) {
|
||||||
val jsonCopy = meta.copy(
|
val jsonCopy = meta.copy(
|
||||||
currentLinks = sortedLinks,
|
currentLinks = sortedLinks,
|
||||||
currentSubtitles = sortedSubs,
|
currentSubtitles = sortedSubs,
|
||||||
currentEpisodeIndex = index
|
currentEpisodeIndex = index
|
||||||
)
|
)
|
||||||
|
|
|
@ -37,6 +37,7 @@ import com.lagradost.cloudstream3.syncproviders.OAuth2API
|
||||||
import com.lagradost.cloudstream3.syncproviders.OAuth2API.Companion.aniListApi
|
import com.lagradost.cloudstream3.syncproviders.OAuth2API.Companion.aniListApi
|
||||||
import com.lagradost.cloudstream3.syncproviders.OAuth2API.Companion.malApi
|
import com.lagradost.cloudstream3.syncproviders.OAuth2API.Companion.malApi
|
||||||
import com.lagradost.cloudstream3.ui.APIRepository
|
import com.lagradost.cloudstream3.ui.APIRepository
|
||||||
|
import com.lagradost.cloudstream3.ui.subtitles.ChromecastSubtitlesFragment
|
||||||
import com.lagradost.cloudstream3.ui.subtitles.SubtitlesFragment
|
import com.lagradost.cloudstream3.ui.subtitles.SubtitlesFragment
|
||||||
import com.lagradost.cloudstream3.utils.HOMEPAGE_API
|
import com.lagradost.cloudstream3.utils.HOMEPAGE_API
|
||||||
import com.lagradost.cloudstream3.utils.InAppUpdater.Companion.runAutoUpdate
|
import com.lagradost.cloudstream3.utils.InAppUpdater.Companion.runAutoUpdate
|
||||||
|
@ -199,6 +200,7 @@ class SettingsFragment : PreferenceFragmentCompat() {
|
||||||
val subPreference = findPreference<Preference>(getString(R.string.subtitle_settings_key))!!
|
val subPreference = findPreference<Preference>(getString(R.string.subtitle_settings_key))!!
|
||||||
val videoCachePreference = findPreference<Preference>(getString(R.string.video_cache_key))!!
|
val videoCachePreference = findPreference<Preference>(getString(R.string.video_cache_key))!!
|
||||||
val settingsManager = PreferenceManager.getDefaultSharedPreferences(requireContext())
|
val settingsManager = PreferenceManager.getDefaultSharedPreferences(requireContext())
|
||||||
|
val chromecastSubsPreference = findPreference<Preference>(getString(R.string.subtitle_settings_chomecast_key))!!
|
||||||
|
|
||||||
videoCachePreference.setOnPreferenceClickListener {
|
videoCachePreference.setOnPreferenceClickListener {
|
||||||
val prefNames = resources.getStringArray(R.array.video_cache_size_names)
|
val prefNames = resources.getStringArray(R.array.video_cache_size_names)
|
||||||
|
@ -225,6 +227,11 @@ class SettingsFragment : PreferenceFragmentCompat() {
|
||||||
return@setOnPreferenceClickListener true
|
return@setOnPreferenceClickListener true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
chromecastSubsPreference.setOnPreferenceClickListener {
|
||||||
|
ChromecastSubtitlesFragment.push(activity, false)
|
||||||
|
return@setOnPreferenceClickListener true
|
||||||
|
}
|
||||||
|
|
||||||
val syncApis = listOf(Pair(R.string.mal_key, malApi), Pair(R.string.anilist_key, aniListApi))
|
val syncApis = listOf(Pair(R.string.mal_key, malApi), Pair(R.string.anilist_key, aniListApi))
|
||||||
for (sync in syncApis) {
|
for (sync in syncApis) {
|
||||||
findPreference<Preference>(getString(sync.first))?.apply {
|
findPreference<Preference>(getString(sync.first))?.apply {
|
||||||
|
|
|
@ -0,0 +1,344 @@
|
||||||
|
package com.lagradost.cloudstream3.ui.subtitles
|
||||||
|
|
||||||
|
import android.app.Activity
|
||||||
|
import android.content.Context
|
||||||
|
import android.content.res.Resources
|
||||||
|
import android.graphics.Color
|
||||||
|
import android.os.Bundle
|
||||||
|
import android.util.DisplayMetrics
|
||||||
|
import android.util.TypedValue
|
||||||
|
import android.view.LayoutInflater
|
||||||
|
import android.view.View
|
||||||
|
import android.view.ViewGroup
|
||||||
|
import android.widget.TextView
|
||||||
|
import android.widget.Toast
|
||||||
|
import androidx.fragment.app.Fragment
|
||||||
|
import com.fasterxml.jackson.annotation.JsonProperty
|
||||||
|
import com.google.android.exoplayer2.text.Cue
|
||||||
|
import com.google.android.gms.cast.TextTrackStyle
|
||||||
|
import com.google.android.gms.cast.TextTrackStyle.*
|
||||||
|
import com.jaredrummler.android.colorpicker.ColorPickerDialog
|
||||||
|
import com.lagradost.cloudstream3.AcraApplication.Companion.getKey
|
||||||
|
import com.lagradost.cloudstream3.CommonActivity.onColorSelectedEvent
|
||||||
|
import com.lagradost.cloudstream3.CommonActivity.onDialogDismissedEvent
|
||||||
|
import com.lagradost.cloudstream3.CommonActivity.showToast
|
||||||
|
import com.lagradost.cloudstream3.R
|
||||||
|
import com.lagradost.cloudstream3.ui.settings.SettingsFragment.Companion.isTvSettings
|
||||||
|
import com.lagradost.cloudstream3.utils.DataStore.setKey
|
||||||
|
import com.lagradost.cloudstream3.utils.Event
|
||||||
|
import com.lagradost.cloudstream3.utils.SingleSelectionHelper.showDialog
|
||||||
|
import com.lagradost.cloudstream3.utils.UIHelper.fixPaddingStatusbar
|
||||||
|
import com.lagradost.cloudstream3.utils.UIHelper.hideSystemUI
|
||||||
|
import com.lagradost.cloudstream3.utils.UIHelper.navigate
|
||||||
|
import com.lagradost.cloudstream3.utils.UIHelper.popCurrentPage
|
||||||
|
import kotlinx.android.synthetic.main.subtitle_settings.*
|
||||||
|
|
||||||
|
const val CHROME_SUBTITLE_KEY = "chome_subtitle_settings"
|
||||||
|
|
||||||
|
data class SaveChromeCaptionStyle(
|
||||||
|
@JsonProperty("fontFamily") var fontFamily: String? = null,
|
||||||
|
@JsonProperty("fontGenericFamily") var fontGenericFamily: Int? = null,
|
||||||
|
@JsonProperty("backgroundColor") var backgroundColor: Int = Color.TRANSPARENT, // transparent, 0x00FFFFFF
|
||||||
|
@JsonProperty("edgeColor") var edgeColor: Int = Color.BLACK, // BLACK
|
||||||
|
@JsonProperty("edgeType") var edgeType: Int = TextTrackStyle.EDGE_TYPE_OUTLINE,
|
||||||
|
@JsonProperty("foregroundColor") var foregroundColor: Int = Color.WHITE,
|
||||||
|
@JsonProperty("fontScale") var fontScale: Float = 1.05f,
|
||||||
|
@JsonProperty("windowColor") var windowColor: Int = Color.TRANSPARENT,
|
||||||
|
)
|
||||||
|
|
||||||
|
class ChromecastSubtitlesFragment : Fragment() {
|
||||||
|
companion object {
|
||||||
|
val applyStyleEvent = Event<SaveChromeCaptionStyle>()
|
||||||
|
|
||||||
|
//fun Context.fromSaveToStyle(data: SaveChromeCaptionStyle): CaptionStyleCompat {
|
||||||
|
// return CaptionStyleCompat(
|
||||||
|
// data.foregroundColor,
|
||||||
|
// data.backgroundColor,
|
||||||
|
// data.windowColor,
|
||||||
|
// data.edgeType,
|
||||||
|
// data.edgeColor,
|
||||||
|
// if (typeface == null) Typeface.SANS_SERIF else ResourcesCompat.getFont(
|
||||||
|
// this,
|
||||||
|
// typeface
|
||||||
|
// )
|
||||||
|
// )
|
||||||
|
//}
|
||||||
|
|
||||||
|
fun push(activity: Activity?, hide: Boolean = true) {
|
||||||
|
activity.navigate(R.id.global_to_navigation_chrome_subtitles, Bundle().apply {
|
||||||
|
putBoolean("hide", hide)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun getDefColor(id: Int): Int {
|
||||||
|
return when (id) {
|
||||||
|
0 -> Color.WHITE
|
||||||
|
1 -> Color.BLACK
|
||||||
|
2 -> Color.TRANSPARENT
|
||||||
|
3 -> Color.TRANSPARENT
|
||||||
|
else -> Color.TRANSPARENT
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun Context.saveStyle(style: SaveChromeCaptionStyle) {
|
||||||
|
this.setKey(CHROME_SUBTITLE_KEY, style)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun getPixels(unit: Int, size: Float): Int {
|
||||||
|
val metrics: DisplayMetrics = Resources.getSystem().displayMetrics
|
||||||
|
return TypedValue.applyDimension(unit, size, metrics).toInt()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun getCurrentSavedStyle(): SaveChromeCaptionStyle {
|
||||||
|
return getKey(CHROME_SUBTITLE_KEY) ?: defaultState
|
||||||
|
}
|
||||||
|
|
||||||
|
private val defaultState = SaveChromeCaptionStyle()
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun onColorSelected(stuff: Pair<Int, Int>) {
|
||||||
|
context?.setColor(stuff.first, stuff.second)
|
||||||
|
if (hide)
|
||||||
|
activity?.hideSystemUI()
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun onDialogDismissed(id: Int) {
|
||||||
|
if (hide)
|
||||||
|
activity?.hideSystemUI()
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun getColor(id: Int): Int {
|
||||||
|
val color = when (id) {
|
||||||
|
0 -> state.foregroundColor
|
||||||
|
1 -> state.edgeColor
|
||||||
|
2 -> state.backgroundColor
|
||||||
|
3 -> state.windowColor
|
||||||
|
|
||||||
|
else -> Color.TRANSPARENT
|
||||||
|
}
|
||||||
|
|
||||||
|
return if (color == Color.TRANSPARENT) Color.BLACK else color
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun Context.setColor(id: Int, color: Int?) {
|
||||||
|
val realColor = color ?: getDefColor(id)
|
||||||
|
when (id) {
|
||||||
|
0 -> state.foregroundColor = realColor
|
||||||
|
1 -> state.edgeColor = realColor
|
||||||
|
2 -> state.backgroundColor = realColor
|
||||||
|
3 -> state.windowColor = realColor
|
||||||
|
|
||||||
|
else -> Unit
|
||||||
|
}
|
||||||
|
updateState()
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun Context.updateState() {
|
||||||
|
//subtitle_text?.setStyle(fromSaveToStyle(state))
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onCreateView(
|
||||||
|
inflater: LayoutInflater,
|
||||||
|
container: ViewGroup?,
|
||||||
|
savedInstanceState: Bundle?,
|
||||||
|
): View? {
|
||||||
|
return inflater.inflate(R.layout.chromecast_subtitle_settings, container, false)
|
||||||
|
}
|
||||||
|
|
||||||
|
private lateinit var state: SaveChromeCaptionStyle
|
||||||
|
private var hide: Boolean = true
|
||||||
|
|
||||||
|
override fun onDestroy() {
|
||||||
|
super.onDestroy()
|
||||||
|
onColorSelectedEvent -= ::onColorSelected
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||||
|
super.onViewCreated(view, savedInstanceState)
|
||||||
|
hide = arguments?.getBoolean("hide") ?: true
|
||||||
|
onColorSelectedEvent += ::onColorSelected
|
||||||
|
onDialogDismissedEvent += ::onDialogDismissed
|
||||||
|
|
||||||
|
context?.fixPaddingStatusbar(subs_root)
|
||||||
|
|
||||||
|
state = getCurrentSavedStyle()
|
||||||
|
context?.updateState()
|
||||||
|
|
||||||
|
val isTvSettings = context?.isTvSettings() == true
|
||||||
|
|
||||||
|
fun View.setFocusableInTv() {
|
||||||
|
this.isFocusableInTouchMode = isTvSettings
|
||||||
|
}
|
||||||
|
|
||||||
|
fun View.setup(id: Int) {
|
||||||
|
setFocusableInTv()
|
||||||
|
|
||||||
|
this.setOnClickListener {
|
||||||
|
activity?.let {
|
||||||
|
ColorPickerDialog.newBuilder()
|
||||||
|
.setDialogId(id)
|
||||||
|
.setShowAlphaSlider(true)
|
||||||
|
.setColor(getColor(id))
|
||||||
|
.show(it)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
this.setOnLongClickListener {
|
||||||
|
it.context.setColor(id, null)
|
||||||
|
showToast(activity, R.string.subs_default_reset_toast, Toast.LENGTH_SHORT)
|
||||||
|
return@setOnLongClickListener true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
subs_text_color.setup(0)
|
||||||
|
subs_outline_color.setup(1)
|
||||||
|
subs_background_color.setup(2)
|
||||||
|
|
||||||
|
val dismissCallback = {
|
||||||
|
if (hide)
|
||||||
|
activity?.hideSystemUI()
|
||||||
|
}
|
||||||
|
|
||||||
|
subs_edge_type.setFocusableInTv()
|
||||||
|
subs_edge_type.setOnClickListener { textView ->
|
||||||
|
val edgeTypes = listOf(
|
||||||
|
Pair(
|
||||||
|
EDGE_TYPE_NONE,
|
||||||
|
textView.context.getString(R.string.subtitles_none)
|
||||||
|
),
|
||||||
|
Pair(
|
||||||
|
EDGE_TYPE_OUTLINE,
|
||||||
|
textView.context.getString(R.string.subtitles_outline)
|
||||||
|
),
|
||||||
|
Pair(
|
||||||
|
EDGE_TYPE_DEPRESSED,
|
||||||
|
textView.context.getString(R.string.subtitles_depressed)
|
||||||
|
),
|
||||||
|
Pair(
|
||||||
|
EDGE_TYPE_DROP_SHADOW,
|
||||||
|
textView.context.getString(R.string.subtitles_shadow)
|
||||||
|
),
|
||||||
|
Pair(
|
||||||
|
EDGE_TYPE_RAISED,
|
||||||
|
textView.context.getString(R.string.subtitles_raised)
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
|
//showBottomDialog
|
||||||
|
activity?.showDialog(
|
||||||
|
edgeTypes.map { it.second },
|
||||||
|
edgeTypes.map { it.first }.indexOf(state.edgeType),
|
||||||
|
(textView as TextView).text.toString(),
|
||||||
|
false,
|
||||||
|
dismissCallback
|
||||||
|
) { index ->
|
||||||
|
state.edgeType = edgeTypes.map { it.first }[index]
|
||||||
|
textView.context.updateState()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
subs_edge_type.setOnLongClickListener {
|
||||||
|
state.edgeType = defaultState.edgeType
|
||||||
|
it.context.updateState()
|
||||||
|
showToast(activity, R.string.subs_default_reset_toast, Toast.LENGTH_SHORT)
|
||||||
|
return@setOnLongClickListener true
|
||||||
|
}
|
||||||
|
|
||||||
|
subs_font_size.setFocusableInTv()
|
||||||
|
subs_font_size.setOnClickListener { textView ->
|
||||||
|
val fontSizes = listOf(
|
||||||
|
Pair(0.75f, "75%"),
|
||||||
|
Pair(0.80f, "80%"),
|
||||||
|
Pair(0.85f, "85%"),
|
||||||
|
Pair(0.90f, "90%"),
|
||||||
|
Pair(0.95f, "95%"),
|
||||||
|
Pair(1.00f, "100%"),
|
||||||
|
Pair(1.05f, textView.context.getString(R.string.normal)),
|
||||||
|
Pair(1.10f, "110%"),
|
||||||
|
Pair(1.15f, "115%"),
|
||||||
|
Pair(1.20f, "120%"),
|
||||||
|
Pair(1.25f, "125%"),
|
||||||
|
Pair(1.30f, "130%"),
|
||||||
|
Pair(1.35f, "135%"),
|
||||||
|
Pair(1.40f, "140%"),
|
||||||
|
Pair(1.45f, "145%"),
|
||||||
|
Pair(1.50f, "150%"),
|
||||||
|
)
|
||||||
|
|
||||||
|
//showBottomDialog
|
||||||
|
activity?.showDialog(
|
||||||
|
fontSizes.map { it.second },
|
||||||
|
fontSizes.map { it.first }.indexOf(state.fontScale),
|
||||||
|
(textView as TextView).text.toString(),
|
||||||
|
false,
|
||||||
|
dismissCallback
|
||||||
|
) { index ->
|
||||||
|
state.fontScale = fontSizes.map { it.first }[index]
|
||||||
|
//textView.context.updateState() // font size not changed
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
subs_font_size.setOnLongClickListener { _ ->
|
||||||
|
state.fontScale = defaultState.fontScale
|
||||||
|
//textView.context.updateState() // font size not changed
|
||||||
|
showToast(activity, R.string.subs_default_reset_toast, Toast.LENGTH_SHORT)
|
||||||
|
return@setOnLongClickListener true
|
||||||
|
}
|
||||||
|
|
||||||
|
subs_font.setFocusableInTv()
|
||||||
|
subs_font.setOnClickListener { textView ->
|
||||||
|
val fontTypes = listOf(
|
||||||
|
Pair(null, textView.context.getString(R.string.normal)),
|
||||||
|
Pair("Droid Sans", "Droid Sans"),
|
||||||
|
Pair("Droid Sans Mono", "Droid Sans Mono"),
|
||||||
|
Pair("Droid Serif Regular", "Droid Serif Regular"),
|
||||||
|
Pair("Cutive Mono", "Cutive Mono"),
|
||||||
|
Pair("Short Stack", "Short Stack"),
|
||||||
|
Pair("Quintessential", "Quintessential"),
|
||||||
|
Pair("Alegreya Sans SC", "Alegreya Sans SC"),
|
||||||
|
)
|
||||||
|
|
||||||
|
//showBottomDialog
|
||||||
|
activity?.showDialog(
|
||||||
|
fontTypes.map { it.second },
|
||||||
|
fontTypes.map { it.first }.indexOf(state.fontFamily),
|
||||||
|
(textView as TextView).text.toString(),
|
||||||
|
false,
|
||||||
|
dismissCallback
|
||||||
|
) { index ->
|
||||||
|
state.fontFamily = fontTypes.map { it.first }[index]
|
||||||
|
textView.context.updateState()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
subs_font.setOnLongClickListener { textView ->
|
||||||
|
state.fontFamily = defaultState.fontFamily
|
||||||
|
textView.context.updateState()
|
||||||
|
showToast(activity, R.string.subs_default_reset_toast, Toast.LENGTH_SHORT)
|
||||||
|
return@setOnLongClickListener true
|
||||||
|
}
|
||||||
|
|
||||||
|
cancel_btt.setOnClickListener {
|
||||||
|
activity?.popCurrentPage()
|
||||||
|
}
|
||||||
|
|
||||||
|
apply_btt.setOnClickListener {
|
||||||
|
it.context.saveStyle(state)
|
||||||
|
applyStyleEvent.invoke(state)
|
||||||
|
//it.context.fromSaveToStyle(state)
|
||||||
|
activity?.popCurrentPage()
|
||||||
|
}
|
||||||
|
|
||||||
|
subtitle_text.setCues(
|
||||||
|
listOf(
|
||||||
|
Cue.Builder()
|
||||||
|
.setTextSize(
|
||||||
|
getPixels(TypedValue.COMPLEX_UNIT_SP, 25.0f).toFloat(),
|
||||||
|
Cue.TEXT_SIZE_TYPE_ABSOLUTE
|
||||||
|
)
|
||||||
|
.setText(subtitle_text.context.getString(R.string.subtitles_example_text))
|
||||||
|
.build()
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
|
@ -16,6 +16,7 @@ import android.widget.Toast
|
||||||
import androidx.annotation.FontRes
|
import androidx.annotation.FontRes
|
||||||
import androidx.core.content.res.ResourcesCompat
|
import androidx.core.content.res.ResourcesCompat
|
||||||
import androidx.fragment.app.Fragment
|
import androidx.fragment.app.Fragment
|
||||||
|
import com.fasterxml.jackson.annotation.JsonProperty
|
||||||
import com.google.android.exoplayer2.text.Cue
|
import com.google.android.exoplayer2.text.Cue
|
||||||
import com.google.android.exoplayer2.ui.CaptionStyleCompat
|
import com.google.android.exoplayer2.ui.CaptionStyleCompat
|
||||||
import com.jaredrummler.android.colorpicker.ColorPickerDialog
|
import com.jaredrummler.android.colorpicker.ColorPickerDialog
|
||||||
|
@ -42,18 +43,18 @@ const val SUBTITLE_AUTO_SELECT_KEY = "subs_auto_select"
|
||||||
const val SUBTITLE_DOWNLOAD_KEY = "subs_auto_download"
|
const val SUBTITLE_DOWNLOAD_KEY = "subs_auto_download"
|
||||||
|
|
||||||
data class SaveCaptionStyle(
|
data class SaveCaptionStyle(
|
||||||
var foregroundColor: Int,
|
@JsonProperty("foregroundColor") var foregroundColor: Int,
|
||||||
var backgroundColor: Int,
|
@JsonProperty("backgroundColor") var backgroundColor: Int,
|
||||||
var windowColor: Int,
|
@JsonProperty("windowColor") var windowColor: Int,
|
||||||
@CaptionStyleCompat.EdgeType
|
@CaptionStyleCompat.EdgeType
|
||||||
var edgeType: Int,
|
@JsonProperty("edgeType") var edgeType: Int,
|
||||||
var edgeColor: Int,
|
@JsonProperty("edgeColor") var edgeColor: Int,
|
||||||
@FontRes
|
@FontRes
|
||||||
var typeface: Int?,
|
@JsonProperty("typeface") var typeface: Int?,
|
||||||
/**in dp**/
|
/**in dp**/
|
||||||
var elevation: Int,
|
@JsonProperty("elevation") var elevation: Int,
|
||||||
/**in sp**/
|
/**in sp**/
|
||||||
var fixedTextSize: Float?,
|
@JsonProperty("fixedTextSize") var fixedTextSize: Float?,
|
||||||
)
|
)
|
||||||
|
|
||||||
const val DEF_SUBS_ELEVATION = 20
|
const val DEF_SUBS_ELEVATION = 20
|
||||||
|
|
|
@ -1,9 +1,6 @@
|
||||||
package com.lagradost.cloudstream3.utils
|
package com.lagradost.cloudstream3.utils
|
||||||
|
|
||||||
import android.net.Uri
|
import android.net.Uri
|
||||||
import com.fasterxml.jackson.databind.DeserializationFeature
|
|
||||||
import com.fasterxml.jackson.databind.json.JsonMapper
|
|
||||||
import com.fasterxml.jackson.module.kotlin.KotlinModule
|
|
||||||
import com.google.android.exoplayer2.util.MimeTypes
|
import com.google.android.exoplayer2.util.MimeTypes
|
||||||
import com.google.android.gms.cast.*
|
import com.google.android.gms.cast.*
|
||||||
import com.google.android.gms.cast.framework.CastSession
|
import com.google.android.gms.cast.framework.CastSession
|
||||||
|
@ -20,9 +17,6 @@ import kotlinx.coroutines.withContext
|
||||||
import org.json.JSONObject
|
import org.json.JSONObject
|
||||||
|
|
||||||
object CastHelper {
|
object CastHelper {
|
||||||
private val mapper: JsonMapper = JsonMapper.builder().addModule(KotlinModule())
|
|
||||||
.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false).build()
|
|
||||||
|
|
||||||
fun getMediaInfo(
|
fun getMediaInfo(
|
||||||
epData: ResultEpisode,
|
epData: ResultEpisode,
|
||||||
holder: MetadataHolder,
|
holder: MetadataHolder,
|
||||||
|
|
157
app/src/main/res/layout/chromecast_subtitle_settings.xml
Normal file
157
app/src/main/res/layout/chromecast_subtitle_settings.xml
Normal file
|
@ -0,0 +1,157 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:id="@+id/subs_root"
|
||||||
|
android:background="?attr/primaryBlackBackground">
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:orientation="vertical"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:paddingStart="20dp"
|
||||||
|
android:paddingEnd="20dp"
|
||||||
|
android:layout_marginTop="20dp"
|
||||||
|
android:layout_marginBottom="10dp"
|
||||||
|
android:textStyle="bold"
|
||||||
|
android:text="@string/chomecast_subtitles_settings"
|
||||||
|
android:textSize="20sp"
|
||||||
|
android:textColor="?attr/textColor"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_rowWeight="1"
|
||||||
|
android:layout_height="wrap_content" />
|
||||||
|
|
||||||
|
<FrameLayout
|
||||||
|
android:visibility="gone"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="75sp">
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:scaleType="centerCrop"
|
||||||
|
android:src="@drawable/subtitles_preview_background"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:contentDescription="@string/preview_background_img_des" />
|
||||||
|
|
||||||
|
<com.google.android.exoplayer2.ui.SubtitleView
|
||||||
|
android:id="@+id/subtitle_text"
|
||||||
|
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_gravity="center"
|
||||||
|
android:foregroundGravity="center"
|
||||||
|
android:layout_height="match_parent" />
|
||||||
|
</FrameLayout>
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:nextFocusDown="@id/subs_font_size"
|
||||||
|
android:nextFocusLeft="@id/apply_btt"
|
||||||
|
android:nextFocusRight="@id/cancel_btt"
|
||||||
|
|
||||||
|
android:id="@+id/subs_font"
|
||||||
|
android:text="@string/subs_font"
|
||||||
|
style="@style/SettingsItem" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:nextFocusUp="@id/subs_font"
|
||||||
|
android:nextFocusDown="@id/subs_text_color"
|
||||||
|
android:nextFocusLeft="@id/apply_btt"
|
||||||
|
android:nextFocusRight="@id/cancel_btt"
|
||||||
|
|
||||||
|
android:id="@+id/subs_font_size"
|
||||||
|
android:text="@string/subs_font_size"
|
||||||
|
style="@style/SettingsItem" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:nextFocusUp="@id/subs_font_size"
|
||||||
|
android:nextFocusDown="@id/subs_outline_color"
|
||||||
|
android:nextFocusLeft="@id/apply_btt"
|
||||||
|
android:nextFocusRight="@id/cancel_btt"
|
||||||
|
|
||||||
|
android:id="@+id/subs_text_color"
|
||||||
|
android:text="@string/subs_text_color"
|
||||||
|
style="@style/SettingsItem" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:nextFocusUp="@id/subs_text_color"
|
||||||
|
android:nextFocusDown="@id/subs_background_color"
|
||||||
|
android:nextFocusLeft="@id/apply_btt"
|
||||||
|
android:nextFocusRight="@id/cancel_btt"
|
||||||
|
|
||||||
|
android:id="@+id/subs_outline_color"
|
||||||
|
android:text="@string/subs_outline_color"
|
||||||
|
style="@style/SettingsItem" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:nextFocusUp="@id/subs_outline_color"
|
||||||
|
android:nextFocusDown="@id/subs_window_color"
|
||||||
|
android:nextFocusLeft="@id/apply_btt"
|
||||||
|
android:nextFocusRight="@id/cancel_btt"
|
||||||
|
|
||||||
|
android:id="@+id/subs_background_color"
|
||||||
|
android:text="@string/subs_background_color"
|
||||||
|
style="@style/SettingsItem" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:visibility="gone"
|
||||||
|
android:nextFocusUp="@id/subs_background_color"
|
||||||
|
android:nextFocusDown="@id/subs_edge_type"
|
||||||
|
android:nextFocusLeft="@id/apply_btt"
|
||||||
|
android:nextFocusRight="@id/cancel_btt"
|
||||||
|
|
||||||
|
android:id="@+id/subs_window_color"
|
||||||
|
android:text="@string/subs_window_color"
|
||||||
|
style="@style/SettingsItem" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:nextFocusUp="@id/subs_window_color"
|
||||||
|
android:nextFocusDown="@id/apply_btt"
|
||||||
|
android:nextFocusLeft="@id/apply_btt"
|
||||||
|
android:nextFocusRight="@id/cancel_btt"
|
||||||
|
|
||||||
|
android:id="@+id/subs_edge_type"
|
||||||
|
android:text="@string/subs_edge_type"
|
||||||
|
style="@style/SettingsItem" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:gravity="center"
|
||||||
|
android:text="@string/subs_hold_to_reset_to_default"
|
||||||
|
android:textSize="14sp"
|
||||||
|
|
||||||
|
android:textColor="?attr/textColor"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_rowWeight="1"
|
||||||
|
android:layout_height="wrap_content" />
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:orientation="horizontal"
|
||||||
|
android:layout_gravity="bottom"
|
||||||
|
android:gravity="bottom|end"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="60dp">
|
||||||
|
|
||||||
|
<com.google.android.material.button.MaterialButton
|
||||||
|
android:nextFocusUp="@id/subs_edge_type"
|
||||||
|
android:nextFocusRight="@id/cancel_btt"
|
||||||
|
style="@style/WhiteButton"
|
||||||
|
android:layout_gravity="center_vertical|end"
|
||||||
|
android:visibility="visible"
|
||||||
|
android:text="@string/sort_apply"
|
||||||
|
android:id="@+id/apply_btt"
|
||||||
|
android:layout_width="wrap_content">
|
||||||
|
|
||||||
|
<requestFocus />
|
||||||
|
</com.google.android.material.button.MaterialButton>
|
||||||
|
|
||||||
|
<com.google.android.material.button.MaterialButton
|
||||||
|
android:nextFocusUp="@id/subs_edge_type"
|
||||||
|
android:nextFocusLeft="@id/apply_btt"
|
||||||
|
style="@style/BlackButton"
|
||||||
|
android:layout_gravity="center_vertical|end"
|
||||||
|
android:text="@string/sort_cancel"
|
||||||
|
android:id="@+id/cancel_btt"
|
||||||
|
android:layout_width="wrap_content" />
|
||||||
|
</LinearLayout>
|
||||||
|
</LinearLayout>
|
||||||
|
</ScrollView>
|
|
@ -81,6 +81,19 @@
|
||||||
/>
|
/>
|
||||||
</action>
|
</action>
|
||||||
|
|
||||||
|
<action android:id="@+id/global_to_navigation_chrome_subtitles"
|
||||||
|
app:destination="@id/navigation_chrome_subtitles"
|
||||||
|
app:enterAnim="@anim/enter_anim"
|
||||||
|
app:exitAnim="@anim/exit_anim"
|
||||||
|
app:popEnterAnim="@anim/enter_anim"
|
||||||
|
app:popExitAnim="@anim/exit_anim">
|
||||||
|
<argument
|
||||||
|
android:name="hide"
|
||||||
|
app:argType="boolean"
|
||||||
|
android:defaultValue="true"
|
||||||
|
/>
|
||||||
|
</action>
|
||||||
|
|
||||||
<action android:id="@+id/global_to_navigation_quick_search"
|
<action android:id="@+id/global_to_navigation_quick_search"
|
||||||
app:destination="@id/navigation_quick_search"
|
app:destination="@id/navigation_quick_search"
|
||||||
app:enterAnim="@anim/enter_anim"
|
app:enterAnim="@anim/enter_anim"
|
||||||
|
@ -168,6 +181,12 @@
|
||||||
android:name="com.lagradost.cloudstream3.ui.subtitles.SubtitlesFragment"
|
android:name="com.lagradost.cloudstream3.ui.subtitles.SubtitlesFragment"
|
||||||
android:label="@string/subtitles_settings"/>
|
android:label="@string/subtitles_settings"/>
|
||||||
|
|
||||||
|
<fragment
|
||||||
|
android:id="@+id/navigation_chrome_subtitles"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:name="com.lagradost.cloudstream3.ui.subtitles.ChromecastSubtitlesFragment"
|
||||||
|
android:label="@string/chomecast_subtitles_settings"/>
|
||||||
|
|
||||||
<fragment
|
<fragment
|
||||||
android:id="@+id/navigation_quick_search"
|
android:id="@+id/navigation_quick_search"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
|
|
|
@ -11,6 +11,7 @@
|
||||||
<string name="fast_forward_button_time_key" translatable="false">fast_forward_button_time</string>
|
<string name="fast_forward_button_time_key" translatable="false">fast_forward_button_time</string>
|
||||||
<string name="benene_count" translatable="false">benene_count</string>
|
<string name="benene_count" translatable="false">benene_count</string>
|
||||||
<string name="subtitle_settings_key" translatable="false">subtitle_settings_key</string>
|
<string name="subtitle_settings_key" translatable="false">subtitle_settings_key</string>
|
||||||
|
<string name="subtitle_settings_chomecast_key" translatable="false">subtitle_settings_chomecast_key</string>
|
||||||
<string name="quality_pref_key" translatable="false">quality_pref_key</string>
|
<string name="quality_pref_key" translatable="false">quality_pref_key</string>
|
||||||
<string name="video_cache_key" translatable="false">video_cache_key</string>
|
<string name="video_cache_key" translatable="false">video_cache_key</string>
|
||||||
<string name="prerelease_commit_hash" translatable="false">unknown_prerelease</string>
|
<string name="prerelease_commit_hash" translatable="false">unknown_prerelease</string>
|
||||||
|
@ -175,6 +176,9 @@
|
||||||
<string name="player_size_settings_des">Remove the black borders</string>
|
<string name="player_size_settings_des">Remove the black borders</string>
|
||||||
<string name="player_subtitles_settings">Subtitles</string>
|
<string name="player_subtitles_settings">Subtitles</string>
|
||||||
<string name="player_subtitles_settings_des">Player subtitles settings</string>
|
<string name="player_subtitles_settings_des">Player subtitles settings</string>
|
||||||
|
<string name="chomecast_subtitles_settings">Chomecast Subtitles</string>
|
||||||
|
<string name="chomecast_subtitles_settings_des">Chromecast subtitles settings</string>
|
||||||
|
|
||||||
<string name="eigengraumode_settings">Eigengravy Mode</string>
|
<string name="eigengraumode_settings">Eigengravy Mode</string>
|
||||||
<string name="eigengraumode_settings_des">Adds a speed option in the player</string>
|
<string name="eigengraumode_settings_des">Adds a speed option in the player</string>
|
||||||
<string name="swipe_to_seek_settings">Swipe to seek</string>
|
<string name="swipe_to_seek_settings">Swipe to seek</string>
|
||||||
|
|
|
@ -11,6 +11,11 @@
|
||||||
android:title="@string/player_subtitles_settings"
|
android:title="@string/player_subtitles_settings"
|
||||||
android:icon="@drawable/ic_outline_subtitles_24"
|
android:icon="@drawable/ic_outline_subtitles_24"
|
||||||
app:summary="@string/player_subtitles_settings_des" />
|
app:summary="@string/player_subtitles_settings_des" />
|
||||||
|
<Preference
|
||||||
|
android:key="@string/subtitle_settings_chomecast_key"
|
||||||
|
android:title="@string/chomecast_subtitles_settings"
|
||||||
|
android:icon="@drawable/ic_outline_subtitles_24"
|
||||||
|
app:summary="@string/chomecast_subtitles_settings_des" />
|
||||||
<Preference
|
<Preference
|
||||||
android:key="@string/quality_pref_key"
|
android:key="@string/quality_pref_key"
|
||||||
android:title="@string/watch_quality_pref"
|
android:title="@string/watch_quality_pref"
|
||||||
|
|
Loading…
Reference in a new issue