From f3944697878bbff59e34891155c5d11cdceb0235 Mon Sep 17 00:00:00 2001 From: LagradOst Date: Thu, 23 Sep 2021 20:08:57 +0200 Subject: [PATCH] fixed chromecast, fixed tenshi, fixed lang providers --- app/build.gradle | 13 ++-- .../com/lagradost/cloudstream3/MainAPI.kt | 37 +++++++++-- .../lagradost/cloudstream3/MainActivity.kt | 50 ++++++++++++++- .../animeproviders/TenshiProvider.kt | 16 +++-- .../cloudstream3/ui/ControllerActivity.kt | 53 ++++++++------- .../cloudstream3/ui/player/PlayerFragment.kt | 64 +++++++++++++++---- .../cloudstream3/ui/result/ResultFragment.kt | 2 +- .../ui/settings/SettingsFragment.kt | 37 +++++++++++ .../cloudstream3/utils/CastHelper.kt | 29 +++------ app/src/main/res/values-sv/strings.xml | 2 +- app/src/main/res/values/strings.xml | 4 ++ app/src/main/res/values/styles.xml | 13 ++-- app/src/main/res/xml/settings.xml | 41 +++++++----- 13 files changed, 266 insertions(+), 95 deletions(-) diff --git a/app/build.gradle b/app/build.gradle index 297a4f99..2a35709d 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -31,8 +31,8 @@ android { applicationId "com.lagradost.cloudstream3" minSdkVersion 21 targetSdkVersion 31 - versionCode 26 - versionName "1.9.10" + versionCode 27 + versionName "1.9.11" resValue "string", "app_version", "${defaultConfig.versionName}${versionNameSuffix ?: ""}" @@ -72,9 +72,6 @@ android { } repositories { - maven { - url 'https://github.com/psiegman/mvn-repo/raw/master/releases' - } maven { url 'https://jitpack.io' } } @@ -108,9 +105,9 @@ dependencies { implementation 'androidx.swiperefreshlayout:swiperefreshlayout:1.1.0' // Exoplayer - implementation 'com.google.android.exoplayer:exoplayer:2.14.2' - implementation 'com.google.android.exoplayer:extension-cast:2.14.2' - implementation "com.google.android.exoplayer:extension-mediasession:2.14.2" + implementation 'com.google.android.exoplayer:exoplayer:2.15.0' + implementation 'com.google.android.exoplayer:extension-cast:2.15.0' + implementation "com.google.android.exoplayer:extension-mediasession:2.15.0" //implementation "com.google.android.exoplayer:extension-leanback:2.14.0" // Bug reports diff --git a/app/src/main/java/com/lagradost/cloudstream3/MainAPI.kt b/app/src/main/java/com/lagradost/cloudstream3/MainAPI.kt index 49a429c3..7468736c 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/MainAPI.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/MainAPI.kt @@ -1,6 +1,7 @@ package com.lagradost.cloudstream3 import android.app.Activity +import android.content.Context import androidx.preference.PreferenceManager import com.fasterxml.jackson.databind.DeserializationFeature import com.fasterxml.jackson.databind.json.JsonMapper @@ -9,6 +10,8 @@ import com.lagradost.cloudstream3.animeproviders.* import com.lagradost.cloudstream3.movieproviders.* import com.lagradost.cloudstream3.utils.ExtractorLink import java.util.* +import kotlin.collections.ArrayList +import kotlin.collections.HashSet const val USER_AGENT = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36" @@ -69,19 +72,30 @@ object APIHolder { return url.replace(getApiFromName(apiName).mainUrl, "").replace("/", "").hashCode() } - fun Activity.getApiSettings(): HashSet { + fun Context.getApiSettings(): HashSet { val settingsManager = PreferenceManager.getDefaultSharedPreferences(this) val hashSet = HashSet() hashSet.addAll(apis.map { it.name }) - return settingsManager.getStringSet( + val set = settingsManager.getStringSet( this.getString(R.string.search_providers_list_key), hashSet )?.toHashSet() ?: hashSet + + val activeLangs = getApiProviderLangSettings() + val list = HashSet() + for (name in set) { + val api = getApiFromNameNull(name) ?: continue + if(activeLangs.contains(api.lang) ) { + list.add(name) + } + } + if(list.isEmpty()) return hashSet + return list } - fun Activity.getApiDubstatusSettings(): HashSet { + fun Context.getApiDubstatusSettings(): HashSet { val settingsManager = PreferenceManager.getDefaultSharedPreferences(this) val hashSet = HashSet() hashSet.addAll(DubStatus.values()) @@ -96,7 +110,20 @@ object APIHolder { return list.filter { names.contains(it) }.map { DubStatus.valueOf(it) }.toHashSet() } - fun Activity.getApiTypeSettings(): HashSet { + fun Context.getApiProviderLangSettings(): HashSet { + val settingsManager = PreferenceManager.getDefaultSharedPreferences(this) + val hashSet = HashSet() + hashSet.add("en") // def is only en + val list = settingsManager.getStringSet( + this.getString(R.string.provider_lang_key), + hashSet.toMutableSet() + ) + + if(list.isNullOrEmpty()) return hashSet + return list.toHashSet() + } + + fun Context.getApiTypeSettings(): HashSet { val settingsManager = PreferenceManager.getDefaultSharedPreferences(this) val hashSet = HashSet() hashSet.addAll(TvType.values()) @@ -120,6 +147,8 @@ abstract class MainAPI { open val name = "NONE" open val mainUrl = "NONE" + open val lang = "en" // ISO_639_1 check SubtitleHelper + /**If link is stored in the "data" string, so links can be instantly loaded*/ open val instantLinkLoading = false diff --git a/app/src/main/java/com/lagradost/cloudstream3/MainActivity.kt b/app/src/main/java/com/lagradost/cloudstream3/MainActivity.kt index 88457b1b..bea1a2b9 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/MainActivity.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/MainActivity.kt @@ -26,7 +26,7 @@ import androidx.navigation.ui.setupWithNavController import androidx.preference.PreferenceManager import androidx.transition.ChangeBounds import androidx.transition.TransitionManager -import com.google.android.gms.cast.framework.CastButtonFactory +import com.google.android.gms.cast.framework.* import com.jaredrummler.android.colorpicker.ColorPickerDialogListener import com.lagradost.cloudstream3.APIHolder.apis import com.lagradost.cloudstream3.APIHolder.getApiDubstatusSettings @@ -80,6 +80,53 @@ class MainActivity : AppCompatActivity(), ColorPickerDialogListener { updateLocale() // android fucks me by chaining lang when rotating the phone } + var mCastSession: CastSession? = null + lateinit var mSessionManager: SessionManager + val mSessionManagerListener: SessionManagerListener by lazy { SessionManagerListenerImpl() } + + private inner class SessionManagerListenerImpl : SessionManagerListener { + override fun onSessionStarting(session: Session) { + } + + override fun onSessionStarted(session: Session, sessionId: String) { + invalidateOptionsMenu() + } + + override fun onSessionStartFailed(session: Session, i: Int) { + } + + override fun onSessionEnding(session: Session) { + } + + override fun onSessionResumed(session: Session, wasSuspended: Boolean) { + invalidateOptionsMenu() + } + + override fun onSessionResumeFailed(session: Session, i: Int) { + } + + override fun onSessionSuspended(session: Session, i: Int) { + } + + override fun onSessionEnded(session: Session, error: Int) { + } + + override fun onSessionResuming(session: Session, s: String) { + } + } + + override fun onResume() { + super.onResume() + mCastSession = mSessionManager.currentCastSession + mSessionManager.addSessionManagerListener(mSessionManagerListener) + } + + override fun onPause() { + super.onPause() + mSessionManager.removeSessionManagerListener(mSessionManagerListener) + mCastSession = null + } + companion object { var canEnterPipMode: Boolean = false var canShowPipMode: Boolean = false @@ -268,6 +315,7 @@ class MainActivity : AppCompatActivity(), ColorPickerDialogListener { ) // THEME IS SET BEFORE VIEW IS CREATED TO APPLY THE THEME TO THE MAIN VIEW updateLocale() super.onCreate(savedInstanceState) + mSessionManager = CastContext.getSharedInstance(this).sessionManager window.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN) diff --git a/app/src/main/java/com/lagradost/cloudstream3/animeproviders/TenshiProvider.kt b/app/src/main/java/com/lagradost/cloudstream3/animeproviders/TenshiProvider.kt index f6f40c37..7fd94920 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/animeproviders/TenshiProvider.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/animeproviders/TenshiProvider.kt @@ -140,12 +140,16 @@ class TenshiProvider : MainAPI() { @SuppressLint("SimpleDateFormat") private fun dateParser(dateString: String): String? { - val format = SimpleDateFormat("dd 'of' MMM',' yyyy") - val newFormat = SimpleDateFormat("dd-MM-yyyy") - val data = format.parse( - dateString.replace("th ", " ").replace("st ", " ").replace("nd ", " ").replace("rd ", " ") - ) ?: return null - return newFormat.format(data) + try { + val format = SimpleDateFormat("dd 'of' MMM',' yyyy") + val newFormat = SimpleDateFormat("dd-MM-yyyy") + val data = format.parse( + dateString.replace("th ", " ").replace("st ", " ").replace("nd ", " ").replace("rd ", " ") + ) ?: return null + return newFormat.format(data) + } catch (e : Exception) { + return null + } } // data class TenshiSearchResponse( diff --git a/app/src/main/java/com/lagradost/cloudstream3/ui/ControllerActivity.kt b/app/src/main/java/com/lagradost/cloudstream3/ui/ControllerActivity.kt index 1d59b2cd..4bb18fdf 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/ui/ControllerActivity.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/ui/ControllerActivity.kt @@ -11,6 +11,7 @@ import com.fasterxml.jackson.databind.DeserializationFeature import com.fasterxml.jackson.databind.json.JsonMapper import com.fasterxml.jackson.module.kotlin.KotlinModule import com.google.android.gms.cast.MediaQueueItem +import com.google.android.gms.cast.MediaSeekOptions import com.google.android.gms.cast.MediaStatus.REPEAT_MODE_REPEAT_OFF import com.google.android.gms.cast.MediaTrack import com.google.android.gms.cast.TextTrackStyle @@ -33,12 +34,17 @@ import com.lagradost.cloudstream3.utils.ExtractorLink import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.withContext import org.json.JSONObject +import kotlin.concurrent.thread class SkipOpController(val view: ImageView) : UIController() { init { view.setImageResource(R.drawable.exo_controls_fastforward) view.setOnClickListener { - remoteMediaClient.seek(remoteMediaClient.approximateStreamPosition + 85000) + remoteMediaClient?.let { + val options = MediaSeekOptions.Builder() + .setPosition(it.approximateStreamPosition + 85000) + it.seek(options.build()) + } } } } @@ -192,15 +198,11 @@ class SelectSourceController(val view: ImageView, val activity: ControllerActivi try { // THIS IS VERY IMPORTANT BECAUSE WE NEVER WANT TO AUTOLOAD THE NEXT EPISODE val currentIdIndex = remoteMediaClient?.getItemIndex() - val nextId = remoteMediaClient.mediaQueue.itemIds?.get(currentIdIndex?.plus(1) ?: 0) - + val nextId = remoteMediaClient?.mediaQueue?.itemIds?.get(currentIdIndex?.plus(1) ?: 0) if (currentIdIndex == null && nextId != null) { awaitLinks( remoteMediaClient?.queueInsertAndPlayItem( - MediaQueueItem.Builder( - mediaItem - ) - .build(), + MediaQueueItem.Builder(mediaItem).build(), nextId, startAt, JSONObject() @@ -223,6 +225,7 @@ class SelectSourceController(val view: ImageView, val activity: ControllerActivi bottomSheetDialog.dismiss() } + } } } @@ -253,8 +256,7 @@ class SelectSourceController(val view: ImageView, val activity: ControllerActivi if (itemCount != null && itemCount - currentIdIndex == 1 && !isLoadingMore) { isLoadingMore = true - - main { + thread { val index = meta.currentEpisodeIndex + 1 val epData = meta.episodes[index] val links = ArrayList() @@ -280,9 +282,8 @@ class SelectSourceController(val view: ImageView, val activity: ControllerActivi currentEpisodeIndex = index ) - val done = withContext(Dispatchers.IO) { + val done = JSONObject(mapper.writeValueAsString(jsonCopy)) - } val mediaInfo = getMediaInfo( epData, @@ -304,19 +305,23 @@ class SelectSourceController(val view: ImageView, val activity: ControllerActivi loadIndex(index + 1) } }*/ + activity.runOnUiThread { + awaitLinks( - awaitLinks( - remoteMediaClient?.queueAppendItem( - MediaQueueItem.Builder(mediaInfo).build(), - JSONObject() - ) - ) { - println("FAILED TO LOAD NEXT ITEM") - // loadIndex(1) + remoteMediaClient?.queueAppendItem( + MediaQueueItem.Builder(mediaInfo).build(), + JSONObject() + ) + + + ) { + println("FAILED TO LOAD NEXT ITEM") + // loadIndex(1) + } + isLoadingMore = false } - - isLoadingMore = false } + } } } @@ -340,7 +345,11 @@ class SkipTimeController(val view: ImageView, forwards: Boolean) : UIController( //view.setImageResource(if (forwards) R.drawable.netflix_skip_forward else R.drawable.netflix_skip_back) view.setImageResource(if (forwards) R.drawable.go_forward_30 else R.drawable.go_back_30) view.setOnClickListener { - remoteMediaClient.seek(remoteMediaClient.approximateStreamPosition + time * 1000 * if (forwards) 1 else -1) + remoteMediaClient?.let { + val options = MediaSeekOptions.Builder() + .setPosition(it.approximateStreamPosition + time * 1000 * if (forwards) 1 else -1) + it.seek(options.build()) + } } } } diff --git a/app/src/main/java/com/lagradost/cloudstream3/ui/player/PlayerFragment.kt b/app/src/main/java/com/lagradost/cloudstream3/ui/player/PlayerFragment.kt index 47039465..e0f90536 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/ui/player/PlayerFragment.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/ui/player/PlayerFragment.kt @@ -14,6 +14,7 @@ import android.database.ContentObserver import android.graphics.Color import android.graphics.drawable.Icon import android.media.AudioManager +import android.media.metrics.PlaybackErrorEvent import android.net.Uri import android.os.* import android.provider.Settings @@ -46,6 +47,7 @@ import com.fasterxml.jackson.module.kotlin.KotlinModule import com.fasterxml.jackson.module.kotlin.readValue import com.google.android.exoplayer2.* import com.google.android.exoplayer2.C.TIME_UNSET +import com.google.android.exoplayer2.PlaybackException.ERROR_CODE_AUDIO_TRACK_INIT_FAILED import com.google.android.exoplayer2.database.ExoDatabaseProvider import com.google.android.exoplayer2.source.DefaultMediaSourceFactory import com.google.android.exoplayer2.trackselection.DefaultTrackSelector @@ -165,7 +167,6 @@ data class UriData( // YE, I KNOW, THIS COULD BE HANDLED A LOT BETTER class PlayerFragment : Fragment() { - // ============ TORRENT ============ //private var torrentStream: TorrentStream? = null private var lastTorrentUrl = "" @@ -752,6 +753,15 @@ class PlayerFragment : Fragment() { private var volumeObserver: SettingsContentObserver? = null companion object { + fun String.toSubtitleMimeType(): String { + return when { + endsWith("vtt", true) -> MimeTypes.TEXT_VTT + endsWith("srt", true) -> MimeTypes.APPLICATION_SUBRIP + endsWith("xml", true) || endsWith("ttml", true) -> MimeTypes.APPLICATION_TTML + else -> MimeTypes.APPLICATION_SUBRIP // TODO get request to see + } + } + fun newInstance(data: PlayerData, startPos: Long? = null): Bundle { return Bundle().apply { //println(data) @@ -1050,7 +1060,7 @@ class PlayerFragment : Fragment() { val epData = getEpisode() ?: return@addCastStateListener val index = links.indexOf(getCurrentUrl()) - context?.startCast( + (activity as MainActivity?)?.mCastSession?.startCast( apiName, currentIsMovie ?: return@addCastStateListener, currentHeaderName, @@ -1737,15 +1747,6 @@ class PlayerFragment : Fragment() { private val updateProgressAction = Runnable { updateProgressBar() }*/ - private fun String.toSubtitleMimeType(): String { - return when { - endsWith("vtt", true) -> MimeTypes.TEXT_VTT - endsWith("srt", true) -> MimeTypes.APPLICATION_SUBRIP - endsWith("xml", true) || endsWith("ttml", true) -> MimeTypes.APPLICATION_TTML - else -> MimeTypes.APPLICATION_SUBRIP // TODO get request to see - } - } - var activeSubtitles: List = listOf() var preferredSubtitles: String = "" @@ -2047,7 +2048,44 @@ class PlayerFragment : Fragment() { } } - override fun onPlayerError(error: ExoPlaybackException) { + override fun onPlayerError(error: PlaybackException) { + println("CURRENT URL: " + currentUrl?.url) + // Lets pray this doesn't spam Toasts :) + val msg = error.message ?: "" + when (val code = error.errorCode) { + PlaybackException.ERROR_CODE_IO_FILE_NOT_FOUND, PlaybackException.ERROR_CODE_IO_NO_PERMISSION, PlaybackException.ERROR_CODE_IO_UNSPECIFIED -> { + if (currentUrl?.url != "") { + showToast( + activity, + "${getString(R.string.source_error)}\n$code\n$msg", + LENGTH_SHORT + ) + tryNextMirror() + } + } + PlaybackException.ERROR_CODE_REMOTE_ERROR, PlaybackException.ERROR_CODE_IO_BAD_HTTP_STATUS, PlaybackException.ERROR_CODE_TIMEOUT, PlaybackException.ERROR_CODE_IO_NETWORK_CONNECTION_FAILED, PlaybackException.ERROR_CODE_IO_INVALID_HTTP_CONTENT_TYPE -> { + showToast(activity, "${getString(R.string.remote_error)}\n$code\n$msg", LENGTH_SHORT) + } + PlaybackException.ERROR_CODE_DECODING_FAILED, PlaybackErrorEvent.ERROR_AUDIO_TRACK_INIT_FAILED, PlaybackErrorEvent.ERROR_AUDIO_TRACK_OTHER, PlaybackException.ERROR_CODE_AUDIO_TRACK_WRITE_FAILED, PlaybackException.ERROR_CODE_DECODER_INIT_FAILED, PlaybackException.ERROR_CODE_DECODER_QUERY_FAILED -> { + showToast( + activity, + "${getString(R.string.render_error)}\n$code\n$msg", + LENGTH_SHORT + ) + } + else -> { + showToast( + activity, + "${getString(R.string.unexpected_error)}\n$code\n$msg", + LENGTH_SHORT + ) + } + } + + super.onPlayerError(error) + } + + /*override fun onPlayerError(error: ExoPlaybackException) { println("CURRENT URL: " + currentUrl?.url) // Lets pray this doesn't spam Toasts :) when (error.type) { @@ -2079,7 +2117,7 @@ class PlayerFragment : Fragment() { ) } } - } + }*/ }) } catch (e: java.lang.IllegalStateException) { println("Warning: Illegal state exception in PlayerFragment") diff --git a/app/src/main/java/com/lagradost/cloudstream3/ui/result/ResultFragment.kt b/app/src/main/java/com/lagradost/cloudstream3/ui/result/ResultFragment.kt index d91fafd2..68de7dfc 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/ui/result/ResultFragment.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/ui/result/ResultFragment.kt @@ -427,7 +427,7 @@ class ResultFragment : Fragment() { fun startChromecast(startIndex: Int) { val eps = currentEpisodes ?: return - context?.startCast( + (activity as MainActivity?)?.mCastSession?.startCast( apiName, currentIsMovie ?: return, currentHeaderName, diff --git a/app/src/main/java/com/lagradost/cloudstream3/ui/settings/SettingsFragment.kt b/app/src/main/java/com/lagradost/cloudstream3/ui/settings/SettingsFragment.kt index 5751a70d..828ea4e6 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/ui/settings/SettingsFragment.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/ui/settings/SettingsFragment.kt @@ -6,7 +6,10 @@ import androidx.appcompat.app.AlertDialog import androidx.preference.Preference import androidx.preference.PreferenceFragmentCompat import androidx.preference.PreferenceManager +import com.lagradost.cloudstream3.APIHolder.apis import com.lagradost.cloudstream3.APIHolder.getApiDubstatusSettings +import com.lagradost.cloudstream3.APIHolder.getApiProviderLangSettings +import com.lagradost.cloudstream3.APIHolder.restrictedApis import com.lagradost.cloudstream3.DubStatus import com.lagradost.cloudstream3.MainActivity.Companion.setLocale import com.lagradost.cloudstream3.MainActivity.Companion.showToast @@ -19,6 +22,7 @@ import com.lagradost.cloudstream3.utils.Qualities import com.lagradost.cloudstream3.utils.SingleSelectionHelper.showBottomDialog import com.lagradost.cloudstream3.utils.SingleSelectionHelper.showDialog import com.lagradost.cloudstream3.utils.SingleSelectionHelper.showMultiDialog +import com.lagradost.cloudstream3.utils.SubtitleHelper import com.lagradost.cloudstream3.utils.UIHelper.hideKeyboard import kotlin.concurrent.thread @@ -50,6 +54,7 @@ class SettingsFragment : PreferenceFragmentCompat() { val watchQualityPreference = findPreference(getString(R.string.quality_pref_key))!! val legalPreference = findPreference(getString(R.string.legal_notice_key))!! val subdubPreference = findPreference(getString(R.string.display_sub_key))!! + val providerLangPreference = findPreference(getString(R.string.provider_lang_key))!! legalPreference.setOnPreferenceClickListener { val builder: AlertDialog.Builder = AlertDialog.Builder(it.context) @@ -85,7 +90,39 @@ class SettingsFragment : PreferenceFragmentCompat() { } } + return@setOnPreferenceClickListener true + } + providerLangPreference.setOnPreferenceClickListener { + val settingsManager = PreferenceManager.getDefaultSharedPreferences(context) + + activity?.getApiProviderLangSettings()?.let { current -> + val allLangs = HashSet() + for (api in apis) { + allLangs.add(api.lang) + } + for (api in restrictedApis) { + allLangs.add(api.lang) + } + + val currentList = ArrayList() + for (i in current) { + currentList.add(allLangs.indexOf(i)) + } + + val names = allLangs.mapNotNull { SubtitleHelper.fromTwoLettersToLanguage(it) } + + context?.showMultiDialog( + names, + currentList, + getString(R.string.provider_lang_settings), + {}) { selectedList -> + settingsManager.edit().putStringSet( + this.getString(R.string.provider_lang_key), + selectedList.map { names[it] }.toMutableSet() + ).apply() + } + } return@setOnPreferenceClickListener true } diff --git a/app/src/main/java/com/lagradost/cloudstream3/utils/CastHelper.kt b/app/src/main/java/com/lagradost/cloudstream3/utils/CastHelper.kt index 00543923..651b261e 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/utils/CastHelper.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/utils/CastHelper.kt @@ -1,15 +1,12 @@ package com.lagradost.cloudstream3.utils -import android.content.Context 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.ext.cast.CastPlayer import com.google.android.exoplayer2.util.MimeTypes import com.google.android.gms.cast.* -import com.google.android.gms.cast.MediaStatus.REPEAT_MODE_REPEAT_OFF -import com.google.android.gms.cast.framework.CastContext +import com.google.android.gms.cast.framework.CastSession import com.google.android.gms.cast.framework.media.RemoteMediaClient import com.google.android.gms.common.api.PendingResult import com.google.android.gms.common.images.WebImage @@ -59,13 +56,16 @@ object CastHelper { .build() } - return MediaInfo.Builder(link.url) + val builder = MediaInfo.Builder(link.url) .setStreamType(MediaInfo.STREAM_TYPE_BUFFERED) .setContentType(MimeTypes.VIDEO_UNKNOWN) - .setCustomData(data) .setMetadata(movieMetadata) .setMediaTracks(tracks) - .build() + data?.let { + builder.setCustomData(data) + } + + return builder.build() } fun awaitLinks(pending: PendingResult?, callback: (Boolean) -> Unit) { @@ -84,8 +84,7 @@ object CastHelper { } } - - fun Context.startCast( + fun CastSession?.startCast( apiName: String, isMovie: Boolean, title: String?, @@ -97,11 +96,10 @@ object CastHelper { startIndex: Int? = null, startTime: Long? = null, ) : Boolean { + if(this == null) return false if (episodes.isEmpty()) return false if (currentLinks.size <= currentEpisodeIndex) return false - val castContext = CastContext.getSharedInstance(this) - val epData = episodes[currentEpisodeIndex] val holder = @@ -112,15 +110,8 @@ object CastHelper { val mediaItem = getMediaInfo(epData, holder, index, JSONObject(mapper.writeValueAsString(holder)), subtitles) - val castPlayer = CastPlayer(castContext) - - castPlayer.repeatMode = REPEAT_MODE_REPEAT_OFF - awaitLinks( - castPlayer.loadItem( - MediaQueueItem.Builder(mediaItem).build(), - startTime ?: 0, - ) + this.remoteMediaClient?.load(MediaLoadRequestData.Builder().setMediaInfo(mediaItem).setCurrentTime(startTime ?: 0L).build() ) ) { if (currentLinks.size > index + 1) startCast( diff --git a/app/src/main/res/values-sv/strings.xml b/app/src/main/res/values-sv/strings.xml index 99a7c529..9f6dcae8 100644 --- a/app/src/main/res/values-sv/strings.xml +++ b/app/src/main/res/values-sv/strings.xml @@ -202,5 +202,5 @@ Återuppta Ett nerladdningsfel uppstod, kolla om appen har lagringsbehörigheter Föredragen videokvalitet - + Allmänna Inställningar diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 82e14b9b..a71f89c9 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -22,6 +22,8 @@ swipe_vertical_enabled_key display_sub_key show_fillers_key + provider_lang_key + %d %s | %sMB @@ -276,4 +278,6 @@ It merely scrapes 3rd-party websites that are publicly accessable via any regular web browser. It is the responsibility of user to avoid any actions that might violate the laws governing his/her locality. Use CloudStream 3 at your own risk. + General + Provider Languages diff --git a/app/src/main/res/values/styles.xml b/app/src/main/res/values/styles.xml index 46be92b1..e550d03e 100644 --- a/app/src/main/res/values/styles.xml +++ b/app/src/main/res/values/styles.xml @@ -177,16 +177,19 @@ ?attr/textColor ?attr/textColor - + +