Fix multiple language related issues

* fix playback for other  shows with no language set in cr API
* fix selection of preferred season for languages other than german
* add support for all content languages to TMDBApiController
* preferSecondary is now preferSubbed, this describes the function more clearly
* remove jsoup, not used anymore
This commit is contained in:
Jannik 2022-03-06 18:43:02 +01:00
parent 75204e522d
commit 0797e9fa3d
Signed by: Seil0
GPG Key ID: E8459F3723C52C24
11 changed files with 61 additions and 70 deletions

View File

@ -59,14 +59,13 @@ dependencies {
implementation 'androidx.lifecycle:lifecycle-viewmodel-ktx:2.3.1'
implementation 'com.google.android.material:material:1.4.0'
implementation 'com.google.code.gson:gson:2.8.8'
implementation 'com.google.code.gson:gson:2.8.8' // TODO remove, still used by metadb
implementation 'com.google.android.exoplayer:exoplayer-core:2.15.0'
implementation 'com.google.android.exoplayer:exoplayer-hls:2.15.0'
implementation 'com.google.android.exoplayer:exoplayer-dash:2.15.0'
implementation 'com.google.android.exoplayer:exoplayer-ui:2.15.0'
implementation 'com.google.android.exoplayer:extension-mediasession:2.15.0'
implementation 'org.jsoup:jsoup:1.14.2'
implementation 'com.github.bumptech.glide:glide:4.12.0'
implementation 'jp.wasabeef:glide-transformations:4.3.0'
implementation 'com.afollestad.material-dialogs:core:3.3.0'

View File

@ -224,22 +224,13 @@ data class Seasons(
@SerialName("items") val items: List<Season>
) {
fun getPreferredSeason(local: Locale): Season {
// try to get the the first seasons which matches the preferred local
items.forEach { season ->
if (season.title.startsWith("(${local.language})", true)) {
return season
}
}
// if there is no season with the preferred local, try to find a subbed season
items.forEach { season ->
if (season.isSubbed) {
return season
}
}
// if there is no preferred language season and no sub, use the first season
return items.first()
return items.firstOrNull { season ->
// try to get the the first seasons which matches the preferred local
season.slugTitle.endsWith("${local.displayLanguage}-dub", true)
} ?: items.firstOrNull { season ->
// if there is no season with the preferred local, try to find a subbed season
season.isSubbed
} ?: items.first() // if no preferred language and no sub, use the first season
}
}
@ -247,6 +238,7 @@ data class Seasons(
data class Season(
@SerialName("id") val id: String,
@SerialName("title") val title: String,
@SerialName("slug_title") val slugTitle: String,
@SerialName("series_id") val seriesId: String,
@SerialName("season_number") val seasonNumber: Int,
@SerialName("is_subbed") val isSubbed: Boolean,
@ -254,7 +246,7 @@ data class Season(
)
val NoneSeasons = Seasons(0, emptyList())
val NoneSeason = Season("", "", "", 0, isSubbed = false, isDubbed = false)
val NoneSeason = Season("", "", "", "", 0, isSubbed = false, isDubbed = false)
/**

View File

@ -8,10 +8,10 @@ import java.util.*
object Preferences {
var preferSecondary = false
internal set
var preferredLocale: Locale = Locale.forLanguageTag("en-US") // TODO this should be saved (potential offline usage) but fetched on start
internal set
var preferSubbed = false
internal set
var autoplay = true
internal set
var devSettings = false
@ -26,15 +26,6 @@ object Preferences {
)
}
fun savePreferSecondary(context: Context, preferSecondary: Boolean) {
with(getSharedPref(context).edit()) {
putBoolean(context.getString(R.string.save_key_prefer_secondary), preferSecondary)
apply()
}
this.preferSecondary = preferSecondary
}
fun savePreferredLocal(context: Context, preferredLocale: Locale) {
with(getSharedPref(context).edit()) {
putString(context.getString(R.string.save_key_preferred_local), preferredLocale.toLanguageTag())
@ -44,6 +35,15 @@ object Preferences {
this.preferredLocale = preferredLocale
}
fun savePreferSecondary(context: Context, preferSubbed: Boolean) {
with(getSharedPref(context).edit()) {
putBoolean(context.getString(R.string.save_key_prefer_secondary), preferSubbed)
apply()
}
this.preferSubbed = preferSubbed
}
fun saveAutoplay(context: Context, autoplay: Boolean) {
with(getSharedPref(context).edit()) {
putBoolean(context.getString(R.string.save_key_autoplay), autoplay)
@ -77,14 +77,14 @@ object Preferences {
fun load(context: Context) {
val sharedPref = getSharedPref(context)
preferSecondary = sharedPref.getBoolean(
context.getString(R.string.save_key_prefer_secondary), false
)
preferredLocale = Locale.forLanguageTag(
sharedPref.getString(
context.getString(R.string.save_key_preferred_local), "en-US"
) ?: "en-US"
)
preferSubbed = sharedPref.getBoolean(
context.getString(R.string.save_key_prefer_secondary), false
)
autoplay = sharedPref.getBoolean(
context.getString(R.string.save_key_autoplay), true
)

View File

@ -113,9 +113,9 @@ class AboutFragment : Fragment() {
"https://github.com/google/material-design-icons", License.APACHE2),
ThirdPartyComponent("Material Dialogs", "", "Aidan Follestad",
"https://github.com/afollestad/material-dialogs", License.APACHE2),
ThirdPartyComponent("Jsoup", "2009 - 2020", "Jonathan Hedley",
"https://jsoup.org/", License.MIT),
ThirdPartyComponent("kotlinx.coroutines", "2016 - 2019", "JetBrains",
ThirdPartyComponent("Ktor", "2014-2021", "JetBrains s.r.o and contributors",
"https://ktor.io/", License.APACHE2),
ThirdPartyComponent("kotlinx.coroutines", "2016-2021", "JetBrains s.r.o",
"https://github.com/Kotlin/kotlinx.coroutines", License.APACHE2),
ThirdPartyComponent("Glide", "2014", "Google Inc.",
"https://github.com/bumptech/glide", License.BSD2),

View File

@ -85,7 +85,7 @@ class AccountFragment : Fragment() {
profile.await().preferredContentSubtitleLanguage
).displayLanguage
}
binding.switchSecondary.isChecked = Preferences.preferSecondary
binding.switchSecondary.isChecked = Preferences.preferSubbed
binding.switchAutoplay.isChecked = Preferences.autoplay
binding.textThemeSelected.text = when (Preferences.theme) {
Theme.DARK -> getString(R.string.theme_dark)

View File

@ -51,9 +51,6 @@ class MediaFragment(private val mediaIdStr: String) : Fragment() {
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
println("onViewCreated")
binding.frameLoading.visibility = View.VISIBLE
// tab layout and pager

View File

@ -47,8 +47,6 @@ import org.mosad.teapod.parser.crunchyroll.NoneEpisodes
import org.mosad.teapod.parser.crunchyroll.NonePlayback
import org.mosad.teapod.preferences.Preferences
import org.mosad.teapod.util.EpisodeMeta
import org.mosad.teapod.util.Meta
import org.mosad.teapod.util.TVShowMeta
import org.mosad.teapod.util.tmdb.TMDBTVSeason
import java.util.*
@ -64,12 +62,12 @@ class PlayerViewModel(application: Application) : AndroidViewModel(application)
private val mediaSession = MediaSessionCompat(application, "TEAPOD_PLAYER_SESSION")
val currentEpisodeChangedListener = ArrayList<() -> Unit>()
private val preferredLanguage = if (Preferences.preferSecondary) Locale.JAPANESE else Locale.GERMAN
private var currentPlayhead: Long = 0
// tmdb/meta data TODO currently not implemented for cr
var mediaMeta: Meta? = null
internal set
// tmdb/meta data
// TODO meta data currently not implemented for cr
// var mediaMeta: Meta? = null
// internal set
var tmdbTVSeason: TMDBTVSeason? =null
internal set
var currentEpisodeMeta: EpisodeMeta? = null
@ -224,8 +222,9 @@ class PlayerViewModel(application: Application) : AndroidViewModel(application)
currentPlayback.streams.adaptive_hls[fallbackLocal.toLanguageTag()]?.url
}
else -> {
// if no language tag is present use the first entry
currentLanguage = Locale.ROOT
currentPlayback.streams.adaptive_hls[Locale.ROOT.toLanguageTag()]?.url ?: ""
currentPlayback.streams.adaptive_hls.entries.first().value.url
}
}
println("stream url: $url")
@ -267,25 +266,25 @@ class PlayerViewModel(application: Application) : AndroidViewModel(application)
return episodes.items.lastOrNull()?.id == currentEpisode.id
}
fun getEpisodeMetaByAoDMediaId(aodMediaId: Int): EpisodeMeta? {
val meta = mediaMeta
return if (meta is TVShowMeta) {
meta.episodes.firstOrNull { it.aodMediaId == aodMediaId }
} else {
null
}
}
// TODO reimplement for cr
private suspend fun loadMediaMeta(aodId: Int): Meta? {
// fun getEpisodeMetaByAoDMediaId(aodMediaId: Int): EpisodeMeta? {
// val meta = mediaMeta
// return if (meta is TVShowMeta) {
// meta.episodes.firstOrNull { it.aodMediaId == aodMediaId }
// } else {
// null
// }
// }
//
// private suspend fun loadMediaMeta(aodId: Int): Meta? {
// return if (media.type == DataTypes.MediaType.TVSHOW) {
// MetaDBController().getTVShowMetadata(aodId)
// } else {
// null
// }
return null
}
//
// return null
// }
/**
* Update the playhead of the current episode, if currentPosition > 1000ms.

View File

@ -34,6 +34,7 @@ import kotlinx.coroutines.coroutineScope
import kotlinx.coroutines.invoke
import kotlinx.serialization.SerializationException
import kotlinx.serialization.json.Json
import org.mosad.teapod.preferences.Preferences
import org.mosad.teapod.util.concatenate
/**
@ -54,7 +55,6 @@ class TMDBApiController {
private val apiUrl = "https://api.themoviedb.org/3"
private val apiKey = "de959cf9c07a08b5ca7cb51cda9a40c2"
private val language = "de"
companion object{
const val imageUrl = "https://image.tmdb.org/t/p/w500"
@ -65,7 +65,10 @@ class TMDBApiController {
parameters: List<Pair<String, Any?>> = emptyList()
): T = coroutineScope {
val path = "$apiUrl$endpoint"
val params = concatenate(listOf("api_key" to apiKey, "language" to language), parameters)
val params = concatenate(
listOf("api_key" to apiKey, "language" to Preferences.preferredLocale.language),
parameters
)
// TODO handle FileNotFoundException
return@coroutineScope (Dispatchers.IO) {

View File

@ -198,7 +198,7 @@
android:id="@+id/imageView3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:contentDescription="@string/settings_secondary"
android:contentDescription="@string/settings_prefer_subbed"
android:minWidth="48dp"
android:minHeight="48dp"
android:padding="9dp"
@ -225,7 +225,7 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="@string/settings_secondary"
android:text="@string/settings_prefer_subbed"
android:textSize="16sp" />
<TextView
@ -234,7 +234,7 @@
android:layout_height="wrap_content"
android:layout_weight="1"
android:maxLines="2"
android:text="@string/settings_secondary_desc"
android:text="@string/settings_prefer_subbed_desc"
android:textColor="?textSecondary" />
</LinearLayout>

View File

@ -42,8 +42,8 @@
<string name="settings_content_language">Bevorzuge Inhaltssprache</string>
<string name="settings_content_language_desc">Englisch</string>
<string name="settings_content_language_none">Keine</string>
<string name="settings_secondary">Bevorzuge Japanisch (OmU)</string>
<string name="settings_secondary_desc">Japanisch verwenden, sofern vorhanden</string>
<string name="settings_prefer_subbed">Bevorzuge OmU</string>
<string name="settings_prefer_subbed_desc">Original Sprache verwenden, sofern vorhanden</string>
<string name="settings_autoplay">Autoplay</string>
<string name="settings_autoplay_desc">Nächste Episode automatisch abspielen</string>
<string name="theme">Design</string>

View File

@ -40,7 +40,7 @@
<string name="component_poster_desc" translatable="false">episode poster</string>
<string name="component_watched_desc" translatable="false">already watched</string>
<!-- settings fragment -->
<!-- account fragment -->
<string name="account">Account</string>
<string name="account_login_ex" translatable="false">user@example.com</string>
<string name="account_login_desc">Tap to edit</string>
@ -50,8 +50,8 @@
<string name="settings_content_language">Preferred content language</string>
<string name="settings_content_language_desc">English</string>
<string name="settings_content_language_none">None</string>
<string name="settings_secondary">Prefer japanese (sub)</string>
<string name="settings_secondary_desc">Use japanese, if present</string>
<string name="settings_prefer_subbed">Prefer subbed</string>
<string name="settings_prefer_subbed_desc">Use original language, if present</string>
<string name="settings_autoplay">Autoplay</string>
<string name="settings_autoplay_desc">Play next episode automatically</string>
<string name="theme">Theme</string>
@ -131,6 +131,7 @@
<string name="preference_file_key" translatable="false">org.mosad.teapod.preferences</string>
<string name="save_key_user_login" translatable="false">org.mosad.teapod.user_login</string>
<string name="save_key_user_password" translatable="false">org.mosad.teapod.user_password</string>
<!-- for legacy reasons the prefer subbed key is called prefer_secondary-->
<string name="save_key_prefer_secondary" translatable="false">org.mosad.teapod.prefer_secondary</string>
<string name="save_key_preferred_local" translatable="false">org.mosad.teapod.preferred_local</string>
<string name="save_key_autoplay" translatable="false">org.mosad.teapod.autoplay</string>