diff --git a/app/src/main/java/com/lagradost/cloudstream3/animeproviders/AnimeFlickProvider.kt b/app/src/main/java/com/lagradost/cloudstream3/animeproviders/AnimeFlickProvider.kt index 518b49dd..4e178f35 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/animeproviders/AnimeFlickProvider.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/animeproviders/AnimeFlickProvider.kt @@ -9,7 +9,6 @@ import com.lagradost.cloudstream3.utils.extractorApis import org.jsoup.Jsoup import java.util.* - class AnimeFlickProvider : MainAPI() { companion object { fun getType(t: String): TvType { diff --git a/app/src/main/java/com/lagradost/cloudstream3/animeproviders/GogoanimeProvider.kt b/app/src/main/java/com/lagradost/cloudstream3/animeproviders/GogoanimeProvider.kt index 427b29ed..738a30f2 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/animeproviders/GogoanimeProvider.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/animeproviders/GogoanimeProvider.kt @@ -10,7 +10,6 @@ import com.lagradost.cloudstream3.utils.getQualityFromName import org.jsoup.Jsoup import java.util.* - class GogoanimeProvider : MainAPI() { companion object { fun getType(t: String): TvType { 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 bde8ae2c..0fad07b8 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/animeproviders/TenshiProvider.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/animeproviders/TenshiProvider.kt @@ -4,7 +4,6 @@ import android.annotation.SuppressLint import com.fasterxml.jackson.annotation.JsonProperty import com.fasterxml.jackson.module.kotlin.readValue import com.lagradost.cloudstream3.* -import com.lagradost.cloudstream3.network.cookies import com.lagradost.cloudstream3.network.get import com.lagradost.cloudstream3.network.text import com.lagradost.cloudstream3.utils.ExtractorLink @@ -16,8 +15,8 @@ import java.util.* class TenshiProvider : MainAPI() { companion object { - var token: String? = null - var cookie: Map = mapOf() + //var token: String? = null + //var cookie: Map = mapOf() fun getType(t: String): TvType { return if (t.contains("OVA") || t.contains("Special")) TvType.ONA @@ -39,7 +38,7 @@ class TenshiProvider : MainAPI() { override val supportedTypes: Set get() = setOf(TvType.Anime, TvType.AnimeMovie, TvType.ONA) - private fun loadToken(): Boolean { + /*private fun loadToken(): Boolean { return try { val response = get(mainUrl) cookie = response.cookies @@ -49,7 +48,7 @@ class TenshiProvider : MainAPI() { } catch (e: Exception) { false } - } + }*/ override fun getMainPage(): HomePageResponse { val items = ArrayList() @@ -259,8 +258,7 @@ class TenshiProvider : MainAPI() { null, it.attr("data-content").trim(), ) - } - ?: ArrayList()) + }) val status = when (document.selectFirst("li.status > .value")?.text()?.trim()) { "Ongoing" -> ShowStatus.Ongoing "Completed" -> ShowStatus.Completed @@ -322,7 +320,7 @@ class TenshiProvider : MainAPI() { headers = mapOf("Referer" to data) ).text - val match = Regex("""sources: (\[(?:.|\s)+?type: ['\"]video\/.*?['\"](?:.|\s)+?\])""").find(sourceHTML) + val match = Regex("""sources: (\[(?:.|\s)+?type: ['"]video/.*?['"](?:.|\s)+?])""").find(sourceHTML) if (match != null) { val qualities = mapper.readValue>( match.destructured.component1() diff --git a/app/src/main/java/com/lagradost/cloudstream3/animeproviders/WatchCartoonOnlineProvider.kt b/app/src/main/java/com/lagradost/cloudstream3/animeproviders/WatchCartoonOnlineProvider.kt index ed25a342..54cfd980 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/animeproviders/WatchCartoonOnlineProvider.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/animeproviders/WatchCartoonOnlineProvider.kt @@ -80,16 +80,16 @@ class WatchCartoonOnlineProvider : MainAPI() { data = mapOf("catara" to query, "konuara" to "episodes") ).text document = Jsoup.parse(response) - items = document.select("#catlist-listview2 > ul > li").filter { it?.text() != null && !it?.text().toString().contains("Episode") } + items = document.select("#catlist-listview2 > ul > li").filter { it?.text() != null && !it.text().toString().contains("Episode") } for (item in items) { val titleHeader = item.selectFirst("a") val title = titleHeader.text() val href = fixUrl(titleHeader.attr("href")) - val isDubbed = title.contains("dubbed") - val set: EnumSet = - EnumSet.of(if (isDubbed) DubStatus.Dubbed else DubStatus.Subbed) + //val isDubbed = title.contains("dubbed") + //val set: EnumSet = + // EnumSet.of(if (isDubbed) DubStatus.Dubbed else DubStatus.Subbed) returnValue.add( TvSeriesSearchResponse( title, diff --git a/app/src/main/java/com/lagradost/cloudstream3/extractors/MixDrop.kt b/app/src/main/java/com/lagradost/cloudstream3/extractors/MixDrop.kt index 13452040..57091b7d 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/extractors/MixDrop.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/extractors/MixDrop.kt @@ -16,7 +16,7 @@ class MixDrop : ExtractorApi() { override fun getUrl(url: String, referer: String?): List? { with(get(url)) { - getAndUnpack(this.text)?.let { unpackedText -> + getAndUnpack(this.text).let { unpackedText -> srcRegex.find(unpackedText)?.groupValues?.get(1)?.let { link -> return listOf( ExtractorLink( diff --git a/app/src/main/java/com/lagradost/cloudstream3/extractors/Mp4Upload.kt b/app/src/main/java/com/lagradost/cloudstream3/extractors/Mp4Upload.kt index b9ca4a7c..46f436ac 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/extractors/Mp4Upload.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/extractors/Mp4Upload.kt @@ -12,7 +12,7 @@ class Mp4Upload : ExtractorApi() { override fun getUrl(url: String, referer: String?): List? { with(get(url)) { - getAndUnpack(this.text)?.let { unpackedText -> + getAndUnpack(this.text).let { unpackedText -> srcRegex.find(unpackedText)?.groupValues?.get(1)?.let { link -> return listOf( ExtractorLink( diff --git a/app/src/main/java/com/lagradost/cloudstream3/extractors/MultiQuality.kt b/app/src/main/java/com/lagradost/cloudstream3/extractors/MultiQuality.kt index 0a5d13b2..e8045592 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/extractors/MultiQuality.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/extractors/MultiQuality.kt @@ -29,7 +29,7 @@ class MultiQuality : ExtractorApi() { } } - override fun getUrl(url: String, referer: String?): List? { + override fun getUrl(url: String, referer: String?): List { val extractedLinksList: MutableList = mutableListOf() with(get(url)) { sourceRegex.findAll(this.text).forEach { sourceMatch -> @@ -65,6 +65,5 @@ class MultiQuality : ExtractorApi() { } return extractedLinksList } - return null } } \ No newline at end of file diff --git a/app/src/main/java/com/lagradost/cloudstream3/extractors/SBPlay.kt b/app/src/main/java/com/lagradost/cloudstream3/extractors/SBPlay.kt index f7c3a3a7..e455e6d2 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/extractors/SBPlay.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/extractors/SBPlay.kt @@ -23,7 +23,7 @@ class SBPlay : ExtractorApi() { val response = get(url, referer = referer).text val document = Jsoup.parse(response) - val links = ArrayList(); + val links = ArrayList() val tree = document.select("table > tbody > tr > td > a") for (item in tree) { diff --git a/app/src/main/java/com/lagradost/cloudstream3/extractors/StreamSB.kt b/app/src/main/java/com/lagradost/cloudstream3/extractors/StreamSB.kt index 4be15ae6..12cfdc0b 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/extractors/StreamSB.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/extractors/StreamSB.kt @@ -24,7 +24,7 @@ class StreamSB : ExtractorApi() { val extractedLinksList: MutableList = mutableListOf() val newUrl = url.replace("sbplay.org/embed-", "sbplay.org/play/").removeSuffix(".html") with(get(newUrl, timeout = 10)) { - getAndUnpack(this.text)?.let { + getAndUnpack(this.text).let { sourceRegex.findAll(it).forEach { sourceMatch -> val extractedUrl = sourceMatch.groupValues[1] if (extractedUrl.contains(".m3u8")) { diff --git a/app/src/main/java/com/lagradost/cloudstream3/movieproviders/TrailersToProvider.kt b/app/src/main/java/com/lagradost/cloudstream3/movieproviders/TrailersToProvider.kt index 33b401d5..a15d3053 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/movieproviders/TrailersToProvider.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/movieproviders/TrailersToProvider.kt @@ -293,7 +293,7 @@ class TrailersToProvider : MainAPI() { Pair( subUrl, fixUrl( - document?.selectFirst("content")?.attr("data-url") + document.selectFirst("content")?.attr("data-url") ?: throw ErrorLoadingException("Link not found") ) ) diff --git a/app/src/main/java/com/lagradost/cloudstream3/movieproviders/VfFilmProvider.kt b/app/src/main/java/com/lagradost/cloudstream3/movieproviders/VfFilmProvider.kt index bbb6b4bf..547dfb5f 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/movieproviders/VfFilmProvider.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/movieproviders/VfFilmProvider.kt @@ -77,10 +77,10 @@ class VfFilmProvider : MainAPI() { private fun getDirect(original: String): String { // original data, https://vf-film.org/?trembed=1&trid=55313&trtype=1 for example val response = get(original).text - val url = "iframe .*src=\\\"(.*?)\\\"".toRegex().find(response)?.groupValues?.get(1).toString() // https://vudeo.net/embed-uweno86lzx8f.html for example + val url = "iframe .*src=\"(.*?)\"".toRegex().find(response)?.groupValues?.get(1).toString() // https://vudeo.net/embed-uweno86lzx8f.html for example val vudoResponse = get(url).text val document = Jsoup.parse(vudoResponse) - val vudoUrl = Regex("sources: \\[\\\"(.*?)\\\"\\]").find(document.html())?.groupValues?.get(1).toString() // direct mp4 link, https://m11.vudeo.net/2vp3ukyw2avjdohilpebtzuct42q5jwvpmpsez3xjs6d7fbs65dpuey2rbra/v.mp4 for exemple + val vudoUrl = Regex("sources: \\[\"(.*?)\"]").find(document.html())?.groupValues?.get(1).toString() // direct mp4 link, https://m11.vudeo.net/2vp3ukyw2avjdohilpebtzuct42q5jwvpmpsez3xjs6d7fbs65dpuey2rbra/v.mp4 for exemple return vudoUrl } diff --git a/app/src/main/java/com/lagradost/cloudstream3/movieproviders/VidEmbedProvider.kt b/app/src/main/java/com/lagradost/cloudstream3/movieproviders/VidEmbedProvider.kt index 1034ad40..532e58db 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/movieproviders/VidEmbedProvider.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/movieproviders/VidEmbedProvider.kt @@ -95,7 +95,7 @@ class VidEmbedProvider : MainAPI() { val description = soup.selectFirst(".post-entry")?.text()?.trim() var poster: String? = null - val episodes = soup.select(".listing.items.lists > .video-block").withIndex().map { (index, li) -> + val episodes = soup.select(".listing.items.lists > .video-block").withIndex().map { (_, li) -> val epTitle = if (li.selectFirst(".name") != null) if (li.selectFirst(".name").text().contains("Episode")) "Episode " + li.selectFirst(".name").text().split("Episode")[1].trim() @@ -162,7 +162,7 @@ class VidEmbedProvider : MainAPI() { // This loads the homepage, which is basically a collection of search results with labels. // Optional function, but make sure to enable hasMainPage if you program this. - override fun getMainPage(): HomePageResponse? { + override fun getMainPage(): HomePageResponse { val urls = listOf( mainUrl, "$mainUrl/movies", @@ -262,8 +262,8 @@ class VidEmbedProvider : MainAPI() { // Having a referer is often required. It's a basic security check most providers have. // Try to replicate what your browser does. - val html = get(it.second, headers = mapOf("referer" to iframeLink)).text - sourceRegex.findAll(html).forEach { match -> + val serverHtml = get(it.second, headers = mapOf("referer" to iframeLink)).text + sourceRegex.findAll(serverHtml).forEach { match -> callback.invoke( ExtractorLink( this.name, @@ -279,7 +279,7 @@ class VidEmbedProvider : MainAPI() { ) ) } - trackRegex.findAll(html).forEach { match -> + trackRegex.findAll(serverHtml).forEach { match -> subtitleCallback.invoke( SubtitleFile( match.groupValues.getOrNull(2) ?: "Unknown", diff --git a/app/src/main/java/com/lagradost/cloudstream3/receivers/VideoDownloadRestartReceiver.kt b/app/src/main/java/com/lagradost/cloudstream3/receivers/VideoDownloadRestartReceiver.kt index cd39034d..785ae655 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/receivers/VideoDownloadRestartReceiver.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/receivers/VideoDownloadRestartReceiver.kt @@ -5,7 +5,6 @@ import android.content.Context import android.content.Intent import android.util.Log - class VideoDownloadRestartReceiver : BroadcastReceiver() { override fun onReceive(context: Context?, intent: Intent?) { Log.i("Broadcast Listened", "Service tried to stop") 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 4bb18fdf..f7c82afa 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/ui/ControllerActivity.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/ui/ControllerActivity.kt @@ -28,15 +28,12 @@ import com.lagradost.cloudstream3.sortUrls import com.lagradost.cloudstream3.ui.result.ResultEpisode import com.lagradost.cloudstream3.utils.CastHelper.awaitLinks import com.lagradost.cloudstream3.utils.CastHelper.getMediaInfo -import com.lagradost.cloudstream3.utils.Coroutines.main import com.lagradost.cloudstream3.utils.DataStore.toKotlinObject 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() { +/*class SkipOpController(val view: ImageView) : UIController() { init { view.setImageResource(R.drawable.exo_controls_fastforward) view.setOnClickListener { @@ -47,12 +44,12 @@ class SkipOpController(val view: ImageView) : UIController() { } } } -} +}*/ private fun RemoteMediaClient.getItemIndex(): Int? { return try { - val index = this.mediaQueue?.itemIds?.indexOf(this.currentItem?.itemId ?: 0) - if (index == null || index < 0) null else index + val index = this.mediaQueue.itemIds.indexOf(this.currentItem?.itemId ?: 0) + if (index < 0) null else index } catch (e: Exception) { null } @@ -136,7 +133,7 @@ class SelectSourceController(val view: ImageView, val activity: ControllerActivi subtitleList.setOnItemClickListener { _, _, which, _ -> if (which == 0) { - remoteMediaClient.setActiveMediaTracks(longArrayOf()) // NO SUBS + remoteMediaClient?.setActiveMediaTracks(longArrayOf()) // NO SUBS } else { val font = TextTrackStyle() font.fontFamily = "Google Sans" //TODO FONT SETTINGS @@ -147,10 +144,10 @@ class SelectSourceController(val view: ImageView, val activity: ControllerActivi font.foregroundColor = Color.WHITE font.fontScale = 1.05f - remoteMediaClient.setTextTrackStyle(font) + remoteMediaClient?.setTextTrackStyle(font) - remoteMediaClient.setActiveMediaTracks(longArrayOf(subTracks[which - 1].id)) - .setResultCallback { + remoteMediaClient?.setActiveMediaTracks(longArrayOf(subTracks[which - 1].id)) + ?.setResultCallback { if (!it.status.isSuccess) { Log.e( "CHROMECAST", "Failed with status code:" + @@ -332,7 +329,9 @@ class SelectSourceController(val view: ImageView, val activity: ControllerActivi } override fun onSessionConnected(castSession: CastSession?) { - super.onSessionConnected(castSession) + castSession?.let { + super.onSessionConnected(it) + } remoteMediaClient?.queueSetRepeatMode(REPEAT_MODE_REPEAT_OFF, JSONObject()) } } diff --git a/app/src/main/java/com/lagradost/cloudstream3/ui/download/DownloadChildFragment.kt b/app/src/main/java/com/lagradost/cloudstream3/ui/download/DownloadChildFragment.kt index c2bb4c9a..4900514e 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/ui/download/DownloadChildFragment.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/ui/download/DownloadChildFragment.kt @@ -54,7 +54,7 @@ class DownloadChildFragment : Fragment() { ?: return@mapNotNull null VisualDownloadChildCached(info.fileLength, info.totalBytes, it) } - } + }.sortedBy { it.data.episode + (it.data.season?: 0)*100000 } if (eps.isEmpty()) { activity?.onBackPressed() return@main diff --git a/app/src/main/java/com/lagradost/cloudstream3/ui/download/DownloadFragment.kt b/app/src/main/java/com/lagradost/cloudstream3/ui/download/DownloadFragment.kt index 2f6c9400..21880e14 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/ui/download/DownloadFragment.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/ui/download/DownloadFragment.kt @@ -102,10 +102,7 @@ class DownloadFragment : Fragment() { } else { val folder = getFolderName(DOWNLOAD_EPISODE_CACHE, click.data.id.toString()) val navController = activity?.findNavController(R.id.nav_host_fragment) - navController?.navigate(R.id.navigation_download_child, Bundle().apply { - putString("folder", folder) - putString("name", click.data.name) - }) + navController?.navigate(R.id.navigation_download_child, DownloadChildFragment.newInstance(click.data.name,folder)) } }, { downloadClickEvent -> diff --git a/app/src/main/java/com/lagradost/cloudstream3/ui/download/DownloadHeaderAdapter.kt b/app/src/main/java/com/lagradost/cloudstream3/ui/download/DownloadHeaderAdapter.kt index e2aced71..79603e72 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/ui/download/DownloadHeaderAdapter.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/ui/download/DownloadHeaderAdapter.kt @@ -1,6 +1,5 @@ package com.lagradost.cloudstream3.ui.download -import android.annotation.SuppressLint import android.view.LayoutInflater import android.view.View import android.view.ViewGroup diff --git a/app/src/main/java/com/lagradost/cloudstream3/ui/home/HomeViewModel.kt b/app/src/main/java/com/lagradost/cloudstream3/ui/home/HomeViewModel.kt index b42ed875..06fd6e26 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/ui/home/HomeViewModel.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/ui/home/HomeViewModel.kt @@ -13,7 +13,6 @@ import com.lagradost.cloudstream3.SearchResponse import com.lagradost.cloudstream3.mvvm.Resource import com.lagradost.cloudstream3.ui.APIRepository import com.lagradost.cloudstream3.ui.APIRepository.Companion.noneApi -import com.lagradost.cloudstream3.ui.APIRepository.Companion.noneRepo import com.lagradost.cloudstream3.ui.APIRepository.Companion.randomApi import com.lagradost.cloudstream3.ui.WatchType import com.lagradost.cloudstream3.utils.DOWNLOAD_HEADER_CACHE 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 f15861e5..408e28bf 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 @@ -33,7 +33,6 @@ import android.widget.* import android.widget.Toast.LENGTH_SHORT import androidx.appcompat.app.AlertDialog import androidx.core.content.ContextCompat -import androidx.core.net.toUri import androidx.core.view.isVisible import androidx.fragment.app.Fragment import androidx.lifecycle.ViewModelProvider @@ -47,7 +46,6 @@ 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 @@ -247,8 +245,6 @@ class PlayerFragment : Fragment() { private lateinit var playerData: PlayerData private lateinit var uriData: UriData private var isDownloadedFile = false - private var downloadId = 0 - private var isLoading = true private var isShowing = true private lateinit var exoPlayer: SimpleExoPlayer @@ -748,8 +744,6 @@ class PlayerFragment : Fragment() { } } - private var volumeObserver: SettingsContentObserver? = null - companion object { fun String.toSubtitleMimeType(): String { return when { @@ -764,7 +758,6 @@ class PlayerFragment : Fragment() { return Bundle().apply { //println(data) putString("data", mapper.writeValueAsString(data)) - println("PUT START: " + startPos) if (startPos != null) { putLong(STATE_RESUME_POSITION, startPos) } @@ -1042,88 +1035,89 @@ class PlayerFragment : Fragment() { exoPlayer.play() } }*/ + activity?.let { act -> + if (act.isCastApiAvailable() && !isDownloadedFile) { + try { + CastButtonFactory.setUpMediaRouteButton(act, player_media_route_button) + val castContext = CastContext.getSharedInstance(requireContext()) - if (activity?.isCastApiAvailable() == true && !isDownloadedFile) { - try { - CastButtonFactory.setUpMediaRouteButton(activity, player_media_route_button) - val castContext = CastContext.getSharedInstance(requireContext()) + if (castContext.castState != CastState.NO_DEVICES_AVAILABLE) player_media_route_button.visibility = + VISIBLE + castContext.addCastStateListener { state -> + if (player_media_route_button != null) { + player_media_route_button.isVisible = state != CastState.NO_DEVICES_AVAILABLE - if (castContext.castState != CastState.NO_DEVICES_AVAILABLE) player_media_route_button.visibility = VISIBLE - castContext.addCastStateListener { state -> - if (player_media_route_button != null) { - player_media_route_button.isVisible = state != CastState.NO_DEVICES_AVAILABLE + if (state == CastState.CONNECTED) { + if (!this::exoPlayer.isInitialized) return@addCastStateListener + val links = sortUrls(getUrls() ?: return@addCastStateListener) + val epData = getEpisode() ?: return@addCastStateListener - if (state == CastState.CONNECTED) { - if (!this::exoPlayer.isInitialized) return@addCastStateListener - val links = sortUrls(getUrls() ?: return@addCastStateListener) - val epData = getEpisode() ?: return@addCastStateListener + val index = links.indexOf(getCurrentUrl()) + activity?.getCastSession()?.startCast( + apiName, + currentIsMovie ?: return@addCastStateListener, + currentHeaderName, + currentPoster, + epData.index, + episodes, + links, + context?.getSubs(supportsDownloadedFiles = false) ?: emptyList(), + index, + exoPlayer.currentPosition + ) - val index = links.indexOf(getCurrentUrl()) - activity?.getCastSession()?.startCast( - apiName, - currentIsMovie ?: return@addCastStateListener, - currentHeaderName, - currentPoster, - epData.index, - episodes, - links, - context?.getSubs(supportsDownloadedFiles = false) ?: emptyList(), - index, - exoPlayer.currentPosition - ) - - /* - val customData = - links.map { JSONObject().put("name", it.name) } - val jsonArray = JSONArray() - for (item in customData) { - jsonArray.put(item) - } - - val mediaItems = links.map { - val movieMetadata = MediaMetadata(MediaMetadata.MEDIA_TYPE_MOVIE) - - movieMetadata.putString(MediaMetadata.KEY_SUBTITLE, - epData.name ?: "Episode ${epData.episode}") - - if (currentHeaderName != null) - movieMetadata.putString(MediaMetadata.KEY_TITLE, currentHeaderName) - - val srcPoster = epData.poster ?: currentPoster - if (srcPoster != null) { - movieMetadata.addImage(WebImage(Uri.parse(srcPoster))) + /* + val customData = + links.map { JSONObject().put("name", it.name) } + val jsonArray = JSONArray() + for (item in customData) { + jsonArray.put(item) } - MediaQueueItem.Builder( - MediaInfo.Builder(it.url) - .setStreamType(MediaInfo.STREAM_TYPE_BUFFERED) - .setContentType(MimeTypes.VIDEO_UNKNOWN) + val mediaItems = links.map { + val movieMetadata = MediaMetadata(MediaMetadata.MEDIA_TYPE_MOVIE) - .setCustomData(JSONObject().put("data", jsonArray)) - .setMetadata(movieMetadata) + movieMetadata.putString(MediaMetadata.KEY_SUBTITLE, + epData.name ?: "Episode ${epData.episode}") + + if (currentHeaderName != null) + movieMetadata.putString(MediaMetadata.KEY_TITLE, currentHeaderName) + + val srcPoster = epData.poster ?: currentPoster + if (srcPoster != null) { + movieMetadata.addImage(WebImage(Uri.parse(srcPoster))) + } + + MediaQueueItem.Builder( + MediaInfo.Builder(it.url) + .setStreamType(MediaInfo.STREAM_TYPE_BUFFERED) + .setContentType(MimeTypes.VIDEO_UNKNOWN) + + .setCustomData(JSONObject().put("data", jsonArray)) + .setMetadata(movieMetadata) + .build() + ) .build() - ) - .build() - }.toTypedArray() + }.toTypedArray() - val castPlayer = CastPlayer(castContext) - castPlayer.loadItems( - mediaItems, - if (index > 0) index else 0, - exoPlayer.currentPosition, - MediaStatus.REPEAT_MODE_REPEAT_SINGLE - )*/ - // activity?.popCurrentPage(isInPlayer = true, isInExpandedView = false, isInResults = false) - safeReleasePlayer() - activity?.popCurrentPage() + val castPlayer = CastPlayer(castContext) + castPlayer.loadItems( + mediaItems, + if (index > 0) index else 0, + exoPlayer.currentPosition, + MediaStatus.REPEAT_MODE_REPEAT_SINGLE + )*/ + // activity?.popCurrentPage(isInPlayer = true, isInExpandedView = false, isInResults = false) + safeReleasePlayer() + activity?.popCurrentPage() + } } } + } catch (e: Exception) { + logError(e) } - } catch (e : Exception) { - logError(e) } } - isDownloadedFile = false arguments?.getString("uriData")?.let { uriData = mapper.readValue(it) @@ -1159,7 +1153,7 @@ class PlayerFragment : Fragment() { activity?.let { it.contentResolver?.registerContentObserver( - android.provider.Settings.System.CONTENT_URI, true, SettingsContentObserver( + Settings.System.CONTENT_URI, true, SettingsContentObserver( Handler( Looper.getMainLooper() ), it @@ -1172,13 +1166,13 @@ class PlayerFragment : Fragment() { observeDirectly(viewModel.episodes) { _episodes -> episodes = _episodes - if (isLoading) { - /*if (playerData.episodeIndex > 0 && playerData.episodeIndex < episodes.size) { + /*if (isLoading) { + if (playerData.episodeIndex > 0 && playerData.episodeIndex < episodes.size) { } else { // WHAT THE FUCK DID YOU DO - }*/ - } + } + }*/ } observe(viewModel.apiName) { @@ -1485,7 +1479,7 @@ class PlayerFragment : Fragment() { requireContext().setKey(RESIZE_MODE_KEY, resizeMode) player_view.resizeMode = resizeModes[resizeMode].first activity?.let { act -> - showToast(act, resizeModes[resizeMode].second, Toast.LENGTH_SHORT); + showToast(act, resizeModes[resizeMode].second, LENGTH_SHORT) } //exoPlayer.videoScalingMode = C.VIDEO_SCALING_MODE_SCALE_TO_FIT_WITH_CROPPING } @@ -1508,18 +1502,6 @@ class PlayerFragment : Fragment() { // initPlayer() } - private fun getRendererIndex(trackIndex: Int): Int? { - if (!this::exoPlayer.isInitialized) return null - - for (renderIndex in 0 until exoPlayer.rendererCount) { - if (exoPlayer.getRendererType(renderIndex) == renderIndex) { - return renderIndex - } - } - - return null - } - private fun getCurrentUrl(): ExtractorLink? { val urls = getUrls() ?: return null for (i in urls) { @@ -2067,7 +2049,11 @@ class PlayerFragment : Fragment() { } } 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$errorName ($code)\n$msg", LENGTH_SHORT) + showToast( + activity, + "${getString(R.string.remote_error)}\n$errorName ($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( diff --git a/app/src/main/java/com/lagradost/cloudstream3/ui/result/ResultViewModel.kt b/app/src/main/java/com/lagradost/cloudstream3/ui/result/ResultViewModel.kt index aa312166..6b063b98 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/ui/result/ResultViewModel.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/ui/result/ResultViewModel.kt @@ -280,7 +280,7 @@ class ResultViewModel : ViewModel() { if (dataList != null) { // TODO dub and sub at the same time val episodes = ArrayList() for ((index, i) in dataList.withIndex()) { - val episode = i.episode ?: (index + 1); + val episode = i.episode ?: (index + 1) episodes.add( context.buildResultEpisode( filterName(i.name), 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 651b261e..f5af6b97 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/utils/CastHelper.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/utils/CastHelper.kt @@ -72,7 +72,7 @@ object CastHelper { if (pending == null) return main { val res = withContext(Dispatchers.IO) { pending.await() } - when (res.status?.statusCode) { + when (res.status.statusCode) { CastStatusCodes.FAILED -> { callback.invoke(true) println("FAILED AND LOAD NEXT") diff --git a/app/src/main/java/com/lagradost/cloudstream3/utils/DownloadFileWorkManager.kt b/app/src/main/java/com/lagradost/cloudstream3/utils/DownloadFileWorkManager.kt index 3cfda3da..c685e7e0 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/utils/DownloadFileWorkManager.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/utils/DownloadFileWorkManager.kt @@ -10,7 +10,6 @@ import com.lagradost.cloudstream3.utils.DataStore.getKey import com.lagradost.cloudstream3.utils.DataStore.removeKey import com.lagradost.cloudstream3.utils.VideoDownloadManager.WORK_KEY_INFO import com.lagradost.cloudstream3.utils.VideoDownloadManager.WORK_KEY_PACKAGE -import com.lagradost.cloudstream3.utils.VideoDownloadManager.createNotification import com.lagradost.cloudstream3.utils.VideoDownloadManager.downloadCheck import com.lagradost.cloudstream3.utils.VideoDownloadManager.downloadEpisode import com.lagradost.cloudstream3.utils.VideoDownloadManager.downloadFromResume diff --git a/app/src/main/java/com/lagradost/cloudstream3/utils/JsUnpacker.kt b/app/src/main/java/com/lagradost/cloudstream3/utils/JsUnpacker.kt index e49067fa..276834da 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/utils/JsUnpacker.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/utils/JsUnpacker.kt @@ -1,9 +1,5 @@ package com.lagradost.cloudstream3.utils -import com.lagradost.cloudstream3.mvvm.logError -import java.lang.Exception -import java.lang.StringBuilder -import java.util.HashMap import java.util.regex.Pattern import kotlin.math.pow diff --git a/app/src/main/java/com/lagradost/cloudstream3/utils/M3u8Helper.kt b/app/src/main/java/com/lagradost/cloudstream3/utils/M3u8Helper.kt index 8d9ff2de..108b1a2a 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/utils/M3u8Helper.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/utils/M3u8Helper.kt @@ -85,7 +85,7 @@ class M3u8Helper { for (match in QUALITY_REGEX.findAll(response)) { var (quality, m3u8Link, m3u8Link2) = match.destructured - if (m3u8Link.isNullOrEmpty()) m3u8Link = m3u8Link2 + if (m3u8Link.isEmpty()) m3u8Link = m3u8Link2 if (absoluteExtensionDetermination(m3u8Link) == "m3u8") { if (isNotCompleteUrl(m3u8Link)) { m3u8Link = "$m3u8Parent/$m3u8Link" @@ -138,7 +138,7 @@ class M3u8Helper { if (secondSelection != null) { val m3u8Response = get(secondSelection.streamUrl, headers = headers).text - var encryptionUri: String? = null + var encryptionUri: String? var encryptionIv = byteArrayOf() var encryptionData = byteArrayOf() diff --git a/app/src/main/java/com/lagradost/cloudstream3/utils/SingleSelectionHelper.kt b/app/src/main/java/com/lagradost/cloudstream3/utils/SingleSelectionHelper.kt index f97ec618..5bb0d246 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/utils/SingleSelectionHelper.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/utils/SingleSelectionHelper.kt @@ -2,7 +2,6 @@ package com.lagradost.cloudstream3.utils import android.app.Dialog import android.content.Context -import android.view.View import android.widget.* import androidx.appcompat.app.AlertDialog import androidx.core.view.isVisible @@ -10,9 +9,7 @@ import androidx.core.view.marginLeft import androidx.core.view.marginRight import androidx.core.view.marginTop import com.google.android.material.bottomsheet.BottomSheetDialog -import com.lagradost.cloudstream3.MainActivity.Companion.updateLocale import com.lagradost.cloudstream3.R -import com.lagradost.cloudstream3.utils.SingleSelectionHelper.showDialog object SingleSelectionHelper { fun Context.showDialog( diff --git a/app/src/main/java/com/lagradost/cloudstream3/utils/SubtitleHelper.kt b/app/src/main/java/com/lagradost/cloudstream3/utils/SubtitleHelper.kt index c63761a9..58044d0e 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/utils/SubtitleHelper.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/utils/SubtitleHelper.kt @@ -16,7 +16,7 @@ object SubtitleHelper { val ISO_639_6: String, ) - fun createISO() { + /*fun createISO() { val url = "https://infogalactic.com/info/List_of_ISO_639-1_codes" val response = get(url).text val document = Jsoup.parse(response) @@ -40,7 +40,7 @@ object SubtitleHelper { } text += ")" println("ISO CREATED:\n$text") - } + }*/ /** lang -> ISO_639_1*/ fun fromLanguageToTwoLetters(input: String): String? { diff --git a/app/src/main/java/com/lagradost/cloudstream3/utils/VideoDownloadManager.kt b/app/src/main/java/com/lagradost/cloudstream3/utils/VideoDownloadManager.kt index 29799864..fa5468e6 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/utils/VideoDownloadManager.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/utils/VideoDownloadManager.kt @@ -661,10 +661,9 @@ object VideoDownloadManager { val contentLength = try { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { // fuck android - connection.contentLengthLong ?: 0L + connection.contentLengthLong } else { - connection.getHeaderField("content-length").toLongOrNull() ?: connection.contentLength?.toLong() - ?: 0L + connection.getHeaderField("content-length").toLongOrNull() ?: connection.contentLength.toLong() } } catch (e: Exception) { logError(e) diff --git a/app/src/test/java/com/lagradost/cloudstream3/ExampleUnitTest.kt b/app/src/test/java/com/lagradost/cloudstream3/ExampleUnitTest.kt deleted file mode 100644 index 6b5eb37e..00000000 --- a/app/src/test/java/com/lagradost/cloudstream3/ExampleUnitTest.kt +++ /dev/null @@ -1,17 +0,0 @@ -package com.lagradost.cloudstream3 - -import org.junit.Test - -import org.junit.Assert.* - -/** - * Example local unit test, which will execute on the development machine (host). - * - * See [testing documentation](http://d.android.com/tools/testing). - */ -class ExampleUnitTest { - @Test - fun addition_isCorrect() { - assertEquals(4, 2 + 2) - } -} \ No newline at end of file diff --git a/app/src/test/java/com/lagradost/cloudstream3/ProviderTests.kt b/app/src/test/java/com/lagradost/cloudstream3/ProviderTests.kt index cc6b588b..550a9999 100644 --- a/app/src/test/java/com/lagradost/cloudstream3/ProviderTests.kt +++ b/app/src/test/java/com/lagradost/cloudstream3/ProviderTests.kt @@ -13,6 +13,115 @@ class ProviderTests { return allApis } + private fun loadLinks(api: MainAPI, url: String?): Boolean { + Assert.assertNotNull("Api ${api.name} has invalid url on episode", url) + if (url == null) return true + var linksLoaded = 0 + try { + val success = api.loadLinks(url, false, {}) { link -> + Assert.assertTrue( + "Api ${api.name} returns link with invalid Quality", + Qualities.values().map { it.value }.contains(link.quality) + ) + Assert.assertTrue("Api ${api.name} returns link with invalid url", link.url.length > 4) + linksLoaded++ + } + if (success) { + return linksLoaded > 0 + } + Assert.assertTrue("Api ${api.name} has returns false on .loadLinks", success) + } catch (e: Exception) { + if (e.cause is NotImplementedError) { + Assert.fail("Provider has not implemented .loadLinks") + } + logError(e) + } + return true + } + + private fun test_single_provider(api: MainAPI) { + val searchQueries = listOf("over", "iron", "guy") + var correctResponses = 0 + var searchResult: List? = null + for (query in searchQueries) { + val response = try { + api.search(query) + } catch (e: Exception) { + if (e.cause is NotImplementedError) { + Assert.fail("Provider has not implemented .search") + } + logError(e) + null + } + if (!response.isNullOrEmpty()) { + correctResponses++ + if (searchResult == null) { + searchResult = response + } + } + } + + if (correctResponses == 0 || searchResult == null) { + println("Api ${api.name} did not return any valid search responses") + return + } + + try { + var validResults = false + for (result in searchResult) { + Assert.assertEquals("Invalid apiName on response on ${api.name}", result.apiName, api.name) + val load = api.load(result.url) ?: continue + Assert.assertEquals("Invalid apiName on load on ${api.name}", load.apiName, result.apiName) + Assert.assertTrue( + "Api ${api.name} on load does not contain any of the supportedTypes", + api.supportedTypes.contains(load.type) + ) + when (load) { + is AnimeLoadResponse -> { + val gotNoEpisodes = + load.dubEpisodes.isNullOrEmpty() && load.subEpisodes.isNullOrEmpty() + if (gotNoEpisodes) { + println("Api ${api.name} got no episodes on ${load.url}") + continue + } + + val url = (load.dubEpisodes ?: load.subEpisodes)?.first()?.url + validResults = loadLinks(api, url) + if (!validResults) continue + } + is MovieLoadResponse -> { + val gotNoEpisodes = load.dataUrl.isBlank() + if (gotNoEpisodes) { + println("Api ${api.name} got no movie on ${load.url}") + continue + } + + validResults = loadLinks(api, load.dataUrl) + if (!validResults) continue + } + is TvSeriesLoadResponse -> { + val gotNoEpisodes = load.episodes.isEmpty() + if (gotNoEpisodes) { + println("Api ${api.name} got no episodes on ${load.url}") + continue + } + + validResults = loadLinks(api, load.episodes.first().data) + if (!validResults) continue + } + } + break + } + + Assert.assertTrue("Api ${api.name} did not load on any}", validResults) + } catch (e: Exception) { + if (e.cause is NotImplementedError) { + Assert.fail("Provider has not implemented .load") + } + logError(e) + } + } + @Test fun providers_exist() { Assert.assertTrue(getAllProviders().isNotEmpty()) @@ -23,7 +132,7 @@ class ProviderTests { val isoNames = SubtitleHelper.languages.map { it.ISO_639_1 } Assert.assertFalse("ISO does not contain any languages", isoNames.isNullOrEmpty()) for (api in getAllProviders()) { - Assert.assertTrue("Api does not contain a mainurl", api.mainUrl != "NONE") + Assert.assertTrue("Api does not contain a mainUrl", api.mainUrl != "NONE") Assert.assertTrue("Api does not contain a name", api.name != "NONE") Assert.assertTrue("Api ${api.name} does not contain a valid language code", isoNames.contains(api.lang)) Assert.assertTrue("Api ${api.name} does not contain any supported types", api.supportedTypes.isNotEmpty()) @@ -57,118 +166,13 @@ class ProviderTests { } } - private fun loadLinks(api: MainAPI, url: String?): Boolean { - Assert.assertNotNull("Api ${api.name} has invalid url on episode", url) - if (url == null) return true - var linksLoaded = 0 - try { - val success = api.loadLinks(url, false, {}) { link -> - Assert.assertTrue( - "Api ${api.name} returns link with invalid Quality", - Qualities.values().map { it.value }.contains(link.quality) - ) - Assert.assertTrue("Api ${api.name} returns link with invalid url", link.url.length > 4) - linksLoaded++ - } - if (success) { - return linksLoaded > 0 - } - Assert.assertTrue("Api ${api.name} has returns false on .loadLinks", success) - } catch (e: Exception) { - if (e.cause is NotImplementedError) { - Assert.fail("Provider has not implemented .loadLinks") - } - logError(e) - } - return true - } - @Test fun provider_correct() { - val searchQueries = listOf("over", "iron", "guy") val providers = getAllProviders() for ((index, api) in providers.withIndex()) { try { println("Trying $api (${index + 1}/${providers.size})") - var correctResponses = 0 - var searchResult: List? = null - for (query in searchQueries) { - val response = try { - api.search(query) - } catch (e: Exception) { - if (e.cause is NotImplementedError) { - Assert.fail("Provider has not implemented .search") - } - logError(e) - null - } - if (!response.isNullOrEmpty()) { - correctResponses++ - if (searchResult == null) { - searchResult = response - } - } - } - - if (correctResponses == 0 || searchResult == null) { - println("Api ${api.name} did not return any valid search responses") - continue - } - - try { - var validResults = false - for (result in searchResult) { - Assert.assertEquals("Invalid apiName on response on ${api.name}", result.apiName, api.name) - val load = api.load(result.url) ?: continue - Assert.assertEquals("Invalid apiName on load on ${api.name}", load.apiName, result.apiName) - Assert.assertTrue( - "Api ${api.name} on load does not contain any of the supportedTypes", - api.supportedTypes.contains(load.type) - ) - when (load) { - is AnimeLoadResponse -> { - val gotNoEpisodes = - load.dubEpisodes.isNullOrEmpty() && load.subEpisodes.isNullOrEmpty() - if (gotNoEpisodes) { - println("Api ${api.name} got no episodes on ${load.url}") - continue - } - - val url = (load.dubEpisodes ?: load.subEpisodes)?.first()?.url - validResults = loadLinks(api, url) - if (!validResults) continue - } - is MovieLoadResponse -> { - val gotNoEpisodes = load.dataUrl.isBlank() - if (gotNoEpisodes) { - println("Api ${api.name} got no movie on ${load.url}") - continue - } - - validResults = loadLinks(api, load.dataUrl) - if (!validResults) continue - } - is TvSeriesLoadResponse -> { - val gotNoEpisodes = load.episodes.isEmpty() - if (gotNoEpisodes) { - println("Api ${api.name} got no episodes on ${load.url}") - continue - } - - validResults = loadLinks(api, load.episodes.first().data) - if (!validResults) continue - } - } - break - } - - Assert.assertTrue("Api ${api.name} did not load on any}", validResults) - } catch (e: Exception) { - if (e.cause is NotImplementedError) { - Assert.fail("Provider has not implemented .load") - } - logError(e) - } + test_single_provider(api) } catch (e: Exception) { logError(e) }