diff --git a/app/phone/src/main/java/dev/jdtech/jellyfin/PlayerActivity.kt b/app/phone/src/main/java/dev/jdtech/jellyfin/PlayerActivity.kt index 1b4eb03f..122bd8bf 100644 --- a/app/phone/src/main/java/dev/jdtech/jellyfin/PlayerActivity.kt +++ b/app/phone/src/main/java/dev/jdtech/jellyfin/PlayerActivity.kt @@ -1,5 +1,6 @@ package dev.jdtech.jellyfin +import android.annotation.SuppressLint import android.app.AppOpsManager import android.app.PictureInPictureParams import android.content.Context @@ -38,6 +39,7 @@ import dagger.hilt.android.AndroidEntryPoint import dev.jdtech.jellyfin.databinding.ActivityPlayerBinding import dev.jdtech.jellyfin.dialogs.SpeedSelectionDialogFragment import dev.jdtech.jellyfin.dialogs.TrackSelectionDialogFragment +import dev.jdtech.jellyfin.models.VideoQuality import dev.jdtech.jellyfin.utils.PlayerGestureHelper import dev.jdtech.jellyfin.utils.PreviewScrubListener import dev.jdtech.jellyfin.viewmodels.PlayerActivityViewModel @@ -288,6 +290,7 @@ class PlayerActivity : BasePlayerActivity() { viewModel.initializePlayer(args.items) } + @SuppressLint("MissingSuperCall") override fun onUserLeaveHint() { super.onUserLeaveHint() if (Build.VERSION.SDK_INT < Build.VERSION_CODES.S && @@ -348,45 +351,29 @@ class PlayerActivity : BasePlayerActivity() { } catch (_: IllegalArgumentException) { } } + private var selectedIndex = 1 // Default to "Original" (index 1) private fun showQualitySelectionDialog() { - val height = viewModel.getOriginalHeight() + val originalHeight = viewModel.getOriginalHeight() // TODO: Rework getting originalHeight val qualityEntries = resources.getStringArray(CoreR.array.quality_entries).toList() val qualityValues = resources.getStringArray(CoreR.array.quality_values).toList() - // Map entries to values - val qualityMap = qualityEntries.zip(qualityValues).toMap() + val qualities = qualityEntries.toMutableList() + val closestQuality = VideoQuality.entries + .filter { it != VideoQuality.Auto && it != VideoQuality.Original } + .minByOrNull { kotlin.math.abs(it.height - originalHeight) } - val qualities: List = - when (height) { - 0 -> qualityEntries - in 1001..1999 -> - listOf( - qualityEntries[0], - "${qualityEntries[1]} (1080p)", - qualityEntries[2], - qualityEntries[3], - qualityEntries[4], - qualityEntries[5], - ) - in 2000..3000 -> - listOf( - qualityEntries[0], - "${qualityEntries[1]} (4K)", - qualityEntries[2], - qualityEntries[3], - qualityEntries[4], - qualityEntries[5], - ) - else -> qualityEntries - } + if (closestQuality != null) { + qualities[1] = "${qualities[1]} (${closestQuality})" + } MaterialAlertDialogBuilder(this) .setTitle("Select Video Quality") - .setItems(qualities.toTypedArray()) { _, which -> - val selectedQualityEntry = qualities[which] - val selectedQualityValue = - qualityMap.entries.find { it.key.contains(selectedQualityEntry.split(" ")[0]) }?.value ?: selectedQualityEntry + .setSingleChoiceItems(qualities.toTypedArray(), selectedIndex) { dialog, which -> + selectedIndex = which + val selectedQualityValue = qualityValues[which] viewModel.changeVideoQuality(selectedQualityValue) - }.show() + dialog.dismiss() + } + .show() } override fun onPictureInPictureModeChanged( diff --git a/core/src/main/java/dev/jdtech/jellyfin/utils/DownloaderImpl.kt b/core/src/main/java/dev/jdtech/jellyfin/utils/DownloaderImpl.kt index 5b608a91..93453796 100644 --- a/core/src/main/java/dev/jdtech/jellyfin/utils/DownloaderImpl.kt +++ b/core/src/main/java/dev/jdtech/jellyfin/utils/DownloaderImpl.kt @@ -416,7 +416,7 @@ class DownloaderImpl( playSessionId, VideoQuality.getBitrate(videoQuality), "ts", - VideoQuality.getQualityInt(videoQuality), + VideoQuality.getHeight(videoQuality), ) downloadUrl.toUri() diff --git a/data/src/main/java/dev/jdtech/jellyfin/models/VideoQuality.kt b/data/src/main/java/dev/jdtech/jellyfin/models/VideoQuality.kt index 46b0f07b..5df83ece 100644 --- a/data/src/main/java/dev/jdtech/jellyfin/models/VideoQuality.kt +++ b/data/src/main/java/dev/jdtech/jellyfin/models/VideoQuality.kt @@ -2,24 +2,28 @@ package dev.jdtech.jellyfin.models enum class VideoQuality( val bitrate: Int, - val qualityString: String, - val qualityInt: Int, + val height: Int, + val width: Int, + val original: Boolean, ) { - PAuto(10000000, "Auto", 1080), - POriginal(1000000000, "Original", 1080), - P1080(8000000, "1080p", 1080), - P720(3000000, "720p", 720), - P480(1500000, "480p", 480), - P360(800000, "360p", 360), - ; + Auto(10000000, 1080, 1920, false), + Original(1000000000, 1080, 1920, true), + P1080(8000000, 1080, 1920, false), + P720(3000000, 720, 1280, false), + P480(1500000, 480, 854, false), + P360(800000, 360, 640, false); + + override fun toString(): String = when (this) { + Auto -> "Auto" + Original -> "Original" + else -> "${height}p" + } companion object { - fun fromString(quality: String): VideoQuality? = entries.find { it.qualityString == quality } - + fun fromString(quality: String): VideoQuality? = entries.find { it.toString() == quality } fun getBitrate(quality: VideoQuality): Int = quality.bitrate - - fun getQualityString(quality: VideoQuality): String = quality.qualityString - - fun getQualityInt(quality: VideoQuality): Int = quality.qualityInt + fun getHeight(quality: VideoQuality): Int = quality.height + fun getWidth(quality: VideoQuality): Int = quality.width + fun getOriginal(quality: VideoQuality): Boolean = quality.original } } \ No newline at end of file diff --git a/data/src/main/java/dev/jdtech/jellyfin/repository/JellyfinRepositoryImpl.kt b/data/src/main/java/dev/jdtech/jellyfin/repository/JellyfinRepositoryImpl.kt index 40d86bc6..e16b9fc5 100644 --- a/data/src/main/java/dev/jdtech/jellyfin/repository/JellyfinRepositoryImpl.kt +++ b/data/src/main/java/dev/jdtech/jellyfin/repository/JellyfinRepositoryImpl.kt @@ -733,7 +733,7 @@ class JellyfinRepositoryImpl( playSessionId: String, videoBitrate: Int, ): String { - val isAuto = videoBitrate == VideoQuality.getBitrate(VideoQuality.PAuto) + val isAuto = videoBitrate == VideoQuality.getBitrate(VideoQuality.Auto) val url = if (!isAuto) { jellyfinApi.api.dynamicHlsApi.getMasterHlsVideoPlaylistUrl( diff --git a/player/video/src/main/java/dev/jdtech/jellyfin/viewmodels/PlayerActivityViewModel.kt b/player/video/src/main/java/dev/jdtech/jellyfin/viewmodels/PlayerActivityViewModel.kt index 3ca1771f..897e84c2 100644 --- a/player/video/src/main/java/dev/jdtech/jellyfin/viewmodels/PlayerActivityViewModel.kt +++ b/player/video/src/main/java/dev/jdtech/jellyfin/viewmodels/PlayerActivityViewModel.kt @@ -524,13 +524,13 @@ constructor( val allSubtitles = - if (VideoQuality.getQualityString(videoQuality) == "Original") { + if (VideoQuality.getOriginal(videoQuality)) { externalSubtitles }else { embeddedSubtitles.apply { addAll(externalSubtitles) } } - val url = if (VideoQuality.getQualityString(videoQuality) == "Original"){ + val url = if (VideoQuality.getOriginal(videoQuality)){ jellyfinRepository.getStreamUrl(currentItem.itemId, currentItem.mediaSourceId, playSessionId) } else { val mediaSourceId = mediaSources[currentMediaItemIndex].id