diff --git a/Changelog.md b/Changelog.md index c5289f5..e99f721 100644 --- a/Changelog.md +++ b/Changelog.md @@ -3,6 +3,8 @@ Change Log: All notable changes to this project will be documented in this section. +### 1.2.2 - Improved bitrate and subtitle selector and fixed control resize issue + ### 1.2.0 - Subtitle improvements: Default subtitle track auto-selected and get Label caption on subtitle selector ### 1.1.9 - Remove getKS call after successful login and updated validatePurchase to return error when valid token not available diff --git a/build.gradle b/build.gradle index 465de97..3727f43 100644 --- a/build.gradle +++ b/build.gradle @@ -15,8 +15,8 @@ plugins { id 'maven-publish' } // Versions of the library modules are matched (eg 1.0 core goes with 1.0 cloudmatrix) to prevent dependency issues -ext.SDK_VERSION_CODE = 21 -ext.SDK_VERSION_NAME = "1.2.0" +ext.SDK_VERSION_CODE = 22 +ext.SDK_VERSION_NAME = "1.2.2" publishing { publications { diff --git a/streamamg-sdk-playkit/src/main/java/com/streamamg/amg_playkit/AMGPlayKit.kt b/streamamg-sdk-playkit/src/main/java/com/streamamg/amg_playkit/AMGPlayKit.kt index 9de3c83..88e3282 100644 --- a/streamamg-sdk-playkit/src/main/java/com/streamamg/amg_playkit/AMGPlayKit.kt +++ b/streamamg-sdk-playkit/src/main/java/com/streamamg/amg_playkit/AMGPlayKit.kt @@ -3,6 +3,7 @@ package com.streamamg.amg_playkit import android.app.Activity import android.content.Context import android.content.pm.ActivityInfo +import android.content.res.Configuration import android.hardware.SensorManager import android.os.Handler import android.os.Looper @@ -11,6 +12,7 @@ import android.util.Log import android.util.TypedValue import android.view.LayoutInflater import android.view.OrientationEventListener +import android.view.View import android.widget.ImageView import android.widget.LinearLayout import com.google.gson.JsonObject @@ -268,6 +270,12 @@ class AMGPlayKit : LinearLayout, AMGPlayerInterface { } } + controlsView.addOnLayoutChangeListener(object : OnLayoutChangeListener { + override fun onLayoutChange(v: View?, left: Int, top: Int, right: Int, bottom: Int, oldLeft: Int, oldTop: Int, oldRight: Int, oldBottom: Int) { + isFullScreen = resources.configuration.orientation == Configuration.ORIENTATION_LANDSCAPE + controlsView.hideFullScreenButton(if (isFullScreen) 0 else 1) + } + }) } private fun checkDefaultCaptionTrack(textTracks: List) { @@ -1007,16 +1015,12 @@ class AMGPlayKit : LinearLayout, AMGPlayerInterface { orientationActivity?.requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED mSensorStateChanges = null mSensorStateChanges = SensorStateChangeActions.WATCH_FOR_PORTAIT_CHANGES - isFullScreen = false - controlsView.hideFullScreenButton(1) } else if (null != mSensorStateChanges && mSensorStateChanges == SensorStateChangeActions.WATCH_FOR_PORTAIT_CHANGES && (orientation >= 300 && orientation <= 359 || orientation >= 0 && orientation <= 45)) { mSensorStateChanges = SensorStateChangeActions.SWITCH_FROM_POTRAIT_TO_STANDARD } else if (null != mSensorStateChanges && mSensorStateChanges == SensorStateChangeActions.SWITCH_FROM_POTRAIT_TO_STANDARD && (orientation <= 300 && orientation >= 240 || orientation <= 130 && orientation >= 60)) { orientationActivity?.requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED mSensorStateChanges = null mSensorStateChanges = SensorStateChangeActions.WATCH_FOR_LANDSCAPE_CHANGES - isFullScreen = true - controlsView.hideFullScreenButton(0) } } } diff --git a/streamamg-sdk-playkit/src/main/java/com/streamamg/amg_playkit/controls/AMGPlayKitStandardControl.kt b/streamamg-sdk-playkit/src/main/java/com/streamamg/amg_playkit/controls/AMGPlayKitStandardControl.kt index 3b67a6f..9508df8 100644 --- a/streamamg-sdk-playkit/src/main/java/com/streamamg/amg_playkit/controls/AMGPlayKitStandardControl.kt +++ b/streamamg-sdk-playkit/src/main/java/com/streamamg/amg_playkit/controls/AMGPlayKitStandardControl.kt @@ -256,11 +256,13 @@ class AMGPlayKitStandardControl : LinearLayout, AMGControlInterface { settingsButton.setOnClickListener { toggleSubtitleSelector(true) toggleBitrateSelector(bitrateSelectorView.visibility == View.VISIBLE) + refreshViewChildrenLayout(this) } subtitleButton.setOnClickListener { toggleBitrateSelector(true) toggleSubtitleSelector(subtitleSelectorView.visibility == View.VISIBLE) + refreshViewChildrenLayout(this) } } @@ -288,6 +290,14 @@ class AMGPlayKitStandardControl : LinearLayout, AMGControlInterface { } } + private fun refreshViewChildrenLayout(view: View) { + view.measure( + MeasureSpec.makeMeasureSpec(view.measuredWidth, MeasureSpec.EXACTLY), + MeasureSpec.makeMeasureSpec(view.measuredHeight, MeasureSpec.EXACTLY) + ) + view.layout(view.left, view.top, view.right, view.bottom) + } + internal fun hideFullScreenButton(orientation: Int) { if (orientation == 0){ fullScreenButton.setImageResource(minimiseIcon) @@ -376,11 +386,13 @@ class AMGPlayKitStandardControl : LinearLayout, AMGControlInterface { startTime.append(" / ${timeForDisplay(duration)}", R.color.white_opacity_70) // endTime.text = timeForDisplay(timeRemaining) - val percentage = position.toFloat() / duration.toFloat() - val lpt = LayoutParams(0, MATCH_PARENT, percentage) - bottomScrubBarTrack.layoutParams = lpt - val lpb = LayoutParams(0, MATCH_PARENT, 1 - percentage) - bottomScrubBarBlank.layoutParams = lpb + if (bottomTrackShouldShow) { + val percentage = position.toFloat() / duration.toFloat() + val lpt = LayoutParams(0, MATCH_PARENT, percentage) + bottomScrubBarTrack.layoutParams = lpt + val lpb = LayoutParams(0, MATCH_PARENT, 1 - percentage) + bottomScrubBarBlank.layoutParams = lpb + } if (scrubBar.progress < scrubBar.max - 50) { liveButton.setText(R.string.go_live) @@ -472,6 +484,7 @@ class AMGPlayKitStandardControl : LinearLayout, AMGControlInterface { if (bottomTrackShouldShow) { bottomScrubBar.visibility = VISIBLE } + refreshViewChildrenLayout(this) } } @@ -503,6 +516,14 @@ class AMGPlayKitStandardControl : LinearLayout, AMGControlInterface { fun createSubtitlesSelector(subtitles: List) { subtitleSelectorView.removeAllViews() + + if (subtitles.isNullOrEmpty()) { + subtitleButton.visibility = View.GONE + return + } else { + subtitleButton.visibility = View.VISIBLE + } + subtitles.forEachIndexed { index, mediaTrack -> subtitleSelectorView.addView(listDivider()) subtitleSelectorView.addView(subtitleButton(mediaTrack, index)) @@ -535,6 +556,7 @@ class AMGPlayKitStandardControl : LinearLayout, AMGControlInterface { subtitleSelectorView.visibility = View.GONE subtitleButton.setBackgroundResource(R.color.transparent) selectedCaption = index + refreshViewChildrenLayout(this) } return btnSubtitle @@ -569,10 +591,18 @@ class AMGPlayKitStandardControl : LinearLayout, AMGControlInterface { fun createBitrateSelector(bitrates: List? = null) { bitrateSelectorView.removeAllViews() + + if (bitrates.isNullOrEmpty()) { + settingsButton.visibility = View.GONE + return + } else { + settingsButton.visibility = View.VISIBLE + } + bitrateSelectorView.addView(bitrateButton(bitrates?.lastOrNull(), 0, "Auto")) bitrates?.forEachIndexed { index, bitrate -> bitrateSelectorView.addView(listDivider()) - bitrateSelectorView.addView(bitrateButton(bitrate, index+1, "${bitrate.bitrate}")) + bitrateSelectorView.addView(bitrateButton(bitrate, index+1, "${bitrate.height}p")) } } @@ -639,6 +669,7 @@ class AMGPlayKitStandardControl : LinearLayout, AMGControlInterface { bitrateSelectorView.visibility = View.GONE settingsButton.setBackgroundResource(R.color.transparent) selectedBitrate = index + refreshViewChildrenLayout(this) } return btnBitrate diff --git a/streamamg-sdk-playkit/src/main/java/com/streamamg/amg_playkit/playkitExtensions/AMGPlayKit+Bitrate.kt b/streamamg-sdk-playkit/src/main/java/com/streamamg/amg_playkit/playkitExtensions/AMGPlayKit+Bitrate.kt index 8f0a92b..cacd572 100644 --- a/streamamg-sdk-playkit/src/main/java/com/streamamg/amg_playkit/playkitExtensions/AMGPlayKit+Bitrate.kt +++ b/streamamg-sdk-playkit/src/main/java/com/streamamg/amg_playkit/playkitExtensions/AMGPlayKit+Bitrate.kt @@ -57,13 +57,24 @@ internal fun AMGPlayKit.updateBitrateSelector(callBack: (List?) -> class MediaContext ( val flavorAssets: List?, ) { + fun fetchBitrates(): List? { -// fun fetchBitrates(): List? { -// return flavorAssets?.mapNotNull { it.bitrate }?.sorted() -// } + var uniqueAssets: MutableMap = mutableMapOf() // MutableMap to store unique assets by height - fun fetchBitrates(): List? { - return flavorAssets?.sortedBy { it.width } + flavorAssets?.forEach { flavorAsset -> + flavorAsset.height?.let { height -> + if (uniqueAssets.containsKey(height)) { + val exisstingBitrate = uniqueAssets[height] + if (exisstingBitrate?.bitrate ?: 0 < flavorAsset.bitrate ?: 0) { + uniqueAssets[height] = flavorAsset // Replace with higher bitrate asset + } + } else { + uniqueAssets[height] = flavorAsset // Add new unique asset + } + } + } + + return uniqueAssets.values.toList().sortedBy { it.bitrate } // Convert MutableMap values to a list and return it sorted } }