feat: multi stream audio support
This commit is contained in:
parent
abcf9fcbef
commit
636a56fb7f
15 changed files with 195 additions and 144 deletions
|
@ -489,7 +489,7 @@ class AnimeWatchAdapter(
|
||||||
val adapter = ArrayAdapter(
|
val adapter = ArrayAdapter(
|
||||||
fragment.requireContext(),
|
fragment.requireContext(),
|
||||||
R.layout.item_dropdown,
|
R.layout.item_dropdown,
|
||||||
parser.extension.sources.map { LanguageMapper.mapLanguageCodeToName(it.lang) }
|
parser.extension.sources.map { LanguageMapper.getLanguageCode(it.lang) }
|
||||||
)
|
)
|
||||||
val items = adapter.count
|
val items = adapter.count
|
||||||
|
|
||||||
|
|
|
@ -371,7 +371,7 @@ class AnimeWatchFragment : Fragment() {
|
||||||
var selectedSetting = allSettings[0]
|
var selectedSetting = allSettings[0]
|
||||||
if (allSettings.size > 1) {
|
if (allSettings.size > 1) {
|
||||||
val names =
|
val names =
|
||||||
allSettings.map { LanguageMapper.mapLanguageCodeToName(it.lang) }.toTypedArray()
|
allSettings.map { LanguageMapper.getLanguageCode(it.lang) }.toTypedArray()
|
||||||
val dialog = AlertDialog.Builder(requireContext(), R.style.MyPopup)
|
val dialog = AlertDialog.Builder(requireContext(), R.style.MyPopup)
|
||||||
.setTitle("Select a Source")
|
.setTitle("Select a Source")
|
||||||
.setSingleChoiceItems(names, -1) { dialog, which ->
|
.setSingleChoiceItems(names, -1) { dialog, which ->
|
||||||
|
|
|
@ -82,7 +82,9 @@ import androidx.media3.datasource.cache.CacheDataSource
|
||||||
import androidx.media3.datasource.okhttp.OkHttpDataSource
|
import androidx.media3.datasource.okhttp.OkHttpDataSource
|
||||||
import androidx.media3.exoplayer.DefaultLoadControl
|
import androidx.media3.exoplayer.DefaultLoadControl
|
||||||
import androidx.media3.exoplayer.ExoPlayer
|
import androidx.media3.exoplayer.ExoPlayer
|
||||||
|
import androidx.media3.exoplayer.hls.HlsMediaSource
|
||||||
import androidx.media3.exoplayer.source.DefaultMediaSourceFactory
|
import androidx.media3.exoplayer.source.DefaultMediaSourceFactory
|
||||||
|
import androidx.media3.exoplayer.source.MergingMediaSource
|
||||||
import androidx.media3.exoplayer.trackselection.DefaultTrackSelector
|
import androidx.media3.exoplayer.trackselection.DefaultTrackSelector
|
||||||
import androidx.media3.exoplayer.util.EventLogger
|
import androidx.media3.exoplayer.util.EventLogger
|
||||||
import androidx.media3.session.MediaSession
|
import androidx.media3.session.MediaSession
|
||||||
|
@ -126,6 +128,7 @@ import ani.dantotsu.media.SubtitleDownloader
|
||||||
import ani.dantotsu.okHttpClient
|
import ani.dantotsu.okHttpClient
|
||||||
import ani.dantotsu.others.AniSkip
|
import ani.dantotsu.others.AniSkip
|
||||||
import ani.dantotsu.others.AniSkip.getType
|
import ani.dantotsu.others.AniSkip.getType
|
||||||
|
import ani.dantotsu.others.LanguageMapper
|
||||||
import ani.dantotsu.others.ResettableTimer
|
import ani.dantotsu.others.ResettableTimer
|
||||||
import ani.dantotsu.others.getSerialized
|
import ani.dantotsu.others.getSerialized
|
||||||
import ani.dantotsu.parsers.AnimeSources
|
import ani.dantotsu.parsers.AnimeSources
|
||||||
|
@ -190,6 +193,7 @@ class ExoplayerView : AppCompatActivity(), Player.Listener, SessionAvailabilityL
|
||||||
private lateinit var cacheFactory: CacheDataSource.Factory
|
private lateinit var cacheFactory: CacheDataSource.Factory
|
||||||
private lateinit var playbackParameters: PlaybackParameters
|
private lateinit var playbackParameters: PlaybackParameters
|
||||||
private lateinit var mediaItem: MediaItem
|
private lateinit var mediaItem: MediaItem
|
||||||
|
private lateinit var mediaSource: MergingMediaSource
|
||||||
private var mediaSession: MediaSession? = null
|
private var mediaSession: MediaSession? = null
|
||||||
|
|
||||||
private lateinit var binding: ActivityExoplayerBinding
|
private lateinit var binding: ActivityExoplayerBinding
|
||||||
|
@ -223,6 +227,7 @@ class ExoplayerView : AppCompatActivity(), Player.Listener, SessionAvailabilityL
|
||||||
|
|
||||||
private var downloadId: String? = null
|
private var downloadId: String? = null
|
||||||
private var hasExtSubtitles = false
|
private var hasExtSubtitles = false
|
||||||
|
private var audioLanguages = mutableListOf<String>()
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
var initialized = false
|
var initialized = false
|
||||||
|
@ -1484,9 +1489,9 @@ class ExoplayerView : AppCompatActivity(), Player.Listener, SessionAvailabilityL
|
||||||
val titleName = ext.server.name.split("/").first()
|
val titleName = ext.server.name.split("/").first()
|
||||||
val episodeName = ext.server.name.split("/").last()
|
val episodeName = ext.server.name.split("/").last()
|
||||||
downloadId = PrefManager.getAnimeDownloadPreferences()
|
downloadId = PrefManager.getAnimeDownloadPreferences()
|
||||||
.getString("$titleName - $episodeName", null) ?:
|
.getString("$titleName - $episodeName", null)
|
||||||
PrefManager.getAnimeDownloadPreferences()
|
?: PrefManager.getAnimeDownloadPreferences()
|
||||||
.getString(ext.server.name, null)
|
.getString(ext.server.name, null)
|
||||||
val exoItem = if (downloadId != null) {
|
val exoItem = if (downloadId != null) {
|
||||||
Helper.downloadManager(this)
|
Helper.downloadManager(this)
|
||||||
.downloadIndex.getDownload(downloadId!!)?.request?.toMediaItem()
|
.downloadIndex.getDownload(downloadId!!)?.request?.toMediaItem()
|
||||||
|
@ -1540,6 +1545,32 @@ class ExoplayerView : AppCompatActivity(), Player.Listener, SessionAvailabilityL
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
val audioMediaItem = mutableListOf<MediaItem>()
|
||||||
|
audioLanguages.clear()
|
||||||
|
ext.audioTracks.forEach {
|
||||||
|
val code = LanguageMapper.getLanguageCode(it.lang)
|
||||||
|
audioLanguages.add(code)
|
||||||
|
audioMediaItem.add(
|
||||||
|
MediaItem.Builder()
|
||||||
|
.setUri(it.url)
|
||||||
|
.setMimeType(MimeTypes.AUDIO_UNKNOWN)
|
||||||
|
.setTag(code)
|
||||||
|
.build()
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
val audioSources = audioMediaItem.map { mediaItem ->
|
||||||
|
if (mediaItem.localConfiguration?.uri.toString().endsWith(".m3u8")) {
|
||||||
|
HlsMediaSource.Factory(cacheFactory).createMediaSource(mediaItem)
|
||||||
|
} else {
|
||||||
|
DefaultMediaSourceFactory(cacheFactory).createMediaSource(mediaItem)
|
||||||
|
}
|
||||||
|
}.toTypedArray()
|
||||||
|
val videoMediaSource = DefaultMediaSourceFactory(cacheFactory)
|
||||||
|
.createMediaSource(mediaItem)
|
||||||
|
mediaSource = MergingMediaSource(videoMediaSource, *audioSources)
|
||||||
|
|
||||||
|
|
||||||
//Source
|
//Source
|
||||||
exoSource.setOnClickListener {
|
exoSource.setOnClickListener {
|
||||||
sourceClick()
|
sourceClick()
|
||||||
|
@ -1615,7 +1646,7 @@ class ExoplayerView : AppCompatActivity(), Player.Listener, SessionAvailabilityL
|
||||||
.build().apply {
|
.build().apply {
|
||||||
playWhenReady = true
|
playWhenReady = true
|
||||||
this.playbackParameters = this@ExoplayerView.playbackParameters
|
this.playbackParameters = this@ExoplayerView.playbackParameters
|
||||||
setMediaItem(mediaItem)
|
setMediaSource(mediaSource)
|
||||||
prepare()
|
prepare()
|
||||||
PrefManager.getCustomVal(
|
PrefManager.getCustomVal(
|
||||||
"${media.id}_${media.anime!!.selectedEpisode}_max",
|
"${media.id}_${media.anime!!.selectedEpisode}_max",
|
||||||
|
@ -1953,7 +1984,7 @@ class ExoplayerView : AppCompatActivity(), Player.Listener, SessionAvailabilityL
|
||||||
}
|
}
|
||||||
exoAudioTrack.isVisible = audioTracks.size > 1
|
exoAudioTrack.isVisible = audioTracks.size > 1
|
||||||
exoAudioTrack.setOnClickListener {
|
exoAudioTrack.setOnClickListener {
|
||||||
TrackGroupDialogFragment(this, audioTracks, TRACK_TYPE_AUDIO)
|
TrackGroupDialogFragment(this, audioTracks, TRACK_TYPE_AUDIO, audioLanguages)
|
||||||
.show(supportFragmentManager, "dialog")
|
.show(supportFragmentManager, "dialog")
|
||||||
}
|
}
|
||||||
if (!hasExtSubtitles) {
|
if (!hasExtSubtitles) {
|
||||||
|
|
|
@ -19,19 +19,13 @@ import java.util.Locale
|
||||||
|
|
||||||
@OptIn(UnstableApi::class)
|
@OptIn(UnstableApi::class)
|
||||||
class TrackGroupDialogFragment(
|
class TrackGroupDialogFragment(
|
||||||
instance: ExoplayerView, trackGroups: ArrayList<Tracks.Group>, type: @TrackType Int
|
private var instance: ExoplayerView,
|
||||||
|
private var trackGroups: ArrayList<Tracks.Group>,
|
||||||
|
private var type: @TrackType Int,
|
||||||
|
private var overrideTrackNames: List<String>? = null
|
||||||
) : BottomSheetDialogFragment() {
|
) : BottomSheetDialogFragment() {
|
||||||
private var _binding: BottomSheetSubtitlesBinding? = null
|
private var _binding: BottomSheetSubtitlesBinding? = null
|
||||||
private val binding get() = _binding!!
|
private val binding get() = _binding!!
|
||||||
private var instance: ExoplayerView
|
|
||||||
private var trackGroups: ArrayList<Tracks.Group>
|
|
||||||
private var type: @TrackType Int
|
|
||||||
|
|
||||||
init {
|
|
||||||
this.instance = instance
|
|
||||||
this.trackGroups = trackGroups
|
|
||||||
this.type = type
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onCreateView(
|
override fun onCreateView(
|
||||||
inflater: LayoutInflater,
|
inflater: LayoutInflater,
|
||||||
|
@ -67,7 +61,8 @@ class TrackGroupDialogFragment(
|
||||||
override fun onBindViewHolder(holder: StreamViewHolder, position: Int) {
|
override fun onBindViewHolder(holder: StreamViewHolder, position: Int) {
|
||||||
val binding = holder.binding
|
val binding = holder.binding
|
||||||
trackGroups[position].let { trackGroup ->
|
trackGroups[position].let { trackGroup ->
|
||||||
when (val language = trackGroup.getTrackFormat(0).language?.lowercase()) {
|
when (val language = overrideTrackNames?.getOrNull(position)
|
||||||
|
?: trackGroup.getTrackFormat(0).language?.lowercase()) {
|
||||||
null -> {
|
null -> {
|
||||||
binding.subtitleTitle.text =
|
binding.subtitleTitle.text =
|
||||||
getString(R.string.unknown_track, "Track $position")
|
getString(R.string.unknown_track, "Track $position")
|
||||||
|
@ -94,7 +89,6 @@ class TrackGroupDialogFragment(
|
||||||
}
|
}
|
||||||
binding.subtitleTitle.text = locale?.let {
|
binding.subtitleTitle.text = locale?.let {
|
||||||
"[${it.language}] ${it.displayName}"
|
"[${it.language}] ${it.displayName}"
|
||||||
|
|
||||||
} ?: getString(R.string.unknown_track, language)
|
} ?: getString(R.string.unknown_track, language)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -548,7 +548,7 @@ class MangaReadAdapter(
|
||||||
val adapter = ArrayAdapter(
|
val adapter = ArrayAdapter(
|
||||||
fragment.requireContext(),
|
fragment.requireContext(),
|
||||||
R.layout.item_dropdown,
|
R.layout.item_dropdown,
|
||||||
parser.extension.sources.map { LanguageMapper.mapLanguageCodeToName(it.lang) }
|
parser.extension.sources.map { LanguageMapper.getLanguageCode(it.lang) }
|
||||||
)
|
)
|
||||||
val items = adapter.count
|
val items = adapter.count
|
||||||
binding?.animeSourceLanguageContainer?.isVisible = items > 1
|
binding?.animeSourceLanguageContainer?.isVisible = items > 1
|
||||||
|
|
|
@ -385,7 +385,7 @@ open class MangaReadFragment : Fragment(), ScanlatorSelectionListener {
|
||||||
var selectedSetting = allSettings[0]
|
var selectedSetting = allSettings[0]
|
||||||
if (allSettings.size > 1) {
|
if (allSettings.size > 1) {
|
||||||
val names =
|
val names =
|
||||||
allSettings.map { LanguageMapper.mapLanguageCodeToName(it.lang) }.toTypedArray()
|
allSettings.map { LanguageMapper.getLanguageCode(it.lang) }.toTypedArray()
|
||||||
val dialog = AlertDialog.Builder(requireContext(), R.style.MyPopup)
|
val dialog = AlertDialog.Builder(requireContext(), R.style.MyPopup)
|
||||||
.setTitle("Select a Source")
|
.setTitle("Select a Source")
|
||||||
.setSingleChoiceItems(names, -1) { dialog, which ->
|
.setSingleChoiceItems(names, -1) { dialog, which ->
|
||||||
|
|
|
@ -1,124 +1,145 @@
|
||||||
package ani.dantotsu.others
|
package ani.dantotsu.others
|
||||||
|
|
||||||
|
import java.util.Locale
|
||||||
|
|
||||||
class LanguageMapper {
|
class LanguageMapper {
|
||||||
companion object {
|
companion object {
|
||||||
|
|
||||||
fun mapLanguageCodeToName(code: String): String {
|
private val codeMap: Map<String, String> = mapOf(
|
||||||
return when (code) {
|
"all" to "Multi",
|
||||||
"all" -> "Multi"
|
"af" to "Afrikaans",
|
||||||
"af" -> "Afrikaans"
|
"am" to "Amharic",
|
||||||
"am" -> "Amharic"
|
"ar" to "Arabic",
|
||||||
"ar" -> "Arabic"
|
"as" to "Assamese",
|
||||||
"as" -> "Assamese"
|
"az" to "Azerbaijani",
|
||||||
"az" -> "Azerbaijani"
|
"be" to "Belarusian",
|
||||||
"be" -> "Belarusian"
|
"bg" to "Bulgarian",
|
||||||
"bg" -> "Bulgarian"
|
"bn" to "Bengali",
|
||||||
"bn" -> "Bengali"
|
"bs" to "Bosnian",
|
||||||
"bs" -> "Bosnian"
|
"ca" to "Catalan",
|
||||||
"ca" -> "Catalan"
|
"ceb" to "Cebuano",
|
||||||
"ceb" -> "Cebuano"
|
"cs" to "Czech",
|
||||||
"cs" -> "Czech"
|
"da" to "Danish",
|
||||||
"da" -> "Danish"
|
"de" to "German",
|
||||||
"de" -> "German"
|
"el" to "Greek",
|
||||||
"el" -> "Greek"
|
"en" to "English",
|
||||||
"en" -> "English"
|
"en-Us" to "English (United States)",
|
||||||
"en-Us" -> "English (United States)"
|
"eo" to "Esperanto",
|
||||||
"eo" -> "Esperanto"
|
"es" to "Spanish",
|
||||||
"es" -> "Spanish"
|
"es-419" to "Spanish (Latin America)",
|
||||||
"es-419" -> "Spanish (Latin America)"
|
"es-ES" to "Spanish (Spain)",
|
||||||
"et" -> "Estonian"
|
"et" to "Estonian",
|
||||||
"eu" -> "Basque"
|
"eu" to "Basque",
|
||||||
"fa" -> "Persian"
|
"fa" to "Persian",
|
||||||
"fi" -> "Finnish"
|
"fi" to "Finnish",
|
||||||
"fil" -> "Filipino"
|
"fil" to "Filipino",
|
||||||
"fo" -> "Faroese"
|
"fo" to "Faroese",
|
||||||
"fr" -> "French"
|
"fr" to "French",
|
||||||
"ga" -> "Irish"
|
"ga" to "Irish",
|
||||||
"gn" -> "Guarani"
|
"gn" to "Guarani",
|
||||||
"gu" -> "Gujarati"
|
"gu" to "Gujarati",
|
||||||
"ha" -> "Hausa"
|
"ha" to "Hausa",
|
||||||
"he" -> "Hebrew"
|
"he" to "Hebrew",
|
||||||
"hi" -> "Hindi"
|
"hi" to "Hindi",
|
||||||
"hr" -> "Croatian"
|
"hr" to "Croatian",
|
||||||
"ht" -> "Haitian Creole"
|
"ht" to "Haitian Creole",
|
||||||
"hu" -> "Hungarian"
|
"hu" to "Hungarian",
|
||||||
"hy" -> "Armenian"
|
"hy" to "Armenian",
|
||||||
"id" -> "Indonesian"
|
"id" to "Indonesian",
|
||||||
"ig" -> "Igbo"
|
"ig" to "Igbo",
|
||||||
"is" -> "Icelandic"
|
"is" to "Icelandic",
|
||||||
"it" -> "Italian"
|
"it" to "Italian",
|
||||||
"ja" -> "Japanese"
|
"ja" to "Japanese",
|
||||||
"jv" -> "Javanese"
|
"jv" to "Javanese",
|
||||||
"ka" -> "Georgian"
|
"ka" to "Georgian",
|
||||||
"kk" -> "Kazakh"
|
"kk" to "Kazakh",
|
||||||
"km" -> "Khmer"
|
"km" to "Khmer",
|
||||||
"kn" -> "Kannada"
|
"kn" to "Kannada",
|
||||||
"ko" -> "Korean"
|
"ko" to "Korean",
|
||||||
"ku" -> "Kurdish"
|
"ku" to "Kurdish",
|
||||||
"ky" -> "Kyrgyz"
|
"ky" to "Kyrgyz",
|
||||||
"la" -> "Latin"
|
"la" to "Latin",
|
||||||
"lb" -> "Luxembourgish"
|
"lb" to "Luxembourgish",
|
||||||
"lo" -> "Lao"
|
"lo" to "Lao",
|
||||||
"lt" -> "Lithuanian"
|
"lt" to "Lithuanian",
|
||||||
"lv" -> "Latvian"
|
"lv" to "Latvian",
|
||||||
"mg" -> "Malagasy"
|
"mg" to "Malagasy",
|
||||||
"mi" -> "Maori"
|
"mi" to "Maori",
|
||||||
"mk" -> "Macedonian"
|
"mk" to "Macedonian",
|
||||||
"ml" -> "Malayalam"
|
"ml" to "Malayalam",
|
||||||
"mn" -> "Mongolian"
|
"mn" to "Mongolian",
|
||||||
"mo" -> "Moldovan"
|
"mo" to "Moldovan",
|
||||||
"mr" -> "Marathi"
|
"mr" to "Marathi",
|
||||||
"ms" -> "Malay"
|
"ms" to "Malay",
|
||||||
"mt" -> "Maltese"
|
"mt" to "Maltese",
|
||||||
"my" -> "Burmese"
|
"my" to "Burmese",
|
||||||
"ne" -> "Nepali"
|
"ne" to "Nepali",
|
||||||
"nl" -> "Dutch"
|
"nl" to "Dutch",
|
||||||
"no" -> "Norwegian"
|
"no" to "Norwegian",
|
||||||
"ny" -> "Chichewa"
|
"ny" to "Chichewa",
|
||||||
"pl" -> "Polish"
|
"pl" to "Polish",
|
||||||
"pt" -> "Portuguese"
|
"pt" to "Portuguese",
|
||||||
"pt-BR" -> "Portuguese (Brazil)"
|
"pt-BR" to "Portuguese (Brazil)",
|
||||||
"pt-PT" -> "Portuguese (Portugal)"
|
"pt-PT" to "Portuguese (Portugal)",
|
||||||
"ps" -> "Pashto"
|
"ps" to "Pashto",
|
||||||
"ro" -> "Romanian"
|
"ro" to "Romanian",
|
||||||
"rm" -> "Romansh"
|
"rm" to "Romansh",
|
||||||
"ru" -> "Russian"
|
"ru" to "Russian",
|
||||||
"sd" -> "Sindhi"
|
"sd" to "Sindhi",
|
||||||
"sh" -> "Serbo-Croatian"
|
"sh" to "Serbo-Croatian",
|
||||||
"si" -> "Sinhala"
|
"si" to "Sinhala",
|
||||||
"sk" -> "Slovak"
|
"sk" to "Slovak",
|
||||||
"sl" -> "Slovenian"
|
"sl" to "Slovenian",
|
||||||
"sm" -> "Samoan"
|
"sm" to "Samoan",
|
||||||
"sn" -> "Shona"
|
"sn" to "Shona",
|
||||||
"so" -> "Somali"
|
"so" to "Somali",
|
||||||
"sq" -> "Albanian"
|
"sq" to "Albanian",
|
||||||
"sr" -> "Serbian"
|
"sr" to "Serbian",
|
||||||
"st" -> "Southern Sotho"
|
"st" to "Southern Sotho",
|
||||||
"sv" -> "Swedish"
|
"sv" to "Swedish",
|
||||||
"sw" -> "Swahili"
|
"sw" to "Swahili",
|
||||||
"ta" -> "Tamil"
|
"ta" to "Tamil",
|
||||||
"te" -> "Telugu"
|
"te" to "Telugu",
|
||||||
"tg" -> "Tajik"
|
"tg" to "Tajik",
|
||||||
"th" -> "Thai"
|
"th" to "Thai",
|
||||||
"ti" -> "Tigrinya"
|
"ti" to "Tigrinya",
|
||||||
"tk" -> "Turkmen"
|
"tk" to "Turkmen",
|
||||||
"tl" -> "Tagalog"
|
"tl" to "Tagalog",
|
||||||
"to" -> "Tongan"
|
"to" to "Tongan",
|
||||||
"tr" -> "Turkish"
|
"tr" to "Turkish",
|
||||||
"uk" -> "Ukrainian"
|
"uk" to "Ukrainian",
|
||||||
"ur" -> "Urdu"
|
"ur" to "Urdu",
|
||||||
"uz" -> "Uzbek"
|
"uz" to "Uzbek",
|
||||||
"vi" -> "Vietnamese"
|
"vi" to "Vietnamese",
|
||||||
"yo" -> "Yoruba"
|
"yo" to "Yoruba",
|
||||||
"zh" -> "Chinese"
|
"zh" to "Chinese",
|
||||||
"zh-Hans" -> "Chinese (Simplified)"
|
"zh-Hans" to "Chinese (Simplified)",
|
||||||
"zh-Hant" -> "Chinese (Traditional)"
|
"zh-Hant" to "Chinese (Traditional)",
|
||||||
"zh-Habt" -> "Chinese (Hakka)"
|
"zh-Habt" to "Chinese (Hakka)",
|
||||||
"zu" -> "Zulu"
|
"zu" to "Zulu"
|
||||||
else -> code
|
)
|
||||||
|
|
||||||
|
fun getLanguage(code: String): String {
|
||||||
|
return if (code.contains("-")) {
|
||||||
|
try {
|
||||||
|
val parts = code.split("-")
|
||||||
|
Locale(parts[0], parts[1]).displayName
|
||||||
|
} catch (ignored: Exception) {
|
||||||
|
code
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
try {
|
||||||
|
Locale(code).displayName
|
||||||
|
} catch (ignored: Exception) {
|
||||||
|
code
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun getLanguageCode(language: String): String {
|
||||||
|
return codeMap.filterValues { it.lowercase() == language.lowercase() }.keys.firstOrNull() ?: "all"
|
||||||
|
}
|
||||||
|
|
||||||
enum class Language(val code: String) {
|
enum class Language(val code: String) {
|
||||||
ALL("all"),
|
ALL("all"),
|
||||||
ARABIC("ar"),
|
ARABIC("ar"),
|
||||||
|
|
|
@ -511,9 +511,10 @@ class VideoServerPassthrough(private val videoServer: VideoServer) : VideoExtrac
|
||||||
override suspend fun extract(): VideoContainer {
|
override suspend fun extract(): VideoContainer {
|
||||||
val vidList = listOfNotNull(videoServer.video?.let { aniVideoToSaiVideo(it) })
|
val vidList = listOfNotNull(videoServer.video?.let { aniVideoToSaiVideo(it) })
|
||||||
val subList = videoServer.video?.subtitleTracks?.map { trackToSubtitle(it) } ?: emptyList()
|
val subList = videoServer.video?.subtitleTracks?.map { trackToSubtitle(it) } ?: emptyList()
|
||||||
|
val audioList = videoServer.video?.audioTracks ?: emptyList()
|
||||||
|
|
||||||
return if (vidList.isNotEmpty()) {
|
return if (vidList.isNotEmpty()) {
|
||||||
VideoContainer(vidList, subList)
|
VideoContainer(vidList, subList, audioList)
|
||||||
} else {
|
} else {
|
||||||
throw Exception("No videos found")
|
throw Exception("No videos found")
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
package ani.dantotsu.parsers
|
package ani.dantotsu.parsers
|
||||||
|
|
||||||
import ani.dantotsu.FileUrl
|
import ani.dantotsu.FileUrl
|
||||||
|
import eu.kanade.tachiyomi.animesource.model.Track
|
||||||
import java.io.Serializable
|
import java.io.Serializable
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -12,6 +13,7 @@ abstract class VideoExtractor : Serializable {
|
||||||
abstract val server: VideoServer
|
abstract val server: VideoServer
|
||||||
var videos: List<Video> = listOf()
|
var videos: List<Video> = listOf()
|
||||||
var subtitles: List<Subtitle> = listOf()
|
var subtitles: List<Subtitle> = listOf()
|
||||||
|
var audioTracks: List<Track> = listOf()
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Extracts videos & subtitles from the `embed`
|
* Extracts videos & subtitles from the `embed`
|
||||||
|
@ -29,6 +31,7 @@ abstract class VideoExtractor : Serializable {
|
||||||
extract().also {
|
extract().also {
|
||||||
videos = it.videos
|
videos = it.videos
|
||||||
subtitles = it.subtitles
|
subtitles = it.subtitles
|
||||||
|
audioTracks = it.audioTracks
|
||||||
return this
|
return this
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -80,7 +83,8 @@ data class VideoServer(
|
||||||
* **/
|
* **/
|
||||||
data class VideoContainer(
|
data class VideoContainer(
|
||||||
val videos: List<Video>,
|
val videos: List<Video>,
|
||||||
val subtitles: List<Subtitle> = listOf()
|
val subtitles: List<Subtitle> = listOf(),
|
||||||
|
val audioTracks: List<Track> = listOf(),
|
||||||
) : Serializable
|
) : Serializable
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -72,7 +72,7 @@ class InstalledAnimeExtensionsFragment : Fragment(), SearchQueryHandler {
|
||||||
if (allSettings.isNotEmpty()) {
|
if (allSettings.isNotEmpty()) {
|
||||||
var selectedSetting = allSettings[0]
|
var selectedSetting = allSettings[0]
|
||||||
if (allSettings.size > 1) {
|
if (allSettings.size > 1) {
|
||||||
val names = allSettings.map { LanguageMapper.mapLanguageCodeToName(it.lang) }
|
val names = allSettings.map { LanguageMapper.getLanguageCode(it.lang) }
|
||||||
.toTypedArray()
|
.toTypedArray()
|
||||||
var selectedIndex = 0
|
var selectedIndex = 0
|
||||||
val dialog = AlertDialog.Builder(requireContext(), R.style.MyPopup)
|
val dialog = AlertDialog.Builder(requireContext(), R.style.MyPopup)
|
||||||
|
@ -295,7 +295,7 @@ class InstalledAnimeExtensionsFragment : Fragment(), SearchQueryHandler {
|
||||||
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
|
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
|
||||||
val extension = getItem(position)
|
val extension = getItem(position)
|
||||||
val nsfw = if (extension.isNsfw) "(18+)" else ""
|
val nsfw = if (extension.isNsfw) "(18+)" else ""
|
||||||
val lang = LanguageMapper.mapLanguageCodeToName(extension.lang)
|
val lang = LanguageMapper.getLanguageCode(extension.lang)
|
||||||
holder.extensionNameTextView.text = extension.name
|
holder.extensionNameTextView.text = extension.name
|
||||||
val versionText = "$lang ${extension.versionName} $nsfw"
|
val versionText = "$lang ${extension.versionName} $nsfw"
|
||||||
holder.extensionVersionTextView.text = versionText
|
holder.extensionVersionTextView.text = versionText
|
||||||
|
|
|
@ -71,7 +71,7 @@ class InstalledMangaExtensionsFragment : Fragment(), SearchQueryHandler {
|
||||||
if (allSettings.isNotEmpty()) {
|
if (allSettings.isNotEmpty()) {
|
||||||
var selectedSetting = allSettings[0]
|
var selectedSetting = allSettings[0]
|
||||||
if (allSettings.size > 1) {
|
if (allSettings.size > 1) {
|
||||||
val names = allSettings.map { LanguageMapper.mapLanguageCodeToName(it.lang) }
|
val names = allSettings.map { LanguageMapper.getLanguageCode(it.lang) }
|
||||||
.toTypedArray()
|
.toTypedArray()
|
||||||
var selectedIndex = 0
|
var selectedIndex = 0
|
||||||
val dialog = AlertDialog.Builder(requireContext(), R.style.MyPopup)
|
val dialog = AlertDialog.Builder(requireContext(), R.style.MyPopup)
|
||||||
|
@ -293,7 +293,7 @@ class InstalledMangaExtensionsFragment : Fragment(), SearchQueryHandler {
|
||||||
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
|
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
|
||||||
val extension = getItem(position) // Use getItem() from ListAdapter
|
val extension = getItem(position) // Use getItem() from ListAdapter
|
||||||
val nsfw = if (extension.isNsfw) "(18+)" else ""
|
val nsfw = if (extension.isNsfw) "(18+)" else ""
|
||||||
val lang = LanguageMapper.mapLanguageCodeToName(extension.lang)
|
val lang = LanguageMapper.getLanguageCode(extension.lang)
|
||||||
holder.extensionNameTextView.text = extension.name
|
holder.extensionNameTextView.text = extension.name
|
||||||
val versionText = "$lang ${extension.versionName} $nsfw"
|
val versionText = "$lang ${extension.versionName} $nsfw"
|
||||||
holder.extensionVersionTextView.text = versionText
|
holder.extensionVersionTextView.text = versionText
|
||||||
|
|
|
@ -222,7 +222,7 @@ class InstalledNovelExtensionsFragment : Fragment(), SearchQueryHandler {
|
||||||
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
|
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
|
||||||
val extension = getItem(position) // Use getItem() from ListAdapter
|
val extension = getItem(position) // Use getItem() from ListAdapter
|
||||||
val nsfw = ""
|
val nsfw = ""
|
||||||
val lang = LanguageMapper.mapLanguageCodeToName("all")
|
val lang = LanguageMapper.getLanguageCode("all")
|
||||||
holder.extensionNameTextView.text = extension.name
|
holder.extensionNameTextView.text = extension.name
|
||||||
val versionText = "$lang ${extension.versionName} $nsfw"
|
val versionText = "$lang ${extension.versionName} $nsfw"
|
||||||
holder.extensionVersionTextView.text = versionText
|
holder.extensionVersionTextView.text = versionText
|
||||||
|
|
|
@ -203,7 +203,7 @@ class AnimeExtensionAdapter(private val clickListener: OnAnimeInstallClickListen
|
||||||
|
|
||||||
fun bind(extension: AnimeExtension.Available) {
|
fun bind(extension: AnimeExtension.Available) {
|
||||||
val nsfw = if (extension.isNsfw) "(18+)" else ""
|
val nsfw = if (extension.isNsfw) "(18+)" else ""
|
||||||
val lang = LanguageMapper.mapLanguageCodeToName(extension.lang)
|
val lang = LanguageMapper.getLanguageCode(extension.lang)
|
||||||
binding.extensionNameTextView.text = extension.name
|
binding.extensionNameTextView.text = extension.name
|
||||||
val versionText = "$lang ${extension.versionName} $nsfw"
|
val versionText = "$lang ${extension.versionName} $nsfw"
|
||||||
binding.extensionVersionTextView.text = versionText
|
binding.extensionVersionTextView.text = versionText
|
||||||
|
|
|
@ -201,7 +201,7 @@ class MangaExtensionAdapter(private val clickListener: OnMangaInstallClickListen
|
||||||
|
|
||||||
fun bind(extension: MangaExtension.Available) {
|
fun bind(extension: MangaExtension.Available) {
|
||||||
val nsfw = if (extension.isNsfw) "(18+)" else ""
|
val nsfw = if (extension.isNsfw) "(18+)" else ""
|
||||||
val lang = LanguageMapper.mapLanguageCodeToName(extension.lang)
|
val lang = LanguageMapper.getLanguageCode(extension.lang)
|
||||||
binding.extensionNameTextView.text = extension.name
|
binding.extensionNameTextView.text = extension.name
|
||||||
val versionText = "$lang ${extension.versionName} $nsfw"
|
val versionText = "$lang ${extension.versionName} $nsfw"
|
||||||
binding.extensionVersionTextView.text = versionText
|
binding.extensionVersionTextView.text = versionText
|
||||||
|
|
|
@ -202,7 +202,7 @@ class NovelExtensionAdapter(private val clickListener: OnNovelInstallClickListen
|
||||||
val extensionIconImageView: ImageView = binding.extensionIconImageView
|
val extensionIconImageView: ImageView = binding.extensionIconImageView
|
||||||
fun bind(extension: NovelExtension.Available) {
|
fun bind(extension: NovelExtension.Available) {
|
||||||
val nsfw = ""
|
val nsfw = ""
|
||||||
val lang = LanguageMapper.mapLanguageCodeToName("all")
|
val lang = LanguageMapper.getLanguageCode("all")
|
||||||
binding.extensionNameTextView.text = extension.name
|
binding.extensionNameTextView.text = extension.name
|
||||||
binding.extensionVersionTextView.text = "$lang ${extension.versionName} $nsfw"
|
binding.extensionVersionTextView.text = "$lang ${extension.versionName} $nsfw"
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue