@ -5,7 +5,7 @@ ext {
|
|||||||
extName = 'فاصل اعلاني'
|
extName = 'فاصل اعلاني'
|
||||||
pkgNameSuffix = 'ar.faselhd'
|
pkgNameSuffix = 'ar.faselhd'
|
||||||
extClass = '.FASELHD'
|
extClass = '.FASELHD'
|
||||||
extVersionCode = 9
|
extVersionCode = 10
|
||||||
libVersion = '13'
|
libVersion = '13'
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -92,29 +92,22 @@ class FASELHD : ConfigurableAnimeSource, ParsedAnimeHttpSource() {
|
|||||||
return episode
|
return episode
|
||||||
}
|
}
|
||||||
|
|
||||||
// Video urls //test commit
|
// Video urls
|
||||||
|
|
||||||
|
override fun videoListSelector() = throw UnsupportedOperationException("Not used.")
|
||||||
|
|
||||||
override fun videoListParse(response: Response): List<Video> {
|
override fun videoListParse(response: Response): List<Video> {
|
||||||
val document = response.asJsoup()
|
val document = response.asJsoup()
|
||||||
val iframe = document.selectFirst("iframe").attr("src")
|
val getSources = "master.m3u8"
|
||||||
val referer = response.request.url.toString()
|
val referer = Headers.headersOf("Referer", "$baseUrl/")
|
||||||
val refererHeaders = Headers.headersOf("referer", referer)
|
val iframe = document.selectFirst("iframe").attr("src").substringBefore("&img")
|
||||||
val iframeResponse = client.newCall(GET(iframe, refererHeaders))
|
val webViewIncpec = client.newBuilder().addInterceptor(GetSourcesInterceptor(getSources, client)).build()
|
||||||
.execute().asJsoup()
|
val lol = webViewIncpec.newCall(GET(iframe, referer)).execute().body!!.string()
|
||||||
return videosFromElement(iframeResponse.selectFirst(videoListSelector()), refererHeaders)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun videoListSelector() = "button.hd_btn:contains(auto)"
|
|
||||||
|
|
||||||
private fun videosFromElement(element: Element, headers: Headers): List<Video> {
|
|
||||||
// val masterUrl = element.data().substringAfter("setup({\"file\":\"").substringBefore("\"").replace("\\/", "/")
|
|
||||||
val masterUrl = element.attr("data-url")
|
|
||||||
val masterPlaylist = client.newCall(GET(masterUrl, headers)).execute().body!!.string()
|
|
||||||
val videoList = mutableListOf<Video>()
|
val videoList = mutableListOf<Video>()
|
||||||
masterPlaylist.substringAfter("#EXT-X-STREAM-INF:").split("#EXT-X-STREAM-INF:").forEach {
|
lol.substringAfter("#EXT-X-STREAM-INF:").split("#EXT-X-STREAM-INF:").forEach {
|
||||||
val quality = it.substringAfter("RESOLUTION=").substringAfter("x").substringBefore(",") + "p"
|
val quality = it.substringAfter("RESOLUTION=").substringAfter("x").substringBefore(",") + "p"
|
||||||
val videoUrl = it.substringAfter("\n").substringBefore("\n").replace("https", "http")
|
val videoUrl = it.substringAfter("\n").substringBefore("\n").replace("https", "http")
|
||||||
videoList.add(Video(videoUrl, quality, videoUrl, headers = headers))
|
videoList.add(Video(videoUrl, quality, videoUrl, headers = referer))
|
||||||
}
|
}
|
||||||
return videoList
|
return videoList
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,99 @@
|
|||||||
|
package eu.kanade.tachiyomi.animeextension.ar.faselhd
|
||||||
|
|
||||||
|
import android.annotation.SuppressLint
|
||||||
|
import android.app.Application
|
||||||
|
import android.os.Handler
|
||||||
|
import android.os.Looper
|
||||||
|
import android.webkit.WebResourceRequest
|
||||||
|
import android.webkit.WebResourceResponse
|
||||||
|
import android.webkit.WebSettings
|
||||||
|
import android.webkit.WebView
|
||||||
|
import android.webkit.WebViewClient
|
||||||
|
import eu.kanade.tachiyomi.network.GET
|
||||||
|
import okhttp3.Headers.Companion.toHeaders
|
||||||
|
import okhttp3.Interceptor
|
||||||
|
import okhttp3.OkHttpClient
|
||||||
|
import okhttp3.Request
|
||||||
|
import okhttp3.Response
|
||||||
|
import uy.kohesive.injekt.Injekt
|
||||||
|
import uy.kohesive.injekt.api.get
|
||||||
|
import java.io.IOException
|
||||||
|
import java.util.concurrent.CountDownLatch
|
||||||
|
import java.util.concurrent.TimeUnit
|
||||||
|
|
||||||
|
class GetSourcesInterceptor(private val getSources: String, private val client: OkHttpClient) : Interceptor {
|
||||||
|
private val context = Injekt.get<Application>()
|
||||||
|
private val handler by lazy { Handler(Looper.getMainLooper()) }
|
||||||
|
|
||||||
|
private val initWebView by lazy {
|
||||||
|
WebSettings.getDefaultUserAgent(context)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Synchronized
|
||||||
|
override fun intercept(chain: Interceptor.Chain): Response {
|
||||||
|
initWebView
|
||||||
|
|
||||||
|
val request = chain.request()
|
||||||
|
|
||||||
|
try {
|
||||||
|
val newRequest = resolveWithWebView(request)
|
||||||
|
|
||||||
|
return chain.proceed(newRequest ?: request)
|
||||||
|
} catch (e: Exception) {
|
||||||
|
throw IOException(e)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressLint("SetJavaScriptEnabled")
|
||||||
|
private fun resolveWithWebView(request: Request): Request? {
|
||||||
|
val latch = CountDownLatch(1)
|
||||||
|
|
||||||
|
var webView: WebView? = null
|
||||||
|
|
||||||
|
val origRequestUrl = request.url.toString()
|
||||||
|
val headers = request.headers.toMultimap().mapValues { it.value.getOrNull(0) ?: "" }.toMutableMap()
|
||||||
|
var newRequest: Request? = null
|
||||||
|
|
||||||
|
handler.post {
|
||||||
|
val webview = WebView(context)
|
||||||
|
webView = webview
|
||||||
|
with(webview.settings) {
|
||||||
|
javaScriptEnabled = true
|
||||||
|
domStorageEnabled = true
|
||||||
|
databaseEnabled = true
|
||||||
|
useWideViewPort = false
|
||||||
|
loadWithOverviewMode = false
|
||||||
|
userAgentString = "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:94.0) Gecko/20100101 Firefox/94.0"
|
||||||
|
}
|
||||||
|
webview.webViewClient = object : WebViewClient() {
|
||||||
|
override fun shouldInterceptRequest(
|
||||||
|
view: WebView,
|
||||||
|
request: WebResourceRequest
|
||||||
|
): WebResourceResponse? {
|
||||||
|
val url = request.url.toString()
|
||||||
|
if (url.contains(getSources)) {
|
||||||
|
val newHeaders = request.requestHeaders.toHeaders()
|
||||||
|
newRequest = GET(url, newHeaders)
|
||||||
|
latch.countDown()
|
||||||
|
}
|
||||||
|
return super.shouldInterceptRequest(view, request)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
webView?.loadUrl(origRequestUrl, headers)
|
||||||
|
}
|
||||||
|
|
||||||
|
latch.await(TIMEOUT_SEC, TimeUnit.SECONDS)
|
||||||
|
|
||||||
|
handler.post {
|
||||||
|
webView?.stopLoading()
|
||||||
|
webView?.destroy()
|
||||||
|
webView = null
|
||||||
|
}
|
||||||
|
return newRequest
|
||||||
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
const val TIMEOUT_SEC: Long = 20
|
||||||
|
}
|
||||||
|
}
|
@ -5,7 +5,7 @@ ext {
|
|||||||
extName = 'فاصل اعلاني افلام بس'
|
extName = 'فاصل اعلاني افلام بس'
|
||||||
pkgNameSuffix = 'ar.faselhdmovies'
|
pkgNameSuffix = 'ar.faselhdmovies'
|
||||||
extClass = '.FASELHDMOVIES'
|
extClass = '.FASELHDMOVIES'
|
||||||
extVersionCode = 6
|
extVersionCode = 7
|
||||||
libVersion = '13'
|
libVersion = '13'
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -75,27 +75,20 @@ class FASELHDMOVIES : ConfigurableAnimeSource, ParsedAnimeHttpSource() {
|
|||||||
|
|
||||||
// Video urls
|
// Video urls
|
||||||
|
|
||||||
|
override fun videoListSelector() = throw UnsupportedOperationException("Not used.")
|
||||||
|
|
||||||
override fun videoListParse(response: Response): List<Video> {
|
override fun videoListParse(response: Response): List<Video> {
|
||||||
val document = response.asJsoup()
|
val document = response.asJsoup()
|
||||||
val iframe = document.selectFirst("iframe").attr("src")
|
val getSources = "master.m3u8"
|
||||||
val referer = response.request.url.toString()
|
val referer = Headers.headersOf("Referer", "$baseUrl/")
|
||||||
val refererHeaders = Headers.headersOf("referer", referer)
|
val iframe = document.selectFirst("iframe").attr("src").substringBefore("&img")
|
||||||
val iframeResponse = client.newCall(GET(iframe, refererHeaders))
|
val webViewIncpec = client.newBuilder().addInterceptor(GetSourcesInterceptor(getSources, client)).build()
|
||||||
.execute().asJsoup()
|
val lol = webViewIncpec.newCall(GET(iframe, referer)).execute().body!!.string()
|
||||||
return videosFromElement(iframeResponse.selectFirst(videoListSelector()), refererHeaders)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun videoListSelector() = "button.hd_btn:contains(auto)"
|
|
||||||
|
|
||||||
private fun videosFromElement(element: Element, headers: Headers): List<Video> {
|
|
||||||
// val masterUrl = element.data().substringAfter("setup({\"file\":\"").substringBefore("\"").replace("\\/", "/")
|
|
||||||
val masterUrl = element.attr("data-url")
|
|
||||||
val masterPlaylist = client.newCall(GET(masterUrl, headers)).execute().body!!.string()
|
|
||||||
val videoList = mutableListOf<Video>()
|
val videoList = mutableListOf<Video>()
|
||||||
masterPlaylist.substringAfter("#EXT-X-STREAM-INF:").split("#EXT-X-STREAM-INF:").forEach {
|
lol.substringAfter("#EXT-X-STREAM-INF:").split("#EXT-X-STREAM-INF:").forEach {
|
||||||
val quality = it.substringAfter("RESOLUTION=").substringAfter("x").substringBefore(",") + "p"
|
val quality = it.substringAfter("RESOLUTION=").substringAfter("x").substringBefore(",") + "p"
|
||||||
val videoUrl = it.substringAfter("\n").substringBefore("\n").replace("https", "http")
|
val videoUrl = it.substringAfter("\n").substringBefore("\n").replace("https", "http")
|
||||||
videoList.add(Video(videoUrl, quality, videoUrl, headers = headers))
|
videoList.add(Video(videoUrl, quality, videoUrl, headers = referer))
|
||||||
}
|
}
|
||||||
return videoList
|
return videoList
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,99 @@
|
|||||||
|
package eu.kanade.tachiyomi.animeextension.ar.faselhdmovies
|
||||||
|
|
||||||
|
import android.annotation.SuppressLint
|
||||||
|
import android.app.Application
|
||||||
|
import android.os.Handler
|
||||||
|
import android.os.Looper
|
||||||
|
import android.webkit.WebResourceRequest
|
||||||
|
import android.webkit.WebResourceResponse
|
||||||
|
import android.webkit.WebSettings
|
||||||
|
import android.webkit.WebView
|
||||||
|
import android.webkit.WebViewClient
|
||||||
|
import eu.kanade.tachiyomi.network.GET
|
||||||
|
import okhttp3.Headers.Companion.toHeaders
|
||||||
|
import okhttp3.Interceptor
|
||||||
|
import okhttp3.OkHttpClient
|
||||||
|
import okhttp3.Request
|
||||||
|
import okhttp3.Response
|
||||||
|
import uy.kohesive.injekt.Injekt
|
||||||
|
import uy.kohesive.injekt.api.get
|
||||||
|
import java.io.IOException
|
||||||
|
import java.util.concurrent.CountDownLatch
|
||||||
|
import java.util.concurrent.TimeUnit
|
||||||
|
|
||||||
|
class GetSourcesInterceptor(private val getSources: String, private val client: OkHttpClient) : Interceptor {
|
||||||
|
private val context = Injekt.get<Application>()
|
||||||
|
private val handler by lazy { Handler(Looper.getMainLooper()) }
|
||||||
|
|
||||||
|
private val initWebView by lazy {
|
||||||
|
WebSettings.getDefaultUserAgent(context)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Synchronized
|
||||||
|
override fun intercept(chain: Interceptor.Chain): Response {
|
||||||
|
initWebView
|
||||||
|
|
||||||
|
val request = chain.request()
|
||||||
|
|
||||||
|
try {
|
||||||
|
val newRequest = resolveWithWebView(request)
|
||||||
|
|
||||||
|
return chain.proceed(newRequest ?: request)
|
||||||
|
} catch (e: Exception) {
|
||||||
|
throw IOException(e)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressLint("SetJavaScriptEnabled")
|
||||||
|
private fun resolveWithWebView(request: Request): Request? {
|
||||||
|
val latch = CountDownLatch(1)
|
||||||
|
|
||||||
|
var webView: WebView? = null
|
||||||
|
|
||||||
|
val origRequestUrl = request.url.toString()
|
||||||
|
val headers = request.headers.toMultimap().mapValues { it.value.getOrNull(0) ?: "" }.toMutableMap()
|
||||||
|
var newRequest: Request? = null
|
||||||
|
|
||||||
|
handler.post {
|
||||||
|
val webview = WebView(context)
|
||||||
|
webView = webview
|
||||||
|
with(webview.settings) {
|
||||||
|
javaScriptEnabled = true
|
||||||
|
domStorageEnabled = true
|
||||||
|
databaseEnabled = true
|
||||||
|
useWideViewPort = false
|
||||||
|
loadWithOverviewMode = false
|
||||||
|
userAgentString = "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:94.0) Gecko/20100101 Firefox/94.0"
|
||||||
|
}
|
||||||
|
webview.webViewClient = object : WebViewClient() {
|
||||||
|
override fun shouldInterceptRequest(
|
||||||
|
view: WebView,
|
||||||
|
request: WebResourceRequest
|
||||||
|
): WebResourceResponse? {
|
||||||
|
val url = request.url.toString()
|
||||||
|
if (url.contains(getSources)) {
|
||||||
|
val newHeaders = request.requestHeaders.toHeaders()
|
||||||
|
newRequest = GET(url, newHeaders)
|
||||||
|
latch.countDown()
|
||||||
|
}
|
||||||
|
return super.shouldInterceptRequest(view, request)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
webView?.loadUrl(origRequestUrl, headers)
|
||||||
|
}
|
||||||
|
|
||||||
|
latch.await(TIMEOUT_SEC, TimeUnit.SECONDS)
|
||||||
|
|
||||||
|
handler.post {
|
||||||
|
webView?.stopLoading()
|
||||||
|
webView?.destroy()
|
||||||
|
webView = null
|
||||||
|
}
|
||||||
|
return newRequest
|
||||||
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
const val TIMEOUT_SEC: Long = 20
|
||||||
|
}
|
||||||
|
}
|
Reference in New Issue
Block a user