Merge branch 'dev' of https://github.com/tapframe/NuvioTV into dev
This commit is contained in:
commit
ec754b73bd
2 changed files with 68 additions and 8 deletions
|
|
@ -4,6 +4,8 @@ import com.nuvio.tv.data.local.StreamAutoPlayMode
|
|||
import com.nuvio.tv.data.local.StreamAutoPlaySource
|
||||
import com.nuvio.tv.domain.model.AddonStreams
|
||||
import com.nuvio.tv.domain.model.Stream
|
||||
import java.net.HttpURLConnection
|
||||
import java.net.URL
|
||||
|
||||
object StreamAutoPlaySelector {
|
||||
fun orderAddonStreams(
|
||||
|
|
@ -17,6 +19,52 @@ object StreamAutoPlaySelector {
|
|||
return orderedAddons + pluginEntries
|
||||
}
|
||||
|
||||
private fun resolvePlayableUrl(stream: Stream): String? {
|
||||
val url = stream.getStreamUrl() ?: return null
|
||||
|
||||
// Pixeldrain is the ONLY host that needs special resolving
|
||||
if ("pixeldrain" in url) {
|
||||
val id = url.substringAfterLast("/")
|
||||
val infoUrl = "https://pixeldrain.dev/api/file/$id/info"
|
||||
|
||||
val infoJson = runCatching { URL(infoUrl).readText() }.getOrNull() ?: return null
|
||||
|
||||
if (!infoJson.contains("\"success\":true")) return null
|
||||
if (!infoJson.contains("\"mime_type\":\"video")) return null
|
||||
|
||||
return "https://pixeldrain.dev/api/file/$id?download"
|
||||
}
|
||||
|
||||
// Everything else: return as-is
|
||||
return url
|
||||
}
|
||||
|
||||
|
||||
|
||||
private fun urlWorks(url: String): Boolean {
|
||||
val lower = url.lowercase()
|
||||
|
||||
// Skip probing for signed or tokened URLs
|
||||
if (listOf("token=", "expires=", "signature=", "sig=", "auth=", "key=", "hash=", "x-amz-", "hdnts=", "cf_")
|
||||
.any { lower.contains(it) }) {
|
||||
return true
|
||||
}
|
||||
|
||||
// Safe HEAD probe for everything else
|
||||
return runCatching {
|
||||
val connection = URL(url).openConnection() as HttpURLConnection
|
||||
connection.requestMethod = "HEAD"
|
||||
connection.connectTimeout = 3000
|
||||
connection.readTimeout = 3000
|
||||
connection.instanceFollowRedirects = true
|
||||
connection.connect()
|
||||
connection.responseCode in 200..399
|
||||
}.getOrElse { false }
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
fun selectAutoPlayStream(
|
||||
streams: List<Stream>,
|
||||
mode: StreamAutoPlayMode,
|
||||
|
|
@ -80,9 +128,9 @@ object StreamAutoPlaySelector {
|
|||
Regex("\\b(${exclusionWords.joinToString("|")})\\b", RegexOption.IGNORE_CASE)
|
||||
} else null
|
||||
|
||||
|
||||
candidateStreams.firstOrNull { stream ->
|
||||
val url = stream.getStreamUrl() ?: return@firstOrNull false
|
||||
// 1. Build list of ALL regex‑matching streams
|
||||
val matchingStreams = candidateStreams.filter { stream ->
|
||||
val url = stream.getStreamUrl() ?: return@filter false
|
||||
|
||||
val searchableText = buildString {
|
||||
append(stream.addonName).append(' ')
|
||||
|
|
@ -91,20 +139,31 @@ object StreamAutoPlaySelector {
|
|||
append(stream.description.orEmpty()).append(' ')
|
||||
append(url)
|
||||
}
|
||||
|
||||
// Must match user include pattern
|
||||
if (!userRegex.containsMatchIn(searchableText)) return@firstOrNull false
|
||||
|
||||
// Must NOT match user exclusion pattern (if any)
|
||||
// Must match include pattern
|
||||
if (!userRegex.containsMatchIn(searchableText)) return@filter false
|
||||
|
||||
// Must NOT match exclusion pattern
|
||||
if (excludeRegex != null && excludeRegex.containsMatchIn(searchableText)) {
|
||||
return@firstOrNull false
|
||||
return@filter false
|
||||
}
|
||||
|
||||
true
|
||||
}
|
||||
|
||||
if (matchingStreams.isEmpty()) return null
|
||||
|
||||
// 2. Try each matching stream until one works
|
||||
for (stream in matchingStreams) {
|
||||
val resolved = resolvePlayableUrl(stream) ?: continue
|
||||
println("Trying resolved stream: $resolved")
|
||||
if (urlWorks(resolved)) return stream
|
||||
|
||||
}
|
||||
// None worked
|
||||
null
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -911,6 +911,7 @@ private fun StreamRegexDialog(
|
|||
"Dolby Atmos / DTS" to "(atmos|truehd|dts[-\\s]?hd|dtsx?)",
|
||||
"English" to "(\\beng\\b|english)",
|
||||
"No CAM/TS" to "^(?!.*\\b(cam|hdcam|ts|telesync)\\b).*$"
|
||||
"No REMUX/HDR" to "(?is)^(?!.*\\b(hdr|hdr10|dv|dolby|vision|hevc|remux|2160p)\\b).+$"
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue