Skip to content

Commit b7c68d2

Browse files
committed
AnimeKhor v2: fix all-server extraction - emission-counted loadExtractor, ok.ru ondemandHls custom handler, dailymotion embed URL direct
1 parent 7b61c96 commit b7c68d2

1 file changed

Lines changed: 49 additions & 10 deletions

File tree

AnimeKhorProvider/src/main/kotlin/com/animekhor/AnimeKhorProvider.kt

Lines changed: 49 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -242,42 +242,57 @@ class AnimeKhorProvider : MainAPI() {
242242
return true
243243
}
244244

245+
// track whether any extractor link was actually emitted, so a native extractor
246+
// that matches the domain but yields nothing doesn't swallow the server silently
247+
var emitted = false
248+
val trackedCallback: (ExtractorLink) -> Unit = { link ->
249+
emitted = true
250+
callback(link)
251+
}
252+
245253
if (host.contains("dailymotion.com") || host.contains("dai.ly")) {
246-
val vidId = Regex("""(?:video/|video=|embed/|/video/)([a-zA-Z0-9_]+)""").find(clean)?.groupValues?.get(1)
247-
if (vidId != null && loadExtractor("https://www.dailymotion.com/video/$vidId", referer, subtitleCallback, callback)) return true
254+
try {
255+
loadExtractor(clean, referer, subtitleCallback, trackedCallback)
256+
if (emitted) return true
257+
} catch (e: Exception) { }
248258
}
249259

250260
if (host.contains("ok.ru") || host.contains("odnoklassniki")) {
251-
if (loadExtractor(clean, referer, subtitleCallback, callback)) return true
261+
if (resolveOkru(clean, label, referer, subtitleCallback, trackedCallback)) return true
262+
try {
263+
loadExtractor(clean, referer, subtitleCallback, trackedCallback)
264+
if (emitted) return true
265+
} catch (e: Exception) { }
252266
}
253267

254268
if (host.contains("rumble.com")) {
255-
if (resolveRumble(clean, label, subtitleCallback, callback)) return true
269+
if (resolveRumble(clean, label, subtitleCallback, trackedCallback)) return true
256270
}
257271

258272
if (host.contains("d.tube")) {
259-
if (resolveDtube(clean, label, subtitleCallback, callback)) return true
273+
if (resolveDtube(clean, label, subtitleCallback, trackedCallback)) return true
260274
}
261275

262276
if (host.contains("turbovid") || host.contains("emturbovid") || host.contains("turboviplay")) {
263-
if (resolveTurbovid(clean, label, referer, subtitleCallback, callback)) return true
277+
if (resolveTurbovid(clean, label, referer, subtitleCallback, trackedCallback)) return true
264278
}
265279

266280
if (host.contains("upns.live") || host.contains("p2pstream.vip")) {
267-
if (resolveUpns(clean, label, subtitleCallback, callback)) return true
281+
if (resolveUpns(clean, label, subtitleCallback, trackedCallback)) return true
268282
}
269283

270284
if (host.contains("bysekoze") || host.contains("byse")) {
271-
if (resolveByse(clean, label, subtitleCallback, callback)) return true
285+
if (resolveByse(clean, label, subtitleCallback, trackedCallback)) return true
272286
}
273287

274288
if (host.contains("abyssplayer") || host.contains("abyss")) {
275-
if (resolveAbyss(clean, label, referer, subtitleCallback, callback)) return true
289+
if (resolveAbyss(clean, label, referer, subtitleCallback, trackedCallback)) return true
276290
}
277291

278292
// generic: native cloudstream extractors (turbovid, vidhide, streamwish, ...)
279293
try {
280-
if (loadExtractor(clean, referer, subtitleCallback, callback)) return true
294+
loadExtractor(clean, referer, subtitleCallback, trackedCallback)
295+
if (emitted) return true
281296
} catch (e: Exception) { }
282297

283298
// generic: scrape the embed page for a direct stream
@@ -304,6 +319,30 @@ class AnimeKhorProvider : MainAPI() {
304319
return false
305320
}
306321

322+
// ok.ru's modern pages put the stream info in a data-options attribute as escaped JSON;
323+
// extract the ondemandHls m3u8 directly (the built-in Odnoklassniki extractor no longer matches)
324+
private suspend fun resolveOkru(
325+
embedUrl: String,
326+
label: String,
327+
referer: String,
328+
subtitleCallback: (SubtitleFile) -> Unit,
329+
callback: (ExtractorLink) -> Unit
330+
): Boolean {
331+
val clean = embedUrl.replace("\\/", "/")
332+
val html = try {
333+
app.get(clean, headers = mapOf("Referer" to referer, "User-Agent" to USER_AGENT)).text
334+
} catch (e: Exception) { return false }
335+
val hls = Regex("""ondemandHls\\":\\"(.*?)\\"""").find(html)?.groupValues?.get(1)
336+
?.replace("""\u0026""", "&")
337+
?.replace("""\/""", "/")
338+
?.trim()
339+
if (hls == null || !hls.startsWith("http")) return false
340+
val links = M3u8Helper.generateM3u8(label, hls, clean)
341+
if (links.isEmpty()) return false
342+
links.forEach { callback(it) }
343+
return true
344+
}
345+
307346
private suspend fun resolveRumble(
308347
embedUrl: String,
309348
label: String,

0 commit comments

Comments
 (0)