forked from recloudstream/cloudstream
fixed some warnings
This commit is contained in:
parent
509a0a6b90
commit
bf18e657f6
29 changed files with 235 additions and 283 deletions
|
@ -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 {
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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<String, String> = mapOf()
|
||||
//var token: String? = null
|
||||
//var cookie: Map<String, String> = 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<TvType>
|
||||
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<HomePageList>()
|
||||
|
@ -259,8 +258,7 @@ class TenshiProvider : MainAPI() {
|
|||
null,
|
||||
it.attr("data-content").trim(),
|
||||
)
|
||||
}
|
||||
?: ArrayList<AnimeEpisode>())
|
||||
})
|
||||
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<List<Quality>>(
|
||||
match.destructured.component1()
|
||||
|
|
|
@ -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<DubStatus> =
|
||||
EnumSet.of(if (isDubbed) DubStatus.Dubbed else DubStatus.Subbed)
|
||||
//val isDubbed = title.contains("dubbed")
|
||||
//val set: EnumSet<DubStatus> =
|
||||
// EnumSet.of(if (isDubbed) DubStatus.Dubbed else DubStatus.Subbed)
|
||||
returnValue.add(
|
||||
TvSeriesSearchResponse(
|
||||
title,
|
||||
|
|
|
@ -16,7 +16,7 @@ class MixDrop : ExtractorApi() {
|
|||
|
||||
override fun getUrl(url: String, referer: String?): List<ExtractorLink>? {
|
||||
with(get(url)) {
|
||||
getAndUnpack(this.text)?.let { unpackedText ->
|
||||
getAndUnpack(this.text).let { unpackedText ->
|
||||
srcRegex.find(unpackedText)?.groupValues?.get(1)?.let { link ->
|
||||
return listOf(
|
||||
ExtractorLink(
|
||||
|
|
|
@ -12,7 +12,7 @@ class Mp4Upload : ExtractorApi() {
|
|||
|
||||
override fun getUrl(url: String, referer: String?): List<ExtractorLink>? {
|
||||
with(get(url)) {
|
||||
getAndUnpack(this.text)?.let { unpackedText ->
|
||||
getAndUnpack(this.text).let { unpackedText ->
|
||||
srcRegex.find(unpackedText)?.groupValues?.get(1)?.let { link ->
|
||||
return listOf(
|
||||
ExtractorLink(
|
||||
|
|
|
@ -29,7 +29,7 @@ class MultiQuality : ExtractorApi() {
|
|||
}
|
||||
}
|
||||
|
||||
override fun getUrl(url: String, referer: String?): List<ExtractorLink>? {
|
||||
override fun getUrl(url: String, referer: String?): List<ExtractorLink> {
|
||||
val extractedLinksList: MutableList<ExtractorLink> = mutableListOf()
|
||||
with(get(url)) {
|
||||
sourceRegex.findAll(this.text).forEach { sourceMatch ->
|
||||
|
@ -65,6 +65,5 @@ class MultiQuality : ExtractorApi() {
|
|||
}
|
||||
return extractedLinksList
|
||||
}
|
||||
return null
|
||||
}
|
||||
}
|
|
@ -23,7 +23,7 @@ class SBPlay : ExtractorApi() {
|
|||
val response = get(url, referer = referer).text
|
||||
val document = Jsoup.parse(response)
|
||||
|
||||
val links = ArrayList<ExtractorLink>();
|
||||
val links = ArrayList<ExtractorLink>()
|
||||
|
||||
val tree = document.select("table > tbody > tr > td > a")
|
||||
for (item in tree) {
|
||||
|
|
|
@ -24,7 +24,7 @@ class StreamSB : ExtractorApi() {
|
|||
val extractedLinksList: MutableList<ExtractorLink> = 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")) {
|
||||
|
|
|
@ -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")
|
||||
)
|
||||
)
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
||||
|
|
|
@ -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",
|
||||
|
|
|
@ -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")
|
||||
|
|
|
@ -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())
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 ->
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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(
|
||||
|
|
|
@ -280,7 +280,7 @@ class ResultViewModel : ViewModel() {
|
|||
if (dataList != null) { // TODO dub and sub at the same time
|
||||
val episodes = ArrayList<ResultEpisode>()
|
||||
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),
|
||||
|
|
|
@ -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")
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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()
|
||||
|
||||
|
|
|
@ -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(
|
||||
|
|
|
@ -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? {
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
}
|
|
@ -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<SearchResponse>? = 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<SearchResponse>? = 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)
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue