mirror of
https://github.com/recloudstream/cloudstream.git
synced 2024-08-15 01:53:11 +00:00
Added sflix downloads, fixed some sflix sources and added image caching (#128)
Waited long enough and it seems to work fine, I will just revert if this fucks up :)
This commit is contained in:
parent
96b5c9658d
commit
596f659a29
14 changed files with 112 additions and 56 deletions
4
.github/workflows/prerelease.yml
vendored
4
.github/workflows/prerelease.yml
vendored
|
@ -15,10 +15,10 @@ jobs:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v2
|
- uses: actions/checkout@v2
|
||||||
- name: Set up JDK 8
|
- name: Set up JDK 11
|
||||||
uses: actions/setup-java@v2
|
uses: actions/setup-java@v2
|
||||||
with:
|
with:
|
||||||
java-version: '8'
|
java-version: '11'
|
||||||
distribution: 'adopt'
|
distribution: 'adopt'
|
||||||
- name: Grant execute permission for gradlew
|
- name: Grant execute permission for gradlew
|
||||||
run: chmod +x gradlew
|
run: chmod +x gradlew
|
||||||
|
|
4
.github/workflows/pull_request.yml
vendored
4
.github/workflows/pull_request.yml
vendored
|
@ -7,10 +7,10 @@ jobs:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v2
|
- uses: actions/checkout@v2
|
||||||
- name: Set up JDK 8
|
- name: Set up JDK 11
|
||||||
uses: actions/setup-java@v2
|
uses: actions/setup-java@v2
|
||||||
with:
|
with:
|
||||||
java-version: '8'
|
java-version: '11'
|
||||||
distribution: 'adopt'
|
distribution: 'adopt'
|
||||||
- name: Grant execute permission for gradlew
|
- name: Grant execute permission for gradlew
|
||||||
run: chmod +x gradlew
|
run: chmod +x gradlew
|
||||||
|
|
|
@ -3,4 +3,4 @@
|
||||||
<component name="CompilerConfiguration">
|
<component name="CompilerConfiguration">
|
||||||
<bytecodeTargetLevel target="11" />
|
<bytecodeTargetLevel target="11" />
|
||||||
</component>
|
</component>
|
||||||
</project>
|
</project>
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
<component name="GradleSettings">
|
<component name="GradleSettings">
|
||||||
<option name="linkedExternalProjectsSettings">
|
<option name="linkedExternalProjectsSettings">
|
||||||
<GradleProjectSettings>
|
<GradleProjectSettings>
|
||||||
|
<option name="delegatedBuild" value="true" />
|
||||||
<option name="testRunner" value="GRADLE" />
|
<option name="testRunner" value="GRADLE" />
|
||||||
<option name="distributionType" value="DEFAULT_WRAPPED" />
|
<option name="distributionType" value="DEFAULT_WRAPPED" />
|
||||||
<option name="externalProjectPath" value="$PROJECT_DIR$" />
|
<option name="externalProjectPath" value="$PROJECT_DIR$" />
|
||||||
|
@ -18,4 +19,4 @@
|
||||||
</GradleProjectSettings>
|
</GradleProjectSettings>
|
||||||
</option>
|
</option>
|
||||||
</component>
|
</component>
|
||||||
</project>
|
</project>
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<project version="4">
|
<project version="4">
|
||||||
<component name="ExternalStorageConfigurationManager" enabled="true" />
|
<component name="ExternalStorageConfigurationManager" enabled="true" />
|
||||||
<component name="ProjectRootManager" version="2" languageLevel="JDK_11" default="true" project-jdk-name="11" project-jdk-type="JavaSDK" />
|
<component name="ProjectRootManager" version="2" languageLevel="JDK_11" project-jdk-name="11" project-jdk-type="JavaSDK" />
|
||||||
</project>
|
</project>
|
|
@ -35,7 +35,7 @@ android {
|
||||||
minSdkVersion 21
|
minSdkVersion 21
|
||||||
targetSdkVersion 31
|
targetSdkVersion 31
|
||||||
versionCode 27
|
versionCode 27
|
||||||
versionName "1.9.11"
|
versionName "1.9.12"
|
||||||
|
|
||||||
resValue "string", "app_version",
|
resValue "string", "app_version",
|
||||||
"${defaultConfig.versionName}${versionNameSuffix ?: ""}"
|
"${defaultConfig.versionName}${versionNameSuffix ?: ""}"
|
||||||
|
@ -105,6 +105,8 @@ dependencies {
|
||||||
implementation "androidx.preference:preference-ktx:1.1.1"
|
implementation "androidx.preference:preference-ktx:1.1.1"
|
||||||
|
|
||||||
implementation 'com.github.bumptech.glide:glide:4.12.0'
|
implementation 'com.github.bumptech.glide:glide:4.12.0'
|
||||||
|
kapt 'com.github.bumptech.glide:compiler:4.12.0'
|
||||||
|
|
||||||
implementation 'jp.wasabeef:glide-transformations:4.0.0'
|
implementation 'jp.wasabeef:glide-transformations:4.0.0'
|
||||||
|
|
||||||
implementation 'androidx.swiperefreshlayout:swiperefreshlayout:1.1.0'
|
implementation 'androidx.swiperefreshlayout:swiperefreshlayout:1.1.0'
|
||||||
|
|
|
@ -3,10 +3,7 @@ package com.lagradost.cloudstream3.extractors
|
||||||
import com.lagradost.cloudstream3.network.get
|
import com.lagradost.cloudstream3.network.get
|
||||||
import com.lagradost.cloudstream3.network.text
|
import com.lagradost.cloudstream3.network.text
|
||||||
import com.lagradost.cloudstream3.network.url
|
import com.lagradost.cloudstream3.network.url
|
||||||
import com.lagradost.cloudstream3.utils.ExtractorApi
|
import com.lagradost.cloudstream3.utils.*
|
||||||
import com.lagradost.cloudstream3.utils.ExtractorLink
|
|
||||||
import com.lagradost.cloudstream3.utils.Qualities
|
|
||||||
import com.lagradost.cloudstream3.utils.getQualityFromName
|
|
||||||
import java.net.URI
|
import java.net.URI
|
||||||
|
|
||||||
class AsianLoad : ExtractorApi() {
|
class AsianLoad : ExtractorApi() {
|
||||||
|
@ -17,8 +14,6 @@ class AsianLoad : ExtractorApi() {
|
||||||
override val requiresReferer: Boolean
|
override val requiresReferer: Boolean
|
||||||
get() = true
|
get() = true
|
||||||
|
|
||||||
private val urlRegex = Regex("""(.*?)([^/]+$)""")
|
|
||||||
private val m3u8UrlRegex = Regex("""RESOLUTION=\d*x(\d*).*\n(.*\.m3u8)""")
|
|
||||||
private val sourceRegex = Regex("""sources:[\W\w]*?file:\s*?["'](.*?)["']""")
|
private val sourceRegex = Regex("""sources:[\W\w]*?file:\s*?["'](.*?)["']""")
|
||||||
override fun getUrl(url: String, referer: String?): List<ExtractorLink> {
|
override fun getUrl(url: String, referer: String?): List<ExtractorLink> {
|
||||||
val extractedLinksList: MutableList<ExtractorLink> = mutableListOf()
|
val extractedLinksList: MutableList<ExtractorLink> = mutableListOf()
|
||||||
|
@ -27,21 +22,25 @@ class AsianLoad : ExtractorApi() {
|
||||||
val extractedUrl = sourceMatch.groupValues[1]
|
val extractedUrl = sourceMatch.groupValues[1]
|
||||||
// Trusting this isn't mp4, may fuck up stuff
|
// Trusting this isn't mp4, may fuck up stuff
|
||||||
if (URI(extractedUrl).path.endsWith(".m3u8")) {
|
if (URI(extractedUrl).path.endsWith(".m3u8")) {
|
||||||
with(get(extractedUrl, referer = this.url)) {
|
M3u8Helper().m3u8Generation(
|
||||||
m3u8UrlRegex.findAll(this.text).forEach { match ->
|
M3u8Helper.M3u8Stream(
|
||||||
|
extractedUrl,
|
||||||
|
headers = mapOf("referer" to this.url)
|
||||||
|
), true
|
||||||
|
)
|
||||||
|
.forEach { stream ->
|
||||||
|
val qualityString = if ((stream.quality ?: 0) == 0) "" else "${stream.quality}p"
|
||||||
extractedLinksList.add(
|
extractedLinksList.add(
|
||||||
ExtractorLink(
|
ExtractorLink(
|
||||||
name,
|
name,
|
||||||
"$name ${match.groupValues[1]}p",
|
"$name $qualityString",
|
||||||
urlRegex.find(this.url)!!.groupValues[1] + match.groupValues[2],
|
stream.streamUrl,
|
||||||
url,
|
url,
|
||||||
getQualityFromName(match.groupValues[1]),
|
getQualityFromName(stream.quality.toString()),
|
||||||
isM3u8 = true
|
true
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
|
||||||
} else if (extractedUrl.endsWith(".mp4")) {
|
} else if (extractedUrl.endsWith(".mp4")) {
|
||||||
extractedLinksList.add(
|
extractedLinksList.add(
|
||||||
ExtractorLink(
|
ExtractorLink(
|
||||||
|
|
|
@ -45,11 +45,12 @@ class WcoStream : ExtractorApi() {
|
||||||
if (mapped.success) {
|
if (mapped.success) {
|
||||||
mapped.media.sources.forEach {
|
mapped.media.sources.forEach {
|
||||||
if (it.file.contains("m3u8")) {
|
if (it.file.contains("m3u8")) {
|
||||||
hlsHelper.m3u8Generation(M3u8Helper.M3u8Stream(it.file, null)).forEach { stream ->
|
hlsHelper.m3u8Generation(M3u8Helper.M3u8Stream(it.file, null), true).forEach { stream ->
|
||||||
|
val qualityString = if ((stream.quality ?: 0) == 0) "" else "${stream.quality}p"
|
||||||
sources.add(
|
sources.add(
|
||||||
ExtractorLink(
|
ExtractorLink(
|
||||||
name,
|
name,
|
||||||
name + if (stream.quality != null) " - ${stream.quality}" else "",
|
"$name $qualityString",
|
||||||
stream.streamUrl,
|
stream.streamUrl,
|
||||||
"",
|
"",
|
||||||
getQualityFromName(stream.quality.toString()),
|
getQualityFromName(stream.quality.toString()),
|
||||||
|
|
|
@ -8,6 +8,7 @@ import com.lagradost.cloudstream3.network.WebViewResolver
|
||||||
import com.lagradost.cloudstream3.network.get
|
import com.lagradost.cloudstream3.network.get
|
||||||
import com.lagradost.cloudstream3.network.text
|
import com.lagradost.cloudstream3.network.text
|
||||||
import com.lagradost.cloudstream3.utils.ExtractorLink
|
import com.lagradost.cloudstream3.utils.ExtractorLink
|
||||||
|
import com.lagradost.cloudstream3.utils.M3u8Helper
|
||||||
import com.lagradost.cloudstream3.utils.getQualityFromName
|
import com.lagradost.cloudstream3.utils.getQualityFromName
|
||||||
import org.jsoup.Jsoup
|
import org.jsoup.Jsoup
|
||||||
import org.jsoup.nodes.Element
|
import org.jsoup.nodes.Element
|
||||||
|
@ -29,7 +30,7 @@ class SflixProvider : MainAPI() {
|
||||||
get() = true
|
get() = true
|
||||||
|
|
||||||
override val hasDownloadSupport: Boolean
|
override val hasDownloadSupport: Boolean
|
||||||
get() = false
|
get() = true
|
||||||
|
|
||||||
override val supportedTypes: Set<TvType>
|
override val supportedTypes: Set<TvType>
|
||||||
get() = setOf(
|
get() = setOf(
|
||||||
|
@ -257,21 +258,39 @@ class SflixProvider : MainAPI() {
|
||||||
)
|
)
|
||||||
|
|
||||||
data class SourceObject(
|
data class SourceObject(
|
||||||
|
@JsonProperty("sources") val sources: List<Sources1?>?,
|
||||||
@JsonProperty("sources_1") val sources1: List<Sources1?>?,
|
@JsonProperty("sources_1") val sources1: List<Sources1?>?,
|
||||||
@JsonProperty("sources_2") val sources2: List<Sources1?>?,
|
@JsonProperty("sources_2") val sources2: List<Sources1?>?,
|
||||||
|
@JsonProperty("sourcesBackup") val sourcesBackup: List<Sources1?>?,
|
||||||
@JsonProperty("tracks") val tracks: List<Tracks?>?
|
@JsonProperty("tracks") val tracks: List<Tracks?>?
|
||||||
)
|
)
|
||||||
|
|
||||||
private fun Sources1.toExtractorLink(): ExtractorLink? {
|
private fun Sources1.toExtractorLink(name: String): List<ExtractorLink>? {
|
||||||
return this.file?.let {
|
return this.file?.let {
|
||||||
ExtractorLink(
|
val isM3u8 = URI(this.file).path.endsWith(".m3u8") || this.type.equals("hls", ignoreCase = true)
|
||||||
this@SflixProvider.name,
|
if (isM3u8) {
|
||||||
this.label?.let { "${this@SflixProvider.name} - $it" } ?: this@SflixProvider.name,
|
M3u8Helper().m3u8Generation(M3u8Helper.M3u8Stream(this.file, null), true).map { stream ->
|
||||||
it,
|
val qualityString = if ((stream.quality ?: 0) == 0) label ?: "" else "${stream.quality}p"
|
||||||
this@SflixProvider.mainUrl,
|
ExtractorLink(
|
||||||
getQualityFromName(this.label ?: ""),
|
this@SflixProvider.name,
|
||||||
URI(this.file).path.endsWith(".m3u8") || this.label.equals("hls", ignoreCase = true),
|
"${this@SflixProvider.name} $qualityString $name",
|
||||||
)
|
stream.streamUrl,
|
||||||
|
mainUrl,
|
||||||
|
getQualityFromName(stream.quality.toString()),
|
||||||
|
true
|
||||||
|
)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
listOf(ExtractorLink(
|
||||||
|
this@SflixProvider.name,
|
||||||
|
this.label?.let { "${this@SflixProvider.name} - $it" } ?: this@SflixProvider.name,
|
||||||
|
it,
|
||||||
|
this@SflixProvider.mainUrl,
|
||||||
|
getQualityFromName(this.type ?: ""),
|
||||||
|
false,
|
||||||
|
))
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -319,18 +338,15 @@ class SflixProvider : MainAPI() {
|
||||||
|
|
||||||
val mapped = mapper.readValue<SourceObject>(sources)
|
val mapped = mapper.readValue<SourceObject>(sources)
|
||||||
|
|
||||||
mapped.sources1?.forEach {
|
val list = listOf(
|
||||||
it?.toExtractorLink()?.let { extractorLink ->
|
mapped.sources1 to "source 1",
|
||||||
callback.invoke(
|
mapped.sources2 to "source 2",
|
||||||
extractorLink
|
mapped.sources to "source 0",
|
||||||
)
|
mapped.sourcesBackup to "source 3"
|
||||||
}
|
)
|
||||||
}
|
list.forEach { subList ->
|
||||||
mapped.sources2?.forEach {
|
subList.first?.forEach {
|
||||||
it?.toExtractorLink()?.let { extractorLink ->
|
it?.toExtractorLink(subList.second)?.forEach(callback)
|
||||||
callback.invoke(
|
|
||||||
extractorLink
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
mapped.tracks?.forEach {
|
mapped.tracks?.forEach {
|
||||||
|
|
|
@ -1,10 +1,8 @@
|
||||||
package com.lagradost.cloudstream3.network
|
package com.lagradost.cloudstream3.network
|
||||||
|
|
||||||
import android.annotation.SuppressLint
|
import android.annotation.SuppressLint
|
||||||
import android.webkit.WebResourceRequest
|
import android.net.http.SslError
|
||||||
import android.webkit.WebResourceResponse
|
import android.webkit.*
|
||||||
import android.webkit.WebView
|
|
||||||
import android.webkit.WebViewClient
|
|
||||||
import com.lagradost.cloudstream3.AcraApplication
|
import com.lagradost.cloudstream3.AcraApplication
|
||||||
import com.lagradost.cloudstream3.utils.Coroutines.main
|
import com.lagradost.cloudstream3.utils.Coroutines.main
|
||||||
import kotlinx.coroutines.delay
|
import kotlinx.coroutines.delay
|
||||||
|
@ -26,6 +24,7 @@ class WebViewResolver(val interceptUrl: Regex) : Interceptor {
|
||||||
@SuppressLint("SetJavaScriptEnabled")
|
@SuppressLint("SetJavaScriptEnabled")
|
||||||
suspend fun resolveUsingWebView(request: Request): Request? {
|
suspend fun resolveUsingWebView(request: Request): Request? {
|
||||||
val url = request.url.toString()
|
val url = request.url.toString()
|
||||||
|
println("Initial web-view request: $url")
|
||||||
var webView: WebView? = null
|
var webView: WebView? = null
|
||||||
|
|
||||||
fun destroyWebView() {
|
fun destroyWebView() {
|
||||||
|
@ -43,6 +42,7 @@ class WebViewResolver(val interceptUrl: Regex) : Interceptor {
|
||||||
webView = WebView(
|
webView = WebView(
|
||||||
AcraApplication.context ?: throw RuntimeException("No base context in WebViewResolver")
|
AcraApplication.context ?: throw RuntimeException("No base context in WebViewResolver")
|
||||||
).apply {
|
).apply {
|
||||||
|
settings.cacheMode
|
||||||
settings.javaScriptEnabled = true
|
settings.javaScriptEnabled = true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -62,10 +62,15 @@ class WebViewResolver(val interceptUrl: Regex) : Interceptor {
|
||||||
10,
|
10,
|
||||||
TimeUnit.MINUTES
|
TimeUnit.MINUTES
|
||||||
)
|
)
|
||||||
|
println("Web-view request finished: $webViewUrl")
|
||||||
destroyWebView()
|
destroyWebView()
|
||||||
}
|
}
|
||||||
return super.shouldInterceptRequest(view, request)
|
return super.shouldInterceptRequest(view, request)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun onReceivedSslError(view: WebView?, handler: SslErrorHandler?, error: SslError?) {
|
||||||
|
handler?.proceed() // Ignore ssl issues
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
webView?.loadUrl(url)
|
webView?.loadUrl(url)
|
||||||
|
@ -83,6 +88,7 @@ class WebViewResolver(val interceptUrl: Regex) : Interceptor {
|
||||||
loop += 1
|
loop += 1
|
||||||
}
|
}
|
||||||
|
|
||||||
|
println("Web-view timeout after ${totalTime / 1000}s")
|
||||||
destroyWebView()
|
destroyWebView()
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,21 @@
|
||||||
|
package com.lagradost.cloudstream3.utils
|
||||||
|
|
||||||
|
import android.content.Context
|
||||||
|
import com.bumptech.glide.GlideBuilder
|
||||||
|
import com.bumptech.glide.annotation.GlideModule
|
||||||
|
import com.bumptech.glide.load.engine.DiskCacheStrategy
|
||||||
|
import com.bumptech.glide.module.AppGlideModule
|
||||||
|
import com.bumptech.glide.request.RequestOptions
|
||||||
|
import com.bumptech.glide.signature.ObjectKey
|
||||||
|
|
||||||
|
@GlideModule
|
||||||
|
class GlideModule : AppGlideModule() {
|
||||||
|
override fun applyOptions(context: Context, builder: GlideBuilder) {
|
||||||
|
super.applyOptions(context, builder)
|
||||||
|
builder.apply {
|
||||||
|
RequestOptions()
|
||||||
|
.diskCacheStrategy(DiskCacheStrategy.ALL)
|
||||||
|
.signature(ObjectKey(System.currentTimeMillis().toShort()))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -12,7 +12,8 @@ import kotlin.math.pow
|
||||||
class M3u8Helper {
|
class M3u8Helper {
|
||||||
private val ENCRYPTION_DETECTION_REGEX = Regex("#EXT-X-KEY:METHOD=([^,]+),")
|
private val ENCRYPTION_DETECTION_REGEX = Regex("#EXT-X-KEY:METHOD=([^,]+),")
|
||||||
private val ENCRYPTION_URL_IV_REGEX = Regex("#EXT-X-KEY:METHOD=([^,]+),URI=\"([^\"]+)\"(?:,IV=(.*))?")
|
private val ENCRYPTION_URL_IV_REGEX = Regex("#EXT-X-KEY:METHOD=([^,]+),URI=\"([^\"]+)\"(?:,IV=(.*))?")
|
||||||
private val QUALITY_REGEX = Regex("""#EXT-X-STREAM-INF:(?:(?:.*?(?:RESOLUTION=\d+x(\d+)).*?\s+(.*))|(?:.*?\s+(.*)))""")
|
private val QUALITY_REGEX =
|
||||||
|
Regex("""#EXT-X-STREAM-INF:(?:(?:.*?(?:RESOLUTION=\d+x(\d+)).*?\s+(.*))|(?:.*?\s+(.*)))""")
|
||||||
private val TS_EXTENSION_REGEX = Regex("""(.*\.ts.*)""")
|
private val TS_EXTENSION_REGEX = Regex("""(.*\.ts.*)""")
|
||||||
|
|
||||||
fun absoluteExtensionDetermination(url: String): String? {
|
fun absoluteExtensionDetermination(url: String): String? {
|
||||||
|
@ -78,7 +79,7 @@ class M3u8Helper {
|
||||||
return !url.contains("https://") && !url.contains("http://")
|
return !url.contains("https://") && !url.contains("http://")
|
||||||
}
|
}
|
||||||
|
|
||||||
fun m3u8Generation(m3u8: M3u8Stream): List<M3u8Stream> {
|
fun m3u8Generation(m3u8: M3u8Stream, returnThis: Boolean): List<M3u8Stream> {
|
||||||
val generate = sequence {
|
val generate = sequence {
|
||||||
val m3u8Parent = getParentLink(m3u8.streamUrl)
|
val m3u8Parent = getParentLink(m3u8.streamUrl)
|
||||||
val response = get(m3u8.streamUrl, headers = m3u8.headers).text
|
val response = get(m3u8.streamUrl, headers = m3u8.headers).text
|
||||||
|
@ -99,7 +100,7 @@ class M3u8Helper {
|
||||||
m3u8Link,
|
m3u8Link,
|
||||||
quality.toIntOrNull(),
|
quality.toIntOrNull(),
|
||||||
m3u8.headers
|
m3u8.headers
|
||||||
)
|
), false
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -111,6 +112,15 @@ class M3u8Helper {
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
if (returnThis) {
|
||||||
|
yield(
|
||||||
|
M3u8Stream(
|
||||||
|
m3u8.streamUrl,
|
||||||
|
0,
|
||||||
|
m3u8.headers
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return generate.toList()
|
return generate.toList()
|
||||||
}
|
}
|
||||||
|
@ -131,7 +141,7 @@ class M3u8Helper {
|
||||||
}
|
}
|
||||||
val headers = selected.headers
|
val headers = selected.headers
|
||||||
|
|
||||||
val streams = qualities.map { m3u8Generation(it) }.flatten()
|
val streams = qualities.map { m3u8Generation(it, false) }.flatten()
|
||||||
//val sslVerification = if (headers.containsKey("ssl_verification")) headers["ssl_verification"].toBoolean() else true
|
//val sslVerification = if (headers.containsKey("ssl_verification")) headers["ssl_verification"].toBoolean() else true
|
||||||
|
|
||||||
val secondSelection = selectBest(streams.ifEmpty { listOf(selected) })
|
val secondSelection = selectBest(streams.ifEmpty { listOf(selected) })
|
||||||
|
|
|
@ -96,7 +96,7 @@ object UIHelper {
|
||||||
fun ImageView?.setImage(url : String?) {
|
fun ImageView?.setImage(url : String?) {
|
||||||
if(this == null || url.isNullOrBlank()) return
|
if(this == null || url.isNullOrBlank()) return
|
||||||
try {
|
try {
|
||||||
Glide.with(this.context)
|
GlideApp.with(this.context)
|
||||||
.load(GlideUrl(url))
|
.load(GlideUrl(url))
|
||||||
.into(this)
|
.into(this)
|
||||||
} catch (e : Exception) {
|
} catch (e : Exception) {
|
||||||
|
|
|
@ -202,7 +202,7 @@ object VideoDownloadManager {
|
||||||
return cachedBitmaps[url]
|
return cachedBitmaps[url]
|
||||||
}
|
}
|
||||||
|
|
||||||
val bitmap = Glide.with(this)
|
val bitmap = GlideApp.with(this)
|
||||||
.asBitmap()
|
.asBitmap()
|
||||||
.load(url).into(720, 720)
|
.load(url).into(720, 720)
|
||||||
.get()
|
.get()
|
||||||
|
|
Loading…
Reference in a new issue