mirror of
https://github.com/recloudstream/cloudstream.git
synced 2024-08-15 01:53:11 +00:00
trailers fix + crash fix
This commit is contained in:
parent
abeda3e758
commit
7a6d16d2c1
12 changed files with 91 additions and 33 deletions
|
@ -107,7 +107,7 @@ dependencies {
|
||||||
testImplementation 'org.json:json:20180813'
|
testImplementation 'org.json:json:20180813'
|
||||||
|
|
||||||
implementation 'androidx.core:core-ktx:1.8.0'
|
implementation 'androidx.core:core-ktx:1.8.0'
|
||||||
implementation 'androidx.appcompat:appcompat:1.4.2'
|
implementation 'androidx.appcompat:appcompat:1.4.2' // need target 32 for 1.5.0
|
||||||
|
|
||||||
// dont change this to 1.6.0 it looks ugly af
|
// dont change this to 1.6.0 it looks ugly af
|
||||||
implementation 'com.google.android.material:material:1.5.0'
|
implementation 'com.google.android.material:material:1.5.0'
|
||||||
|
@ -194,7 +194,7 @@ dependencies {
|
||||||
//implementation 'com.github.HaarigerHarald:android-youtubeExtractor:master-SNAPSHOT'
|
//implementation 'com.github.HaarigerHarald:android-youtubeExtractor:master-SNAPSHOT'
|
||||||
|
|
||||||
// newpipe yt
|
// newpipe yt
|
||||||
implementation 'com.github.recloudstream:NewPipeExtractor:master-SNAPSHOT'
|
implementation 'com.github.recloudstream:NewPipeExtractor:0.22.1'
|
||||||
coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs:1.1.5'
|
coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs:1.1.5'
|
||||||
|
|
||||||
// Library/extensions searching with Levenshtein distance
|
// Library/extensions searching with Levenshtein distance
|
||||||
|
|
|
@ -236,8 +236,8 @@ object APIHolder {
|
||||||
val defaultSet = default.map { it.toString() }.toSet()
|
val defaultSet = default.map { it.toString() }.toSet()
|
||||||
val currentPrefMedia = try {
|
val currentPrefMedia = try {
|
||||||
PreferenceManager.getDefaultSharedPreferences(this)
|
PreferenceManager.getDefaultSharedPreferences(this)
|
||||||
.getStringSet(this.getString(R.string.prefer_media_type_key), defaultSet)
|
.getStringSet(this.getString(R.string.prefer_media_type_key), defaultSet)
|
||||||
?.mapNotNull { it.toIntOrNull() ?: return@mapNotNull null }
|
?.mapNotNull { it.toIntOrNull() ?: return@mapNotNull null }
|
||||||
} catch (e: Throwable) {
|
} catch (e: Throwable) {
|
||||||
null
|
null
|
||||||
} ?: default
|
} ?: default
|
||||||
|
@ -891,8 +891,11 @@ data class TvSeriesSearchResponse(
|
||||||
) : SearchResponse
|
) : SearchResponse
|
||||||
|
|
||||||
data class TrailerData(
|
data class TrailerData(
|
||||||
var mirros: List<ExtractorLink>,
|
val extractorUrl: String,
|
||||||
var subtitles: List<SubtitleFile> = emptyList(),
|
val referer: String?,
|
||||||
|
val raw: Boolean,
|
||||||
|
//var mirros: List<ExtractorLink>,
|
||||||
|
//var subtitles: List<SubtitleFile> = emptyList(),
|
||||||
)
|
)
|
||||||
|
|
||||||
interface LoadResponse {
|
interface LoadResponse {
|
||||||
|
@ -971,7 +974,8 @@ interface LoadResponse {
|
||||||
addRaw: Boolean = false
|
addRaw: Boolean = false
|
||||||
) {
|
) {
|
||||||
if (!isTrailersEnabled || trailerUrl.isNullOrBlank()) return
|
if (!isTrailersEnabled || trailerUrl.isNullOrBlank()) return
|
||||||
val links = arrayListOf<ExtractorLink>()
|
this.trailers.add(TrailerData(trailerUrl, referer, addRaw))
|
||||||
|
/*val links = arrayListOf<ExtractorLink>()
|
||||||
val subs = arrayListOf<SubtitleFile>()
|
val subs = arrayListOf<SubtitleFile>()
|
||||||
if (!loadExtractor(
|
if (!loadExtractor(
|
||||||
trailerUrl,
|
trailerUrl,
|
||||||
|
@ -995,12 +999,13 @@ interface LoadResponse {
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
this.trailers.add(TrailerData(links, subs))
|
this.trailers.add(TrailerData(links, subs))
|
||||||
}
|
}*/
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
fun LoadResponse.addTrailer(newTrailers: List<ExtractorLink>) {
|
fun LoadResponse.addTrailer(newTrailers: List<ExtractorLink>) {
|
||||||
trailers.addAll(newTrailers.map { TrailerData(listOf(it)) })
|
trailers.addAll(newTrailers.map { TrailerData(listOf(it)) })
|
||||||
}
|
}*/
|
||||||
|
|
||||||
suspend fun LoadResponse.addTrailer(
|
suspend fun LoadResponse.addTrailer(
|
||||||
trailerUrls: List<String>?,
|
trailerUrls: List<String>?,
|
||||||
|
@ -1008,7 +1013,8 @@ interface LoadResponse {
|
||||||
addRaw: Boolean = false
|
addRaw: Boolean = false
|
||||||
) {
|
) {
|
||||||
if (!isTrailersEnabled || trailerUrls == null) return
|
if (!isTrailersEnabled || trailerUrls == null) return
|
||||||
val trailers = trailerUrls.filter { it.isNotBlank() }.apmap { trailerUrl ->
|
trailers.addAll(trailerUrls.map { TrailerData(it, referer, addRaw) })
|
||||||
|
/*val trailers = trailerUrls.filter { it.isNotBlank() }.apmap { trailerUrl ->
|
||||||
val links = arrayListOf<ExtractorLink>()
|
val links = arrayListOf<ExtractorLink>()
|
||||||
val subs = arrayListOf<SubtitleFile>()
|
val subs = arrayListOf<SubtitleFile>()
|
||||||
if (!loadExtractor(
|
if (!loadExtractor(
|
||||||
|
@ -1031,7 +1037,7 @@ interface LoadResponse {
|
||||||
links to subs
|
links to subs
|
||||||
}
|
}
|
||||||
}.map { (links, subs) -> TrailerData(links, subs) }
|
}.map { (links, subs) -> TrailerData(links, subs) }
|
||||||
this.trailers.addAll(trailers)
|
this.trailers.addAll(trailers)*/
|
||||||
}
|
}
|
||||||
|
|
||||||
fun LoadResponse.addImdbId(id: String?) {
|
fun LoadResponse.addImdbId(id: String?) {
|
||||||
|
|
|
@ -127,8 +127,8 @@ fun CoroutineScope.launchSafe(
|
||||||
val obj: suspend CoroutineScope.() -> Unit = {
|
val obj: suspend CoroutineScope.() -> Unit = {
|
||||||
try {
|
try {
|
||||||
block()
|
block()
|
||||||
} catch (e: Exception) {
|
} catch (throwable: Throwable) {
|
||||||
logError(e)
|
logError(throwable)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -84,8 +84,8 @@ object RepositoryManager {
|
||||||
// Normal parsed function not working?
|
// Normal parsed function not working?
|
||||||
// return response.parsedSafe()
|
// return response.parsedSafe()
|
||||||
tryParseJson<Array<SitePlugin>>(response.text)?.toList() ?: emptyList()
|
tryParseJson<Array<SitePlugin>>(response.text)?.toList() ?: emptyList()
|
||||||
} catch (e : Exception) {
|
} catch (t : Throwable) {
|
||||||
logError(e)
|
logError(t)
|
||||||
emptyList()
|
emptyList()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -279,8 +279,8 @@ class SelectSourceController(val view: ImageView, val activity: ControllerActivi
|
||||||
val currentPosition = remoteMediaClient?.approximateStreamPosition
|
val currentPosition = remoteMediaClient?.approximateStreamPosition
|
||||||
if (currentDuration != null && currentPosition != null)
|
if (currentDuration != null && currentPosition != null)
|
||||||
DataStoreHelper.setViewPos(epData.id, currentPosition, currentDuration)
|
DataStoreHelper.setViewPos(epData.id, currentPosition, currentDuration)
|
||||||
} catch (e : Exception) {
|
} catch (t : Throwable) {
|
||||||
logError(e)
|
logError(t)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (itemCount != null && itemCount - currentIdIndex == 1 && !isLoadingMore) {
|
if (itemCount != null && itemCount - currentIdIndex == 1 && !isLoadingMore) {
|
||||||
|
|
|
@ -148,10 +148,10 @@ class DownloadHeaderAdapter(
|
||||||
),
|
),
|
||||||
mbString
|
mbString
|
||||||
)
|
)
|
||||||
} catch (e : Exception) {
|
} catch (t : Throwable) {
|
||||||
// you probably formatted incorrectly
|
// you probably formatted incorrectly
|
||||||
extraInfo.text = "Error"
|
extraInfo.text = "Error"
|
||||||
logError(e)
|
logError(t)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -112,9 +112,9 @@ class DownloadViewModel : ViewModel() {
|
||||||
_usedBytes.postValue(localTotalBytes - localBytesAvailable - localDownloadedBytes)
|
_usedBytes.postValue(localTotalBytes - localBytesAvailable - localDownloadedBytes)
|
||||||
_availableBytes.postValue(localBytesAvailable)
|
_availableBytes.postValue(localBytesAvailable)
|
||||||
_downloadBytes.postValue(localDownloadedBytes)
|
_downloadBytes.postValue(localDownloadedBytes)
|
||||||
} catch (e : Exception) {
|
} catch (t : Throwable) {
|
||||||
_downloadBytes.postValue(0)
|
_downloadBytes.postValue(0)
|
||||||
logError(e)
|
logError(t)
|
||||||
}
|
}
|
||||||
|
|
||||||
_headerCards.postValue(visual)
|
_headerCards.postValue(visual)
|
||||||
|
|
|
@ -304,6 +304,11 @@ fun SelectPopup.getOptions(context: Context): List<String> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
data class ExtractedTrailerData(
|
||||||
|
var mirros: List<ExtractorLink>,
|
||||||
|
var subtitles: List<SubtitleFile> = emptyList(),
|
||||||
|
)
|
||||||
|
|
||||||
class ResultViewModel2 : ViewModel() {
|
class ResultViewModel2 : ViewModel() {
|
||||||
private var currentResponse: LoadResponse? = null
|
private var currentResponse: LoadResponse? = null
|
||||||
|
|
||||||
|
@ -349,9 +354,9 @@ class ResultViewModel2 : ViewModel() {
|
||||||
MutableLiveData(Some.None)
|
MutableLiveData(Some.None)
|
||||||
val episodesCountText: LiveData<Some<UiText>> = _episodesCountText
|
val episodesCountText: LiveData<Some<UiText>> = _episodesCountText
|
||||||
|
|
||||||
private val _trailers: MutableLiveData<List<TrailerData>> = MutableLiveData(mutableListOf())
|
private val _trailers: MutableLiveData<List<ExtractedTrailerData>> =
|
||||||
val trailers: LiveData<List<TrailerData>> = _trailers
|
MutableLiveData(mutableListOf())
|
||||||
|
val trailers: LiveData<List<ExtractedTrailerData>> = _trailers
|
||||||
|
|
||||||
private val _dubSubSelections: MutableLiveData<List<Pair<UiText?, DubStatus>>> =
|
private val _dubSubSelections: MutableLiveData<List<Pair<UiText?, DubStatus>>> =
|
||||||
MutableLiveData(emptyList())
|
MutableLiveData(emptyList())
|
||||||
|
@ -1784,12 +1789,58 @@ class ResultViewModel2 : ViewModel() {
|
||||||
return ResumeWatchingStatus(progress = progress, isMovie = isMovie, result = episode)
|
return ResumeWatchingStatus(progress = progress, isMovie = isMovie, result = episode)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun loadTrailers(loadResponse: LoadResponse) = ioSafe {
|
||||||
|
_trailers.postValue(getTrailers(loadResponse, 3)) // we dont want to fetch too many trailers
|
||||||
|
}
|
||||||
|
|
||||||
|
private suspend fun getTrailers(
|
||||||
|
loadResponse: LoadResponse,
|
||||||
|
limit: Int = 0
|
||||||
|
): List<ExtractedTrailerData> =
|
||||||
|
coroutineScope {
|
||||||
|
var currentCount = 0
|
||||||
|
return@coroutineScope loadResponse.trailers.apmap { trailerData ->
|
||||||
|
try {
|
||||||
|
val links = arrayListOf<ExtractorLink>()
|
||||||
|
val subs = arrayListOf<SubtitleFile>()
|
||||||
|
if (!loadExtractor(
|
||||||
|
trailerData.extractorUrl,
|
||||||
|
trailerData.referer,
|
||||||
|
{ subs.add(it) },
|
||||||
|
{ links.add(it) }) && trailerData.raw
|
||||||
|
) {
|
||||||
|
arrayListOf(
|
||||||
|
ExtractorLink(
|
||||||
|
"",
|
||||||
|
"Trailer",
|
||||||
|
trailerData.extractorUrl,
|
||||||
|
trailerData.referer ?: "",
|
||||||
|
Qualities.Unknown.value,
|
||||||
|
trailerData.extractorUrl.contains(".m3u8")
|
||||||
|
)
|
||||||
|
) to arrayListOf()
|
||||||
|
} else {
|
||||||
|
links to subs
|
||||||
|
}.also { (extractor, _) ->
|
||||||
|
if (extractor.isNotEmpty() && limit != 0) {
|
||||||
|
currentCount++
|
||||||
|
if (currentCount >= limit) {
|
||||||
|
cancel()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (e: Throwable) {
|
||||||
|
logError(e)
|
||||||
|
null
|
||||||
|
}
|
||||||
|
}.filterNotNull().map { (links, subs) -> ExtractedTrailerData(links, subs) }
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// this instantly updates the metadata on the page
|
// this instantly updates the metadata on the page
|
||||||
private fun postPage(loadResponse: LoadResponse, apiRepository: APIRepository) {
|
private fun postPage(loadResponse: LoadResponse, apiRepository: APIRepository) {
|
||||||
_recommendations.postValue(loadResponse.recommendations ?: emptyList())
|
_recommendations.postValue(loadResponse.recommendations ?: emptyList())
|
||||||
_page.postValue(Resource.Success(loadResponse.toResultData(apiRepository)))
|
_page.postValue(Resource.Success(loadResponse.toResultData(apiRepository)))
|
||||||
_trailers.postValue(loadResponse.trailers)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fun hasLoaded() = currentResponse != null
|
fun hasLoaded() = currentResponse != null
|
||||||
|
@ -1914,6 +1965,7 @@ class ResultViewModel2 : ViewModel() {
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
loadTrailers(data.value)
|
||||||
postSuccessful(
|
postSuccessful(
|
||||||
data.value,
|
data.value,
|
||||||
updateEpisodes = true,
|
updateEpisodes = true,
|
||||||
|
|
|
@ -246,8 +246,8 @@ class SyncViewModel : ViewModel() {
|
||||||
if (syncs.containsKey(aniListApi.idPrefix)) {
|
if (syncs.containsKey(aniListApi.idPrefix)) {
|
||||||
try { // swap can throw error
|
try { // swap can throw error
|
||||||
Collections.swap(current, current.indexOfFirst { it.first == aniListApi.idPrefix }, 0)
|
Collections.swap(current, current.indexOfFirst { it.first == aniListApi.idPrefix }, 0)
|
||||||
} catch (e : Exception) {
|
} catch (t : Throwable) {
|
||||||
logError(e)
|
logError(t)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -136,8 +136,8 @@ object UIHelper {
|
||||||
navigation, arguments
|
navigation, arguments
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
} catch (e : Exception) {
|
} catch (t : Throwable) {
|
||||||
logError(e)
|
logError(t)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1612,8 +1612,8 @@ object VideoDownloadManager {
|
||||||
.mapIndexed { index, any -> DownloadQueueResumePackage(index, any) }
|
.mapIndexed { index, any -> DownloadQueueResumePackage(index, any) }
|
||||||
.toTypedArray()
|
.toTypedArray()
|
||||||
setKey(KEY_RESUME_QUEUE_PACKAGES, dQueue)
|
setKey(KEY_RESUME_QUEUE_PACKAGES, dQueue)
|
||||||
} catch (e : Exception) {
|
} catch (t : Throwable) {
|
||||||
logError(e)
|
logError(t)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -53,8 +53,8 @@ class CenterZoomLayoutManager : LinearLayoutManager {
|
||||||
largestTag = tag
|
largestTag = tag
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (e : Exception) {
|
} catch (t : Throwable) {
|
||||||
logError(e)
|
logError(t)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue