2021-05-19 18:44:02 +00:00
|
|
|
package com.lagradost.cloudstream3.utils
|
|
|
|
|
2022-01-07 19:27:25 +00:00
|
|
|
import android.net.Uri
|
2023-11-05 22:33:11 +00:00
|
|
|
import com.fasterxml.jackson.annotation.JsonIgnore
|
2023-09-06 20:42:22 +00:00
|
|
|
import com.lagradost.cloudstream3.SubtitleFile
|
|
|
|
import com.lagradost.cloudstream3.TvType
|
|
|
|
import com.lagradost.cloudstream3.USER_AGENT
|
|
|
|
import com.lagradost.cloudstream3.app
|
|
|
|
import com.lagradost.cloudstream3.extractors.AStreamHub
|
|
|
|
import com.lagradost.cloudstream3.extractors.Acefile
|
|
|
|
import com.lagradost.cloudstream3.extractors.Ahvsh
|
|
|
|
import com.lagradost.cloudstream3.extractors.Aico
|
|
|
|
import com.lagradost.cloudstream3.extractors.AsianLoad
|
|
|
|
import com.lagradost.cloudstream3.extractors.Bestx
|
|
|
|
import com.lagradost.cloudstream3.extractors.Blogger
|
|
|
|
import com.lagradost.cloudstream3.extractors.BullStream
|
|
|
|
import com.lagradost.cloudstream3.extractors.ByteShare
|
|
|
|
import com.lagradost.cloudstream3.extractors.Cda
|
|
|
|
import com.lagradost.cloudstream3.extractors.Cdnplayer
|
|
|
|
import com.lagradost.cloudstream3.extractors.Chillx
|
|
|
|
import com.lagradost.cloudstream3.extractors.CineGrabber
|
|
|
|
import com.lagradost.cloudstream3.extractors.Cinestart
|
|
|
|
import com.lagradost.cloudstream3.extractors.DBfilm
|
|
|
|
import com.lagradost.cloudstream3.extractors.Dailymotion
|
|
|
|
import com.lagradost.cloudstream3.extractors.DatabaseGdrive
|
|
|
|
import com.lagradost.cloudstream3.extractors.DatabaseGdrive2
|
|
|
|
import com.lagradost.cloudstream3.extractors.DesuArcg
|
|
|
|
import com.lagradost.cloudstream3.extractors.DesuDrive
|
|
|
|
import com.lagradost.cloudstream3.extractors.DesuOdchan
|
|
|
|
import com.lagradost.cloudstream3.extractors.DesuOdvip
|
|
|
|
import com.lagradost.cloudstream3.extractors.Dokicloud
|
|
|
|
import com.lagradost.cloudstream3.extractors.DoodCxExtractor
|
|
|
|
import com.lagradost.cloudstream3.extractors.DoodLaExtractor
|
|
|
|
import com.lagradost.cloudstream3.extractors.DoodPmExtractor
|
|
|
|
import com.lagradost.cloudstream3.extractors.DoodShExtractor
|
|
|
|
import com.lagradost.cloudstream3.extractors.DoodSoExtractor
|
|
|
|
import com.lagradost.cloudstream3.extractors.DoodToExtractor
|
|
|
|
import com.lagradost.cloudstream3.extractors.DoodWatchExtractor
|
|
|
|
import com.lagradost.cloudstream3.extractors.DoodWfExtractor
|
|
|
|
import com.lagradost.cloudstream3.extractors.DoodWsExtractor
|
|
|
|
import com.lagradost.cloudstream3.extractors.DoodYtExtractor
|
|
|
|
import com.lagradost.cloudstream3.extractors.Dooood
|
|
|
|
import com.lagradost.cloudstream3.extractors.Embedgram
|
|
|
|
import com.lagradost.cloudstream3.extractors.Evoload
|
|
|
|
import com.lagradost.cloudstream3.extractors.Evoload1
|
|
|
|
import com.lagradost.cloudstream3.extractors.FEmbed
|
|
|
|
import com.lagradost.cloudstream3.extractors.FEnet
|
|
|
|
import com.lagradost.cloudstream3.extractors.Fastream
|
|
|
|
import com.lagradost.cloudstream3.extractors.FeHD
|
|
|
|
import com.lagradost.cloudstream3.extractors.Fembed9hd
|
|
|
|
import com.lagradost.cloudstream3.extractors.FileMoon
|
|
|
|
import com.lagradost.cloudstream3.extractors.FileMoonIn
|
|
|
|
import com.lagradost.cloudstream3.extractors.FileMoonSx
|
|
|
|
import com.lagradost.cloudstream3.extractors.Filesim
|
|
|
|
import com.lagradost.cloudstream3.extractors.Fplayer
|
|
|
|
import com.lagradost.cloudstream3.extractors.GMPlayer
|
|
|
|
import com.lagradost.cloudstream3.extractors.Gdriveplayer
|
|
|
|
import com.lagradost.cloudstream3.extractors.Gdriveplayerapi
|
|
|
|
import com.lagradost.cloudstream3.extractors.Gdriveplayerapp
|
|
|
|
import com.lagradost.cloudstream3.extractors.Gdriveplayerbiz
|
|
|
|
import com.lagradost.cloudstream3.extractors.Gdriveplayerco
|
|
|
|
import com.lagradost.cloudstream3.extractors.Gdriveplayerfun
|
|
|
|
import com.lagradost.cloudstream3.extractors.Gdriveplayerio
|
|
|
|
import com.lagradost.cloudstream3.extractors.Gdriveplayerme
|
|
|
|
import com.lagradost.cloudstream3.extractors.Gdriveplayerorg
|
|
|
|
import com.lagradost.cloudstream3.extractors.Gdriveplayerus
|
|
|
|
import com.lagradost.cloudstream3.extractors.Gofile
|
|
|
|
import com.lagradost.cloudstream3.extractors.GuardareStream
|
|
|
|
import com.lagradost.cloudstream3.extractors.Guccihide
|
|
|
|
import com.lagradost.cloudstream3.extractors.Hxfile
|
|
|
|
import com.lagradost.cloudstream3.extractors.JWPlayer
|
|
|
|
import com.lagradost.cloudstream3.extractors.Jawcloud
|
|
|
|
import com.lagradost.cloudstream3.extractors.Jeniusplay
|
|
|
|
import com.lagradost.cloudstream3.extractors.Keephealth
|
|
|
|
import com.lagradost.cloudstream3.extractors.KotakAnimeid
|
|
|
|
import com.lagradost.cloudstream3.extractors.Kotakajair
|
|
|
|
import com.lagradost.cloudstream3.extractors.Krakenfiles
|
|
|
|
import com.lagradost.cloudstream3.extractors.LayarKaca
|
|
|
|
import com.lagradost.cloudstream3.extractors.Linkbox
|
|
|
|
import com.lagradost.cloudstream3.extractors.Luxubu
|
|
|
|
import com.lagradost.cloudstream3.extractors.Lvturbo
|
|
|
|
import com.lagradost.cloudstream3.extractors.Maxstream
|
|
|
|
import com.lagradost.cloudstream3.extractors.Mcloud
|
|
|
|
import com.lagradost.cloudstream3.extractors.Megacloud
|
|
|
|
import com.lagradost.cloudstream3.extractors.Meownime
|
2023-09-25 11:48:05 +00:00
|
|
|
import com.lagradost.cloudstream3.extractors.Minoplres
|
2023-09-06 20:42:22 +00:00
|
|
|
import com.lagradost.cloudstream3.extractors.MixDrop
|
|
|
|
import com.lagradost.cloudstream3.extractors.MixDropBz
|
|
|
|
import com.lagradost.cloudstream3.extractors.MixDropCh
|
|
|
|
import com.lagradost.cloudstream3.extractors.MixDropTo
|
|
|
|
import com.lagradost.cloudstream3.extractors.Movhide
|
|
|
|
import com.lagradost.cloudstream3.extractors.Moviehab
|
|
|
|
import com.lagradost.cloudstream3.extractors.MoviehabNet
|
|
|
|
import com.lagradost.cloudstream3.extractors.Moviesapi
|
|
|
|
import com.lagradost.cloudstream3.extractors.Moviesm4u
|
|
|
|
import com.lagradost.cloudstream3.extractors.Mp4Upload
|
|
|
|
import com.lagradost.cloudstream3.extractors.Mvidoo
|
|
|
|
import com.lagradost.cloudstream3.extractors.MwvnVizcloudInfo
|
2024-01-03 09:24:12 +00:00
|
|
|
import com.lagradost.cloudstream3.extractors.MyCloud
|
2023-09-06 20:42:22 +00:00
|
|
|
import com.lagradost.cloudstream3.extractors.Neonime7n
|
|
|
|
import com.lagradost.cloudstream3.extractors.Neonime8n
|
2023-12-31 20:31:05 +00:00
|
|
|
import com.lagradost.cloudstream3.extractors.Odnoklassniki
|
|
|
|
import com.lagradost.cloudstream3.extractors.TauVideo
|
|
|
|
import com.lagradost.cloudstream3.extractors.SibNet
|
|
|
|
import com.lagradost.cloudstream3.extractors.ContentX
|
2024-01-17 22:28:17 +00:00
|
|
|
import com.lagradost.cloudstream3.extractors.EmturbovidExtractor
|
2023-12-31 20:31:05 +00:00
|
|
|
import com.lagradost.cloudstream3.extractors.Hotlinger
|
2024-01-08 22:45:53 +00:00
|
|
|
import com.lagradost.cloudstream3.extractors.FourCX
|
2024-02-15 20:42:11 +00:00
|
|
|
import com.lagradost.cloudstream3.extractors.PlayRu
|
|
|
|
import com.lagradost.cloudstream3.extractors.FourPlayRu
|
2023-12-31 20:31:05 +00:00
|
|
|
import com.lagradost.cloudstream3.extractors.HDMomPlayer
|
|
|
|
import com.lagradost.cloudstream3.extractors.HDPlayerSystem
|
|
|
|
import com.lagradost.cloudstream3.extractors.VideoSeyred
|
|
|
|
import com.lagradost.cloudstream3.extractors.PeaceMakerst
|
|
|
|
import com.lagradost.cloudstream3.extractors.HDStreamAble
|
|
|
|
import com.lagradost.cloudstream3.extractors.RapidVid
|
|
|
|
import com.lagradost.cloudstream3.extractors.TRsTX
|
|
|
|
import com.lagradost.cloudstream3.extractors.VidMoxy
|
|
|
|
import com.lagradost.cloudstream3.extractors.PixelDrain
|
|
|
|
import com.lagradost.cloudstream3.extractors.MailRu
|
2024-01-21 14:35:33 +00:00
|
|
|
import com.lagradost.cloudstream3.extractors.Mediafire
|
2023-12-31 20:31:05 +00:00
|
|
|
import com.lagradost.cloudstream3.extractors.OkRuSSL
|
|
|
|
import com.lagradost.cloudstream3.extractors.OkRuHTTP
|
2023-09-06 20:42:22 +00:00
|
|
|
import com.lagradost.cloudstream3.extractors.Okrulink
|
|
|
|
import com.lagradost.cloudstream3.extractors.PlayLtXyz
|
|
|
|
import com.lagradost.cloudstream3.extractors.PlayerVoxzer
|
|
|
|
import com.lagradost.cloudstream3.extractors.Rabbitstream
|
|
|
|
import com.lagradost.cloudstream3.extractors.Rasacintaku
|
|
|
|
import com.lagradost.cloudstream3.extractors.SBfull
|
|
|
|
import com.lagradost.cloudstream3.extractors.Sbasian
|
|
|
|
import com.lagradost.cloudstream3.extractors.Sbface
|
|
|
|
import com.lagradost.cloudstream3.extractors.Sbflix
|
|
|
|
import com.lagradost.cloudstream3.extractors.Sblona
|
|
|
|
import com.lagradost.cloudstream3.extractors.Sblongvu
|
|
|
|
import com.lagradost.cloudstream3.extractors.Sbnet
|
|
|
|
import com.lagradost.cloudstream3.extractors.Sbrapid
|
|
|
|
import com.lagradost.cloudstream3.extractors.Sbsonic
|
|
|
|
import com.lagradost.cloudstream3.extractors.Sbspeed
|
|
|
|
import com.lagradost.cloudstream3.extractors.Sbthe
|
|
|
|
import com.lagradost.cloudstream3.extractors.Sendvid
|
|
|
|
import com.lagradost.cloudstream3.extractors.ShaveTape
|
|
|
|
import com.lagradost.cloudstream3.extractors.Solidfiles
|
|
|
|
import com.lagradost.cloudstream3.extractors.Ssbstream
|
|
|
|
import com.lagradost.cloudstream3.extractors.StreamM4u
|
|
|
|
import com.lagradost.cloudstream3.extractors.StreamSB
|
|
|
|
import com.lagradost.cloudstream3.extractors.StreamSB1
|
|
|
|
import com.lagradost.cloudstream3.extractors.StreamSB10
|
|
|
|
import com.lagradost.cloudstream3.extractors.StreamSB11
|
|
|
|
import com.lagradost.cloudstream3.extractors.StreamSB2
|
|
|
|
import com.lagradost.cloudstream3.extractors.StreamSB3
|
|
|
|
import com.lagradost.cloudstream3.extractors.StreamSB4
|
|
|
|
import com.lagradost.cloudstream3.extractors.StreamSB5
|
|
|
|
import com.lagradost.cloudstream3.extractors.StreamSB6
|
|
|
|
import com.lagradost.cloudstream3.extractors.StreamSB7
|
|
|
|
import com.lagradost.cloudstream3.extractors.StreamSB8
|
|
|
|
import com.lagradost.cloudstream3.extractors.StreamSB9
|
|
|
|
import com.lagradost.cloudstream3.extractors.StreamTape
|
|
|
|
import com.lagradost.cloudstream3.extractors.StreamTapeNet
|
2024-01-08 22:46:19 +00:00
|
|
|
import com.lagradost.cloudstream3.extractors.StreamTapeXyz
|
2024-01-16 17:36:02 +00:00
|
|
|
import com.lagradost.cloudstream3.extractors.StreamWishExtractor
|
2023-09-06 20:42:22 +00:00
|
|
|
import com.lagradost.cloudstream3.extractors.StreamhideCom
|
|
|
|
import com.lagradost.cloudstream3.extractors.StreamhideTo
|
|
|
|
import com.lagradost.cloudstream3.extractors.Streamhub2
|
|
|
|
import com.lagradost.cloudstream3.extractors.Streamlare
|
|
|
|
import com.lagradost.cloudstream3.extractors.StreamoUpload
|
|
|
|
import com.lagradost.cloudstream3.extractors.Streamplay
|
|
|
|
import com.lagradost.cloudstream3.extractors.Streamsss
|
|
|
|
import com.lagradost.cloudstream3.extractors.Supervideo
|
|
|
|
import com.lagradost.cloudstream3.extractors.Tantifilm
|
|
|
|
import com.lagradost.cloudstream3.extractors.Tomatomatela
|
|
|
|
import com.lagradost.cloudstream3.extractors.TomatomatelalClub
|
|
|
|
import com.lagradost.cloudstream3.extractors.Tubeless
|
|
|
|
import com.lagradost.cloudstream3.extractors.Upstream
|
|
|
|
import com.lagradost.cloudstream3.extractors.UpstreamExtractor
|
|
|
|
import com.lagradost.cloudstream3.extractors.Uqload
|
|
|
|
import com.lagradost.cloudstream3.extractors.Uqload1
|
|
|
|
import com.lagradost.cloudstream3.extractors.Uqload2
|
|
|
|
import com.lagradost.cloudstream3.extractors.Userload
|
|
|
|
import com.lagradost.cloudstream3.extractors.Userscloud
|
|
|
|
import com.lagradost.cloudstream3.extractors.Uservideo
|
|
|
|
import com.lagradost.cloudstream3.extractors.Vanfem
|
|
|
|
import com.lagradost.cloudstream3.extractors.Vicloud
|
|
|
|
import com.lagradost.cloudstream3.extractors.VidSrcExtractor
|
|
|
|
import com.lagradost.cloudstream3.extractors.VidSrcExtractor2
|
|
|
|
import com.lagradost.cloudstream3.extractors.VideoVard
|
|
|
|
import com.lagradost.cloudstream3.extractors.VideovardSX
|
|
|
|
import com.lagradost.cloudstream3.extractors.Vidgomunime
|
|
|
|
import com.lagradost.cloudstream3.extractors.Vidgomunimesb
|
2024-01-16 17:36:02 +00:00
|
|
|
import com.lagradost.cloudstream3.extractors.VidhideExtractor
|
2023-09-06 20:42:22 +00:00
|
|
|
import com.lagradost.cloudstream3.extractors.Vidmoly
|
|
|
|
import com.lagradost.cloudstream3.extractors.Vidmolyme
|
|
|
|
import com.lagradost.cloudstream3.extractors.Vido
|
2023-12-08 16:28:16 +00:00
|
|
|
import com.lagradost.cloudstream3.extractors.Vidplay
|
2024-01-03 09:24:12 +00:00
|
|
|
import com.lagradost.cloudstream3.extractors.VidplayOnline
|
2023-09-06 20:42:22 +00:00
|
|
|
import com.lagradost.cloudstream3.extractors.Vidstreamz
|
|
|
|
import com.lagradost.cloudstream3.extractors.Vizcloud
|
|
|
|
import com.lagradost.cloudstream3.extractors.Vizcloud2
|
|
|
|
import com.lagradost.cloudstream3.extractors.VizcloudCloud
|
|
|
|
import com.lagradost.cloudstream3.extractors.VizcloudDigital
|
|
|
|
import com.lagradost.cloudstream3.extractors.VizcloudInfo
|
|
|
|
import com.lagradost.cloudstream3.extractors.VizcloudLive
|
|
|
|
import com.lagradost.cloudstream3.extractors.VizcloudOnline
|
|
|
|
import com.lagradost.cloudstream3.extractors.VizcloudSite
|
|
|
|
import com.lagradost.cloudstream3.extractors.VizcloudXyz
|
|
|
|
import com.lagradost.cloudstream3.extractors.Voe
|
|
|
|
import com.lagradost.cloudstream3.extractors.Watchx
|
|
|
|
import com.lagradost.cloudstream3.extractors.WcoStream
|
|
|
|
import com.lagradost.cloudstream3.extractors.Wibufile
|
|
|
|
import com.lagradost.cloudstream3.extractors.XStreamCdn
|
|
|
|
import com.lagradost.cloudstream3.extractors.YourUpload
|
|
|
|
import com.lagradost.cloudstream3.extractors.YoutubeExtractor
|
|
|
|
import com.lagradost.cloudstream3.extractors.YoutubeMobileExtractor
|
|
|
|
import com.lagradost.cloudstream3.extractors.YoutubeNoCookieExtractor
|
|
|
|
import com.lagradost.cloudstream3.extractors.YoutubeShortLinkExtractor
|
|
|
|
import com.lagradost.cloudstream3.extractors.Yufiles
|
|
|
|
import com.lagradost.cloudstream3.extractors.Zorofile
|
|
|
|
import com.lagradost.cloudstream3.extractors.Zplayer
|
|
|
|
import com.lagradost.cloudstream3.extractors.ZplayerV2
|
|
|
|
import com.lagradost.cloudstream3.extractors.Ztreamhub
|
2022-07-26 02:31:58 +00:00
|
|
|
import com.lagradost.cloudstream3.mvvm.logError
|
2023-09-03 21:32:43 +00:00
|
|
|
import com.lagradost.cloudstream3.mvvm.normalSafeApiCall
|
2022-01-29 21:25:12 +00:00
|
|
|
import kotlinx.coroutines.delay
|
2024-01-17 21:32:22 +00:00
|
|
|
import me.xdrop.fuzzywuzzy.FuzzySearch
|
2021-09-30 15:51:34 +00:00
|
|
|
import org.jsoup.Jsoup
|
2023-09-03 21:32:43 +00:00
|
|
|
import java.net.URL
|
2023-09-06 18:53:43 +00:00
|
|
|
import java.util.UUID
|
2021-05-19 18:44:02 +00:00
|
|
|
|
2022-07-10 02:08:11 +00:00
|
|
|
/**
|
|
|
|
* For use in the ConcatenatingMediaSource.
|
|
|
|
* If features are missing (headers), please report and we can add it.
|
|
|
|
* @param durationUs use Long.toUs() for easier input
|
|
|
|
* */
|
|
|
|
data class PlayListItem(
|
|
|
|
val url: String,
|
|
|
|
val durationUs: Long,
|
|
|
|
)
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Converts Seconds to MicroSeconds, multiplication by 1_000_000
|
|
|
|
* */
|
|
|
|
fun Long.toUs(): Long {
|
|
|
|
return this * 1_000_000
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* If your site has an unorthodox m3u8-like system where there are multiple smaller videos concatenated
|
|
|
|
* use this.
|
|
|
|
* */
|
|
|
|
data class ExtractorLinkPlayList(
|
|
|
|
override val source: String,
|
|
|
|
override val name: String,
|
|
|
|
val playlist: List<PlayListItem>,
|
|
|
|
override val referer: String,
|
|
|
|
override val quality: Int,
|
|
|
|
override val headers: Map<String, String> = mapOf(),
|
|
|
|
/** Used for getExtractorVerifierJob() */
|
|
|
|
override val extractorData: String? = null,
|
2023-09-03 21:32:43 +00:00
|
|
|
override val type: ExtractorLinkType,
|
2022-07-16 19:35:58 +00:00
|
|
|
) : ExtractorLink(
|
2023-09-03 21:32:43 +00:00
|
|
|
source = source,
|
|
|
|
name = name,
|
|
|
|
url = "",
|
|
|
|
referer = referer,
|
|
|
|
quality = quality,
|
|
|
|
headers = headers,
|
|
|
|
extractorData = extractorData,
|
|
|
|
type = type
|
|
|
|
) {
|
|
|
|
constructor(
|
|
|
|
source: String,
|
|
|
|
name: String,
|
|
|
|
playlist: List<PlayListItem>,
|
|
|
|
referer: String,
|
|
|
|
quality: Int,
|
|
|
|
isM3u8: Boolean = false,
|
|
|
|
headers: Map<String, String> = mapOf(),
|
|
|
|
extractorData: String? = null,
|
|
|
|
) : this(
|
|
|
|
source = source,
|
|
|
|
name = name,
|
|
|
|
playlist = playlist,
|
|
|
|
referer = referer,
|
|
|
|
quality = quality,
|
|
|
|
type = if (isM3u8) ExtractorLinkType.M3U8 else ExtractorLinkType.VIDEO,
|
|
|
|
headers = headers,
|
|
|
|
extractorData = extractorData,
|
|
|
|
)
|
|
|
|
}
|
2022-07-10 02:08:11 +00:00
|
|
|
|
2023-09-03 21:32:43 +00:00
|
|
|
/** Metadata about the file type used for downloads and exoplayer hint,
|
|
|
|
* if you respond with the wrong one the file will fail to download or be played */
|
|
|
|
enum class ExtractorLinkType {
|
|
|
|
/** Single stream of bytes no matter the actual file type */
|
|
|
|
VIDEO,
|
|
|
|
/** Split into several .ts files, has support for encrypted m3u8s */
|
|
|
|
M3U8,
|
|
|
|
/** Like m3u8 but uses xml, currently no download support */
|
|
|
|
DASH,
|
|
|
|
/** No support at the moment */
|
|
|
|
TORRENT,
|
|
|
|
/** No support at the moment */
|
|
|
|
MAGNET,
|
|
|
|
}
|
2022-07-10 02:08:11 +00:00
|
|
|
|
2023-09-03 21:32:43 +00:00
|
|
|
private fun inferTypeFromUrl(url: String): ExtractorLinkType {
|
|
|
|
val path = normalSafeApiCall { URL(url).path }
|
|
|
|
return when {
|
|
|
|
path?.endsWith(".m3u8") == true -> ExtractorLinkType.M3U8
|
|
|
|
path?.endsWith(".mpd") == true -> ExtractorLinkType.DASH
|
|
|
|
path?.endsWith(".torrent") == true -> ExtractorLinkType.TORRENT
|
|
|
|
url.startsWith("magnet:") -> ExtractorLinkType.MAGNET
|
|
|
|
else -> ExtractorLinkType.VIDEO
|
|
|
|
}
|
|
|
|
}
|
|
|
|
val INFER_TYPE : ExtractorLinkType? = null
|
2023-09-06 18:53:43 +00:00
|
|
|
|
2023-09-06 20:42:22 +00:00
|
|
|
/**
|
|
|
|
* UUID for the ClearKey DRM scheme.
|
|
|
|
*
|
|
|
|
*
|
|
|
|
* ClearKey is supported on Android devices running Android 5.0 (API Level 21) and up.
|
|
|
|
*/
|
|
|
|
val CLEARKEY_UUID = UUID(-0x1d8e62a7567a4c37L, 0x781AB030AF78D30EL)
|
|
|
|
|
|
|
|
/**
|
|
|
|
* UUID for the Widevine DRM scheme.
|
|
|
|
*
|
|
|
|
*
|
|
|
|
* Widevine is supported on Android devices running Android 4.3 (API Level 18) and up.
|
|
|
|
*/
|
|
|
|
val WIDEVINE_UUID = UUID(-0x121074568629b532L, -0x5c37d8232ae2de13L)
|
|
|
|
|
|
|
|
/**
|
|
|
|
* UUID for the PlayReady DRM scheme.
|
|
|
|
*
|
|
|
|
*
|
|
|
|
* PlayReady is supported on all AndroidTV devices. Note that most other Android devices do not
|
|
|
|
* provide PlayReady support.
|
|
|
|
*/
|
|
|
|
val PLAYREADY_UUID = UUID(-0x65fb0f8667bfbd7aL, -0x546d19a41f77a06bL)
|
|
|
|
|
2023-09-06 18:53:43 +00:00
|
|
|
open class DrmExtractorLink private constructor(
|
|
|
|
override val source: String,
|
|
|
|
override val name: String,
|
|
|
|
override val url: String,
|
|
|
|
override val referer: String,
|
|
|
|
override val quality: Int,
|
|
|
|
override val headers: Map<String, String> = mapOf(),
|
|
|
|
/** Used for getExtractorVerifierJob() */
|
|
|
|
override val extractorData: String? = null,
|
|
|
|
override val type: ExtractorLinkType,
|
|
|
|
open val kid : String,
|
|
|
|
open val key : String,
|
2023-09-06 20:42:22 +00:00
|
|
|
open val uuid : UUID,
|
2023-09-06 18:53:43 +00:00
|
|
|
open val kty : String,
|
|
|
|
|
|
|
|
open val keyRequestParameters : HashMap<String, String>
|
|
|
|
) : ExtractorLink(
|
|
|
|
source, name, url, referer, quality, type, headers, extractorData
|
|
|
|
) {
|
|
|
|
constructor(
|
|
|
|
source: String,
|
|
|
|
name: String,
|
|
|
|
url: String,
|
|
|
|
referer: String,
|
|
|
|
quality: Int,
|
|
|
|
/** the type of the media, use INFER_TYPE if you want to auto infer the type from the url */
|
|
|
|
type: ExtractorLinkType?,
|
|
|
|
headers: Map<String, String> = mapOf(),
|
|
|
|
/** Used for getExtractorVerifierJob() */
|
|
|
|
extractorData: String? = null,
|
|
|
|
kid : String,
|
|
|
|
key : String,
|
2023-09-06 20:42:22 +00:00
|
|
|
uuid : UUID = CLEARKEY_UUID,
|
2023-09-06 18:53:43 +00:00
|
|
|
kty : String = "oct",
|
|
|
|
keyRequestParameters : HashMap<String, String> = hashMapOf(),
|
|
|
|
) : this(
|
|
|
|
source = source,
|
|
|
|
name = name,
|
|
|
|
url = url,
|
|
|
|
referer = referer,
|
|
|
|
quality = quality,
|
|
|
|
headers = headers,
|
|
|
|
extractorData = extractorData,
|
|
|
|
type = type ?: inferTypeFromUrl(url),
|
|
|
|
kid = kid,
|
|
|
|
key = key,
|
|
|
|
uuid = uuid,
|
|
|
|
keyRequestParameters = keyRequestParameters,
|
|
|
|
kty = kty,
|
|
|
|
)
|
|
|
|
}
|
|
|
|
|
2023-03-10 19:45:11 +00:00
|
|
|
open class ExtractorLink constructor(
|
2022-07-10 02:08:11 +00:00
|
|
|
open val source: String,
|
|
|
|
open val name: String,
|
2021-08-22 17:14:48 +00:00
|
|
|
override val url: String,
|
|
|
|
override val referer: String,
|
2022-07-10 02:08:11 +00:00
|
|
|
open val quality: Int,
|
2022-02-11 09:17:04 +00:00
|
|
|
override val headers: Map<String, String> = mapOf(),
|
|
|
|
/** Used for getExtractorVerifierJob() */
|
2022-07-10 02:08:11 +00:00
|
|
|
open val extractorData: String? = null,
|
2023-09-03 21:32:43 +00:00
|
|
|
open val type: ExtractorLinkType,
|
2022-07-11 20:42:48 +00:00
|
|
|
) : VideoDownloadManager.IDownloadableMinimum {
|
2023-09-09 21:53:35 +00:00
|
|
|
val isM3u8 : Boolean get() = type == ExtractorLinkType.M3U8
|
|
|
|
val isDash : Boolean get() = type == ExtractorLinkType.DASH
|
2023-11-05 22:33:11 +00:00
|
|
|
|
|
|
|
@JsonIgnore
|
2023-10-03 14:50:34 +00:00
|
|
|
fun getAllHeaders() : Map<String, String> {
|
|
|
|
if (referer.isBlank()) {
|
|
|
|
return headers
|
|
|
|
} else if (headers.keys.none { it.equals("referer", ignoreCase = true) }) {
|
|
|
|
return headers + mapOf("referer" to referer)
|
|
|
|
}
|
|
|
|
return headers
|
|
|
|
}
|
|
|
|
|
2023-09-03 21:32:43 +00:00
|
|
|
constructor(
|
|
|
|
source: String,
|
|
|
|
name: String,
|
|
|
|
url: String,
|
|
|
|
referer: String,
|
|
|
|
quality: Int,
|
|
|
|
/** the type of the media, use INFER_TYPE if you want to auto infer the type from the url */
|
|
|
|
type: ExtractorLinkType?,
|
|
|
|
headers: Map<String, String> = mapOf(),
|
|
|
|
/** Used for getExtractorVerifierJob() */
|
|
|
|
extractorData: String? = null,
|
|
|
|
) : this(
|
|
|
|
source = source,
|
|
|
|
name = name,
|
|
|
|
url = url,
|
|
|
|
referer = referer,
|
|
|
|
quality = quality,
|
|
|
|
headers = headers,
|
|
|
|
extractorData = extractorData,
|
|
|
|
type = type ?: inferTypeFromUrl(url)
|
|
|
|
)
|
|
|
|
|
2023-03-10 19:45:11 +00:00
|
|
|
/**
|
|
|
|
* Old constructor without isDash, allows for backwards compatibility with extensions.
|
|
|
|
* Should be removed after all extensions have updated their cloudstream.jar
|
|
|
|
**/
|
|
|
|
constructor(
|
|
|
|
source: String,
|
|
|
|
name: String,
|
|
|
|
url: String,
|
|
|
|
referer: String,
|
|
|
|
quality: Int,
|
|
|
|
isM3u8: Boolean = false,
|
|
|
|
headers: Map<String, String> = mapOf(),
|
|
|
|
/** Used for getExtractorVerifierJob() */
|
|
|
|
extractorData: String? = null
|
|
|
|
) : this(source, name, url, referer, quality, isM3u8, headers, extractorData, false)
|
|
|
|
|
2023-09-03 21:32:43 +00:00
|
|
|
constructor(
|
|
|
|
source: String,
|
|
|
|
name: String,
|
|
|
|
url: String,
|
|
|
|
referer: String,
|
|
|
|
quality: Int,
|
|
|
|
isM3u8: Boolean = false,
|
|
|
|
headers: Map<String, String> = mapOf(),
|
|
|
|
/** Used for getExtractorVerifierJob() */
|
|
|
|
extractorData: String? = null,
|
|
|
|
isDash: Boolean,
|
|
|
|
) : this(
|
|
|
|
source = source,
|
|
|
|
name = name,
|
|
|
|
url = url,
|
|
|
|
referer = referer,
|
|
|
|
quality = quality,
|
|
|
|
headers = headers,
|
|
|
|
extractorData = extractorData,
|
|
|
|
type = if (isDash) ExtractorLinkType.DASH else if (isM3u8) ExtractorLinkType.M3U8 else ExtractorLinkType.VIDEO
|
|
|
|
)
|
|
|
|
|
2022-07-11 20:42:48 +00:00
|
|
|
override fun toString(): String {
|
2023-09-03 21:32:43 +00:00
|
|
|
return "ExtractorLink(name=$name, url=$url, referer=$referer, type=$type)"
|
2022-07-11 20:42:48 +00:00
|
|
|
}
|
|
|
|
}
|
2021-05-19 18:44:02 +00:00
|
|
|
|
2022-01-07 19:27:25 +00:00
|
|
|
data class ExtractorUri(
|
2022-04-18 18:49:17 +00:00
|
|
|
val uri: Uri,
|
|
|
|
val name: String,
|
2022-01-07 19:27:25 +00:00
|
|
|
|
|
|
|
val basePath: String? = null,
|
|
|
|
val relativePath: String? = null,
|
|
|
|
val displayName: String? = null,
|
|
|
|
|
2022-04-18 18:49:17 +00:00
|
|
|
val id: Int? = null,
|
|
|
|
val parentId: Int? = null,
|
|
|
|
val episode: Int? = null,
|
|
|
|
val season: Int? = null,
|
|
|
|
val headerName: String? = null,
|
2022-01-07 19:27:25 +00:00
|
|
|
val tvType: TvType? = null,
|
|
|
|
)
|
|
|
|
|
2021-08-22 17:14:48 +00:00
|
|
|
data class ExtractorSubtitleLink(
|
|
|
|
val name: String,
|
|
|
|
override val url: String,
|
|
|
|
override val referer: String,
|
2021-09-11 18:44:37 +00:00
|
|
|
override val headers: Map<String, String> = mapOf()
|
2021-08-22 17:14:48 +00:00
|
|
|
) : VideoDownloadManager.IDownloadableMinimum
|
2021-05-28 13:38:06 +00:00
|
|
|
|
2022-07-16 19:35:58 +00:00
|
|
|
/**
|
|
|
|
* Removes https:// and www.
|
|
|
|
* To match urls regardless of schema, perhaps Uri() can be used?
|
|
|
|
*/
|
|
|
|
val schemaStripRegex = Regex("""^(https:|)//(www\.|)""")
|
|
|
|
|
2023-06-14 17:30:39 +00:00
|
|
|
enum class Qualities(var value: Int, val defaultPriority: Int) {
|
|
|
|
Unknown(400, 4),
|
|
|
|
P144(144, 0), // 144p
|
|
|
|
P240(240, 2), // 240p
|
|
|
|
P360(360, 3), // 360p
|
|
|
|
P480(480, 4), // 480p
|
|
|
|
P720(720, 5), // 720p
|
|
|
|
P1080(1080, 6), // 1080p
|
|
|
|
P1440(1440, 7), // 1440p
|
|
|
|
P2160(2160, 8); // 4k or 2160p
|
2022-04-15 13:06:43 +00:00
|
|
|
|
|
|
|
companion object {
|
2022-04-18 18:49:17 +00:00
|
|
|
fun getStringByInt(qual: Int?): String {
|
2022-04-15 13:06:43 +00:00
|
|
|
return when (qual) {
|
2022-04-18 22:00:49 +00:00
|
|
|
0 -> "Auto"
|
2022-04-18 18:49:17 +00:00
|
|
|
Unknown.value -> ""
|
|
|
|
P2160.value -> "4K"
|
2022-05-30 12:13:11 +00:00
|
|
|
null -> ""
|
2022-04-18 18:49:17 +00:00
|
|
|
else -> "${qual}p"
|
2022-04-15 13:06:43 +00:00
|
|
|
}
|
|
|
|
}
|
2023-09-03 21:32:43 +00:00
|
|
|
|
2023-06-14 17:30:39 +00:00
|
|
|
fun getStringByIntFull(quality: Int): String {
|
|
|
|
return when (quality) {
|
|
|
|
0 -> "Auto"
|
|
|
|
Unknown.value -> "Unknown"
|
|
|
|
P2160.value -> "4K"
|
|
|
|
else -> "${quality}p"
|
|
|
|
}
|
|
|
|
}
|
2022-04-15 13:06:43 +00:00
|
|
|
}
|
2021-05-19 18:44:02 +00:00
|
|
|
}
|
|
|
|
|
2022-04-15 13:06:43 +00:00
|
|
|
fun getQualityFromName(qualityName: String?): Int {
|
2022-04-18 18:49:17 +00:00
|
|
|
if (qualityName == null)
|
2022-04-15 13:06:43 +00:00
|
|
|
return Qualities.Unknown.value
|
2022-04-18 18:49:17 +00:00
|
|
|
|
|
|
|
val match = qualityName.lowercase().replace("p", "").trim()
|
|
|
|
return when (match) {
|
2021-08-24 21:06:40 +00:00
|
|
|
"4k" -> Qualities.P2160
|
2022-04-18 18:49:17 +00:00
|
|
|
else -> null
|
|
|
|
}?.value ?: match.toIntOrNull() ?: Qualities.Unknown.value
|
2021-06-16 22:31:41 +00:00
|
|
|
}
|
|
|
|
|
2021-05-19 18:44:02 +00:00
|
|
|
private val packedRegex = Regex("""eval\(function\(p,a,c,k,e,.*\)\)""")
|
|
|
|
fun getPacked(string: String): String? {
|
|
|
|
return packedRegex.find(string)?.value
|
|
|
|
}
|
|
|
|
|
2021-09-25 10:07:40 +00:00
|
|
|
fun getAndUnpack(string: String): String {
|
2021-05-19 18:44:02 +00:00
|
|
|
val packedText = getPacked(string)
|
2021-09-25 10:07:40 +00:00
|
|
|
return JsUnpacker(packedText).unpack() ?: string
|
2021-05-19 18:44:02 +00:00
|
|
|
}
|
|
|
|
|
2022-07-27 16:27:49 +00:00
|
|
|
suspend fun unshortenLinkSafe(url: String): String {
|
2022-07-26 02:31:58 +00:00
|
|
|
return try {
|
|
|
|
if (ShortLink.isShortLink(url))
|
|
|
|
ShortLink.unshorten(url)
|
|
|
|
else url
|
|
|
|
} catch (e: Exception) {
|
|
|
|
logError(e)
|
|
|
|
url
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-07-27 17:36:31 +00:00
|
|
|
suspend fun loadExtractor(
|
|
|
|
url: String,
|
|
|
|
subtitleCallback: (SubtitleFile) -> Unit,
|
|
|
|
callback: (ExtractorLink) -> Unit
|
|
|
|
): Boolean {
|
|
|
|
return loadExtractor(
|
|
|
|
url = url,
|
|
|
|
referer = null,
|
|
|
|
subtitleCallback = subtitleCallback,
|
|
|
|
callback = callback
|
|
|
|
)
|
|
|
|
}
|
|
|
|
|
2021-12-12 01:49:41 +00:00
|
|
|
/**
|
|
|
|
* Tries to load the appropriate extractor based on link, returns true if any extractor is loaded.
|
|
|
|
* */
|
2022-04-18 18:49:17 +00:00
|
|
|
suspend fun loadExtractor(
|
|
|
|
url: String,
|
|
|
|
referer: String? = null,
|
2022-07-27 17:36:31 +00:00
|
|
|
subtitleCallback: (SubtitleFile) -> Unit,
|
2022-04-18 18:49:17 +00:00
|
|
|
callback: (ExtractorLink) -> Unit
|
|
|
|
): Boolean {
|
2022-07-26 02:31:58 +00:00
|
|
|
val currentUrl = unshortenLinkSafe(url)
|
2022-07-27 17:54:53 +00:00
|
|
|
val compareUrl = currentUrl.lowercase().replace(schemaStripRegex, "")
|
2021-08-25 22:16:20 +00:00
|
|
|
for (extractor in extractorApis) {
|
2022-07-27 17:54:53 +00:00
|
|
|
if (compareUrl.startsWith(extractor.mainUrl.replace(schemaStripRegex, ""))) {
|
2022-07-27 17:36:31 +00:00
|
|
|
extractor.getSafeUrl(currentUrl, referer, subtitleCallback, callback)
|
2021-12-12 01:49:41 +00:00
|
|
|
return true
|
2021-08-25 22:16:20 +00:00
|
|
|
}
|
|
|
|
}
|
2022-07-26 02:31:58 +00:00
|
|
|
|
2024-01-17 21:32:22 +00:00
|
|
|
// this is to match mirror domains - like example.com, example.net
|
|
|
|
for (extractor in extractorApis) {
|
|
|
|
if (FuzzySearch.partialRatio(
|
|
|
|
extractor.mainUrl,
|
|
|
|
currentUrl
|
|
|
|
) > 80
|
|
|
|
) {
|
|
|
|
extractor.getSafeUrl(currentUrl, referer, subtitleCallback, callback)
|
|
|
|
return true
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-12-12 01:49:41 +00:00
|
|
|
return false
|
2021-08-25 22:16:20 +00:00
|
|
|
}
|
|
|
|
|
2022-08-20 07:46:57 +00:00
|
|
|
val extractorApis: MutableList<ExtractorApi> = arrayListOf(
|
|
|
|
//AllProvider(),
|
|
|
|
WcoStream(),
|
|
|
|
Vidstreamz(),
|
|
|
|
Vizcloud(),
|
|
|
|
Vizcloud2(),
|
|
|
|
VizcloudOnline(),
|
|
|
|
VizcloudXyz(),
|
|
|
|
VizcloudLive(),
|
|
|
|
VizcloudInfo(),
|
|
|
|
MwvnVizcloudInfo(),
|
|
|
|
VizcloudDigital(),
|
|
|
|
VizcloudCloud(),
|
|
|
|
VizcloudSite(),
|
|
|
|
VideoVard(),
|
|
|
|
VideovardSX(),
|
|
|
|
Mp4Upload(),
|
|
|
|
StreamTape(),
|
2022-11-06 11:13:45 +00:00
|
|
|
StreamTapeNet(),
|
|
|
|
ShaveTape(),
|
2024-01-08 22:46:19 +00:00
|
|
|
StreamTapeXyz(),
|
2022-08-20 07:46:57 +00:00
|
|
|
|
|
|
|
//mixdrop extractors
|
|
|
|
MixDropBz(),
|
|
|
|
MixDropCh(),
|
|
|
|
MixDropTo(),
|
|
|
|
|
|
|
|
MixDrop(),
|
|
|
|
|
|
|
|
Mcloud(),
|
|
|
|
XStreamCdn(),
|
|
|
|
|
|
|
|
StreamSB(),
|
2023-07-09 23:52:03 +00:00
|
|
|
Sblona(),
|
2023-05-20 23:37:17 +00:00
|
|
|
Vidgomunimesb(),
|
2022-08-20 07:46:57 +00:00
|
|
|
StreamSB1(),
|
|
|
|
StreamSB2(),
|
|
|
|
StreamSB3(),
|
|
|
|
StreamSB4(),
|
|
|
|
StreamSB5(),
|
|
|
|
StreamSB6(),
|
|
|
|
StreamSB7(),
|
|
|
|
StreamSB8(),
|
|
|
|
StreamSB9(),
|
|
|
|
StreamSB10(),
|
2023-02-25 21:18:48 +00:00
|
|
|
StreamSB11(),
|
2022-08-20 07:46:57 +00:00
|
|
|
SBfull(),
|
|
|
|
// Streamhub(), cause Streamhub2() works
|
|
|
|
Streamhub2(),
|
|
|
|
Ssbstream(),
|
2022-08-26 12:07:53 +00:00
|
|
|
Sbthe(),
|
2022-09-02 16:19:20 +00:00
|
|
|
Vidgomunime(),
|
2022-09-12 19:38:33 +00:00
|
|
|
Sbflix(),
|
2022-09-14 09:43:35 +00:00
|
|
|
Streamsss(),
|
2022-10-26 15:38:46 +00:00
|
|
|
Sbspeed(),
|
2023-07-09 23:52:03 +00:00
|
|
|
Sbsonic(),
|
|
|
|
Sbface(),
|
|
|
|
Sbrapid(),
|
|
|
|
Lvturbo(),
|
2022-08-20 07:46:57 +00:00
|
|
|
|
|
|
|
Fastream(),
|
2022-09-04 23:13:17 +00:00
|
|
|
|
2022-08-20 07:46:57 +00:00
|
|
|
FEmbed(),
|
|
|
|
FeHD(),
|
|
|
|
Fplayer(),
|
|
|
|
DBfilm(),
|
|
|
|
Luxubu(),
|
|
|
|
LayarKaca(),
|
2022-08-31 14:54:39 +00:00
|
|
|
Rasacintaku(),
|
2022-09-04 23:13:17 +00:00
|
|
|
FEnet(),
|
2022-10-26 15:38:46 +00:00
|
|
|
Kotakajair(),
|
|
|
|
Cdnplayer(),
|
2022-08-20 07:46:57 +00:00
|
|
|
// WatchSB(), 'cause StreamSB.kt works
|
|
|
|
Uqload(),
|
|
|
|
Uqload1(),
|
2023-02-25 21:18:48 +00:00
|
|
|
Uqload2(),
|
2022-08-20 07:46:57 +00:00
|
|
|
Evoload(),
|
|
|
|
Evoload1(),
|
2022-09-04 23:13:17 +00:00
|
|
|
UpstreamExtractor(),
|
2022-08-20 07:46:57 +00:00
|
|
|
|
2023-12-31 20:31:05 +00:00
|
|
|
Odnoklassniki(),
|
|
|
|
TauVideo(),
|
|
|
|
SibNet(),
|
|
|
|
ContentX(),
|
|
|
|
Hotlinger(),
|
2024-01-08 22:45:53 +00:00
|
|
|
FourCX(),
|
2024-02-15 20:42:11 +00:00
|
|
|
PlayRu(),
|
|
|
|
FourPlayRu(),
|
2023-12-31 20:31:05 +00:00
|
|
|
HDMomPlayer(),
|
|
|
|
HDPlayerSystem(),
|
|
|
|
VideoSeyred(),
|
|
|
|
PeaceMakerst(),
|
|
|
|
HDStreamAble(),
|
|
|
|
RapidVid(),
|
|
|
|
TRsTX(),
|
|
|
|
VidMoxy(),
|
|
|
|
PixelDrain(),
|
|
|
|
MailRu(),
|
|
|
|
|
2022-08-20 07:46:57 +00:00
|
|
|
Tomatomatela(),
|
2023-01-21 09:25:06 +00:00
|
|
|
TomatomatelalClub(),
|
2022-08-20 07:46:57 +00:00
|
|
|
Cinestart(),
|
2023-12-31 20:31:05 +00:00
|
|
|
OkRuSSL(),
|
|
|
|
OkRuHTTP(),
|
2023-01-21 09:25:06 +00:00
|
|
|
Okrulink(),
|
2023-02-14 15:11:20 +00:00
|
|
|
Sendvid(),
|
2022-08-20 07:46:57 +00:00
|
|
|
|
|
|
|
// dood extractors
|
|
|
|
DoodCxExtractor(),
|
|
|
|
DoodPmExtractor(),
|
|
|
|
DoodToExtractor(),
|
|
|
|
DoodSoExtractor(),
|
|
|
|
DoodLaExtractor(),
|
2023-07-09 23:52:03 +00:00
|
|
|
Dooood(),
|
2022-08-20 07:46:57 +00:00
|
|
|
DoodWsExtractor(),
|
|
|
|
DoodShExtractor(),
|
|
|
|
DoodWatchExtractor(),
|
2022-09-12 19:38:33 +00:00
|
|
|
DoodWfExtractor(),
|
2023-02-25 21:18:48 +00:00
|
|
|
DoodYtExtractor(),
|
2022-08-20 07:46:57 +00:00
|
|
|
|
|
|
|
AsianLoad(),
|
|
|
|
|
|
|
|
// GenericM3U8(),
|
|
|
|
Jawcloud(),
|
|
|
|
Zplayer(),
|
|
|
|
ZplayerV2(),
|
|
|
|
Upstream(),
|
|
|
|
|
|
|
|
Maxstream(),
|
|
|
|
Tantifilm(),
|
|
|
|
Userload(),
|
|
|
|
Supervideo(),
|
|
|
|
GuardareStream(),
|
2022-10-16 17:42:32 +00:00
|
|
|
CineGrabber(),
|
2023-01-29 22:51:25 +00:00
|
|
|
Vanfem(),
|
2022-08-20 07:46:57 +00:00
|
|
|
|
|
|
|
// StreamSB.kt works
|
|
|
|
// SBPlay(),
|
|
|
|
// SBPlay1(),
|
|
|
|
// SBPlay2(),
|
|
|
|
|
|
|
|
PlayerVoxzer(),
|
|
|
|
|
|
|
|
BullStream(),
|
|
|
|
GMPlayer(),
|
|
|
|
|
|
|
|
Blogger(),
|
|
|
|
Solidfiles(),
|
|
|
|
YourUpload(),
|
|
|
|
|
|
|
|
Hxfile(),
|
|
|
|
KotakAnimeid(),
|
|
|
|
Neonime8n(),
|
|
|
|
Neonime7n(),
|
|
|
|
Yufiles(),
|
|
|
|
Aico(),
|
|
|
|
|
|
|
|
JWPlayer(),
|
|
|
|
Meownime(),
|
|
|
|
DesuArcg(),
|
|
|
|
DesuOdchan(),
|
|
|
|
DesuOdvip(),
|
|
|
|
DesuDrive(),
|
|
|
|
|
2023-05-14 16:19:04 +00:00
|
|
|
Chillx(),
|
2023-07-12 16:15:25 +00:00
|
|
|
Moviesapi(),
|
2023-05-14 16:19:04 +00:00
|
|
|
Watchx(),
|
|
|
|
Bestx(),
|
|
|
|
Keephealth(),
|
|
|
|
Sbnet(),
|
|
|
|
Sbasian(),
|
|
|
|
Sblongvu(),
|
|
|
|
Fembed9hd(),
|
|
|
|
StreamM4u(),
|
|
|
|
Krakenfiles(),
|
|
|
|
Gofile(),
|
|
|
|
Vicloud(),
|
|
|
|
Uservideo(),
|
2023-08-01 13:50:02 +00:00
|
|
|
Userscloud(),
|
2023-05-14 16:19:04 +00:00
|
|
|
|
|
|
|
Movhide(),
|
|
|
|
StreamhideCom(),
|
2023-07-09 23:52:03 +00:00
|
|
|
StreamhideTo(),
|
|
|
|
Wibufile(),
|
2023-05-14 16:19:04 +00:00
|
|
|
FileMoonIn(),
|
|
|
|
Moviesm4u(),
|
2022-08-20 07:46:57 +00:00
|
|
|
Filesim(),
|
2023-07-09 23:52:03 +00:00
|
|
|
Ahvsh(),
|
|
|
|
Guccihide(),
|
2023-01-29 22:51:25 +00:00
|
|
|
FileMoon(),
|
2023-02-25 21:18:48 +00:00
|
|
|
FileMoonSx(),
|
|
|
|
Vido(),
|
2022-08-20 07:46:57 +00:00
|
|
|
Linkbox(),
|
|
|
|
Acefile(),
|
2023-09-25 11:48:05 +00:00
|
|
|
Minoplres(), // formerly SpeedoStream
|
2022-08-26 12:07:53 +00:00
|
|
|
Zorofile(),
|
2022-09-04 23:13:17 +00:00
|
|
|
Embedgram(),
|
|
|
|
Mvidoo(),
|
|
|
|
Streamplay(),
|
2022-10-10 19:43:56 +00:00
|
|
|
Vidmoly(),
|
|
|
|
Vidmolyme(),
|
|
|
|
Voe(),
|
2023-05-20 23:37:17 +00:00
|
|
|
Tubeless(),
|
2022-10-26 15:38:46 +00:00
|
|
|
Moviehab(),
|
2022-10-31 19:47:15 +00:00
|
|
|
MoviehabNet(),
|
|
|
|
Jeniusplay(),
|
2023-07-24 02:01:50 +00:00
|
|
|
StreamoUpload(),
|
2022-08-20 07:46:57 +00:00
|
|
|
|
2022-09-12 19:38:33 +00:00
|
|
|
Gdriveplayerapi(),
|
|
|
|
Gdriveplayerapp(),
|
|
|
|
Gdriveplayerfun(),
|
|
|
|
Gdriveplayerio(),
|
|
|
|
Gdriveplayerme(),
|
|
|
|
Gdriveplayerbiz(),
|
|
|
|
Gdriveplayerorg(),
|
|
|
|
Gdriveplayerus(),
|
|
|
|
Gdriveplayerco(),
|
|
|
|
Gdriveplayer(),
|
2022-09-14 09:43:35 +00:00
|
|
|
DatabaseGdrive(),
|
2022-10-26 15:38:46 +00:00
|
|
|
DatabaseGdrive2(),
|
2024-01-21 14:35:33 +00:00
|
|
|
Mediafire(),
|
2022-09-12 19:38:33 +00:00
|
|
|
|
2022-08-20 07:46:57 +00:00
|
|
|
YoutubeExtractor(),
|
|
|
|
YoutubeShortLinkExtractor(),
|
|
|
|
YoutubeMobileExtractor(),
|
|
|
|
YoutubeNoCookieExtractor(),
|
|
|
|
Streamlare(),
|
|
|
|
VidSrcExtractor(),
|
|
|
|
VidSrcExtractor2(),
|
2022-09-04 18:54:54 +00:00
|
|
|
PlayLtXyz(),
|
2022-10-01 13:06:39 +00:00
|
|
|
AStreamHub(),
|
2023-12-08 16:28:16 +00:00
|
|
|
Vidplay(),
|
2024-01-03 09:24:12 +00:00
|
|
|
VidplayOnline(),
|
|
|
|
MyCloud(),
|
2023-01-02 11:42:58 +00:00
|
|
|
|
2023-01-14 12:07:21 +00:00
|
|
|
Cda(),
|
|
|
|
Dailymotion(),
|
2023-01-27 23:44:00 +00:00
|
|
|
ByteShare(),
|
2023-08-05 01:11:46 +00:00
|
|
|
Ztreamhub(),
|
|
|
|
Rabbitstream(),
|
|
|
|
Dokicloud(),
|
|
|
|
Megacloud(),
|
2024-01-16 17:36:02 +00:00
|
|
|
VidhideExtractor(),
|
2024-01-17 22:28:17 +00:00
|
|
|
StreamWishExtractor(),
|
|
|
|
EmturbovidExtractor()
|
2022-08-20 07:46:57 +00:00
|
|
|
)
|
|
|
|
|
2021-05-19 18:44:02 +00:00
|
|
|
|
2021-05-20 15:22:28 +00:00
|
|
|
fun getExtractorApiFromName(name: String): ExtractorApi {
|
|
|
|
for (api in extractorApis) {
|
|
|
|
if (api.name == name) return api
|
|
|
|
}
|
|
|
|
return extractorApis[0]
|
|
|
|
}
|
|
|
|
|
|
|
|
fun requireReferer(name: String): Boolean {
|
|
|
|
return getExtractorApiFromName(name).requiresReferer
|
|
|
|
}
|
|
|
|
|
2021-05-19 18:44:02 +00:00
|
|
|
fun httpsify(url: String): String {
|
|
|
|
return if (url.startsWith("//")) "https:$url" else url
|
|
|
|
}
|
|
|
|
|
2022-04-18 18:49:17 +00:00
|
|
|
suspend fun getPostForm(requestUrl: String, html: String): String? {
|
2021-09-30 15:51:34 +00:00
|
|
|
val document = Jsoup.parse(html)
|
|
|
|
val inputs = document.select("Form > input")
|
|
|
|
if (inputs.size < 4) return null
|
|
|
|
var op: String? = null
|
|
|
|
var id: String? = null
|
|
|
|
var mode: String? = null
|
|
|
|
var hash: String? = null
|
|
|
|
|
|
|
|
for (input in inputs) {
|
|
|
|
val value = input.attr("value") ?: continue
|
|
|
|
when (input.attr("name")) {
|
|
|
|
"op" -> op = value
|
|
|
|
"id" -> id = value
|
|
|
|
"mode" -> mode = value
|
|
|
|
"hash" -> hash = value
|
2022-01-07 19:27:25 +00:00
|
|
|
else -> Unit
|
2021-09-30 15:51:34 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
if (op == null || id == null || mode == null || hash == null) {
|
|
|
|
return null
|
|
|
|
}
|
2022-01-29 21:25:12 +00:00
|
|
|
delay(5000) // ye this is needed, wont work with 0 delay
|
2021-09-30 15:51:34 +00:00
|
|
|
|
2022-04-18 18:49:17 +00:00
|
|
|
return app.post(
|
2021-09-30 15:51:34 +00:00
|
|
|
requestUrl,
|
|
|
|
headers = mapOf(
|
|
|
|
"content-type" to "application/x-www-form-urlencoded",
|
|
|
|
"referer" to requestUrl,
|
|
|
|
"user-agent" to USER_AGENT,
|
|
|
|
"accept" to "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9"
|
|
|
|
),
|
|
|
|
data = mapOf("op" to op, "id" to id, "mode" to mode, "hash" to hash)
|
|
|
|
).text
|
|
|
|
}
|
|
|
|
|
2022-10-10 19:43:56 +00:00
|
|
|
fun ExtractorApi.fixUrl(url: String): String {
|
|
|
|
if (url.startsWith("http") ||
|
|
|
|
// Do not fix JSON objects when passed as urls.
|
|
|
|
url.startsWith("{\"")
|
|
|
|
) {
|
|
|
|
return url
|
|
|
|
}
|
|
|
|
if (url.isEmpty()) {
|
|
|
|
return ""
|
|
|
|
}
|
|
|
|
|
|
|
|
val startsWithNoHttp = url.startsWith("//")
|
|
|
|
if (startsWithNoHttp) {
|
|
|
|
return "https:$url"
|
|
|
|
} else {
|
|
|
|
if (url.startsWith('/')) {
|
|
|
|
return mainUrl + url
|
|
|
|
}
|
|
|
|
return "$mainUrl/$url"
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-05-19 18:44:02 +00:00
|
|
|
abstract class ExtractorApi {
|
|
|
|
abstract val name: String
|
|
|
|
abstract val mainUrl: String
|
|
|
|
abstract val requiresReferer: Boolean
|
|
|
|
|
2022-08-09 08:33:16 +00:00
|
|
|
/** Determines which plugin a given extractor is from */
|
|
|
|
var sourcePlugin: String? = null
|
|
|
|
|
2022-07-27 17:36:31 +00:00
|
|
|
//suspend fun getSafeUrl(url: String, referer: String? = null): List<ExtractorLink>? {
|
|
|
|
// return suspendSafeApiCall { getUrl(url, referer) }
|
|
|
|
//}
|
|
|
|
|
|
|
|
// this is the new extractorapi, override to add subtitles and stuff
|
|
|
|
open suspend fun getUrl(
|
|
|
|
url: String,
|
|
|
|
referer: String? = null,
|
|
|
|
subtitleCallback: (SubtitleFile) -> Unit,
|
|
|
|
callback: (ExtractorLink) -> Unit
|
|
|
|
) {
|
|
|
|
getUrl(url, referer)?.forEach(callback)
|
|
|
|
}
|
|
|
|
|
|
|
|
suspend fun getSafeUrl(
|
|
|
|
url: String,
|
|
|
|
referer: String? = null,
|
|
|
|
subtitleCallback: (SubtitleFile) -> Unit,
|
|
|
|
callback: (ExtractorLink) -> Unit
|
|
|
|
) {
|
|
|
|
try {
|
|
|
|
getUrl(url, referer, subtitleCallback, callback)
|
|
|
|
} catch (e: Exception) {
|
|
|
|
logError(e)
|
|
|
|
}
|
2021-07-23 16:41:37 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Will throw errors, use getSafeUrl if you don't want to handle the exception yourself
|
|
|
|
*/
|
2022-07-27 17:36:31 +00:00
|
|
|
open suspend fun getUrl(url: String, referer: String? = null): List<ExtractorLink>? {
|
|
|
|
return emptyList()
|
|
|
|
}
|
2021-05-19 18:44:02 +00:00
|
|
|
|
2021-05-20 15:22:28 +00:00
|
|
|
open fun getExtractorUrl(id: String): String {
|
2021-05-19 18:44:02 +00:00
|
|
|
return id
|
|
|
|
}
|
2023-11-05 22:33:11 +00:00
|
|
|
}
|