From d64faac74cc4ba3f9b4776504a312ed8247cf972 Mon Sep 17 00:00:00 2001 From: Kai Date: Tue, 17 Jun 2025 10:26:33 -0500 Subject: [PATCH] simplify quality selector text Changelog: changed --- app/src/main/assets/scripts/source.js | 2 + .../java/com/futo/platformplayer/Settings.kt | 16 ++-- .../futo/platformplayer/UISlideOverlays.kt | 76 ++++++++++--------- .../streams/sources/DashManifestSource.kt | 2 + .../streams/sources/HLSManifestSource.kt | 2 + .../streams/sources/HLSVariantUrlSource.kt | 3 +- .../models/streams/sources/IVideoSource.kt | 1 + .../streams/sources/LocalVideoSource.kt | 7 +- .../models/streams/sources/VideoUrlSource.kt | 4 +- .../models/sources/JSDashManifestRawSource.kt | 3 + .../js/models/sources/JSDashManifestSource.kt | 2 + .../sources/JSDashManifestWidevineSource.kt | 1 + .../js/models/sources/JSHLSManifestSource.kt | 1 + .../js/models/sources/JSVideoUrlSource.kt | 2 + .../models/sources/LocalVideoFileSource.kt | 1 + .../mainactivity/main/VideoDetailView.kt | 73 ++++++++++++------ app/src/main/res/values/strings.xml | 2 + 17 files changed, 131 insertions(+), 67 deletions(-) diff --git a/app/src/main/assets/scripts/source.js b/app/src/main/assets/scripts/source.js index 0638f079..67406c1c 100644 --- a/app/src/main/assets/scripts/source.js +++ b/app/src/main/assets/scripts/source.js @@ -403,6 +403,8 @@ class VideoUrlSource { this.bitrate = obj.bitrate ?? 0; this.duration = obj.duration ?? 0; this.url = obj.url; + if(obj.frameRate) + this.frameRate = obj.frameRate; if(obj.requestModifier) this.requestModifier = obj.requestModifier; } diff --git a/app/src/main/java/com/futo/platformplayer/Settings.kt b/app/src/main/java/com/futo/platformplayer/Settings.kt index 6cb27e3f..d6c2d9f3 100644 --- a/app/src/main/java/com/futo/platformplayer/Settings.kt +++ b/app/src/main/java/com/futo/platformplayer/Settings.kt @@ -442,14 +442,18 @@ class Settings : FragmentedStorageFileJson() { fun getPreferredPreviewQualityPixelCount(): Int = preferedQualityToPixels(preferredPreviewQuality); @AdvancedField - @FormField(R.string.simplify_sources, FieldForm.TOGGLE, R.string.simplify_sources_description, 4) + @FormField(R.string.show_advanced_media_source_metadata, FieldForm.TOGGLE, R.string.show_advanced_media_source_metadata_desc, 4) + var showAdvancedMediaSourceMetadata: Boolean = false; + + @AdvancedField + @FormField(R.string.simplify_sources, FieldForm.TOGGLE, R.string.simplify_sources_description, 5) var simplifySources: Boolean = true; @AdvancedField - @FormField(R.string.always_allow_reverse_landscape_auto_rotate, FieldForm.TOGGLE, R.string.always_allow_reverse_landscape_auto_rotate_description, 5) + @FormField(R.string.always_allow_reverse_landscape_auto_rotate, FieldForm.TOGGLE, R.string.always_allow_reverse_landscape_auto_rotate_description, 6) var alwaysAllowReverseLandscapeAutoRotate: Boolean = true - @FormField(R.string.background_behavior, FieldForm.DROPDOWN, -1, 6) + @FormField(R.string.background_behavior, FieldForm.DROPDOWN, -1, 7) @DropdownFieldOptionsId(R.array.player_background_behavior) var backgroundPlay: Int = 2; @@ -457,7 +461,7 @@ class Settings : FragmentedStorageFileJson() { fun isBackgroundPictureInPicture() = backgroundPlay == 2; @AdvancedField - @FormField(R.string.resume_after_preview, FieldForm.DROPDOWN, R.string.when_watching_a_video_in_preview_mode_resume_at_the_position_when_opening_the_video_code, 7) + @FormField(R.string.resume_after_preview, FieldForm.DROPDOWN, R.string.when_watching_a_video_in_preview_mode_resume_at_the_position_when_opening_the_video_code, 8) @DropdownFieldOptionsId(R.array.resume_after_preview) var resumeAfterPreview: Int = 1; @@ -469,7 +473,7 @@ class Settings : FragmentedStorageFileJson() { return false; } - @FormField(R.string.chapter_update_fps_title, FieldForm.DROPDOWN, R.string.chapter_update_fps_description, 8) + @FormField(R.string.chapter_update_fps_title, FieldForm.DROPDOWN, R.string.chapter_update_fps_description, 9) @DropdownFieldOptionsId(R.array.chapter_fps) var chapterUpdateFPS: Int = 0; @@ -484,7 +488,7 @@ class Settings : FragmentedStorageFileJson() { } @AdvancedField - @FormField(R.string.live_chat_webview, FieldForm.TOGGLE, R.string.use_the_live_chat_web_window_when_available_over_native_implementation, 9) + @FormField(R.string.live_chat_webview, FieldForm.TOGGLE, R.string.use_the_live_chat_web_window_when_available_over_native_implementation, 10) var useLiveChatWindow: Boolean = true; @FormField(R.string.restart_after_audio_focus_loss, FieldForm.DROPDOWN, R.string.restart_playback_when_gaining_audio_focus_after_a_loss, 11) diff --git a/app/src/main/java/com/futo/platformplayer/UISlideOverlays.kt b/app/src/main/java/com/futo/platformplayer/UISlideOverlays.kt index 83387081..60b83988 100644 --- a/app/src/main/java/com/futo/platformplayer/UISlideOverlays.kt +++ b/app/src/main/java/com/futo/platformplayer/UISlideOverlays.kt @@ -74,6 +74,9 @@ import kotlinx.coroutines.launch import kotlinx.coroutines.withContext import java.io.ByteArrayInputStream import androidx.core.net.toUri +import androidx.media3.common.Format +import com.futo.platformplayer.others.Language +import java.util.Locale class UISlideOverlays { companion object { @@ -344,14 +347,18 @@ class UISlideOverlays { if (source is IHLSManifestAudioSource) { val variant = HLS.mediaRenditionToVariant(MediaRendition("AUDIO", playlist.baseUri, "Single Playlist", null, null, null, null, null))!! - val estSize = VideoHelper.estimateSourceSize(variant); - val prefix = if(estSize > 0) "±" + estSize.toHumanBytesSize() + " " else ""; + val language = variant.language + val mainText = when { + language != Language.UNKNOWN && variant.bitrate == Format.NO_VALUE -> Locale.forLanguageTag(language).displayLanguage + language == Language.UNKNOWN && variant.bitrate != Format.NO_VALUE -> variant.bitrate.toHumanBitrate() + language != Language.UNKNOWN && variant.bitrate != Format.NO_VALUE -> "${Locale.forLanguageTag(language).displayLanguage} ${variant.bitrate.toHumanBitrate()}" + else -> "Default" + } audioButtons.add(SlideUpMenuItem( container.context, R.drawable.ic_music, - variant.name, - listOf(variant.language, variant.codec).mapNotNull { x -> x.ifEmpty { null } }.joinToString(", "), - (prefix + variant.codec).trim(), + if (variant.name != "") variant.name else mainText, + if (Settings.instance.playback.showAdvancedMediaSourceMetadata) variant.codec.trim() else "", tag = variant, call = { selectedAudioVariant = variant @@ -363,14 +370,12 @@ class UISlideOverlays { } else { val variant = HLS.variantReferenceToVariant(VariantPlaylistReference(playlist.baseUri, StreamInfo(null, null, null, null, null, null, null, null, null))) - val estSize = VideoHelper.estimateSourceSize(variant); - val prefix = if(estSize > 0) "±" + estSize.toHumanBytesSize() + " " else ""; videoButtons.add(SlideUpMenuItem( container.context, R.drawable.ic_movie, - variant.name, - "${variant.width}x${variant.height}", - (prefix + variant.codec).trim(), + if (variant.name != "") variant.name else "${variant.width}p${variant.frameRate ?: ""}", + if (Settings.instance.playback.showAdvancedMediaSourceMetadata) variant.codec.trim() else "", + if (Settings.instance.playback.showAdvancedMediaSourceMetadata) variant.bitrate?.toHumanBitrate() else "", tag = variant, call = { selectedVideoVariant = variant @@ -385,16 +390,19 @@ class UISlideOverlays { } else if (playlist is HlsMultivariantPlaylist) { masterPlaylist = HLS.parseMasterPlaylist(masterPlaylistContent, resolvedPlaylistUrl) - masterPlaylist.getAudioSources().forEach { it -> - - val estSize = VideoHelper.estimateSourceSize(it); - val prefix = if(estSize > 0) "±" + estSize.toHumanBytesSize() + " " else ""; + masterPlaylist.getAudioSources().forEach { + val language = it.language + val mainText = when { + language != Language.UNKNOWN && it.bitrate == Format.NO_VALUE -> Locale.forLanguageTag(language).displayLanguage + language == Language.UNKNOWN && it.bitrate != Format.NO_VALUE -> it.bitrate.toHumanBitrate() + language != Language.UNKNOWN && it.bitrate != Format.NO_VALUE -> "${Locale.forLanguageTag(language).displayLanguage} ${it.bitrate.toHumanBitrate()}" + else -> "Default" + } audioButtons.add(SlideUpMenuItem( container.context, R.drawable.ic_music, - it.name, - listOf(it.language, it.codec).mapNotNull { x -> x.ifEmpty { null } }.joinToString(", "), - (prefix + it.codec).trim(), + if (it.name != "") it.name else mainText, + if (Settings.instance.playback.showAdvancedMediaSourceMetadata) it.codec.trim() else "", tag = it, call = { selectedAudioVariant = it @@ -414,14 +422,12 @@ class UISlideOverlays { }*/ masterPlaylist.getVideoSources().forEach { - val estSize = VideoHelper.estimateSourceSize(it); - val prefix = if(estSize > 0) "±" + estSize.toHumanBytesSize() + " " else ""; videoButtons.add(SlideUpMenuItem( container.context, R.drawable.ic_movie, - it.name, - "${it.width}x${it.height}", - (prefix + it.codec).trim(), + if (it.name != "") it.name else "${it.height}p${it.frameRate ?: ""}", + if (Settings.instance.playback.showAdvancedMediaSourceMetadata) it.codec.trim() else "", + if (Settings.instance.playback.showAdvancedMediaSourceMetadata) it.bitrate?.toHumanBitrate() else "", tag = it, call = { selectedVideoVariant = it @@ -535,9 +541,9 @@ class UISlideOverlays { SlideUpMenuItem( container.context, R.drawable.ic_movie, - it.name, - "${it.width}x${it.height}", - (prefix + it.codec).trim(), + if (it.name != "") it.name else "${it.height}p${it.frameRate ?: ""}", + if (Settings.instance.playback.showAdvancedMediaSourceMetadata) it.codec.trim() else "", + if (Settings.instance.playback.showAdvancedMediaSourceMetadata) it.bitrate?.toHumanBitrate() ?: "" else "", tag = it, call = { selectedVideo = it @@ -573,8 +579,7 @@ class UISlideOverlays { SlideUpMenuItem( container.context, R.drawable.ic_movie, - it.name, - "HLS", + if (it.name != "") it.name else "HLS", tag = it, call = { showHlsPicker(video, it, it.url, container) @@ -606,14 +611,18 @@ class UISlideOverlays { .map { when (it) { is IAudioUrlSource -> { - val estSize = VideoHelper.estimateSourceSize(it); - val prefix = if(estSize > 0) "±" + estSize.toHumanBytesSize() + " " else ""; + val mainText = when { + it.language != Language.UNKNOWN && it.bitrate == Format.NO_VALUE -> Locale.forLanguageTag(it.language).displayLanguage + it.language == Language.UNKNOWN && it.bitrate != Format.NO_VALUE -> it.bitrate.toHumanBitrate() + it.language != Language.UNKNOWN && it.bitrate != Format.NO_VALUE -> "${Locale.forLanguageTag(it.language).displayLanguage} ${it.bitrate.toHumanBitrate()}" + else -> "Default" + } SlideUpMenuItem( container.context, R.drawable.ic_music, - it.name, - "${it.bitrate}", - (prefix + it.codec).trim(), + if (it.name != "") it.name else mainText, + if (Settings.instance.playback.showAdvancedMediaSourceMetadata) it.codec.trim() ?: "" else "", + if (Settings.instance.playback.showAdvancedMediaSourceMetadata) (if (it.original) "Original" else "") else "", tag = it, call = { selectedAudio = it @@ -647,8 +656,7 @@ class UISlideOverlays { SlideUpMenuItem( container.context, R.drawable.ic_movie, - it.name, - "HLS Audio", + if (it.name != "") it.name else "HLS Audio", tag = it, call = { showHlsPicker(video, it, it.url, container) diff --git a/app/src/main/java/com/futo/platformplayer/api/media/models/streams/sources/DashManifestSource.kt b/app/src/main/java/com/futo/platformplayer/api/media/models/streams/sources/DashManifestSource.kt index 3d117516..c3eb571f 100644 --- a/app/src/main/java/com/futo/platformplayer/api/media/models/streams/sources/DashManifestSource.kt +++ b/app/src/main/java/com/futo/platformplayer/api/media/models/streams/sources/DashManifestSource.kt @@ -9,6 +9,8 @@ class DashManifestSource : IVideoSource, IDashManifestSource { override val bitrate: Int? = null; override val url : String; override val duration: Long get() = 0; + // only used for single source DASH + override val frameRate: Int? = null override var priority: Boolean = false; diff --git a/app/src/main/java/com/futo/platformplayer/api/media/models/streams/sources/HLSManifestSource.kt b/app/src/main/java/com/futo/platformplayer/api/media/models/streams/sources/HLSManifestSource.kt index 52304473..d570665c 100644 --- a/app/src/main/java/com/futo/platformplayer/api/media/models/streams/sources/HLSManifestSource.kt +++ b/app/src/main/java/com/futo/platformplayer/api/media/models/streams/sources/HLSManifestSource.kt @@ -9,6 +9,8 @@ class HLSManifestSource : IVideoSource, IHLSManifestSource { override val bitrate : Int? = null; override val url : String; override val duration: Long = 0; + override val frameRate: Int? + get() = null override var priority: Boolean = false; diff --git a/app/src/main/java/com/futo/platformplayer/api/media/models/streams/sources/HLSVariantUrlSource.kt b/app/src/main/java/com/futo/platformplayer/api/media/models/streams/sources/HLSVariantUrlSource.kt index 854cf9b8..52a5fa21 100644 --- a/app/src/main/java/com/futo/platformplayer/api/media/models/streams/sources/HLSVariantUrlSource.kt +++ b/app/src/main/java/com/futo/platformplayer/api/media/models/streams/sources/HLSVariantUrlSource.kt @@ -12,7 +12,8 @@ class HLSVariantVideoUrlSource( override val bitrate: Int?, override val duration: Long, override val priority: Boolean, - val url: String + val url: String, + override val frameRate: Int? = null ) : IVideoUrlSource { override fun getVideoUrl(): String { return url diff --git a/app/src/main/java/com/futo/platformplayer/api/media/models/streams/sources/IVideoSource.kt b/app/src/main/java/com/futo/platformplayer/api/media/models/streams/sources/IVideoSource.kt index 867c1ee5..b578f556 100644 --- a/app/src/main/java/com/futo/platformplayer/api/media/models/streams/sources/IVideoSource.kt +++ b/app/src/main/java/com/futo/platformplayer/api/media/models/streams/sources/IVideoSource.kt @@ -9,4 +9,5 @@ interface IVideoSource { val bitrate : Int?; val duration: Long; val priority: Boolean; + val frameRate: Int? } \ No newline at end of file diff --git a/app/src/main/java/com/futo/platformplayer/api/media/models/streams/sources/LocalVideoSource.kt b/app/src/main/java/com/futo/platformplayer/api/media/models/streams/sources/LocalVideoSource.kt index 5d15ddb8..2b653fd0 100644 --- a/app/src/main/java/com/futo/platformplayer/api/media/models/streams/sources/LocalVideoSource.kt +++ b/app/src/main/java/com/futo/platformplayer/api/media/models/streams/sources/LocalVideoSource.kt @@ -13,6 +13,7 @@ class LocalVideoSource : IVideoSource, IStreamMetaDataSource { override val name : String; override val bitrate : Int; override val duration : Long; + override val frameRate: Int? override var priority: Boolean = false; @@ -22,7 +23,7 @@ class LocalVideoSource : IVideoSource, IStreamMetaDataSource { //Only for particular videos override var streamMetaData: StreamMetaData? = null; - constructor(name : String, filePath : String, fileSize: Long, width : Int = 0, height : Int = 0, duration: Long = 0, container : String = "", codec : String = "", bitrate : Int = 0) { + constructor(name : String, filePath : String, fileSize: Long, width : Int = 0, height : Int = 0, duration: Long = 0, container : String = "", codec : String = "", bitrate : Int = 0, frameRate : Int? = null) { this.name = name; this.width = width; this.height = height; @@ -32,6 +33,7 @@ class LocalVideoSource : IVideoSource, IStreamMetaDataSource { this.filePath = filePath; this.fileSize = fileSize; this.bitrate = bitrate; + this.frameRate = frameRate } companion object { @@ -45,7 +47,8 @@ class LocalVideoSource : IVideoSource, IStreamMetaDataSource { source.duration, overrideContainer ?: source.container, source.codec, - source.bitrate?:0 + source.bitrate?:0, + source.frameRate ); } } diff --git a/app/src/main/java/com/futo/platformplayer/api/media/models/streams/sources/VideoUrlSource.kt b/app/src/main/java/com/futo/platformplayer/api/media/models/streams/sources/VideoUrlSource.kt index 490b8d4c..d8aac3cd 100644 --- a/app/src/main/java/com/futo/platformplayer/api/media/models/streams/sources/VideoUrlSource.kt +++ b/app/src/main/java/com/futo/platformplayer/api/media/models/streams/sources/VideoUrlSource.kt @@ -13,6 +13,7 @@ open class VideoUrlSource( override val container : String = "", override val codec : String = "", override val bitrate : Int? = 0, + override val frameRate: Int? = null, override var priority: Boolean = false ) : IVideoUrlSource, IStreamMetaDataSource { @@ -38,7 +39,8 @@ open class VideoUrlSource( source.duration, source.container, source.codec, - source.bitrate + source.bitrate, + source.frameRate ); ret.streamMetaData = streamData; diff --git a/app/src/main/java/com/futo/platformplayer/api/media/platforms/js/models/sources/JSDashManifestRawSource.kt b/app/src/main/java/com/futo/platformplayer/api/media/platforms/js/models/sources/JSDashManifestRawSource.kt index d6ff7455..6290f5ec 100644 --- a/app/src/main/java/com/futo/platformplayer/api/media/platforms/js/models/sources/JSDashManifestRawSource.kt +++ b/app/src/main/java/com/futo/platformplayer/api/media/platforms/js/models/sources/JSDashManifestRawSource.kt @@ -31,6 +31,8 @@ open class JSDashManifestRawSource: JSSource, IVideoSource, IJSDashManifestRawSo override val bitrate: Int?; override val duration: Long; override val priority: Boolean; + // only used for single source DASH + override val frameRate: Int? var url: String?; override var manifest: String?; @@ -52,6 +54,7 @@ open class JSDashManifestRawSource: JSSource, IVideoSource, IJSDashManifestRawSo codec = _obj.getOrDefault(config, "codec", contextName, "") ?: ""; bitrate = _obj.getOrDefault(config, "bitrate", contextName, 0) ?: 0; duration = _obj.getOrDefault(config, "duration", contextName, 0) ?: 0; + frameRate = _obj.getOrNull(config, "frameRate", contextName); priority = _obj.getOrDefault(config, "priority", contextName, false) ?: false; canMerge = _obj.getOrDefault(config, "canMerge", contextName, false) ?: false; hasGenerate = _obj.has("generate"); diff --git a/app/src/main/java/com/futo/platformplayer/api/media/platforms/js/models/sources/JSDashManifestSource.kt b/app/src/main/java/com/futo/platformplayer/api/media/platforms/js/models/sources/JSDashManifestSource.kt index 3070a2d4..336ab903 100644 --- a/app/src/main/java/com/futo/platformplayer/api/media/platforms/js/models/sources/JSDashManifestSource.kt +++ b/app/src/main/java/com/futo/platformplayer/api/media/platforms/js/models/sources/JSDashManifestSource.kt @@ -18,6 +18,8 @@ class JSDashManifestSource : IVideoUrlSource, IDashManifestSource, JSSource { override val bitrate: Int? = null; override val url : String; override val duration: Long; + // only used for single source DASH + override val frameRate: Int? = null override var priority: Boolean = false; diff --git a/app/src/main/java/com/futo/platformplayer/api/media/platforms/js/models/sources/JSDashManifestWidevineSource.kt b/app/src/main/java/com/futo/platformplayer/api/media/platforms/js/models/sources/JSDashManifestWidevineSource.kt index be72d3a0..a3c2c831 100644 --- a/app/src/main/java/com/futo/platformplayer/api/media/platforms/js/models/sources/JSDashManifestWidevineSource.kt +++ b/app/src/main/java/com/futo/platformplayer/api/media/platforms/js/models/sources/JSDashManifestWidevineSource.kt @@ -20,6 +20,7 @@ class JSDashManifestWidevineSource : IVideoUrlSource, IDashManifestSource, override val bitrate: Int? = null override val url: String override val duration: Long + override val frameRate: Int? = null override var priority: Boolean = false diff --git a/app/src/main/java/com/futo/platformplayer/api/media/platforms/js/models/sources/JSHLSManifestSource.kt b/app/src/main/java/com/futo/platformplayer/api/media/platforms/js/models/sources/JSHLSManifestSource.kt index 606d107c..60e4bed6 100644 --- a/app/src/main/java/com/futo/platformplayer/api/media/platforms/js/models/sources/JSHLSManifestSource.kt +++ b/app/src/main/java/com/futo/platformplayer/api/media/platforms/js/models/sources/JSHLSManifestSource.kt @@ -18,6 +18,7 @@ class JSHLSManifestSource : IHLSManifestSource, JSSource { override val bitrate : Int? = null; override val url : String; override val duration: Long; + override val frameRate: Int? = null override var priority: Boolean = false; diff --git a/app/src/main/java/com/futo/platformplayer/api/media/platforms/js/models/sources/JSVideoUrlSource.kt b/app/src/main/java/com/futo/platformplayer/api/media/platforms/js/models/sources/JSVideoUrlSource.kt index 66246f56..e470668b 100644 --- a/app/src/main/java/com/futo/platformplayer/api/media/platforms/js/models/sources/JSVideoUrlSource.kt +++ b/app/src/main/java/com/futo/platformplayer/api/media/platforms/js/models/sources/JSVideoUrlSource.kt @@ -16,6 +16,7 @@ open class JSVideoUrlSource : IVideoUrlSource, JSSource { override val name : String; override val bitrate : Int; override val duration: Long; + override val frameRate: Int? private val url : String; override var priority: Boolean = false; @@ -31,6 +32,7 @@ open class JSVideoUrlSource : IVideoUrlSource, JSSource { name = _obj.getOrThrow(config, "name", contextName); bitrate = _obj.getOrThrow(config, "bitrate", contextName); duration = _obj.getOrThrow(config, "duration", contextName).toLong(); + frameRate = _obj.getOrNull(config, "frameRate", contextName); url = _obj.getOrThrow(config, "url", contextName); priority = obj.getOrNull(config, "priority", contextName) ?: false; diff --git a/app/src/main/java/com/futo/platformplayer/api/media/platforms/local/models/sources/LocalVideoFileSource.kt b/app/src/main/java/com/futo/platformplayer/api/media/platforms/local/models/sources/LocalVideoFileSource.kt index 9e2f7792..4c59135c 100644 --- a/app/src/main/java/com/futo/platformplayer/api/media/platforms/local/models/sources/LocalVideoFileSource.kt +++ b/app/src/main/java/com/futo/platformplayer/api/media/platforms/local/models/sources/LocalVideoFileSource.kt @@ -19,6 +19,7 @@ class LocalVideoFileSource: IVideoSource { override val bitrate: Int = 0 override val duration: Long; override val priority: Boolean = false; + override val frameRate: Int? = null constructor(file: File) { name = file.name; diff --git a/app/src/main/java/com/futo/platformplayer/fragment/mainactivity/main/VideoDetailView.kt b/app/src/main/java/com/futo/platformplayer/fragment/mainactivity/main/VideoDetailView.kt index 2aec6eaf..de7ec63a 100644 --- a/app/src/main/java/com/futo/platformplayer/fragment/mainactivity/main/VideoDetailView.kt +++ b/app/src/main/java/com/futo/platformplayer/fragment/mainactivity/main/VideoDetailView.kt @@ -101,6 +101,7 @@ import com.futo.platformplayer.getNowDiffSeconds import com.futo.platformplayer.helpers.VideoHelper import com.futo.platformplayer.logging.Logger import com.futo.platformplayer.models.Subscription +import com.futo.platformplayer.others.Language import com.futo.platformplayer.receivers.MediaControlReceiver import com.futo.platformplayer.selectBestImage import com.futo.platformplayer.states.AnnouncementType @@ -2230,8 +2231,9 @@ class VideoDetailView : ConstraintLayout { .map { SlideUpMenuItem(this.context, R.drawable.ic_movie, - it.name, - "${it.width}x${it.height}", + if (it.name != "") it.name else "${it.height}p${it.frameRate ?: ""}", + if (Settings.instance.playback.showAdvancedMediaSourceMetadata) it.codec.trim() else "", + if (Settings.instance.playback.showAdvancedMediaSourceMetadata) it.bitrate?.toHumanBitrate() ?: "" else "", tag = it, call = { handleSelectVideoTrack(it) }); }.toList().toTypedArray()) @@ -2240,10 +2242,18 @@ class VideoDetailView : ConstraintLayout { SlideUpMenuGroup(this.context, context.getString(R.string.offline_audio), "audio", *localAudioSource .map { + val mainText = when { + it.language != Language.UNKNOWN && it.bitrate == Format.NO_VALUE -> Locale.forLanguageTag(it.language).displayLanguage + it.language == Language.UNKNOWN && it.bitrate != Format.NO_VALUE -> it.bitrate.toHumanBitrate() + it.language != Language.UNKNOWN && it.bitrate != Format.NO_VALUE -> "${Locale.forLanguageTag(it.language).displayLanguage} ${it.bitrate.toHumanBitrate()}" + else -> "Default" + } + SlideUpMenuItem(this.context, R.drawable.ic_music, - it.name, - it.bitrate.toHumanBitrate(), + if (it.name != "") it.name else mainText, + if (Settings.instance.playback.showAdvancedMediaSourceMetadata) it.codec.trim() ?: "" else "", + if (Settings.instance.playback.showAdvancedMediaSourceMetadata) (if (it.original) "Original" else "") else "", tag = it, call = { handleSelectAudioTrack(it) }); }.toList().toTypedArray()) @@ -2260,36 +2270,49 @@ class VideoDetailView : ConstraintLayout { this.context, context.getString(R.string.stream_video), "video", (listOf( SlideUpMenuItem(this.context, R.drawable.ic_movie, "Auto", tag = "auto", call = { _player.selectVideoTrack(-1) }) ) + (liveStreamVideoFormats.map { - SlideUpMenuItem(this.context, R.drawable.ic_movie, it.label - ?: it.containerMimeType - ?: it.bitrate.toString(), "${it.width}x${it.height}", tag = it, call = { _player.selectVideoTrack(it.height) }); + val frameRate = + if (it.frameRate.toInt() == Format.NO_VALUE) "" else it.frameRate.toInt() + SlideUpMenuItem( + this.context, R.drawable.ic_movie, "${it.height}p${frameRate}", + if (Settings.instance.playback.showAdvancedMediaSourceMetadata) it.containerMimeType ?: "" else "", + if (Settings.instance.playback.showAdvancedMediaSourceMetadata) it.label ?: it.bitrate.toHumanBitrate() else "", + tag = it, call = { _player.selectVideoTrack(it.height) }); })) ) else null, - if(liveStreamAudioFormats?.isEmpty() == false) - SlideUpMenuGroup(this.context, context.getString(R.string.stream_audio), "audio", + if (liveStreamAudioFormats?.isEmpty() == false) + SlideUpMenuGroup( + this.context, context.getString(R.string.stream_audio), "audio", *liveStreamAudioFormats .map { - SlideUpMenuItem(this.context, + val language = it.language + val mainText = when { + language != null && it.bitrate == Format.NO_VALUE -> Locale.forLanguageTag(language).displayLanguage + language == null && it.bitrate != Format.NO_VALUE -> it.bitrate.toHumanBitrate() + language != null && it.bitrate != Format.NO_VALUE -> "${Locale.forLanguageTag(language).displayLanguage} ${it.bitrate.toHumanBitrate()}" + else -> "Default" + } + SlideUpMenuItem( + this.context, R.drawable.ic_music, - "${it.label ?: it.containerMimeType} ${it.bitrate}", - "", + mainText, + if (Settings.instance.playback.showAdvancedMediaSourceMetadata) it.containerMimeType ?: "" else "", + if (Settings.instance.playback.showAdvancedMediaSourceMetadata) it.label else "", tag = it, call = { _player.selectAudioTrack(it.bitrate) }); - }.toList().toTypedArray()) + }.toList().toTypedArray() + ) else null, if(bestVideoSources.isNotEmpty()) SlideUpMenuGroup(this.context, context.getString(R.string.video), "video", *bestVideoSources .map { - val estSize = VideoHelper.estimateSourceSize(it); - val prefix = if(estSize > 0) "±" + estSize.toHumanBytesSize() + " " else ""; SlideUpMenuItem(this.context, R.drawable.ic_movie, - it!!.name, - if (it.width > 0 && it.height > 0) "${it.width}x${it.height}" else "", - (prefix + it.codec.trim()).trim(), + if (it.name != "") it.name else "${it.height}p${it.frameRate ?: ""}", + if (Settings.instance.playback.showAdvancedMediaSourceMetadata) it.codec.trim() else "", + if (Settings.instance.playback.showAdvancedMediaSourceMetadata) it.bitrate?.toHumanBitrate() ?: "" else "", tag = it, call = { handleSelectVideoTrack(it) }); }.toList().toTypedArray()) @@ -2298,13 +2321,17 @@ class VideoDetailView : ConstraintLayout { SlideUpMenuGroup(this.context, context.getString(R.string.audio), "audio", *bestAudioSources .map { - val estSize = VideoHelper.estimateSourceSize(it); - val prefix = if(estSize > 0) "±" + estSize.toHumanBytesSize() + " " else ""; + val mainText = when { + it.language != Language.UNKNOWN && it.bitrate == Format.NO_VALUE -> Locale.forLanguageTag(it.language).displayLanguage + it.language == Language.UNKNOWN && it.bitrate != Format.NO_VALUE -> it.bitrate.toHumanBitrate() + it.language != Language.UNKNOWN && it.bitrate != Format.NO_VALUE -> "${Locale.forLanguageTag(it.language).displayLanguage} ${it.bitrate.toHumanBitrate()}" + else -> "Default" + } SlideUpMenuItem(this.context, R.drawable.ic_music, - it.name, - it.bitrate.toHumanBitrate(), - (prefix + it.codec.trim()).trim(), + if (it.name != "") it.name else mainText, + if (Settings.instance.playback.showAdvancedMediaSourceMetadata) it.codec.trim() ?: "" else "", + if (Settings.instance.playback.showAdvancedMediaSourceMetadata) (if (it.original) "Original" else "") else "", tag = it, call = { handleSelectAudioTrack(it) }); }.toList().toTypedArray()) diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index b2831cec..03eca42c 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -300,6 +300,7 @@ Check disabled plugins for updates Planned Content Notifications Schedules discovered planned content as notifications, resulting in more accurate notifications for this content. + When displaying media sources show advanced metadata like container and codec Attempt to utilize byte ranges Auto Update Always allow reverse landscape auto-rotate @@ -348,6 +349,7 @@ Default Audio Quality Default Playback Speed Default Video Quality + Show Advanced Media Source Metadata Deletes license keys from app Download when Enable Video Cache