bugfixes: deviceId / code: New Enum VideoQuality
This commit is contained in:
parent
ba580f8769
commit
6dded2e726
11 changed files with 121 additions and 109 deletions
|
@ -45,6 +45,7 @@ import dev.jdtech.jellyfin.viewmodels.PlayerEvents
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import timber.log.Timber
|
import timber.log.Timber
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
import dev.jdtech.jellyfin.core.R as CoreR
|
||||||
|
|
||||||
var isControlsLocked: Boolean = false
|
var isControlsLocked: Boolean = false
|
||||||
|
|
||||||
|
@ -348,20 +349,44 @@ class PlayerActivity : BasePlayerActivity() {
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun showQualitySelectionDialog() {
|
private fun showQualitySelectionDialog() {
|
||||||
val height = viewModel.getOriginalHeight() // TODO: rewrite getting height stuff I don't like that its only update after changing quality
|
val height = viewModel.getOriginalHeight()
|
||||||
val qualities = when (height) {
|
val qualityEntries = resources.getStringArray(CoreR.array.quality_entries).toList()
|
||||||
0 -> arrayOf("Auto", "Original - Max", "720p - 2Mbps", "480p - 1Mbps", "360p - 800kbps")
|
val qualityValues = resources.getStringArray(CoreR.array.quality_values).toList()
|
||||||
in 1001..1999 -> arrayOf("Auto", "Original (1080p) - Max", "720p - 2Mbps", "480p - 1Mbps", "360p - 800kbps")
|
|
||||||
in 2000..3000 -> arrayOf("Auto", "Original (4K) - Max", "720p - 2Mbps", "480p - 1Mbps", "360p - 800kbps")
|
// Map entries to values
|
||||||
else -> arrayOf("Auto", "Original - Max", "720p - 2Mbps", "480p - 1Mbps", "360p - 800kbps")
|
val qualityMap = qualityEntries.zip(qualityValues).toMap()
|
||||||
}
|
|
||||||
|
val qualities: List<String> =
|
||||||
|
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
|
||||||
|
}
|
||||||
MaterialAlertDialogBuilder(this)
|
MaterialAlertDialogBuilder(this)
|
||||||
.setTitle("Select Video Quality")
|
.setTitle("Select Video Quality")
|
||||||
.setItems(qualities) { _, which ->
|
.setItems(qualities.toTypedArray()) { _, which ->
|
||||||
val selectedQuality = qualities[which]
|
val selectedQualityEntry = qualities[which]
|
||||||
viewModel.changeVideoQuality(selectedQuality)
|
val selectedQualityValue =
|
||||||
}
|
qualityMap.entries.find { it.key.contains(selectedQualityEntry.split(" ")[0]) }?.value ?: selectedQualityEntry
|
||||||
.show()
|
viewModel.changeVideoQuality(selectedQualityValue)
|
||||||
|
}.show()
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onPictureInPictureModeChanged(
|
override fun onPictureInPictureModeChanged(
|
||||||
|
|
|
@ -413,8 +413,8 @@ class EpisodeBottomSheetFragment : BottomSheetDialogFragment() {
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun createPickQualityDialog() {
|
private fun createPickQualityDialog() {
|
||||||
val qualityEntries = resources.getStringArray(CoreR.array.quality_entries)
|
val qualityEntries = resources.getStringArray(CoreR.array.download_quality_entries)
|
||||||
val qualityValues = resources.getStringArray(CoreR.array.quality_values)
|
val qualityValues = resources.getStringArray(CoreR.array.download_quality_values)
|
||||||
val quality = appPreferences.downloadQuality
|
val quality = appPreferences.downloadQuality
|
||||||
val currentQualityIndex = qualityValues.indexOf(quality)
|
val currentQualityIndex = qualityValues.indexOf(quality)
|
||||||
var selectedQuality = quality
|
var selectedQuality = quality
|
||||||
|
|
|
@ -506,8 +506,8 @@ class MovieFragment : Fragment() {
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun createPickQualityDialog() {
|
private fun createPickQualityDialog() {
|
||||||
val qualityEntries = resources.getStringArray(CoreR.array.quality_entries)
|
val qualityEntries = resources.getStringArray(CoreR.array.download_quality_entries)
|
||||||
val qualityValues = resources.getStringArray(CoreR.array.quality_values)
|
val qualityValues = resources.getStringArray(CoreR.array.download_quality_values)
|
||||||
val quality = appPreferences.downloadQuality
|
val quality = appPreferences.downloadQuality
|
||||||
val currentQualityIndex = qualityValues.indexOf(quality)
|
val currentQualityIndex = qualityValues.indexOf(quality)
|
||||||
var selectedQuality = quality
|
var selectedQuality = quality
|
||||||
|
|
|
@ -16,6 +16,7 @@ import dev.jdtech.jellyfin.models.FindroidSource
|
||||||
import dev.jdtech.jellyfin.models.FindroidSources
|
import dev.jdtech.jellyfin.models.FindroidSources
|
||||||
import dev.jdtech.jellyfin.models.FindroidTrickplayInfo
|
import dev.jdtech.jellyfin.models.FindroidTrickplayInfo
|
||||||
import dev.jdtech.jellyfin.models.UiText
|
import dev.jdtech.jellyfin.models.UiText
|
||||||
|
import dev.jdtech.jellyfin.models.VideoQuality
|
||||||
import dev.jdtech.jellyfin.models.toFindroidEpisodeDto
|
import dev.jdtech.jellyfin.models.toFindroidEpisodeDto
|
||||||
import dev.jdtech.jellyfin.models.toFindroidMediaStreamDto
|
import dev.jdtech.jellyfin.models.toFindroidMediaStreamDto
|
||||||
import dev.jdtech.jellyfin.models.toFindroidMovieDto
|
import dev.jdtech.jellyfin.models.toFindroidMovieDto
|
||||||
|
@ -395,19 +396,12 @@ class DownloaderImpl(
|
||||||
itemId: UUID,
|
itemId: UUID,
|
||||||
quality: String,
|
quality: String,
|
||||||
): Uri? {
|
): Uri? {
|
||||||
val maxBitrate =
|
val videoQuality = VideoQuality.fromString(quality)!!
|
||||||
when (quality) {
|
|
||||||
"720p" -> 2000000 // 2 Mbps
|
|
||||||
"480p" -> 1000000 // 1 Mbps
|
|
||||||
"360p" -> 800000 // 800Kbps
|
|
||||||
else -> 2000000
|
|
||||||
}
|
|
||||||
|
|
||||||
return try {
|
return try {
|
||||||
val deviceProfile =
|
val deviceProfile =
|
||||||
jellyfinRepository.buildDeviceProfile(maxBitrate, "mkv", EncodingContext.STATIC)
|
jellyfinRepository.buildDeviceProfile(VideoQuality.getBitrate(videoQuality), "mkv", EncodingContext.STATIC)
|
||||||
val playbackInfo =
|
val playbackInfo =
|
||||||
jellyfinRepository.getPostedPlaybackInfo(itemId, false, deviceProfile, maxBitrate)
|
jellyfinRepository.getPostedPlaybackInfo(itemId, false, deviceProfile, VideoQuality.getBitrate(videoQuality))
|
||||||
val mediaSourceId =
|
val mediaSourceId =
|
||||||
playbackInfo.content.mediaSources
|
playbackInfo.content.mediaSources
|
||||||
.firstOrNull()
|
.firstOrNull()
|
||||||
|
@ -420,36 +414,14 @@ class DownloaderImpl(
|
||||||
deviceId,
|
deviceId,
|
||||||
mediaSourceId,
|
mediaSourceId,
|
||||||
playSessionId,
|
playSessionId,
|
||||||
maxBitrate,
|
VideoQuality.getBitrate(videoQuality),
|
||||||
"ts",
|
"ts",
|
||||||
|
VideoQuality.getQualityInt(videoQuality)
|
||||||
)
|
)
|
||||||
|
|
||||||
val transcodeUri = buildTranscodeUri(downloadUrl, maxBitrate, quality)
|
downloadUrl.toUri()
|
||||||
transcodeUri
|
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
null
|
null
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: I believe building upon the uri is not necessary anymore all is handled in the sdk api
|
|
||||||
private fun buildTranscodeUri(
|
|
||||||
transcodingUrl: String,
|
|
||||||
maxBitrate: Int,
|
|
||||||
quality: String,
|
|
||||||
): Uri {
|
|
||||||
val resolution =
|
|
||||||
when (quality) {
|
|
||||||
"720p" -> "720"
|
|
||||||
"480p" -> "480"
|
|
||||||
"360p" -> "360"
|
|
||||||
else -> "720"
|
|
||||||
}
|
|
||||||
return Uri
|
|
||||||
.parse(transcodingUrl)
|
|
||||||
.buildUpon()
|
|
||||||
.appendQueryParameter("MaxVideoHeight", resolution)
|
|
||||||
.appendQueryParameter("MaxVideoBitRate", maxBitrate.toString())
|
|
||||||
.appendQueryParameter("subtitleMethod", "External")
|
|
||||||
.build()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,13 +26,31 @@
|
||||||
<item>opensles</item>
|
<item>opensles</item>
|
||||||
</string-array>
|
</string-array>
|
||||||
<string-array name="quality_entries">
|
<string-array name="quality_entries">
|
||||||
|
<item>Auto</item>
|
||||||
<item>Original</item>
|
<item>Original</item>
|
||||||
<item>720p - 2Mbps</item>
|
<item>1080p - 8Mbps</item>
|
||||||
<item>480p - 1Mbps</item>
|
<item>720p - 3Mbps</item>
|
||||||
|
<item>480p - 1.5Mbps</item>
|
||||||
<item>360p - 800Kbps</item>
|
<item>360p - 800Kbps</item>
|
||||||
</string-array>
|
</string-array>
|
||||||
<string-array name="quality_values">
|
<string-array name="quality_values">
|
||||||
|
<item>Auto</item>
|
||||||
<item>Original</item>
|
<item>Original</item>
|
||||||
|
<item>1080p</item>
|
||||||
|
<item>720p</item>
|
||||||
|
<item>480p</item>
|
||||||
|
<item>360p</item>
|
||||||
|
</string-array>
|
||||||
|
<string-array name="download_quality_entries">
|
||||||
|
<item>Original</item>
|
||||||
|
<item>1080p - 8Mbps</item>
|
||||||
|
<item>720p - 3Mbps</item>
|
||||||
|
<item>480p - 1.5Mbps</item>
|
||||||
|
<item>360p - 800Kbps</item>
|
||||||
|
</string-array>
|
||||||
|
<string-array name="download_quality_values">
|
||||||
|
<item>Original</item>
|
||||||
|
<item>1080p</item>
|
||||||
<item>720p</item>
|
<item>720p</item>
|
||||||
<item>480p</item>
|
<item>480p</item>
|
||||||
<item>360p</item>
|
<item>360p</item>
|
||||||
|
|
|
@ -14,8 +14,8 @@
|
||||||
android:key="pref_downloads_quality"
|
android:key="pref_downloads_quality"
|
||||||
android:title="Download Quality"
|
android:title="Download Quality"
|
||||||
android:defaultValue="Original"
|
android:defaultValue="Original"
|
||||||
android:entries="@array/quality_entries"
|
android:entries="@array/download_quality_entries"
|
||||||
android:entryValues="@array/quality_values"
|
android:entryValues="@array/download_quality_values"
|
||||||
android:summary="%s" />
|
android:summary="%s" />
|
||||||
<SwitchPreferenceCompat
|
<SwitchPreferenceCompat
|
||||||
android:defaultValue="false"
|
android:defaultValue="false"
|
||||||
|
|
|
@ -0,0 +1,25 @@
|
||||||
|
package dev.jdtech.jellyfin.models
|
||||||
|
|
||||||
|
enum class VideoQuality(
|
||||||
|
val bitrate: Int,
|
||||||
|
val qualityString: String,
|
||||||
|
val qualityInt: Int,
|
||||||
|
) {
|
||||||
|
PAuto(10000000, "Auto", 1080),
|
||||||
|
POriginal(1000000000, "Original", 1080),
|
||||||
|
P1080(8000000, "1080p", 1080),
|
||||||
|
P720(3000000, "720p", 720),
|
||||||
|
P480(1500000, "480p", 480),
|
||||||
|
P360(800000, "360p", 360),
|
||||||
|
;
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
fun fromString(quality: String): VideoQuality? = entries.find { it.qualityString == quality }
|
||||||
|
|
||||||
|
fun getBitrate(quality: VideoQuality): Int = quality.bitrate
|
||||||
|
|
||||||
|
fun getQualityString(quality: VideoQuality): String = quality.qualityString
|
||||||
|
|
||||||
|
fun getQualityInt(quality: VideoQuality): Int = quality.qualityInt
|
||||||
|
}
|
||||||
|
}
|
|
@ -143,8 +143,6 @@ interface JellyfinRepository {
|
||||||
|
|
||||||
suspend fun getDeviceId(): String
|
suspend fun getDeviceId(): String
|
||||||
|
|
||||||
suspend fun getVideoTranscodeBitRate(transcodeResolution: Int): Pair<Int, Int>
|
|
||||||
|
|
||||||
suspend fun buildDeviceProfile(
|
suspend fun buildDeviceProfile(
|
||||||
maxBitrate: Int,
|
maxBitrate: Int,
|
||||||
container: String,
|
container: String,
|
||||||
|
@ -156,10 +154,9 @@ interface JellyfinRepository {
|
||||||
deviceId: String,
|
deviceId: String,
|
||||||
mediaSourceId: String,
|
mediaSourceId: String,
|
||||||
playSessionId: String,
|
playSessionId: String,
|
||||||
videoBitrate:
|
videoBitrate: Int,
|
||||||
@Suppress("ktlint:standard:max-line-length")
|
|
||||||
Int,
|
|
||||||
container: String,
|
container: String,
|
||||||
|
maxHeight: Int,
|
||||||
): String
|
): String
|
||||||
|
|
||||||
suspend fun getTranscodedVideoStream(
|
suspend fun getTranscodedVideoStream(
|
||||||
|
|
|
@ -16,6 +16,7 @@ import dev.jdtech.jellyfin.models.FindroidShow
|
||||||
import dev.jdtech.jellyfin.models.FindroidSource
|
import dev.jdtech.jellyfin.models.FindroidSource
|
||||||
import dev.jdtech.jellyfin.models.Intro
|
import dev.jdtech.jellyfin.models.Intro
|
||||||
import dev.jdtech.jellyfin.models.SortBy
|
import dev.jdtech.jellyfin.models.SortBy
|
||||||
|
import dev.jdtech.jellyfin.models.VideoQuality
|
||||||
import dev.jdtech.jellyfin.models.toFindroidCollection
|
import dev.jdtech.jellyfin.models.toFindroidCollection
|
||||||
import dev.jdtech.jellyfin.models.toFindroidEpisode
|
import dev.jdtech.jellyfin.models.toFindroidEpisode
|
||||||
import dev.jdtech.jellyfin.models.toFindroidItem
|
import dev.jdtech.jellyfin.models.toFindroidItem
|
||||||
|
@ -609,15 +610,6 @@ class JellyfinRepositoryImpl(
|
||||||
|
|
||||||
override fun getUserId(): UUID = jellyfinApi.userId!!
|
override fun getUserId(): UUID = jellyfinApi.userId!!
|
||||||
|
|
||||||
override suspend fun getVideoTranscodeBitRate(transcodeResolution: Int): Pair<Int, Int> =
|
|
||||||
when (transcodeResolution) {
|
|
||||||
1080 -> 8000000 to 384000 // Adjusted for personal can be other values
|
|
||||||
720 -> 2000000 to 384000 // 720p
|
|
||||||
480 -> 1000000 to 384000 // 480p
|
|
||||||
360 -> 800000 to 128000 // 360p
|
|
||||||
else -> 12000000 to 384000 // its adaptive but setting max here
|
|
||||||
}
|
|
||||||
|
|
||||||
override suspend fun buildDeviceProfile(
|
override suspend fun buildDeviceProfile(
|
||||||
maxBitrate: Int,
|
maxBitrate: Int,
|
||||||
container: String,
|
container: String,
|
||||||
|
@ -631,7 +623,7 @@ class JellyfinRepositoryImpl(
|
||||||
supportsPersistentIdentifier = true,
|
supportsPersistentIdentifier = true,
|
||||||
deviceProfile =
|
deviceProfile =
|
||||||
DeviceProfile(
|
DeviceProfile(
|
||||||
name = "AnanasUser",
|
name = "FindroidUser",
|
||||||
id = getUserId().toString(),
|
id = getUserId().toString(),
|
||||||
maxStaticBitrate = maxBitrate,
|
maxStaticBitrate = maxBitrate,
|
||||||
maxStreamingBitrate = maxBitrate,
|
maxStreamingBitrate = maxBitrate,
|
||||||
|
@ -648,8 +640,8 @@ class JellyfinRepositoryImpl(
|
||||||
container = container,
|
container = container,
|
||||||
context = context,
|
context = context,
|
||||||
protocol = MediaStreamProtocol.HLS,
|
protocol = MediaStreamProtocol.HLS,
|
||||||
audioCodec = "aac,ac3,eac3",
|
audioCodec = "aac",
|
||||||
videoCodec = "hevc,h264",
|
videoCodec = "h264",
|
||||||
type = DlnaProfileType.VIDEO,
|
type = DlnaProfileType.VIDEO,
|
||||||
conditions =
|
conditions =
|
||||||
listOf(
|
listOf(
|
||||||
|
@ -712,6 +704,7 @@ class JellyfinRepositoryImpl(
|
||||||
playSessionId: String,
|
playSessionId: String,
|
||||||
videoBitrate: Int,
|
videoBitrate: Int,
|
||||||
container: String,
|
container: String,
|
||||||
|
maxHeight: Int,
|
||||||
): String {
|
): String {
|
||||||
val url =
|
val url =
|
||||||
jellyfinApi.videosApi.getVideoStreamByContainerUrl(
|
jellyfinApi.videosApi.getVideoStreamByContainerUrl(
|
||||||
|
@ -721,10 +714,11 @@ class JellyfinRepositoryImpl(
|
||||||
mediaSourceId = mediaSourceId,
|
mediaSourceId = mediaSourceId,
|
||||||
playSessionId = playSessionId,
|
playSessionId = playSessionId,
|
||||||
videoBitRate = videoBitrate,
|
videoBitRate = videoBitrate,
|
||||||
audioBitRate = 384000,
|
audioBitRate = 128000,
|
||||||
videoCodec = "hevc",
|
videoCodec = "h264",
|
||||||
audioCodec = "aac,ac3,eac3",
|
audioCodec = "aac",
|
||||||
container = container,
|
container = container,
|
||||||
|
maxHeight = maxHeight,
|
||||||
startTimeTicks = 0,
|
startTimeTicks = 0,
|
||||||
copyTimestamps = true,
|
copyTimestamps = true,
|
||||||
subtitleMethod = SubtitleDeliveryMethod.EXTERNAL,
|
subtitleMethod = SubtitleDeliveryMethod.EXTERNAL,
|
||||||
|
@ -739,7 +733,7 @@ class JellyfinRepositoryImpl(
|
||||||
playSessionId: String,
|
playSessionId: String,
|
||||||
videoBitrate: Int,
|
videoBitrate: Int,
|
||||||
): String {
|
): String {
|
||||||
val isAuto = videoBitrate == 12000000
|
val isAuto = videoBitrate == VideoQuality.getBitrate(VideoQuality.PAuto)
|
||||||
val url =
|
val url =
|
||||||
if (!isAuto) {
|
if (!isAuto) {
|
||||||
jellyfinApi.api.dynamicHlsApi.getMasterHlsVideoPlaylistUrl(
|
jellyfinApi.api.dynamicHlsApi.getMasterHlsVideoPlaylistUrl(
|
||||||
|
@ -750,9 +744,9 @@ class JellyfinRepositoryImpl(
|
||||||
playSessionId = playSessionId,
|
playSessionId = playSessionId,
|
||||||
videoBitRate = videoBitrate,
|
videoBitRate = videoBitrate,
|
||||||
enableAdaptiveBitrateStreaming = false,
|
enableAdaptiveBitrateStreaming = false,
|
||||||
audioBitRate = 384000, // could also be passed with audioBitrate but i preferred not as its not much data anyways
|
audioBitRate = 128000,
|
||||||
videoCodec = "hevc,h264",
|
videoCodec = "h264",
|
||||||
audioCodec = "aac,ac3,eac3",
|
audioCodec = "aac",
|
||||||
startTimeTicks = 0,
|
startTimeTicks = 0,
|
||||||
copyTimestamps = true,
|
copyTimestamps = true,
|
||||||
subtitleMethod = SubtitleDeliveryMethod.EXTERNAL,
|
subtitleMethod = SubtitleDeliveryMethod.EXTERNAL,
|
||||||
|
@ -768,8 +762,8 @@ class JellyfinRepositoryImpl(
|
||||||
mediaSourceId = mediaSourceId,
|
mediaSourceId = mediaSourceId,
|
||||||
playSessionId = playSessionId,
|
playSessionId = playSessionId,
|
||||||
enableAdaptiveBitrateStreaming = true,
|
enableAdaptiveBitrateStreaming = true,
|
||||||
videoCodec = "hevc",
|
videoCodec = "h264",
|
||||||
audioCodec = "aac,ac3,eac3",
|
audioCodec = "aac",
|
||||||
startTimeTicks = 0,
|
startTimeTicks = 0,
|
||||||
copyTimestamps = true,
|
copyTimestamps = true,
|
||||||
subtitleMethod = SubtitleDeliveryMethod.EXTERNAL,
|
subtitleMethod = SubtitleDeliveryMethod.EXTERNAL,
|
||||||
|
@ -782,10 +776,7 @@ class JellyfinRepositoryImpl(
|
||||||
}
|
}
|
||||||
|
|
||||||
override suspend fun getDeviceId(): String {
|
override suspend fun getDeviceId(): String {
|
||||||
val devices = jellyfinApi.devicesApi.getDevices(getUserId())
|
return jellyfinApi.api.deviceInfo.id
|
||||||
return devices.content.items
|
|
||||||
?.firstOrNull()
|
|
||||||
?.id!!
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override suspend fun stopEncodingProcess(playSessionId: String) {
|
override suspend fun stopEncodingProcess(playSessionId: String) {
|
||||||
|
|
|
@ -330,10 +330,6 @@ class JellyfinRepositoryOfflineImpl(
|
||||||
TODO("Not yet implemented")
|
TODO("Not yet implemented")
|
||||||
}
|
}
|
||||||
|
|
||||||
override suspend fun getVideoTranscodeBitRate(transcodeResolution: Int): Pair<Int, Int> {
|
|
||||||
TODO("Not yet implemented")
|
|
||||||
}
|
|
||||||
|
|
||||||
override suspend fun buildDeviceProfile(
|
override suspend fun buildDeviceProfile(
|
||||||
maxBitrate: Int,
|
maxBitrate: Int,
|
||||||
container: String,
|
container: String,
|
||||||
|
@ -349,6 +345,7 @@ class JellyfinRepositoryOfflineImpl(
|
||||||
playSessionId: String,
|
playSessionId: String,
|
||||||
videoBitrate: Int,
|
videoBitrate: Int,
|
||||||
container: String,
|
container: String,
|
||||||
|
maxHeight: Int,
|
||||||
): String {
|
): String {
|
||||||
TODO("Not yet implemented")
|
TODO("Not yet implemented")
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,6 +28,7 @@ import dev.jdtech.jellyfin.models.Intro
|
||||||
import dev.jdtech.jellyfin.models.PlayerChapter
|
import dev.jdtech.jellyfin.models.PlayerChapter
|
||||||
import dev.jdtech.jellyfin.models.PlayerItem
|
import dev.jdtech.jellyfin.models.PlayerItem
|
||||||
import dev.jdtech.jellyfin.models.Trickplay
|
import dev.jdtech.jellyfin.models.Trickplay
|
||||||
|
import dev.jdtech.jellyfin.models.VideoQuality
|
||||||
import dev.jdtech.jellyfin.mpv.MPVPlayer
|
import dev.jdtech.jellyfin.mpv.MPVPlayer
|
||||||
import dev.jdtech.jellyfin.player.video.R
|
import dev.jdtech.jellyfin.player.video.R
|
||||||
import dev.jdtech.jellyfin.repository.JellyfinRepository
|
import dev.jdtech.jellyfin.repository.JellyfinRepository
|
||||||
|
@ -464,17 +465,6 @@ constructor(
|
||||||
eventsChannel.trySend(PlayerEvents.IsPlayingChanged(isPlaying))
|
eventsChannel.trySend(PlayerEvents.IsPlayingChanged(isPlaying))
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun getTranscodeResolutions(preferredQuality: String): Int {
|
|
||||||
return when (preferredQuality) {
|
|
||||||
"1080p" -> 1080 // TODO: 1080p this logic is based on 1080p being original
|
|
||||||
"720p - 2Mbps" -> 720
|
|
||||||
"480p - 1Mbps" -> 480
|
|
||||||
"360p - 800kbps" -> 360
|
|
||||||
"Auto" -> 1
|
|
||||||
else -> 1080 //default to Original
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fun changeVideoQuality(quality: String) {
|
fun changeVideoQuality(quality: String) {
|
||||||
val mediaId = player.currentMediaItem?.mediaId ?: return
|
val mediaId = player.currentMediaItem?.mediaId ?: return
|
||||||
val currentItem = items.firstOrNull { it.itemId.toString() == mediaId } ?: return
|
val currentItem = items.firstOrNull { it.itemId.toString() == mediaId } ?: return
|
||||||
|
@ -482,12 +472,9 @@ constructor(
|
||||||
|
|
||||||
viewModelScope.launch {
|
viewModelScope.launch {
|
||||||
try {
|
try {
|
||||||
val transcodingResolution = getTranscodeResolutions(quality)
|
val videoQuality = VideoQuality.fromString(quality)!!
|
||||||
val (videoBitRate, audioBitRate) = jellyfinRepository.getVideoTranscodeBitRate(
|
val deviceProfile = jellyfinRepository.buildDeviceProfile(VideoQuality.getBitrate(videoQuality), "mkv", EncodingContext.STREAMING)
|
||||||
transcodingResolution
|
val playbackInfo = jellyfinRepository.getPostedPlaybackInfo(currentItem.itemId,true,deviceProfile,VideoQuality.getBitrate(videoQuality))
|
||||||
)
|
|
||||||
val deviceProfile = jellyfinRepository.buildDeviceProfile(videoBitRate, "mkv", EncodingContext.STREAMING)
|
|
||||||
val playbackInfo = jellyfinRepository.getPostedPlaybackInfo(currentItem.itemId,true,deviceProfile,videoBitRate)
|
|
||||||
val playSessionId = playbackInfo.content.playSessionId
|
val playSessionId = playbackInfo.content.playSessionId
|
||||||
if (playSessionId != null) {
|
if (playSessionId != null) {
|
||||||
jellyfinRepository.stopEncodingProcess(playSessionId)
|
jellyfinRepository.stopEncodingProcess(playSessionId)
|
||||||
|
@ -537,18 +524,18 @@ constructor(
|
||||||
|
|
||||||
|
|
||||||
val allSubtitles =
|
val allSubtitles =
|
||||||
if (transcodingResolution == 1080) {
|
if (VideoQuality.getQualityString(videoQuality) == "Original") {
|
||||||
externalSubtitles
|
externalSubtitles
|
||||||
}else {
|
}else {
|
||||||
embeddedSubtitles.apply { addAll(externalSubtitles) }
|
embeddedSubtitles.apply { addAll(externalSubtitles) }
|
||||||
}
|
}
|
||||||
|
|
||||||
val url = if (transcodingResolution == 1080){
|
val url = if (VideoQuality.getQualityString(videoQuality) == "Original"){
|
||||||
jellyfinRepository.getStreamUrl(currentItem.itemId, currentItem.mediaSourceId, playSessionId)
|
jellyfinRepository.getStreamUrl(currentItem.itemId, currentItem.mediaSourceId, playSessionId)
|
||||||
} else {
|
} else {
|
||||||
val mediaSourceId = mediaSources[currentMediaItemIndex].id
|
val mediaSourceId = mediaSources[currentMediaItemIndex].id
|
||||||
val deviceId = jellyfinRepository.getDeviceId()
|
val deviceId = jellyfinRepository.getDeviceId()
|
||||||
val url = jellyfinRepository.getTranscodedVideoStream(currentItem.itemId, deviceId ,mediaSourceId, playSessionId!!, videoBitRate)
|
val url = jellyfinRepository.getTranscodedVideoStream(currentItem.itemId, deviceId ,mediaSourceId, playSessionId!!, VideoQuality.getBitrate(videoQuality))
|
||||||
val uriBuilder = url.toUri().buildUpon()
|
val uriBuilder = url.toUri().buildUpon()
|
||||||
val apiKey = jellyfinApi.api.accessToken // TODO: add in repo
|
val apiKey = jellyfinApi.api.accessToken // TODO: add in repo
|
||||||
uriBuilder.appendQueryParameter("api_key",apiKey )
|
uriBuilder.appendQueryParameter("api_key",apiKey )
|
||||||
|
|
Loading…
Reference in a new issue