[skip ci] refactor: Make extensions use the dailymotion-extractor lib (#2160)
This commit is contained in:
parent
602e91e363
commit
4b0cf15499
@ -34,7 +34,7 @@ class DailymotionExtractor(private val client: OkHttpClient, private val headers
|
||||
|
||||
private val playlistUtils by lazy { PlaylistUtils(client, headers) }
|
||||
|
||||
fun videosFromUrl(url: String, prefix: String, baseUrl: String = "", password: String? = null): List<Video> {
|
||||
fun videosFromUrl(url: String, prefix: String = "Dailymotion - ", baseUrl: String = "", password: String? = null): List<Video> {
|
||||
val htmlString = client.newCall(GET(url)).execute().use { it.body.string() }
|
||||
|
||||
val internalData = htmlString.substringAfter("\"dmInternalData\":").substringBefore("</script>")
|
||||
|
@ -1,4 +1,5 @@
|
||||
dependencies {
|
||||
implementation(project(':lib-dailymotion-extractor'))
|
||||
implementation(project(':lib-okru-extractor'))
|
||||
implementation(project(':lib-gdriveplayer-extractor'))
|
||||
implementation "dev.datlag.jsunpacker:jsunpacker:1.0.1"
|
||||
|
@ -2,11 +2,11 @@ package eu.kanade.tachiyomi.animeextension.all.animexin
|
||||
|
||||
import androidx.preference.ListPreference
|
||||
import androidx.preference.PreferenceScreen
|
||||
import eu.kanade.tachiyomi.animeextension.all.animexin.extractors.DailymotionExtractor
|
||||
import eu.kanade.tachiyomi.animeextension.all.animexin.extractors.DoodExtractor
|
||||
import eu.kanade.tachiyomi.animeextension.all.animexin.extractors.VidstreamingExtractor
|
||||
import eu.kanade.tachiyomi.animeextension.all.animexin.extractors.YouTubeExtractor
|
||||
import eu.kanade.tachiyomi.animesource.model.Video
|
||||
import eu.kanade.tachiyomi.lib.dailymotionextractor.DailymotionExtractor
|
||||
import eu.kanade.tachiyomi.lib.gdriveplayerextractor.GdrivePlayerExtractor
|
||||
import eu.kanade.tachiyomi.lib.okruextractor.OkruExtractor
|
||||
import eu.kanade.tachiyomi.multisrc.animestream.AnimeStream
|
||||
@ -27,7 +27,7 @@ class AnimeXin : AnimeStream(
|
||||
}
|
||||
|
||||
url.contains("dailymotion") -> {
|
||||
DailymotionExtractor(client).videosFromUrl(url, prefix = prefix)
|
||||
DailymotionExtractor(client, headers).videosFromUrl(url, prefix)
|
||||
}
|
||||
url.contains("https://dood") -> {
|
||||
DoodExtractor(client).videosFromUrl(url, quality = name)
|
||||
|
@ -1,91 +0,0 @@
|
||||
package eu.kanade.tachiyomi.animeextension.all.animexin.extractors
|
||||
|
||||
import eu.kanade.tachiyomi.animesource.model.Track
|
||||
import eu.kanade.tachiyomi.animesource.model.Video
|
||||
import eu.kanade.tachiyomi.network.GET
|
||||
import kotlinx.serialization.Serializable
|
||||
import kotlinx.serialization.decodeFromString
|
||||
import kotlinx.serialization.json.Json
|
||||
import okhttp3.HttpUrl.Companion.toHttpUrl
|
||||
import okhttp3.OkHttpClient
|
||||
import uy.kohesive.injekt.injectLazy
|
||||
|
||||
@Serializable
|
||||
data class DailyQuality(
|
||||
val qualities: Auto,
|
||||
val subtitles: Subtitle? = null,
|
||||
) {
|
||||
@Serializable
|
||||
data class Auto(
|
||||
val auto: List<Item>,
|
||||
) {
|
||||
@Serializable
|
||||
data class Item(
|
||||
val type: String,
|
||||
val url: String,
|
||||
)
|
||||
}
|
||||
|
||||
@Serializable
|
||||
data class Subtitle(
|
||||
val data: Map<String, SubtitleObject>,
|
||||
) {
|
||||
@Serializable
|
||||
data class SubtitleObject(
|
||||
val label: String,
|
||||
val urls: List<String>,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
class DailymotionExtractor(private val client: OkHttpClient) {
|
||||
|
||||
private val json: Json by injectLazy()
|
||||
|
||||
fun videosFromUrl(url: String, prefix: String): List<Video> {
|
||||
val videoList = mutableListOf<Video>()
|
||||
val htmlString = client.newCall(GET(url)).execute().body.string()
|
||||
|
||||
val internalData = htmlString.substringAfter("\"dmInternalData\":").substringBefore("</script>")
|
||||
val ts = internalData.substringAfter("\"ts\":").substringBefore(",")
|
||||
val v1st = internalData.substringAfter("\"v1st\":\"").substringBefore("\",")
|
||||
|
||||
val jsonUrl = "https://www.dailymotion.com/player/metadata/video/${url.toHttpUrl().encodedPath}?locale=en-US&dmV1st=$v1st&dmTs=$ts&is_native_app=0"
|
||||
val parsed = json.decodeFromString<DailyQuality>(
|
||||
client.newCall(GET(jsonUrl))
|
||||
.execute().body.string(),
|
||||
)
|
||||
|
||||
val subtitleList = mutableListOf<Track>()
|
||||
if (parsed.subtitles != null) {
|
||||
try {
|
||||
subtitleList.addAll(
|
||||
parsed.subtitles.data.map { k ->
|
||||
Track(
|
||||
k.value.urls.first(),
|
||||
k.value.label,
|
||||
)
|
||||
},
|
||||
)
|
||||
} catch (a: Exception) { }
|
||||
}
|
||||
|
||||
val masterUrl = parsed.qualities.auto.first().url
|
||||
|
||||
val masterPlaylist = client.newCall(GET(masterUrl)).execute().body.string()
|
||||
|
||||
val separator = "#EXT-X-STREAM-INF"
|
||||
masterPlaylist.substringAfter(separator).split(separator).map {
|
||||
val quality = it.substringAfter("RESOLUTION=").substringAfter("x").substringBefore(",NAME") + "p"
|
||||
var videoUrl = it.substringAfter("\n").substringBefore("\n")
|
||||
|
||||
try {
|
||||
videoList.add(Video(videoUrl, prefix + quality, videoUrl, subtitleTracks = subtitleList))
|
||||
} catch (a: Exception) {
|
||||
videoList.add(Video(videoUrl, prefix + quality, videoUrl))
|
||||
}
|
||||
}
|
||||
|
||||
return videoList
|
||||
}
|
||||
}
|
@ -1,3 +1,4 @@
|
||||
dependencies {
|
||||
implementation(project(':lib-dailymotion-extractor'))
|
||||
implementation(project(':lib-playlist-utils'))
|
||||
}
|
||||
|
@ -1,8 +1,8 @@
|
||||
package eu.kanade.tachiyomi.animeextension.en.donghuastream
|
||||
|
||||
import eu.kanade.tachiyomi.animeextension.en.donghuastream.extractors.DailymotionExtractor
|
||||
import eu.kanade.tachiyomi.animeextension.en.donghuastream.extractors.StreamPlayExtractor
|
||||
import eu.kanade.tachiyomi.animesource.model.Video
|
||||
import eu.kanade.tachiyomi.lib.dailymotionextractor.DailymotionExtractor
|
||||
import eu.kanade.tachiyomi.multisrc.animestream.AnimeStream
|
||||
|
||||
class DonghuaStream : AnimeStream(
|
||||
|
@ -1,77 +0,0 @@
|
||||
package eu.kanade.tachiyomi.animeextension.en.donghuastream.extractors
|
||||
|
||||
import eu.kanade.tachiyomi.animesource.model.Track
|
||||
import eu.kanade.tachiyomi.animesource.model.Video
|
||||
import eu.kanade.tachiyomi.lib.playlistutils.PlaylistUtils
|
||||
import eu.kanade.tachiyomi.network.GET
|
||||
import kotlinx.serialization.Serializable
|
||||
import kotlinx.serialization.json.Json
|
||||
import okhttp3.Headers
|
||||
import okhttp3.HttpUrl.Companion.toHttpUrl
|
||||
import okhttp3.OkHttpClient
|
||||
import okhttp3.Response
|
||||
import uy.kohesive.injekt.injectLazy
|
||||
|
||||
class DailymotionExtractor(private val client: OkHttpClient, private val headers: Headers) {
|
||||
|
||||
private val json: Json by injectLazy()
|
||||
|
||||
private val playlistUtils by lazy { PlaylistUtils(client, headers) }
|
||||
|
||||
fun videosFromUrl(url: String, prefix: String): List<Video> {
|
||||
val htmlString = client.newCall(GET(url)).execute().use { it.body.string() }
|
||||
|
||||
val internalData = htmlString.substringAfter("\"dmInternalData\":").substringBefore("</script>")
|
||||
val ts = internalData.substringAfter("\"ts\":").substringBefore(",")
|
||||
val v1st = internalData.substringAfter("\"v1st\":\"").substringBefore("\",")
|
||||
|
||||
val videoQuery = url.toHttpUrl().queryParameter("video") ?: url.toHttpUrl().encodedPath
|
||||
|
||||
val jsonUrl = "https://www.dailymotion.com/player/metadata/video/$videoQuery?locale=en-US&dmV1st=$v1st&dmTs=$ts&is_native_app=0"
|
||||
val parsed = client.newCall(GET(jsonUrl)).execute().parseAs<DailyQuality>()
|
||||
|
||||
val subtitleList = parsed.subtitles?.data?.map { k ->
|
||||
Track(
|
||||
k.value.urls.first(),
|
||||
k.value.label,
|
||||
)
|
||||
} ?: emptyList()
|
||||
|
||||
val masterUrl = parsed.qualities.auto.first().url
|
||||
|
||||
return playlistUtils.extractFromHls(masterUrl, subtitleList = subtitleList, videoNameGen = { q -> "$prefix$q" })
|
||||
}
|
||||
|
||||
@Serializable
|
||||
data class DailyQuality(
|
||||
val qualities: Auto,
|
||||
val subtitles: Subtitle? = null,
|
||||
) {
|
||||
@Serializable
|
||||
data class Auto(
|
||||
val auto: List<Item>,
|
||||
) {
|
||||
@Serializable
|
||||
data class Item(
|
||||
val type: String,
|
||||
val url: String,
|
||||
)
|
||||
}
|
||||
|
||||
@Serializable
|
||||
data class Subtitle(
|
||||
val data: Map<String, SubtitleObject>,
|
||||
) {
|
||||
@Serializable
|
||||
data class SubtitleObject(
|
||||
val label: String,
|
||||
val urls: List<String>,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
private inline fun <reified T> Response.parseAs(transform: (String) -> String = { it }): T {
|
||||
val responseBody = use { transform(it.body.string()) }
|
||||
return json.decodeFromString(responseBody)
|
||||
}
|
||||
}
|
@ -1,3 +1,4 @@
|
||||
dependencies {
|
||||
implementation(project(":lib-dailymotion-extractor"))
|
||||
implementation(project(":lib-okru-extractor"))
|
||||
}
|
||||
|
@ -3,8 +3,8 @@ package eu.kanade.tachiyomi.animeextension.all.lmanime
|
||||
import androidx.preference.ListPreference
|
||||
import androidx.preference.MultiSelectListPreference
|
||||
import androidx.preference.PreferenceScreen
|
||||
import eu.kanade.tachiyomi.animeextension.all.lmanime.extractors.DailymotionExtractor
|
||||
import eu.kanade.tachiyomi.animesource.model.Video
|
||||
import eu.kanade.tachiyomi.lib.dailymotionextractor.DailymotionExtractor
|
||||
import eu.kanade.tachiyomi.lib.okruextractor.OkruExtractor
|
||||
import eu.kanade.tachiyomi.multisrc.animestream.AnimeStream
|
||||
import eu.kanade.tachiyomi.util.asJsoup
|
||||
@ -39,7 +39,7 @@ class LMAnime : AnimeStream(
|
||||
"ok.ru" in url ->
|
||||
OkruExtractor(client).videosFromUrl(url, prefix)
|
||||
"dailymotion.com" in url ->
|
||||
DailymotionExtractor(client).videosFromUrl(url, "Dailymotion ($name)")
|
||||
DailymotionExtractor(client, headers).videosFromUrl(url, "Dailymotion ($name)")
|
||||
else -> emptyList()
|
||||
}
|
||||
}
|
||||
|
@ -1,50 +0,0 @@
|
||||
package eu.kanade.tachiyomi.animeextension.all.lmanime.extractors
|
||||
|
||||
import eu.kanade.tachiyomi.animesource.model.Video
|
||||
import eu.kanade.tachiyomi.network.GET
|
||||
import kotlinx.serialization.Serializable
|
||||
import kotlinx.serialization.decodeFromString
|
||||
import kotlinx.serialization.json.Json
|
||||
import okhttp3.OkHttpClient
|
||||
import uy.kohesive.injekt.injectLazy
|
||||
|
||||
@Serializable
|
||||
data class DailyQuality(
|
||||
val qualities: Auto,
|
||||
) {
|
||||
@Serializable
|
||||
data class Auto(
|
||||
val auto: List<Video>,
|
||||
) {
|
||||
@Serializable
|
||||
data class Video(
|
||||
val type: String,
|
||||
val url: String,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
class DailymotionExtractor(private val client: OkHttpClient) {
|
||||
private val json: Json by injectLazy()
|
||||
|
||||
fun videosFromUrl(url: String, prefix: String): List<Video> {
|
||||
val id = url.substringBefore("?").substringAfterLast("/")
|
||||
val jsonUrl = "https://www.dailymotion.com/player/metadata/video/$id"
|
||||
val jsonRequest = client.newCall(GET(jsonUrl)).execute().body.string()
|
||||
val parsed = json.decodeFromString<DailyQuality>(jsonRequest)
|
||||
|
||||
val masterUrl = parsed.qualities.auto.first().url
|
||||
val masterPlaylist = client.newCall(GET(masterUrl)).execute().body.string()
|
||||
|
||||
val separator = "#EXT-X-STREAM-INF"
|
||||
return masterPlaylist.substringAfter(separator).split(separator).map {
|
||||
val resolution = it.substringAfter("RESOLUTION=")
|
||||
.substringAfter("x")
|
||||
.substringBefore(",NAME") + "p"
|
||||
val quality = "$prefix $resolution"
|
||||
val videoUrl = it.substringAfter("\n").substringBefore("\n")
|
||||
|
||||
Video(videoUrl, quality, videoUrl)
|
||||
}
|
||||
}
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
dependencies {
|
||||
implementation(project(':lib-dailymotion-extractor'))
|
||||
implementation(project(':lib-okru-extractor'))
|
||||
implementation(project(':lib-playlist-utils'))
|
||||
}
|
||||
|
@ -1,8 +1,8 @@
|
||||
package eu.kanade.tachiyomi.animeextension.en.luciferdonghua
|
||||
|
||||
import android.util.Base64
|
||||
import eu.kanade.tachiyomi.animeextension.en.luciferdonghua.extractors.DailymotionExtractor
|
||||
import eu.kanade.tachiyomi.animesource.model.Video
|
||||
import eu.kanade.tachiyomi.lib.dailymotionextractor.DailymotionExtractor
|
||||
import eu.kanade.tachiyomi.lib.okruextractor.OkruExtractor
|
||||
import eu.kanade.tachiyomi.multisrc.animestream.AnimeStream
|
||||
import org.jsoup.Jsoup
|
||||
@ -35,7 +35,7 @@ class LuciferDonghua : AnimeStream(
|
||||
OkruExtractor(client).videosFromUrl(url, prefix = prefix)
|
||||
}
|
||||
url.contains("dailymotion") -> {
|
||||
DailymotionExtractor(client, headers).videosFromUrl(url, prefix = prefix)
|
||||
DailymotionExtractor(client, headers).videosFromUrl(url, prefix)
|
||||
}
|
||||
else -> emptyList()
|
||||
}
|
||||
|
@ -1,84 +0,0 @@
|
||||
package eu.kanade.tachiyomi.animeextension.en.luciferdonghua.extractors
|
||||
|
||||
import eu.kanade.tachiyomi.animesource.model.Track
|
||||
import eu.kanade.tachiyomi.animesource.model.Video
|
||||
import eu.kanade.tachiyomi.lib.playlistutils.PlaylistUtils
|
||||
import eu.kanade.tachiyomi.network.GET
|
||||
import kotlinx.serialization.Serializable
|
||||
import kotlinx.serialization.json.Json
|
||||
import kotlinx.serialization.json.JsonElement
|
||||
import okhttp3.Headers
|
||||
import okhttp3.HttpUrl.Companion.toHttpUrl
|
||||
import okhttp3.OkHttpClient
|
||||
import okhttp3.Response
|
||||
import uy.kohesive.injekt.injectLazy
|
||||
|
||||
class DailymotionExtractor(private val client: OkHttpClient, private val headers: Headers) {
|
||||
|
||||
private val json: Json by injectLazy()
|
||||
|
||||
private val playlistUtils by lazy { PlaylistUtils(client, headers) }
|
||||
|
||||
fun videosFromUrl(url: String, prefix: String): List<Video> {
|
||||
val htmlString = client.newCall(GET(url)).execute().use { it.body.string() }
|
||||
|
||||
val internalData = htmlString.substringAfter("\"dmInternalData\":").substringBefore("</script>")
|
||||
val ts = internalData.substringAfter("\"ts\":").substringBefore(",")
|
||||
val v1st = internalData.substringAfter("\"v1st\":\"").substringBefore("\",")
|
||||
|
||||
val videoQuery = url.toHttpUrl().queryParameter("video") ?: url.toHttpUrl().pathSegments.last()
|
||||
|
||||
val jsonUrl = "https://www.dailymotion.com/player/metadata/video/$videoQuery?locale=en-US&dmV1st=$v1st&dmTs=$ts&is_native_app=0"
|
||||
val parsed = client.newCall(GET(jsonUrl)).execute().parseAs<DailyQuality>()
|
||||
|
||||
// Blame dailymotion for this monstrosity
|
||||
val subtitlesString = parsed.subtitles.data.toString()
|
||||
val subtitleList = if (subtitlesString == "[]") {
|
||||
emptyList()
|
||||
} else {
|
||||
json.decodeFromString<Map<String, DailyQuality.SubtitleObject>>(subtitlesString).map { k ->
|
||||
Track(
|
||||
k.value.urls.first(),
|
||||
k.value.label,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
val masterUrl = parsed.qualities.auto.first().url
|
||||
|
||||
return playlistUtils.extractFromHls(masterUrl, subtitleList = subtitleList, videoNameGen = { q -> "$prefix$q" })
|
||||
}
|
||||
|
||||
@Serializable
|
||||
data class DailyQuality(
|
||||
val qualities: Auto,
|
||||
val subtitles: Subtitle,
|
||||
) {
|
||||
@Serializable
|
||||
data class Auto(
|
||||
val auto: List<Item>,
|
||||
) {
|
||||
@Serializable
|
||||
data class Item(
|
||||
val type: String,
|
||||
val url: String,
|
||||
)
|
||||
}
|
||||
|
||||
@Serializable
|
||||
data class Subtitle(
|
||||
val data: JsonElement,
|
||||
)
|
||||
|
||||
@Serializable
|
||||
data class SubtitleObject(
|
||||
val label: String,
|
||||
val urls: List<String>,
|
||||
)
|
||||
}
|
||||
|
||||
private inline fun <reified T> Response.parseAs(transform: (String) -> String = { it }): T {
|
||||
val responseBody = use { transform(it.body.string()) }
|
||||
return json.decodeFromString(responseBody)
|
||||
}
|
||||
}
|
3
multisrc/overrides/dooplay/donghuax/additional.gradle
Normal file
3
multisrc/overrides/dooplay/donghuax/additional.gradle
Normal file
@ -0,0 +1,3 @@
|
||||
dependencies {
|
||||
implementation(project(':lib-dailymotion-extractor'))
|
||||
}
|
@ -2,12 +2,12 @@ package eu.kanade.tachiyomi.animeextension.pt.donghuax
|
||||
|
||||
import androidx.preference.ListPreference
|
||||
import androidx.preference.PreferenceScreen
|
||||
import eu.kanade.tachiyomi.animeextension.pt.donghuax.extractors.DailymotionExtractor
|
||||
import eu.kanade.tachiyomi.animesource.model.AnimeFilter
|
||||
import eu.kanade.tachiyomi.animesource.model.AnimeFilterList
|
||||
import eu.kanade.tachiyomi.animesource.model.AnimesPage
|
||||
import eu.kanade.tachiyomi.animesource.model.SEpisode
|
||||
import eu.kanade.tachiyomi.animesource.model.Video
|
||||
import eu.kanade.tachiyomi.lib.dailymotionextractor.DailymotionExtractor
|
||||
import eu.kanade.tachiyomi.multisrc.dooplay.DooPlay
|
||||
import eu.kanade.tachiyomi.network.GET
|
||||
import eu.kanade.tachiyomi.network.POST
|
||||
@ -240,7 +240,7 @@ class DonghuaX : DooPlay(
|
||||
GET(url),
|
||||
).execute().asJsoup().selectFirst("vm-dailymotion[video-id]")?.attr("video-id")
|
||||
id?.let {
|
||||
DailymotionExtractor(client).videosFromUrl("https://www.dailymotion.com/embed/video/$it", "Dailymotion - ")
|
||||
DailymotionExtractor(client, headers).videosFromUrl("https://www.dailymotion.com/embed/video/$it")
|
||||
} ?: emptyList()
|
||||
}
|
||||
url.contains("csst.online") -> {
|
||||
|
@ -1,56 +0,0 @@
|
||||
package eu.kanade.tachiyomi.animeextension.pt.donghuax.extractors
|
||||
|
||||
import eu.kanade.tachiyomi.animesource.model.Video
|
||||
import eu.kanade.tachiyomi.network.GET
|
||||
import kotlinx.serialization.Serializable
|
||||
import kotlinx.serialization.decodeFromString
|
||||
import kotlinx.serialization.json.Json
|
||||
import okhttp3.Headers
|
||||
import okhttp3.OkHttpClient
|
||||
import uy.kohesive.injekt.injectLazy
|
||||
|
||||
@Serializable
|
||||
data class DailyQuality(
|
||||
val qualities: Auto,
|
||||
) {
|
||||
@Serializable
|
||||
data class Auto(
|
||||
val auto: List<Video>,
|
||||
) {
|
||||
@Serializable
|
||||
data class Video(
|
||||
val type: String,
|
||||
val url: String,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
class DailymotionExtractor(private val client: OkHttpClient) {
|
||||
private val json: Json by injectLazy()
|
||||
|
||||
fun videosFromUrl(url: String, prefix: String): List<Video> {
|
||||
val id = url.substringBefore("?").substringAfterLast("/")
|
||||
val jsonUrl = "https://www.dailymotion.com/player/metadata/video/$id"
|
||||
val jsonRequest = client.newCall(GET(jsonUrl)).execute().body.string()
|
||||
val parsed = json.decodeFromString<DailyQuality>(jsonRequest)
|
||||
|
||||
val masterUrl = parsed.qualities.auto.first().url
|
||||
val masterPlaylist = client.newCall(GET(masterUrl)).execute().body.string()
|
||||
|
||||
val separator = "#EXT-X-STREAM-INF"
|
||||
return masterPlaylist.substringAfter(separator).split(separator).map {
|
||||
val resolution = it.substringAfter("RESOLUTION=")
|
||||
.substringAfter("x")
|
||||
.substringBefore(",NAME") + "p"
|
||||
val quality = "$prefix $resolution"
|
||||
val videoUrl = it.substringAfter("\n").substringBefore("\n")
|
||||
|
||||
val videoHeaders = Headers.headersOf(
|
||||
"Referer",
|
||||
"https://www.dailymotion.com/",
|
||||
)
|
||||
|
||||
Video(videoUrl, quality, videoUrl, headers = videoHeaders)
|
||||
}
|
||||
}
|
||||
}
|
@ -12,6 +12,7 @@ ext {
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation(project(':lib-dailymotion-extractor'))
|
||||
implementation(project(':lib-dood-extractor'))
|
||||
implementation(project(':lib-okru-extractor'))
|
||||
implementation(project(':lib-mp4upload-extractor'))
|
||||
|
@ -3,7 +3,6 @@ package eu.kanade.tachiyomi.animeextension.ar.witanime
|
||||
import android.app.Application
|
||||
import androidx.preference.ListPreference
|
||||
import androidx.preference.PreferenceScreen
|
||||
import eu.kanade.tachiyomi.animeextension.ar.witanime.extractors.DailymotionExtractor
|
||||
import eu.kanade.tachiyomi.animeextension.ar.witanime.extractors.SharedExtractor
|
||||
import eu.kanade.tachiyomi.animeextension.ar.witanime.extractors.SoraPlayExtractor
|
||||
import eu.kanade.tachiyomi.animesource.ConfigurableAnimeSource
|
||||
@ -12,6 +11,7 @@ import eu.kanade.tachiyomi.animesource.model.SAnime
|
||||
import eu.kanade.tachiyomi.animesource.model.SEpisode
|
||||
import eu.kanade.tachiyomi.animesource.model.Video
|
||||
import eu.kanade.tachiyomi.animesource.online.ParsedAnimeHttpSource
|
||||
import eu.kanade.tachiyomi.lib.dailymotionextractor.DailymotionExtractor
|
||||
import eu.kanade.tachiyomi.lib.doodextractor.DoodExtractor
|
||||
import eu.kanade.tachiyomi.lib.mp4uploadextractor.Mp4uploadExtractor
|
||||
import eu.kanade.tachiyomi.lib.okruextractor.OkruExtractor
|
||||
@ -135,7 +135,7 @@ class WitAnime : ConfigurableAnimeSource, ParsedAnimeHttpSource() {
|
||||
private val soraPlayExtractor by lazy { SoraPlayExtractor(client) }
|
||||
private val doodExtractor by lazy { DoodExtractor(client) }
|
||||
private val sharedExtractor by lazy { SharedExtractor(client) }
|
||||
private val dailymotionExtractor by lazy { DailymotionExtractor(client) }
|
||||
private val dailymotionExtractor by lazy { DailymotionExtractor(client, headers) }
|
||||
private val okruExtractor by lazy { OkruExtractor(client) }
|
||||
private val mp4uploadExtractor by lazy { Mp4uploadExtractor(client) }
|
||||
private val vidBomExtractor by lazy { VidBomExtractor(client) }
|
||||
@ -159,7 +159,7 @@ class WitAnime : ConfigurableAnimeSource, ParsedAnimeHttpSource() {
|
||||
}
|
||||
|
||||
url.contains("dailymotion") -> {
|
||||
dailymotionExtractor.videosFromUrl(url, headers)
|
||||
dailymotionExtractor.videosFromUrl(url)
|
||||
}
|
||||
url.contains("ok.ru") -> {
|
||||
okruExtractor.videosFromUrl(url)
|
||||
|
@ -1,22 +0,0 @@
|
||||
package eu.kanade.tachiyomi.animeextension.ar.witanime.extractors
|
||||
|
||||
import eu.kanade.tachiyomi.animesource.model.Video
|
||||
import eu.kanade.tachiyomi.network.GET
|
||||
import okhttp3.Headers
|
||||
import okhttp3.OkHttpClient
|
||||
|
||||
class DailymotionExtractor(private val client: OkHttpClient) {
|
||||
fun videosFromUrl(url: String, headers: Headers): List<Video> {
|
||||
val id = url.split("/").last()
|
||||
val request = GET("https://www.dailymotion.com/player/metadata/video/$id", headers)
|
||||
val body = client.newCall(request).execute().body.string()
|
||||
val streamURL = body.substringAfter("{\"type\":\"application\\/x-mpegURL\",\"url\":\"")
|
||||
.substringBefore("\"")
|
||||
.replace("\\", "")
|
||||
|
||||
val sources = client.newCall(GET(streamURL)).execute().body.string()
|
||||
return Regex("#EXT(?:.*?)NAME=\"(.*?)\",PROGRESSIVE-URI=\"(.*?)\"").findAll(sources).map {
|
||||
Video(it.groupValues[2], "Dailymotion: ${it.groupValues[1]}p", it.groupValues[2])
|
||||
}.toList()
|
||||
}
|
||||
}
|
@ -11,6 +11,7 @@ ext {
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation(project(':lib-dailymotion-extractor'))
|
||||
implementation(project(':lib-mp4upload-extractor'))
|
||||
implementation(project(':lib-yourupload-extractor'))
|
||||
implementation "dev.datlag.jsunpacker:jsunpacker:1.0.1"
|
||||
|
@ -4,7 +4,6 @@ import android.app.Application
|
||||
import android.content.SharedPreferences
|
||||
import androidx.preference.ListPreference
|
||||
import androidx.preference.PreferenceScreen
|
||||
import eu.kanade.tachiyomi.animeextension.en.kissanime.extractors.DailymotionExtractor
|
||||
import eu.kanade.tachiyomi.animeextension.en.kissanime.extractors.VodstreamExtractor
|
||||
import eu.kanade.tachiyomi.animesource.ConfigurableAnimeSource
|
||||
import eu.kanade.tachiyomi.animesource.model.AnimeFilterList
|
||||
@ -13,6 +12,7 @@ import eu.kanade.tachiyomi.animesource.model.SAnime
|
||||
import eu.kanade.tachiyomi.animesource.model.SEpisode
|
||||
import eu.kanade.tachiyomi.animesource.model.Video
|
||||
import eu.kanade.tachiyomi.animesource.online.ParsedAnimeHttpSource
|
||||
import eu.kanade.tachiyomi.lib.dailymotionextractor.DailymotionExtractor
|
||||
import eu.kanade.tachiyomi.lib.mp4uploadextractor.Mp4uploadExtractor
|
||||
import eu.kanade.tachiyomi.lib.youruploadextractor.YourUploadExtractor
|
||||
import eu.kanade.tachiyomi.network.GET
|
||||
@ -232,7 +232,7 @@ class KissAnime : ConfigurableAnimeSource, ParsedAnimeHttpSource() {
|
||||
VodstreamExtractor(client).getVideosFromUrl(url, referer = referer, prefix = "${server.name} - ")
|
||||
}
|
||||
url.contains("dailymotion") -> {
|
||||
DailymotionExtractor(client).videosFromUrl(url, prefix = "${server.name} - ", password = server.password, baseUrl = baseUrl)
|
||||
DailymotionExtractor(client, headers).videosFromUrl(url, "${server.name} - ", baseUrl, server.password)
|
||||
}
|
||||
else -> null
|
||||
}
|
||||
|
@ -1,174 +0,0 @@
|
||||
package eu.kanade.tachiyomi.animeextension.en.kissanime.extractors
|
||||
|
||||
import eu.kanade.tachiyomi.animesource.model.Video
|
||||
import eu.kanade.tachiyomi.network.GET
|
||||
import eu.kanade.tachiyomi.network.POST
|
||||
import kotlinx.serialization.Serializable
|
||||
import kotlinx.serialization.decodeFromString
|
||||
import kotlinx.serialization.json.Json
|
||||
import okhttp3.Headers
|
||||
import okhttp3.HttpUrl.Companion.toHttpUrl
|
||||
import okhttp3.MediaType.Companion.toMediaType
|
||||
import okhttp3.OkHttpClient
|
||||
import okhttp3.RequestBody.Companion.toRequestBody
|
||||
import uy.kohesive.injekt.injectLazy
|
||||
|
||||
class DailymotionExtractor(private val client: OkHttpClient) {
|
||||
|
||||
private val json: Json by injectLazy()
|
||||
|
||||
fun videosFromUrl(url: String, prefix: String, baseUrl: String, password: String?): List<Video> {
|
||||
val videoList = mutableListOf<Video>()
|
||||
val htmlString = client.newCall(GET(url)).execute().body.string()
|
||||
|
||||
val internalData = htmlString.substringAfter("\"dmInternalData\":").substringBefore("</script>")
|
||||
val ts = internalData.substringAfter("\"ts\":").substringBefore(",")
|
||||
val v1st = internalData.substringAfter("\"v1st\":\"").substringBefore("\",")
|
||||
|
||||
val jsonUrl = "https://www.dailymotion.com/player/metadata/video${url.toHttpUrl().encodedPath}?locale=en-US&dmV1st=$v1st&dmTs=$ts&is_native_app=0"
|
||||
|
||||
var parsed = json.decodeFromString<DailyQuality>(
|
||||
client.newCall(GET(jsonUrl))
|
||||
.execute().body.string(),
|
||||
)
|
||||
var playlistHeaders = Headers.headersOf()
|
||||
val videoHeaders = Headers.headersOf(
|
||||
"Accept",
|
||||
"*/*",
|
||||
"Origin",
|
||||
"https://www.dailymotion.com",
|
||||
"Referer",
|
||||
"https://www.dailymotion.com/",
|
||||
)
|
||||
|
||||
if (parsed.error != null) {
|
||||
if (parsed.error!!.type == "password_protected") {
|
||||
val postUrl = "https://graphql.api.dailymotion.com/oauth/token"
|
||||
val clientId = htmlString.substringAfter("client_id\":\"").substringBefore("\"")
|
||||
val clientSecret = htmlString.substringAfter("client_secret\":\"").substringBefore("\"")
|
||||
val scope = htmlString.substringAfter("client_scope\":\"").substringBefore("\"")
|
||||
|
||||
val tokenHeaders = Headers.headersOf(
|
||||
"Accept",
|
||||
"application/json, text/plain, */*",
|
||||
"Content-Type",
|
||||
"application/x-www-form-urlencoded",
|
||||
"Origin",
|
||||
"https://www.dailymotion.com",
|
||||
"Referer",
|
||||
"https://www.dailymotion.com/",
|
||||
)
|
||||
val tokenBody = "client_id=$clientId&client_secret=$clientSecret&traffic_segment=$ts&visitor_id=$v1st&grant_type=client_credentials&scope=$scope".toRequestBody("application/x-www-form-urlencoded".toMediaType())
|
||||
val tokenResponse = client.newCall(
|
||||
POST(postUrl, body = tokenBody, headers = tokenHeaders),
|
||||
).execute()
|
||||
val tokenParsed = json.decodeFromString<TokenResponse>(tokenResponse.body.string())
|
||||
|
||||
val idUrl = "https://graphql.api.dailymotion.com/"
|
||||
val idHeaders = Headers.headersOf(
|
||||
"Accept", "application/json, text/plain, */*",
|
||||
"Authorization", "${tokenParsed.token_type} ${tokenParsed.access_token}",
|
||||
"Content-Type", "application/json",
|
||||
"Origin", "https://www.dailymotion.com",
|
||||
"Referer", "https://www.dailymotion.com/",
|
||||
)
|
||||
|
||||
val idData = """
|
||||
{
|
||||
"query":"query playerPasswordQuery(${'$'}videoId:String!,${'$'}password:String!){video(xid:${'$'}videoId,password:${'$'}password){id xid}}",
|
||||
"variables":{
|
||||
"videoId":"${parsed.id!!}",
|
||||
"password":"$password"
|
||||
}
|
||||
}
|
||||
""".trimIndent().toRequestBody("application/json".toMediaType())
|
||||
|
||||
val idResponse = client.newCall(
|
||||
POST(idUrl, body = idData, headers = idHeaders),
|
||||
).execute()
|
||||
val idParsed = json.decodeFromString<ProtectedResponse>(idResponse.body.string()).data.video
|
||||
|
||||
val dmvk = htmlString.substringAfter("\"dmvk\":\"").substringBefore("\"")
|
||||
val getVideoIdUrl = "https://www.dailymotion.com/player/metadata/video/${idParsed.xid}?embedder=${"$baseUrl/"}&locale=en-US&dmV1st=$v1st&dmTs=$ts&is_native_app=0"
|
||||
val getVideoIdHeaders = Headers.headersOf(
|
||||
"Accept",
|
||||
"*/*",
|
||||
"Cookie",
|
||||
"dmvk=$dmvk; ts=$ts; v1st=$v1st; usprivacy=1---; client_token=${tokenParsed.access_token}",
|
||||
"Referer",
|
||||
url,
|
||||
)
|
||||
playlistHeaders = Headers.headersOf(
|
||||
"Accept",
|
||||
"*/*",
|
||||
"Cookie",
|
||||
"dmvk=$dmvk; ts=$ts; v1st=$v1st; usprivacy=1---; client_token=${tokenParsed.access_token}",
|
||||
"Referer",
|
||||
url,
|
||||
)
|
||||
val getVideoIdResponse = client.newCall(GET(getVideoIdUrl, headers = getVideoIdHeaders)).execute()
|
||||
val videoQualityBody = getVideoIdResponse.body.string()
|
||||
parsed = json.decodeFromString<DailyQuality>(videoQualityBody)
|
||||
}
|
||||
}
|
||||
|
||||
val masterUrl = parsed.qualities!!.auto.first().url
|
||||
|
||||
val masterPlaylist = client.newCall(GET(masterUrl, headers = playlistHeaders)).execute().body.string()
|
||||
|
||||
val separator = "#EXT-X-STREAM-INF"
|
||||
masterPlaylist.substringAfter(separator).split(separator).map {
|
||||
val quality = it.substringAfter("RESOLUTION=").substringAfter("x").substringBefore(",NAME") + "p"
|
||||
var videoUrl = it.substringAfter("\n").substringBefore("\n")
|
||||
|
||||
videoList.add(Video(videoUrl, prefix + quality, videoUrl, headers = videoHeaders))
|
||||
}
|
||||
|
||||
return videoList
|
||||
}
|
||||
|
||||
@Serializable
|
||||
data class TokenResponse(
|
||||
val access_token: String,
|
||||
val token_type: String,
|
||||
)
|
||||
|
||||
@Serializable
|
||||
data class ProtectedResponse(
|
||||
val data: DataObject,
|
||||
) {
|
||||
@Serializable
|
||||
data class DataObject(
|
||||
val video: VideoObject,
|
||||
) {
|
||||
@Serializable
|
||||
data class VideoObject(
|
||||
val id: String,
|
||||
val xid: String,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@Serializable
|
||||
data class DailyQuality(
|
||||
val error: Error? = null,
|
||||
val id: String? = null,
|
||||
val qualities: Auto? = null,
|
||||
) {
|
||||
@Serializable
|
||||
data class Error(
|
||||
val type: String,
|
||||
)
|
||||
|
||||
@Serializable
|
||||
data class Auto(
|
||||
val auto: List<Item>,
|
||||
) {
|
||||
@Serializable
|
||||
data class Item(
|
||||
val type: String,
|
||||
val url: String,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
@ -11,6 +11,7 @@ ext {
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation(project(':lib-dailymotion-extractor'))
|
||||
implementation(project(':lib-gdriveplayer-extractor'))
|
||||
implementation(project(':lib-okru-extractor'))
|
||||
implementation "dev.datlag.jsunpacker:jsunpacker:1.0.1"
|
||||
|
@ -4,7 +4,6 @@ import android.app.Application
|
||||
import android.content.SharedPreferences
|
||||
import androidx.preference.ListPreference
|
||||
import androidx.preference.PreferenceScreen
|
||||
import eu.kanade.tachiyomi.animeextension.en.myanime.extractors.DailymotionExtractor
|
||||
import eu.kanade.tachiyomi.animeextension.en.myanime.extractors.YouTubeExtractor
|
||||
import eu.kanade.tachiyomi.animesource.ConfigurableAnimeSource
|
||||
import eu.kanade.tachiyomi.animesource.model.AnimeFilter
|
||||
@ -13,6 +12,7 @@ import eu.kanade.tachiyomi.animesource.model.SAnime
|
||||
import eu.kanade.tachiyomi.animesource.model.SEpisode
|
||||
import eu.kanade.tachiyomi.animesource.model.Video
|
||||
import eu.kanade.tachiyomi.animesource.online.ParsedAnimeHttpSource
|
||||
import eu.kanade.tachiyomi.lib.dailymotionextractor.DailymotionExtractor
|
||||
import eu.kanade.tachiyomi.lib.gdriveplayerextractor.GdrivePlayerExtractor
|
||||
import eu.kanade.tachiyomi.lib.okruextractor.OkruExtractor
|
||||
import eu.kanade.tachiyomi.network.GET
|
||||
@ -207,7 +207,7 @@ class Myanime : ConfigurableAnimeSource, ParsedAnimeHttpSource() {
|
||||
|
||||
when {
|
||||
url.contains("dailymotion") -> {
|
||||
DailymotionExtractor(client).videosFromUrl(url)
|
||||
DailymotionExtractor(client, headers).videosFromUrl(url)
|
||||
}
|
||||
url.contains("ok.ru") -> {
|
||||
OkruExtractor(client).videosFromUrl(url)
|
||||
|
@ -1,85 +0,0 @@
|
||||
package eu.kanade.tachiyomi.animeextension.en.myanime.extractors
|
||||
|
||||
import eu.kanade.tachiyomi.animesource.model.Track
|
||||
import eu.kanade.tachiyomi.animesource.model.Video
|
||||
import eu.kanade.tachiyomi.network.GET
|
||||
import kotlinx.serialization.Serializable
|
||||
import kotlinx.serialization.decodeFromString
|
||||
import kotlinx.serialization.json.Json
|
||||
import kotlinx.serialization.json.JsonElement
|
||||
import okhttp3.HttpUrl.Companion.toHttpUrl
|
||||
import okhttp3.OkHttpClient
|
||||
import uy.kohesive.injekt.injectLazy
|
||||
|
||||
@Serializable
|
||||
data class DailyQuality(
|
||||
val qualities: Auto,
|
||||
val subtitles: Subtitle? = null,
|
||||
) {
|
||||
@Serializable
|
||||
data class Auto(
|
||||
val auto: List<Item>,
|
||||
) {
|
||||
@Serializable
|
||||
data class Item(
|
||||
val type: String,
|
||||
val url: String,
|
||||
)
|
||||
}
|
||||
|
||||
// @Serializable
|
||||
// data class SubtitleObject(
|
||||
// val label: String,
|
||||
// val urls: List<String>,
|
||||
// )
|
||||
|
||||
@Serializable
|
||||
data class Subtitle(
|
||||
// data can be either an empty list, or `Map<String, SubtitleObject>`
|
||||
val data: JsonElement? = null,
|
||||
)
|
||||
}
|
||||
|
||||
class DailymotionExtractor(private val client: OkHttpClient) {
|
||||
|
||||
private val json: Json by injectLazy()
|
||||
|
||||
fun videosFromUrl(url: String, prefix: String = "Dailymotion - "): List<Video> {
|
||||
val videoList = mutableListOf<Video>()
|
||||
val htmlString = client.newCall(GET(url)).execute().body.string()
|
||||
|
||||
val internalData = htmlString.substringAfter("\"dmInternalData\":").substringBefore("</script>")
|
||||
val ts = internalData.substringAfter("\"ts\":").substringBefore(",")
|
||||
val v1st = internalData.substringAfter("\"v1st\":\"").substringBefore("\",")
|
||||
|
||||
val jsonUrl = "https://www.dailymotion.com/player/metadata/video${url.toHttpUrl().encodedPath}?locale=en-US&dmV1st=$v1st&dmTs=$ts&is_native_app=0"
|
||||
val parsed = json.decodeFromString<DailyQuality>(
|
||||
client.newCall(GET(jsonUrl))
|
||||
.execute().body.string(),
|
||||
)
|
||||
val subtitleList = mutableListOf<Track>()
|
||||
// if (parsed.subtitles != null) {
|
||||
// if (parsed.subtitles.data.toString() != "[]") {
|
||||
//
|
||||
// }
|
||||
// }
|
||||
|
||||
val masterUrl = parsed.qualities.auto.first().url
|
||||
|
||||
val masterPlaylist = client.newCall(GET(masterUrl)).execute().body.string()
|
||||
|
||||
val separator = "#EXT-X-STREAM-INF"
|
||||
masterPlaylist.substringAfter(separator).split(separator).map {
|
||||
val quality = it.substringAfter("RESOLUTION=").substringAfter("x").substringBefore(",NAME") + "p"
|
||||
var videoUrl = it.substringAfter("\n").substringBefore("\n")
|
||||
|
||||
try {
|
||||
videoList.add(Video(videoUrl, prefix + quality, videoUrl, subtitleTracks = subtitleList))
|
||||
} catch (a: Exception) {
|
||||
videoList.add(Video(videoUrl, prefix + quality, videoUrl))
|
||||
}
|
||||
}
|
||||
|
||||
return videoList
|
||||
}
|
||||
}
|
@ -11,6 +11,7 @@ ext {
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation(project(':lib-dailymotion-extractor'))
|
||||
implementation(project(':lib-mp4upload-extractor'))
|
||||
implementation(project(':lib-sibnet-extractor'))
|
||||
implementation "dev.datlag.jsunpacker:jsunpacker:1.0.1"
|
||||
|
@ -6,7 +6,6 @@ import androidx.preference.ListPreference
|
||||
import androidx.preference.PreferenceScreen
|
||||
import androidx.preference.SwitchPreferenceCompat
|
||||
import eu.kanade.tachiyomi.animeextension.pl.wbijam.extractors.CdaPlExtractor
|
||||
import eu.kanade.tachiyomi.animeextension.pl.wbijam.extractors.DailymotionExtractor
|
||||
import eu.kanade.tachiyomi.animeextension.pl.wbijam.extractors.VkExtractor
|
||||
import eu.kanade.tachiyomi.animesource.ConfigurableAnimeSource
|
||||
import eu.kanade.tachiyomi.animesource.model.AnimeFilterList
|
||||
@ -15,6 +14,7 @@ import eu.kanade.tachiyomi.animesource.model.SAnime
|
||||
import eu.kanade.tachiyomi.animesource.model.SEpisode
|
||||
import eu.kanade.tachiyomi.animesource.model.Video
|
||||
import eu.kanade.tachiyomi.animesource.online.ParsedAnimeHttpSource
|
||||
import eu.kanade.tachiyomi.lib.dailymotionextractor.DailymotionExtractor
|
||||
import eu.kanade.tachiyomi.lib.mp4uploadextractor.Mp4uploadExtractor
|
||||
import eu.kanade.tachiyomi.lib.sibnetextractor.SibnetExtractor
|
||||
import eu.kanade.tachiyomi.network.GET
|
||||
@ -295,7 +295,7 @@ class Wbijam : ConfigurableAnimeSource, ParsedAnimeHttpSource() {
|
||||
VkExtractor(client).getVideosFromUrl(serverUrl, headers)
|
||||
}
|
||||
serverUrl.contains("dailymotion") -> {
|
||||
DailymotionExtractor(client).videosFromUrl(serverUrl, headers)
|
||||
DailymotionExtractor(client, headers).videosFromUrl(serverUrl)
|
||||
}
|
||||
else -> null
|
||||
}
|
||||
|
@ -1,70 +0,0 @@
|
||||
package eu.kanade.tachiyomi.animeextension.pl.wbijam.extractors
|
||||
|
||||
import eu.kanade.tachiyomi.animesource.model.Video
|
||||
import eu.kanade.tachiyomi.network.GET
|
||||
import kotlinx.serialization.Serializable
|
||||
import kotlinx.serialization.decodeFromString
|
||||
import kotlinx.serialization.json.Json
|
||||
import okhttp3.Headers
|
||||
import okhttp3.HttpUrl.Companion.toHttpUrl
|
||||
import okhttp3.OkHttpClient
|
||||
import uy.kohesive.injekt.injectLazy
|
||||
|
||||
class DailymotionExtractor(private val client: OkHttpClient) {
|
||||
|
||||
private val json: Json by injectLazy()
|
||||
|
||||
fun videosFromUrl(url: String, headers: Headers): List<Video> {
|
||||
val videoList = mutableListOf<Video>()
|
||||
val htmlString = client.newCall(GET(url)).execute().body.string()
|
||||
|
||||
val internalData = htmlString.substringAfter("\"dmInternalData\":").substringBefore("</script>")
|
||||
val ts = internalData.substringAfter("\"ts\":").substringBefore(",")
|
||||
val v1st = internalData.substringAfter("\"v1st\":\"").substringBefore("\",")
|
||||
|
||||
val jsonUrl = "https://www.dailymotion.com/player/metadata/video/${url.toHttpUrl().encodedPath}?locale=en-US&dmV1st=$v1st&dmTs=$ts&is_native_app=0"
|
||||
val parsed = json.decodeFromString<DailyQuality>(
|
||||
client.newCall(GET(jsonUrl))
|
||||
.execute().body.string(),
|
||||
)
|
||||
|
||||
val masterUrl = parsed.qualities.auto.first().url
|
||||
|
||||
val masterPlaylist = client.newCall(GET(masterUrl)).execute().body.string()
|
||||
|
||||
val separator = "#EXT-X-STREAM-INF"
|
||||
masterPlaylist.substringAfter(separator).split(separator).map {
|
||||
val quality = it.substringAfter("RESOLUTION=").substringAfter("x").substringBefore(",NAME") + "p"
|
||||
val videoUrl = it.substringAfter("\n").substringBefore("\n")
|
||||
|
||||
val videoHeaders = headers.newBuilder()
|
||||
.add("Accept", "*/*")
|
||||
.add("Host", videoUrl.toHttpUrl().host)
|
||||
.add("Origin", "https://www.dailymotion.com")
|
||||
.add("Referer", "https://www.dailymotion.com")
|
||||
.build()
|
||||
|
||||
videoList.add(
|
||||
Video(videoUrl, "Dailymotion - $quality", videoUrl, headers = videoHeaders),
|
||||
)
|
||||
}
|
||||
|
||||
return videoList
|
||||
}
|
||||
|
||||
@Serializable
|
||||
data class DailyQuality(
|
||||
val qualities: Auto,
|
||||
) {
|
||||
@Serializable
|
||||
data class Auto(
|
||||
val auto: List<Item>,
|
||||
) {
|
||||
@Serializable
|
||||
data class Item(
|
||||
val type: String,
|
||||
val url: String,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user