From 92d03fc163356a7b4929166f8f498b9218740449 Mon Sep 17 00:00:00 2001 From: Horis <821938089@qq.com> Date: Sat, 14 Jan 2023 20:07:21 +0800 Subject: [PATCH] Add Dailymotion Extractor (#312) --- .../cloudstream3/extractors/Dailymotion.kt | 102 ++++++++++++++++++ .../cloudstream3/utils/ExtractorApi.kt | 3 +- 2 files changed, 104 insertions(+), 1 deletion(-) create mode 100644 app/src/main/java/com/lagradost/cloudstream3/extractors/Dailymotion.kt diff --git a/app/src/main/java/com/lagradost/cloudstream3/extractors/Dailymotion.kt b/app/src/main/java/com/lagradost/cloudstream3/extractors/Dailymotion.kt new file mode 100644 index 00000000..125e4bcf --- /dev/null +++ b/app/src/main/java/com/lagradost/cloudstream3/extractors/Dailymotion.kt @@ -0,0 +1,102 @@ +package com.lagradost.cloudstream3.extractors + +import com.fasterxml.jackson.annotation.JsonProperty +import com.lagradost.cloudstream3.SubtitleFile +import com.lagradost.cloudstream3.app +import com.lagradost.cloudstream3.utils.AppUtils.tryParseJson +import com.lagradost.cloudstream3.utils.ExtractorApi +import com.lagradost.cloudstream3.utils.ExtractorLink +import com.lagradost.cloudstream3.utils.Qualities +import java.net.URL + +open class Dailymotion : ExtractorApi() { + override val mainUrl = "https://www.dailymotion.com" + override val name = "Dailymotion" + override val requiresReferer = false + + @Suppress("RegExpSimplifiable") + private val videoIdRegex = "^[kx][a-zA-Z0-9]+\$".toRegex() + + // https://www.dailymotion.com/video/k3JAHfletwk94ayCVIu + // https://www.dailymotion.com/embed/video/k3JAHfletwk94ayCVIu + override suspend fun getUrl( + url: String, + referer: String?, + subtitleCallback: (SubtitleFile) -> Unit, + callback: (ExtractorLink) -> Unit + ) { + val embedUrl = getEmbedUrl(url) ?: return + val doc = app.get(embedUrl).document + val prefix = "window.__PLAYER_CONFIG__ = " + val configStr = doc.selectFirst("script:containsData($prefix)")?.data() ?: return + val config = tryParseJson(configStr.substringAfter(prefix)) ?: return + val id = getVideoId(embedUrl) ?: return + val dmV1st = config.dmInternalData.v1st + val dmTs = config.dmInternalData.ts + val metaDataUrl = + "$mainUrl/player/metadata/video/$id?locale=en&dmV1st=$dmV1st&dmTs=$dmTs&is_native_app=0" + val cookies = mapOf( + "v1st" to dmV1st, + "dmvk" to config.context.dmvk, + "ts" to dmTs.toString() + ) + val metaData = app.get(metaDataUrl, referer = embedUrl, cookies = cookies) + .parsedSafe() ?: return + metaData.qualities.forEach { (key, video) -> + video.forEach { + callback.invoke( + ExtractorLink( + name, + "$name $key", + it.url, + "", + Qualities.Unknown.value, + true + ) + ) + } + } + } + + private fun getEmbedUrl(url: String): String? { + if (url.contains("/embed/")) { + return url + } + val vid = getVideoId(url) ?: return null + return "$mainUrl/embed/video/$vid" + } + + private fun getVideoId(url: String): String? { + val path = URL(url).path + val id = path.substringAfter("video/") + if (id.matches(videoIdRegex)) { + return id + } + return null + } + + data class Config( + val context: Context, + val dmInternalData: InternalData + ) + + data class InternalData( + val ts: Int, + val v1st: String + ) + + data class Context( + @JsonProperty("access_token") val accessToken: String?, + val dmvk: String, + ) + + data class MetaData( + val qualities: Map> + ) + + data class VideoLink( + val type: String, + val url: String + ) + +} diff --git a/app/src/main/java/com/lagradost/cloudstream3/utils/ExtractorApi.kt b/app/src/main/java/com/lagradost/cloudstream3/utils/ExtractorApi.kt index cf6d0bae..3978eb62 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/utils/ExtractorApi.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/utils/ExtractorApi.kt @@ -357,7 +357,8 @@ val extractorApis: MutableList = arrayListOf( PlayLtXyz(), AStreamHub(), - Cda() + Cda(), + Dailymotion(), )