Dantotsu/app/src/main/java/ani/dantotsu/parsers/VideoExtractor.kt
2024-01-26 00:29:19 -06:00

182 lines
No EOL
4.7 KiB
Kotlin

package ani.dantotsu.parsers
import ani.dantotsu.FileUrl
import java.io.Serializable
/**
* Used to extract videos from a specific video host,
*
* A new instance is created for every embeds/iframes of that Episode
* **/
abstract class VideoExtractor : Serializable {
abstract val server: VideoServer
var videos: List<Video> = listOf()
var subtitles: List<Subtitle> = listOf()
/**
* Extracts videos & subtitles from the `embed`
*
* returns a container containing both videos & subtitles (optional)
* **/
abstract suspend fun extract(): VideoContainer
/**
* Loads videos & subtitles from a given Url
*
* & returns itself with the data loaded
* **/
open suspend fun load(): VideoExtractor {
extract().also {
videos = it.videos
subtitles = it.subtitles
return this
}
}
/**
* Gets called when a Video from this extractor starts playing
*
* Useful for Extractor that require Polling
* **/
open suspend fun onVideoPlayed(video: Video?) {}
/**
* Called when a particular video has been stopped playing
**/
open suspend fun onVideoStopped(video: Video?) {}
}
/**
* A simple class containing name, link & extraData(in case you want to give some to it) of the embed which shows the video present on the site
*
* `name` variable is used when checking if there was a Default Server Selected with the same name
*
*
* **/
data class VideoServer(
val name: String,
val embed: FileUrl,
val extraData: Map<String, String>? = null,
val video: eu.kanade.tachiyomi.animesource.model.Video? = null,
val offline: Boolean = false
) : Serializable {
constructor(name: String, embedUrl: String, extraData: Map<String, String>? = null)
: this(name, FileUrl(embedUrl), extraData)
constructor(name: String, offline: Boolean, extraData: Map<String, String>?)
: this(name, FileUrl(""), extraData, null, offline)
constructor(
name: String,
embedUrl: String,
extraData: Map<String, String>? = null,
video: eu.kanade.tachiyomi.animesource.model.Video?
)
: this(name, FileUrl(embedUrl), extraData, video)
}
/**
* A Container for keeping video & subtitles, so you dont need to check backend
* **/
data class VideoContainer(
val videos: List<Video>,
val subtitles: List<Subtitle> = listOf()
) : Serializable
/**
* The Class which contains all the information about a Video
* **/
data class Video(
/**
* Will represent quality to user in form of `"${quality}p"` (1080p)
*
* If quality is null, shows "Unknown Quality"
*
* If isM3U8 is true, shows "Multi Quality"
* **/
val quality: Int?,
/**
* Mime type / Format of the video,
*
* If not a "CONTAINER" format, the app show video as a "Multi Quality" Link
* "CONTAINER" formats are Mp4 & Mkv
* **/
val format: VideoType,
/**
* The direct url to the Video
*
* Supports mp4, mkv, dash & m3u8, afaik
* **/
val file: FileUrl,
/**
* use getSize(url) to get this size,
*
* no need to set it on M3U8 links
* **/
val size: Double? = null,
/**
* In case, you want to show some extra notes to the User
*
* Ex: "Backup" which could be used if the site provides some
* **/
val extraNote: String? = null,
) : Serializable {
constructor(
quality: Int? = null,
videoType: VideoType,
url: String,
size: Double?,
extraNote: String? = null
)
: this(quality, videoType, FileUrl(url), size, extraNote)
constructor(quality: Int? = null, videoType: VideoType, url: String, size: Double?)
: this(quality, videoType, FileUrl(url), size)
constructor(quality: Int? = null, videoType: VideoType, url: String)
: this(quality, videoType, FileUrl(url))
}
/**
* The Class which contains the link to a subtitle file of a specific language
* **/
data class Subtitle(
/**
* Language of the Subtitle
*
* for now app will directly try to select "English".
* Probably in rework we can add more subtitles support
* **/
val language: String,
/**
* The direct url to the Subtitle
* **/
val file: FileUrl,
/**
* format of the Subtitle
*
* Supports VTT, SRT & ASS
* **/
val type: SubtitleType = SubtitleType.VTT,
) : Serializable {
constructor(language: String, url: String, type: SubtitleType = SubtitleType.VTT) : this(
language,
FileUrl(url),
type
)
}
enum class VideoType {
CONTAINER, M3U8, DASH
}
enum class SubtitleType {
VTT, ASS, SRT, UNKNOWN
}