From 3b33abb68dfddd3f7ad4acea32548833e3def70d Mon Sep 17 00:00:00 2001 From: pratim Date: Thu, 9 Nov 2023 10:25:57 +0530 Subject: [PATCH 01/13] use the beam intermediate states to update UI --- .../meeting/HlsStreamingToggleBottomSheet.kt | 55 ----- .../hms/roomkit/ui/meeting/MeetingFragment.kt | 220 +++++++++--------- .../roomkit/ui/meeting/MeetingViewModel.kt | 59 ++--- .../hms/roomkit/ui/meeting/PreviewFragment.kt | 5 +- .../ui/meeting/RecordingTimesUseCase.kt | 4 +- .../ui/meeting/SessionOptionBottomSheet.kt | 8 +- ...ingState.kt => StreamingRecordingState.kt} | 4 +- .../live/hms/roomkit/ui/theme/ThemeExt.kt | 7 + .../main/res/drawable/ic_recording_pause.xml | 10 + .../src/main/res/layout/fragment_meeting.xml | 11 + 10 files changed, 177 insertions(+), 206 deletions(-) delete mode 100644 room-kit/src/main/java/live/hms/roomkit/ui/meeting/HlsStreamingToggleBottomSheet.kt rename room-kit/src/main/java/live/hms/roomkit/ui/meeting/{RecordingState.kt => StreamingRecordingState.kt} (52%) create mode 100644 room-kit/src/main/res/drawable/ic_recording_pause.xml diff --git a/room-kit/src/main/java/live/hms/roomkit/ui/meeting/HlsStreamingToggleBottomSheet.kt b/room-kit/src/main/java/live/hms/roomkit/ui/meeting/HlsStreamingToggleBottomSheet.kt deleted file mode 100644 index 8bf909f97..000000000 --- a/room-kit/src/main/java/live/hms/roomkit/ui/meeting/HlsStreamingToggleBottomSheet.kt +++ /dev/null @@ -1,55 +0,0 @@ -package live.hms.roomkit.ui.meeting - -import android.os.Bundle -import android.view.LayoutInflater -import android.view.View -import android.view.ViewGroup -import android.widget.Toast -import androidx.fragment.app.activityViewModels -import com.google.android.material.bottomsheet.BottomSheetDialogFragment -import live.hms.roomkit.databinding.HlsBottomSheetDialogBinding -import live.hms.roomkit.ui.meeting.participants.meetingToHlsUrl -import live.hms.roomkit.util.setOnSingleClickListener -import live.hms.roomkit.util.viewLifecycle -import live.hms.video.sdk.models.HMSHlsRecordingConfig - - -class HlsStreamingToggleBottomSheet( - private val meetingUrl: String, - private val hlsStateChangeListener: (Boolean) -> Unit -) : BottomSheetDialogFragment() { - - private var binding by viewLifecycle() - private val meetingViewModel: MeetingViewModel by activityViewModels() - - override fun onCreateView( - inflater: LayoutInflater, - container: ViewGroup?, - savedInstanceState: Bundle? - ): View { - binding = HlsBottomSheetDialogBinding.inflate(inflater, container, false) - return binding.root - } - - override fun onViewCreated(view: View, savedInstanceState: Bundle?) { - super.onViewCreated(view, savedInstanceState) - - binding.closeBtn.setOnClickListener { - dismiss() - } - - binding.btnGoLive.apply { - setOnSingleClickListener(1000) { - val videoOnDemand = binding.switchRecordStream.isChecked - meetingViewModel.startHls( - meetingUrl.meetingToHlsUrl(), - recordingConfig = HMSHlsRecordingConfig(true, videoOnDemand) - ) - meetingViewModel.hlsToggleUpdateLiveData.observe(requireActivity()) { - dismiss() - hlsStateChangeListener.invoke(it) - } - } - } - } -} \ No newline at end of file diff --git a/room-kit/src/main/java/live/hms/roomkit/ui/meeting/MeetingFragment.kt b/room-kit/src/main/java/live/hms/roomkit/ui/meeting/MeetingFragment.kt index 4a78b581f..3a66aabed 100644 --- a/room-kit/src/main/java/live/hms/roomkit/ui/meeting/MeetingFragment.kt +++ b/room-kit/src/main/java/live/hms/roomkit/ui/meeting/MeetingFragment.kt @@ -36,7 +36,6 @@ import androidx.navigation.fragment.findNavController import androidx.navigation.fragment.navArgs import com.bumptech.glide.Glide import com.google.android.material.imageview.ShapeableImageView -import com.google.android.material.snackbar.Snackbar import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.launch import kotlinx.coroutines.withContext @@ -72,10 +71,11 @@ import live.hms.video.audio.HMSAudioManager import live.hms.video.error.HMSException import live.hms.video.media.tracks.HMSLocalAudioTrack import live.hms.video.media.tracks.HMSLocalVideoTrack -import live.hms.video.polls.models.HmsPoll import live.hms.video.sdk.HMSActionResultListener import live.hms.video.sdk.models.HMSHlsRecordingConfig import live.hms.video.sdk.models.HMSRemovedFromRoom +import live.hms.video.sdk.models.enums.HMSRecordingState +import live.hms.video.sdk.models.enums.HMSStreamingState val LEAVE_INFORMATION_PERSON = "bundle-leave-information-person" @@ -91,9 +91,7 @@ class MeetingFragment : Fragment() { private var binding by viewLifecycle() private lateinit var currentFragment: Fragment - - - + private var hasStartedHls: Boolean = false private lateinit var settings: SettingsStore var countDownTimer: CountDownTimer? = null @@ -168,6 +166,7 @@ class MeetingFragment : Fragment() { override fun onDestroy() { super.onDestroy() isCountdownManuallyCancelled = true + hasStartedHls = false countDownTimer?.cancel() unregisterPipActionListener() } @@ -217,59 +216,70 @@ class MeetingFragment : Fragment() { } } - private fun updateGoLiveButton(recordingState: RecordingState) { - if ((meetingViewModel.isHlsKitUrl || meetingViewModel.hmsSDK.getLocalPeer() - ?.isWebrtcPeer() == true) && (meetingViewModel.isAllowedToHlsStream() || meetingViewModel.isAllowedToRtmpStream()) - ) { -// binding.buttonGoLive?.visibility = View.VISIBLE - } else { -// binding.buttonGoLive?.visibility = View.GONE - } - if (recordingState == RecordingState.STREAMING_AND_RECORDING ) { - binding.meetingFragmentProgress?.visibility = View.GONE -// binding.buttonGoLive?.setImageDrawable( -// ContextCompat.getDrawable( -// requireContext(), -// R.drawable.ic_stop_circle -// ) -// ) -// binding.buttonGoLive?.setBackgroundAndColor(DefaultTheme.getColours()?.alertErrorDefault, -// DefaultTheme.getDefaults().error_default) - binding.liveTitleCard?.visibility = View.VISIBLE - binding.tvViewersCountCard?.visibility = View.VISIBLE - binding.recordingSignal.visibility = View.VISIBLE - - if (meetingViewModel.isRTMPRunning()) { - binding.liveTitle?.text = "Live with RTMP" - } else { - binding.liveTitle?.text = "Live" + private fun updateStreamingRecordingViews(recordingState: StreamingRecordingState) { + when (recordingState) { + StreamingRecordingState.STREAMING_AND_RECORDING -> { + binding.recordingPause.visibility = + if (meetingViewModel.hmsSDK.getRoom()?.hlsRecordingState?.state == HMSRecordingState.PAUSED) { + View.VISIBLE + } else { + View.GONE + } + if (hasStartedHls && + meetingViewModel.hmsSDK.getRoom()?.hlsStreamingState?.state == HMSStreamingState.STARTING) { + binding.meetingFragmentProgress.visibility = View.GONE + } else { + binding.meetingFragmentProgress.visibility = View.GONE + } + + + binding.liveTitleCard.visibility = View.VISIBLE + binding.tvViewersCountCard.visibility = View.VISIBLE + binding.recordingSignal.visibility = View.VISIBLE + + if (meetingViewModel.isRTMPRunning()) { + binding.liveTitle.text = "Live with RTMP" + } else { + binding.liveTitle.text = "Live" + } + binding.tvViewersCount.visibility = View.VISIBLE + binding.tvViewersCountCard.visibility = View.VISIBLE + setupRecordingTimeView() } - binding.tvViewersCount?.visibility = View.VISIBLE - binding.tvViewersCountCard.visibility = View.VISIBLE - setupRecordingTimeView() - } else if (recordingState == RecordingState.RECORDING ){ - binding.liveTitleCard?.visibility = View.GONE - binding.recordingSignal.visibility = View.VISIBLE - binding.tvViewersCount?.visibility = View.GONE - binding.tvViewersCountCard.visibility = View.GONE - } else if (recordingState == RecordingState.STREAMING) { - binding.liveTitleCard?.visibility = View.VISIBLE - binding.tvViewersCountCard?.visibility = View.VISIBLE - binding.recordingSignal.visibility = View.GONE - - if (meetingViewModel.isRTMPRunning()) { - binding.liveTitle?.text = "Live with RTMP" - } else { - binding.liveTitle?.text = "Live" + StreamingRecordingState.RECORDING -> { + binding.recordingPause.visibility = + if (meetingViewModel.hmsSDK.getRoom()?.hlsRecordingState?.state == HMSRecordingState.PAUSED) { + View.VISIBLE + } else { + View.GONE + } + binding.recordingPause.visibility = View.GONE + binding.liveTitleCard.visibility = View.GONE + binding.recordingSignal.visibility = View.VISIBLE + binding.tvViewersCount.visibility = View.GONE + binding.tvViewersCountCard.visibility = View.GONE + } + StreamingRecordingState.STREAMING -> { + binding.recordingPause.visibility = View.GONE + binding.liveTitleCard.visibility = View.VISIBLE + binding.tvViewersCountCard.visibility = View.VISIBLE + binding.recordingSignal.visibility = View.GONE + + if (meetingViewModel.isRTMPRunning()) { + binding.liveTitle.text = "Live with RTMP" + } else { + binding.liveTitle.text = "Live" + } + binding.tvViewersCount.visibility = View.VISIBLE + binding.tvViewersCountCard.visibility = View.VISIBLE + } + StreamingRecordingState.NOT_RECORDING_OR_STREAMING -> { + binding.recordingPause.visibility = View.GONE + binding.recordingSignal.visibility = View.GONE + binding.liveTitleCard.visibility = View.GONE + binding.tvViewersCount.visibility = View.GONE + binding.tvViewersCountCard.visibility = View.GONE } - binding.tvViewersCount?.visibility = View.VISIBLE - binding.tvViewersCountCard.visibility = View.VISIBLE - } - else { - binding.recordingSignal.visibility = View.GONE - binding.liveTitleCard?.visibility = View.GONE - binding.tvViewersCount?.visibility = View.GONE - binding.tvViewersCountCard.visibility = View.GONE } } @@ -315,20 +325,7 @@ class MeetingFragment : Fragment() { super.onViewCreated(view, savedInstanceState) binding.applyTheme() initObservers() - meetingViewModel.isRecording.observe( - viewLifecycleOwner, - Observer { - updateGoLiveButton(it) - }) - - meetingViewModel.isHandRaised.observe(viewLifecycleOwner) { isHandRaised -> - if (isHandRaised) { - binding.buttonRaiseHand?.setIconDisabled(R.drawable.ic_raise_hand) - } else { - binding.buttonRaiseHand?.setIconEnabled(R.drawable.ic_raise_hand) - } - } binding.iconSend.setOnSingleClickListener { val messageStr = binding.editTextMessage.text.toString().trim() if (messageStr.isNotEmpty()) { @@ -361,7 +358,8 @@ class MeetingFragment : Fragment() { } else { //start HLS stream if (args.startHlsStream && meetingViewModel.isAllowedToHlsStream()) { - binding.meetingFragmentProgress?.visibility = View.VISIBLE + binding.meetingFragmentProgress.visibility = View.VISIBLE + hasStartedHls = true meetingViewModel.startHls(settings.lastUsedMeetingUrl, HMSHlsRecordingConfig(true, false)) } @@ -376,15 +374,6 @@ class MeetingFragment : Fragment() { activity?.moveTaskToBack(false) } - /*Intent(requireContext(), HomeActivity::class.java).apply { - crashlyticsLog(TAG, "MeetingActivity.finish() -> going to HomeActivity :: $this") - if (details != null) { - putExtra(LEAVE_INFORMATION_PERSON, details.peerWhoRemoved?.name ?: "Someone") - putExtra(LEAVE_INFORMATION_REASON, details.reason) - putExtra(LEAVE_INFROMATION_WAS_END_ROOM, details.roomWasEnded) - } - startActivity(this) - }*/ requireActivity().finish() } @@ -403,16 +392,47 @@ class MeetingFragment : Fragment() { chatViewModel.receivedMessage(it) } - meetingViewModel.isRecordingInProgess.observe(viewLifecycleOwner) { - if (it) { - binding.recordingSignalProgress.visibility = View.VISIBLE - } else { - binding.recordingSignalProgress.visibility = View.GONE + meetingViewModel.recordingState.observe(viewLifecycleOwner) { state -> + when (state) { + HMSRecordingState.STARTING -> { + binding.recordingSignalProgress.visibility = View.VISIBLE + binding.recordingSignal.visibility = View.GONE + binding.recordingPause.visibility = View.GONE + } + HMSRecordingState.RESUMED, HMSRecordingState.STARTED -> { + binding.recordingSignalProgress.visibility = View.GONE + binding.recordingSignal.visibility = View.VISIBLE + binding.recordingPause.visibility = View.GONE + } + HMSRecordingState.PAUSED -> { + binding.recordingSignalProgress.visibility = View.GONE + binding.recordingSignal.visibility = View.GONE + binding.recordingPause.visibility = View.VISIBLE + } + HMSRecordingState.FAILED, HMSRecordingState.NONE, HMSRecordingState.STOPPED -> { + binding.recordingSignalProgress.visibility = View.GONE + binding.recordingSignal.visibility = View.GONE + binding.recordingPause.visibility = View.GONE + } } } + meetingViewModel.isRecording.observe( + viewLifecycleOwner, + Observer { + updateStreamingRecordingViews(it) + }) + + + meetingViewModel.isHandRaised.observe(viewLifecycleOwner) { isHandRaised -> + if (isHandRaised) { + binding.buttonRaiseHand.setIconDisabled(R.drawable.ic_raise_hand) + } else { + binding.buttonRaiseHand.setIconEnabled(R.drawable.ic_raise_hand) + } + } - meetingViewModel.isRecording.observe(viewLifecycleOwner) {recordingState -> + meetingViewModel.isRecording.observe(viewLifecycleOwner) { val isRecording = meetingViewModel.isRecordingState() binding.recordingSignal.visibility = if (isRecording) View.VISIBLE else View.GONE } @@ -424,8 +444,8 @@ class MeetingFragment : Fragment() { meetingViewModel.hlsToggleUpdateLiveData.observe(viewLifecycleOwner) { when(it) { - true -> binding.meetingFragmentProgress?.visibility = View.VISIBLE - false -> binding.meetingFragmentProgress?.visibility = View.GONE + true -> binding.meetingFragmentProgress.visibility = View.VISIBLE + false -> binding.meetingFragmentProgress.visibility = View.GONE } } @@ -1026,7 +1046,7 @@ class MeetingFragment : Fragment() { } binding.progressBar.root.visibility = View.GONE - binding.meetingFragmentProgress?.visibility = View.GONE + binding.meetingFragmentProgress.visibility = View.GONE } private fun showProgressBar() { @@ -1282,31 +1302,7 @@ class MeetingFragment : Fragment() { object : OnBackPressedCallback(true) { override fun handleOnBackPressed() { Log.v(TAG, "initOnBackPress -> handleOnBackPressed") - val recordingState = meetingViewModel.isRecording.value - -// if (recordingState == RecordingState.NOT_RECORDING_OR_STREAMING && meetingViewModel.isHlsKitUrl -// ) { -// -// val endCallDialog = Dialog(requireContext()) -// endCallDialog.setContentView(R.layout.exit_confirmation_dialog) -// endCallDialog.findViewById(R.id.dialog_title).text = -// "Leave Meeting" -// endCallDialog.findViewById(R.id.dialog_description).text = -// "You're about to quit the meeting, are you sure?" -// endCallDialog.findViewById(R.id.cancel_btn).text = -// "Don’t Leave" -// endCallDialog.findViewById(R.id.accept_btn).text = "Leave" -// endCallDialog.findViewById(R.id.cancel_btn) -// .setOnClickListener { endCallDialog.dismiss() } -// endCallDialog.findViewById(R.id.accept_btn) -// .setOnClickListener { -// endCallDialog.dismiss() -// meetingViewModel.leaveMeeting() -// } -// endCallDialog.show() -// } else { inflateExitFlow() -// } } }) } diff --git a/room-kit/src/main/java/live/hms/roomkit/ui/meeting/MeetingViewModel.kt b/room-kit/src/main/java/live/hms/roomkit/ui/meeting/MeetingViewModel.kt index 0dce3267d..44fb1480b 100644 --- a/room-kit/src/main/java/live/hms/roomkit/ui/meeting/MeetingViewModel.kt +++ b/room-kit/src/main/java/live/hms/roomkit/ui/meeting/MeetingViewModel.kt @@ -333,14 +333,14 @@ class MeetingViewModel( val isLocalAudioEnabled = MutableLiveData(settings.publishAudio) val isLocalVideoEnabled = MutableLiveData(settings.publishVideo) - private val _isRecording = MutableLiveData(RecordingState.NOT_RECORDING_OR_STREAMING) - val isRecording: LiveData = _isRecording + private val _isRecording = MutableLiveData(StreamingRecordingState.NOT_RECORDING_OR_STREAMING) + val isRecording: LiveData = _isRecording private var hmsRoom: HMSRoom? = null // Live data for enabling/disabling mute buttons val isLocalAudioPresent = MutableLiveData(false) val isLocalVideoPresent = MutableLiveData(false) - val isRecordingInProgess = MutableLiveData(false) + val recordingState = MutableLiveData(HMSRecordingState.NONE) // Live data containing all the current tracks in a meeting private val _liveDataTracks = MutableLiveData(_tracks) @@ -476,7 +476,7 @@ class MeetingViewModel( override fun onRoomUpdate(type: HMSRoomUpdate, hmsRoom: HMSRoom) { roomState.postValue(Pair(type, hmsRoom)) // This will keep the isRecording value updated correctly in preview. It will not be called after join. - _isRecording.postValue(getRecordingState(hmsRoom)) + _isRecording.postValue(getStreamingRecordingState(hmsRoom)) if (type == HMSRoomUpdate.ROOM_PEER_COUNT_UPDATED) { peerCount.postValue(hmsRoom.peerCount) } @@ -702,7 +702,7 @@ class MeetingViewModel( val hlsUrl = room.hlsStreamingState?.variants?.get(0)?.hlsStreamUrl switchToHlsViewIfRequired(room.localPeer?.hmsRole, hlsUrl) _isRecording.postValue( - getRecordingState(room) + getStreamingRecordingState(room) ) sessionMetadataUseCase.setPinnedMessageUpdateListener( { message -> _sessionMetadata.postValue(message) }, @@ -825,34 +825,31 @@ class MeetingViewModel( HMSRoomUpdate.ROOM_PEER_COUNT_UPDATED -> peerCount.postValue(hmsRoom.peerCount) HMSRoomUpdate.SERVER_RECORDING_STATE_UPDATED -> { _isRecording.postValue( - getRecordingState(hmsRoom) + getStreamingRecordingState(hmsRoom) ) showServerInfo(hmsRoom) } HMSRoomUpdate.RTMP_STREAMING_STATE_UPDATED -> { _isRecording.postValue( - getRecordingState(hmsRoom) + getStreamingRecordingState(hmsRoom) ) showRtmpInfo(hmsRoom) } HMSRoomUpdate.BROWSER_RECORDING_STATE_UPDATED -> { _isRecording.postValue( - getRecordingState(hmsRoom) + getStreamingRecordingState(hmsRoom) ) showRecordInfo(hmsRoom) - if (hmsRoom.browserRecordingState?.initialising == true) - isRecordingInProgess.postValue(true) - else (hmsRoom.browserRecordingState?.running == true) - isRecordingInProgess.postValue(false) + recordingState.postValue(hmsRoom.browserRecordingState.state) } HMSRoomUpdate.HLS_STREAMING_STATE_UPDATED -> { _isRecording.postValue( - getRecordingState(hmsRoom) + getStreamingRecordingState(hmsRoom) ) switchToHlsViewIfRequired() showHlsInfo(hmsRoom) @@ -860,9 +857,11 @@ class MeetingViewModel( HMSRoomUpdate.HLS_RECORDING_STATE_UPDATED -> { _isRecording.postValue( - getRecordingState(hmsRoom) + getStreamingRecordingState(hmsRoom) ) showHlsRecordingInfo(hmsRoom) + + recordingState.postValue(hmsRoom.hlsRecordingState.state) } else -> { @@ -1095,29 +1094,31 @@ class MeetingViewModel( } fun isServerRecordingEnabled(room: HMSRoom): Boolean { - return room.serverRecordingState?.running == true + return room.serverRecordingState.state == HMSRecordingState.STARTED } - private fun getRecordingState(room: HMSRoom): RecordingState { + private fun getStreamingRecordingState(room: HMSRoom): StreamingRecordingState { - val recording = room.browserRecordingState?.running == true || - room.hlsRecordingState?.running == true - val streaming = room.rtmpHMSRtmpStreamingState?.running == true || - room.hlsStreamingState?.running == true + val runningRecordingStates = listOf(HMSRecordingState.STARTING, HMSRecordingState.STARTED, HMSRecordingState.PAUSED, HMSRecordingState.RESUMED) + val runningStreamingStates = listOf(HMSStreamingState.STARTING, HMSStreamingState.STARTED) + val recording = (room.browserRecordingState.state in runningRecordingStates) || + (room.hlsRecordingState.state in runningRecordingStates) + val streaming = (room.rtmpHMSRtmpStreamingState.state in runningStreamingStates) || + (room.hlsStreamingState.state in runningStreamingStates) return if (recording && streaming) { - RecordingState.STREAMING_AND_RECORDING + StreamingRecordingState.STREAMING_AND_RECORDING } else if (recording) { - RecordingState.RECORDING + StreamingRecordingState.RECORDING } else if (streaming) { - RecordingState.STREAMING + StreamingRecordingState.STREAMING } else { - RecordingState.NOT_RECORDING_OR_STREAMING + StreamingRecordingState.NOT_RECORDING_OR_STREAMING } } - fun isHlsRunning() = hmsRoom?.hlsStreamingState?.running == true - fun isRTMPRunning() = hmsRoom?.rtmpHMSRtmpStreamingState?.running == true + fun isHlsRunning() = hmsSDK.getRoom()?.hlsStreamingState?.state == HMSStreamingState.STARTED + fun isRTMPRunning() = hmsSDK.getRoom()?.rtmpHMSRtmpStreamingState?.state == HMSStreamingState.STARTED fun setStatetoOngoing() { state.postValue(MeetingState.Ongoing()) @@ -1565,7 +1566,7 @@ class MeetingViewModel( runnable: Runnable? = null ) { // It's streaming if there are rtmp urls present. - isRecordingInProgess.postValue(true) + recordingState.postValue(HMSRecordingState.STARTING) Log.v(TAG, "Starting recording. url: $rtmpInjectUrls") hmsSDK.startRtmpOrRecording( HMSRecordingConfig( @@ -1575,7 +1576,7 @@ class MeetingViewModel( inputWidthHeight ), object : HMSActionResultListener { override fun onError(error: HMSException) { - isRecordingInProgess.postValue(false) + recordingState.postValue(HMSRecordingState.FAILED) Log.d(TAG, "RTMP recording error: $error") // restore the current state runnable?.run() @@ -2136,7 +2137,7 @@ class MeetingViewModel( } fun isRecordingState(): Boolean { - return isRecording.value == RecordingState.RECORDING || isRecording.value == RecordingState.STREAMING_AND_RECORDING + return isRecording.value == StreamingRecordingState.RECORDING || isRecording.value == StreamingRecordingState.STREAMING_AND_RECORDING } fun requestBringOnStage(handRaisePeer: HMSPeer, onStageRole: String) { diff --git a/room-kit/src/main/java/live/hms/roomkit/ui/meeting/PreviewFragment.kt b/room-kit/src/main/java/live/hms/roomkit/ui/meeting/PreviewFragment.kt index b81acc37e..056f657cd 100644 --- a/room-kit/src/main/java/live/hms/roomkit/ui/meeting/PreviewFragment.kt +++ b/room-kit/src/main/java/live/hms/roomkit/ui/meeting/PreviewFragment.kt @@ -57,6 +57,7 @@ import live.hms.video.sdk.models.HMSLocalPeer import live.hms.video.sdk.models.HMSPeer import live.hms.video.sdk.models.HMSRoom import live.hms.video.sdk.models.enums.HMSPeerUpdate +import live.hms.video.sdk.models.enums.HMSStreamingState import live.hms.video.sdk.models.role.PublishParams import live.hms.videoview.VideoViewStateChangeListener @@ -332,10 +333,10 @@ class PreviewFragment : Fragment() { binding.participantCountText.text = it.second.peerCount.formatNames().orEmpty() binding.iconParticipants.startBounceAnimationUpwards() } - isHlsRunning = it.second.hlsStreamingState?.running == true + isHlsRunning = it.second.hlsStreamingState.state == HMSStreamingState.STARTED updateJoinButtonTextIfHlsIsEnabled(it?.second?.localPeer?.hmsRole?.name) - if (it.second.hlsStreamingState?.running == true) { + if (it.second.hlsStreamingState.state == HMSStreamingState.STARTED) { binding.liveHlsGroup.visibility = View.VISIBLE binding.hlsSession.startBounceAnimationUpwards() } else { diff --git a/room-kit/src/main/java/live/hms/roomkit/ui/meeting/RecordingTimesUseCase.kt b/room-kit/src/main/java/live/hms/roomkit/ui/meeting/RecordingTimesUseCase.kt index d0905ff51..c809f95a9 100644 --- a/room-kit/src/main/java/live/hms/roomkit/ui/meeting/RecordingTimesUseCase.kt +++ b/room-kit/src/main/java/live/hms/roomkit/ui/meeting/RecordingTimesUseCase.kt @@ -1,6 +1,8 @@ package live.hms.roomkit.ui.meeting import live.hms.video.sdk.models.HMSRoom +import live.hms.video.sdk.models.enums.HMSRecordingState +import live.hms.video.sdk.models.enums.HMSStreamingState import java.text.SimpleDateFormat import java.util.* @@ -26,7 +28,7 @@ class RecordingTimesUseCase() { fun showHlsInfo(room: HMSRoom, isRecordingEvent: Boolean) : String { val prefix = if(isRecordingEvent) "RecordingEvent:" else "StreamingEvent:" - return "$prefix: HLS Streaming: ${room.hlsStreamingState?.running}, Recording: ${room.hlsRecordingState?.running}, Variants: ${room.hlsStreamingState?.variants}, Recording Config: ${room.hlsRecordingState?.hlsRecordingConfig}" + return "$prefix: HLS Streaming: ${room.hlsStreamingState.state == HMSStreamingState.STARTED}, Recording: ${room.hlsRecordingState.state == HMSRecordingState.STARTED}, Variants: ${room.hlsStreamingState.variants}, Recording Config: ${room.hlsRecordingState.hlsRecordingConfig}" } private fun convertTimes(startedAt : Long?, stoppedAt: Long?) : Pair { diff --git a/room-kit/src/main/java/live/hms/roomkit/ui/meeting/SessionOptionBottomSheet.kt b/room-kit/src/main/java/live/hms/roomkit/ui/meeting/SessionOptionBottomSheet.kt index 320c2cadb..028e0ef41 100644 --- a/room-kit/src/main/java/live/hms/roomkit/ui/meeting/SessionOptionBottomSheet.kt +++ b/room-kit/src/main/java/live/hms/roomkit/ui/meeting/SessionOptionBottomSheet.kt @@ -18,8 +18,8 @@ import live.hms.roomkit.databinding.BottomSheetOptionBinding import live.hms.roomkit.ui.GridOptionItem import live.hms.roomkit.ui.theme.HMSPrebuiltTheme import live.hms.roomkit.ui.theme.getColorOrDefault -import live.hms.roomkit.util.contextSafe import live.hms.roomkit.util.viewLifecycle +import live.hms.video.sdk.models.enums.HMSRecordingState class SessionOptionBottomSheet( private val onScreenShareClicked: () -> Unit, @@ -159,7 +159,7 @@ class SessionOptionBottomSheet( - meetingViewModel.isRecording.observe(viewLifecycleOwner) {recordingState -> + meetingViewModel.isRecording.observe(viewLifecycleOwner) { val isRecording = meetingViewModel.isRecordingState() recordingOption.setSelectedButton(isRecording) recordingOption.setText(if (isRecording) resources.getString(R.string.stop_recording) else resources.getString(R.string.start_record_meeting)) @@ -181,9 +181,9 @@ class SessionOptionBottomSheet( } - meetingViewModel.isRecordingInProgess.observe(viewLifecycleOwner) { + meetingViewModel.recordingState.observe(viewLifecycleOwner) { Log.d("SessionOptionBottoSheet", "isRecordingInProgess: $it") - recordingOption.showProgress(it) + recordingOption.showProgress(it == HMSRecordingState.STARTING) } } diff --git a/room-kit/src/main/java/live/hms/roomkit/ui/meeting/RecordingState.kt b/room-kit/src/main/java/live/hms/roomkit/ui/meeting/StreamingRecordingState.kt similarity index 52% rename from room-kit/src/main/java/live/hms/roomkit/ui/meeting/RecordingState.kt rename to room-kit/src/main/java/live/hms/roomkit/ui/meeting/StreamingRecordingState.kt index 1dd3bb12b..708061223 100644 --- a/room-kit/src/main/java/live/hms/roomkit/ui/meeting/RecordingState.kt +++ b/room-kit/src/main/java/live/hms/roomkit/ui/meeting/StreamingRecordingState.kt @@ -1,10 +1,8 @@ package live.hms.roomkit.ui.meeting -enum class RecordingState { +enum class StreamingRecordingState { RECORDING, NOT_RECORDING_OR_STREAMING, - RECORDING_TRANSITIONING_TO_NOT_RECORDING, - NOT_RECORDING_TRANSITION_IN_PROGRESS, STREAMING, STREAMING_AND_RECORDING } \ No newline at end of file diff --git a/room-kit/src/main/java/live/hms/roomkit/ui/theme/ThemeExt.kt b/room-kit/src/main/java/live/hms/roomkit/ui/theme/ThemeExt.kt index 24ae45b83..a1395fc84 100644 --- a/room-kit/src/main/java/live/hms/roomkit/ui/theme/ThemeExt.kt +++ b/room-kit/src/main/java/live/hms/roomkit/ui/theme/ThemeExt.kt @@ -461,6 +461,13 @@ internal fun FragmentMeetingBinding.applyTheme() { ) ) + recordingPause.drawable.setTint( + getColorOrDefault( + HMSPrebuiltTheme.getColours()?.onSurfaceHigh, + HMSPrebuiltTheme.getDefaults().onsurface_high_emp + ) + ) + recordingSignalProgress.progressTintList = ColorStateList.valueOf( getColorOrDefault( HMSPrebuiltTheme.getColours()?.onSurfaceHigh, diff --git a/room-kit/src/main/res/drawable/ic_recording_pause.xml b/room-kit/src/main/res/drawable/ic_recording_pause.xml new file mode 100644 index 000000000..78e65d08f --- /dev/null +++ b/room-kit/src/main/res/drawable/ic_recording_pause.xml @@ -0,0 +1,10 @@ + + + diff --git a/room-kit/src/main/res/layout/fragment_meeting.xml b/room-kit/src/main/res/layout/fragment_meeting.xml index 60fd43bf9..9a3f056d1 100644 --- a/room-kit/src/main/res/layout/fragment_meeting.xml +++ b/room-kit/src/main/res/layout/fragment_meeting.xml @@ -160,6 +160,17 @@ android:layout_width="20dp" android:layout_height="20dp"/> + + Date: Thu, 9 Nov 2023 15:26:32 +0530 Subject: [PATCH 02/13] Update MeetingFragment.kt --- .../live/hms/roomkit/ui/meeting/MeetingFragment.kt | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/room-kit/src/main/java/live/hms/roomkit/ui/meeting/MeetingFragment.kt b/room-kit/src/main/java/live/hms/roomkit/ui/meeting/MeetingFragment.kt index 4a78b581f..bd897cb41 100644 --- a/room-kit/src/main/java/live/hms/roomkit/ui/meeting/MeetingFragment.kt +++ b/room-kit/src/main/java/live/hms/roomkit/ui/meeting/MeetingFragment.kt @@ -8,6 +8,7 @@ import android.app.RemoteAction import android.content.Context import android.content.Intent import android.content.SharedPreferences +import android.content.pm.ActivityInfo import android.graphics.Color import android.graphics.drawable.GradientDrawable import android.graphics.drawable.Icon @@ -748,6 +749,16 @@ class MeetingFragment : Fragment() { } } + //handle orientation change + when(mode) { + is MeetingViewMode.HLS_VIEWER -> { + contextSafe { context, activity -> activity?.requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_SENSOR } + } + else -> { + contextSafe { context, activity -> activity?.requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_PORTRAIT } + } + } + childFragmentManager .beginTransaction() .replace(R.id.fragment_container, currentFragment) From dd4e1aa8dcd0ec2cb3142d628261488e4d9b5db1 Mon Sep 17 00:00:00 2001 From: Gulzar Date: Thu, 9 Nov 2023 17:04:39 +0530 Subject: [PATCH 03/13] Update MeetingFragment.kt --- .../java/live/hms/roomkit/ui/meeting/MeetingFragment.kt | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/room-kit/src/main/java/live/hms/roomkit/ui/meeting/MeetingFragment.kt b/room-kit/src/main/java/live/hms/roomkit/ui/meeting/MeetingFragment.kt index bd897cb41..4aa56ab6a 100644 --- a/room-kit/src/main/java/live/hms/roomkit/ui/meeting/MeetingFragment.kt +++ b/room-kit/src/main/java/live/hms/roomkit/ui/meeting/MeetingFragment.kt @@ -1221,6 +1221,12 @@ class MeetingFragment : Fragment() { } } binding.chatMessages.visibility = binding.chatView.visibility + binding.chatMessages.setOnClickListener { + if (controlBarsVisible) + hideControlBars() + else + showControlBars(true) + } // Scroll to the latest message if it's visible if (binding.chatMessages.visibility == View.VISIBLE) { val position = chatAdapter.itemCount - 1 From 36d920548dad40f6c4127eda4cce1c5d127850a0 Mon Sep 17 00:00:00 2001 From: pratim Date: Thu, 9 Nov 2023 20:21:28 +0530 Subject: [PATCH 04/13] Added seperate live data for recording and streamingState --- .../hms/roomkit/ui/meeting/MeetingActivity.kt | 5 +- .../hms/roomkit/ui/meeting/MeetingFragment.kt | 253 +++++++----------- .../roomkit/ui/meeting/MeetingViewModel.kt | 73 ++--- .../ui/meeting/SessionOptionBottomSheet.kt | 7 +- .../live/hms/roomkit/ui/theme/ThemeExt.kt | 4 +- .../src/main/res/layout/fragment_meeting.xml | 2 +- 6 files changed, 134 insertions(+), 210 deletions(-) diff --git a/room-kit/src/main/java/live/hms/roomkit/ui/meeting/MeetingActivity.kt b/room-kit/src/main/java/live/hms/roomkit/ui/meeting/MeetingActivity.kt index b69d59171..c6b18547d 100644 --- a/room-kit/src/main/java/live/hms/roomkit/ui/meeting/MeetingActivity.kt +++ b/room-kit/src/main/java/live/hms/roomkit/ui/meeting/MeetingActivity.kt @@ -134,7 +134,10 @@ class MeetingActivity : AppCompatActivity() { } private fun initViewModels() { - meetingViewModel.isRecording.observe(this) { + meetingViewModel.recordingState.observe(this) { + invalidateOptionsMenu() + } + meetingViewModel.streamingState.observe(this) { invalidateOptionsMenu() } meetingViewModel.pinnedTrack.observe(this) { diff --git a/room-kit/src/main/java/live/hms/roomkit/ui/meeting/MeetingFragment.kt b/room-kit/src/main/java/live/hms/roomkit/ui/meeting/MeetingFragment.kt index 3a66aabed..106285894 100644 --- a/room-kit/src/main/java/live/hms/roomkit/ui/meeting/MeetingFragment.kt +++ b/room-kit/src/main/java/live/hms/roomkit/ui/meeting/MeetingFragment.kt @@ -128,7 +128,7 @@ class MeetingFragment : Fragment() { override fun onResume() { super.onResume() isCountdownManuallyCancelled = false - setupRecordingTimeView() + setupStreamingTimeView() settings.registerOnSharedPreferenceChangeListener(onSettingsChangeListener) } @@ -180,7 +180,7 @@ class MeetingFragment : Fragment() { override fun onStart() { super.onStart() isCountdownManuallyCancelled = false - setupRecordingTimeView() + setupStreamingTimeView() } private fun updateActionVolumeMenuIcon( @@ -216,74 +216,7 @@ class MeetingFragment : Fragment() { } } - private fun updateStreamingRecordingViews(recordingState: StreamingRecordingState) { - when (recordingState) { - StreamingRecordingState.STREAMING_AND_RECORDING -> { - binding.recordingPause.visibility = - if (meetingViewModel.hmsSDK.getRoom()?.hlsRecordingState?.state == HMSRecordingState.PAUSED) { - View.VISIBLE - } else { - View.GONE - } - if (hasStartedHls && - meetingViewModel.hmsSDK.getRoom()?.hlsStreamingState?.state == HMSStreamingState.STARTING) { - binding.meetingFragmentProgress.visibility = View.GONE - } else { - binding.meetingFragmentProgress.visibility = View.GONE - } - - - binding.liveTitleCard.visibility = View.VISIBLE - binding.tvViewersCountCard.visibility = View.VISIBLE - binding.recordingSignal.visibility = View.VISIBLE - - if (meetingViewModel.isRTMPRunning()) { - binding.liveTitle.text = "Live with RTMP" - } else { - binding.liveTitle.text = "Live" - } - binding.tvViewersCount.visibility = View.VISIBLE - binding.tvViewersCountCard.visibility = View.VISIBLE - setupRecordingTimeView() - } - StreamingRecordingState.RECORDING -> { - binding.recordingPause.visibility = - if (meetingViewModel.hmsSDK.getRoom()?.hlsRecordingState?.state == HMSRecordingState.PAUSED) { - View.VISIBLE - } else { - View.GONE - } - binding.recordingPause.visibility = View.GONE - binding.liveTitleCard.visibility = View.GONE - binding.recordingSignal.visibility = View.VISIBLE - binding.tvViewersCount.visibility = View.GONE - binding.tvViewersCountCard.visibility = View.GONE - } - StreamingRecordingState.STREAMING -> { - binding.recordingPause.visibility = View.GONE - binding.liveTitleCard.visibility = View.VISIBLE - binding.tvViewersCountCard.visibility = View.VISIBLE - binding.recordingSignal.visibility = View.GONE - - if (meetingViewModel.isRTMPRunning()) { - binding.liveTitle.text = "Live with RTMP" - } else { - binding.liveTitle.text = "Live" - } - binding.tvViewersCount.visibility = View.VISIBLE - binding.tvViewersCountCard.visibility = View.VISIBLE - } - StreamingRecordingState.NOT_RECORDING_OR_STREAMING -> { - binding.recordingPause.visibility = View.GONE - binding.recordingSignal.visibility = View.GONE - binding.liveTitleCard.visibility = View.GONE - binding.tvViewersCount.visibility = View.GONE - binding.tvViewersCountCard.visibility = View.GONE - } - } - } - - private fun setupRecordingTimeView() { + private fun setupStreamingTimeView() { countDownTimer?.cancel() countDownTimer = object : CountDownTimer(1000, 1000) { override fun onTick(l: Long) { @@ -292,8 +225,8 @@ class MeetingFragment : Fragment() { ?: meetingViewModel.hmsSDK.getRoom()?.rtmpHMSRtmpStreamingState?.startedAt startedAt?.let { if (startedAt > 0) { - binding.tvRecordingTime?.visibility = View.VISIBLE - binding.tvRecordingTime?.text = + binding.tvStreamingTime.visibility = View.VISIBLE + binding.tvStreamingTime.text = millisecondsToTime(System.currentTimeMillis().minus(startedAt)) } } @@ -325,14 +258,17 @@ class MeetingFragment : Fragment() { super.onViewCreated(view, savedInstanceState) binding.applyTheme() initObservers() + initButtons() + initOnBackPress() - binding.iconSend.setOnSingleClickListener { - val messageStr = binding.editTextMessage.text.toString().trim() - if (messageStr.isNotEmpty()) { - chatViewModel.sendMessage(messageStr) - binding.editTextMessage.setText("") - } + if (meetingViewModel.state.value is MeetingState.Disconnected) { + // Handles configuration changes + meetingViewModel.startMeeting() + } else { + //start HLS stream + startHLSStreamingIfRequired() } + ChatUseCase().initiate(chatViewModel.messages, viewLifecycleOwner, chatAdapter, binding.chatMessages, chatViewModel, null) { meetingViewModel.prebuiltInfoContainer.isChatEnabled() } @@ -349,21 +285,6 @@ class MeetingFragment : Fragment() { ): View { binding = FragmentMeetingBinding.inflate(inflater, container, false) - initButtons() - initOnBackPress() - - if (meetingViewModel.state.value is MeetingState.Disconnected) { - // Handles configuration changes - meetingViewModel.startMeeting() - } else { - //start HLS stream - if (args.startHlsStream && meetingViewModel.isAllowedToHlsStream()) { - binding.meetingFragmentProgress.visibility = View.VISIBLE - hasStartedHls = true - meetingViewModel.startHls(settings.lastUsedMeetingUrl, HMSHlsRecordingConfig(true, false)) - } - - } return binding.root } @@ -377,14 +298,72 @@ class MeetingFragment : Fragment() { requireActivity().finish() } + private fun updateRecordingViews(state: HMSRecordingState) { + when (state) { + HMSRecordingState.STARTING -> { + binding.recordingSignalProgress.visibility = View.VISIBLE + binding.recordingSignal.visibility = View.GONE + binding.recordingPause.visibility = View.GONE + } + HMSRecordingState.RESUMED, HMSRecordingState.STARTED -> { + binding.recordingSignalProgress.visibility = View.GONE + binding.recordingSignal.visibility = View.VISIBLE + binding.recordingPause.visibility = View.GONE + } + HMSRecordingState.PAUSED -> { + binding.recordingSignalProgress.visibility = View.GONE + binding.recordingSignal.visibility = View.GONE + binding.recordingPause.visibility = View.VISIBLE + } + HMSRecordingState.FAILED, HMSRecordingState.NONE, HMSRecordingState.STOPPED -> { + binding.recordingSignalProgress.visibility = View.GONE + binding.recordingSignal.visibility = View.GONE + binding.recordingPause.visibility = View.GONE + } + } + } + + private fun updateStreamingViews(state: HMSStreamingState) { + when (state) { + HMSStreamingState.STARTING -> { + // Remove the loader on getting STARTING notification for any peer who has hlsStreaming permission + if (meetingViewModel.isAllowedToHlsStream()) { + binding.meetingFragmentProgress.visibility = View.GONE + } + } + + HMSStreamingState.STARTED -> { + binding.meetingFragmentProgress.visibility = View.GONE + binding.liveTitleCard.visibility = View.VISIBLE + if (meetingViewModel.isRTMPRunning()) { + binding.liveTitle.text = "Live with RTMP" + } else { + binding.liveTitle.text = "Live" + } + binding.tvViewersCountCard.visibility = View.VISIBLE + binding.tvViewersCount.visibility = View.VISIBLE + setupStreamingTimeView() + } + + HMSStreamingState.NONE, HMSStreamingState.STOPPED, HMSStreamingState.FAILED -> { + if (state != HMSStreamingState.NONE) + binding.meetingFragmentProgress.visibility = View.GONE + binding.liveTitleCard.visibility = View.GONE + binding.tvViewersCount.visibility = View.GONE + binding.tvViewersCountCard.visibility = View.GONE + } + + } + } + private fun initObservers() { meetingViewModel.showHlsStreamYetToStartError.observe(viewLifecycleOwner) { showError -> - binding.streamYetToStartContainer?.visibility = if (showError) View.VISIBLE else View.GONE + binding.streamYetToStartContainer.visibility = if (showError) View.VISIBLE else View.GONE } meetingViewModel.peerCount.observe(viewLifecycleOwner) { - binding.tvViewersCount?.text =it.toString() + binding.tvViewersCount.text =it.toString() } @@ -393,36 +372,12 @@ class MeetingFragment : Fragment() { } meetingViewModel.recordingState.observe(viewLifecycleOwner) { state -> - when (state) { - HMSRecordingState.STARTING -> { - binding.recordingSignalProgress.visibility = View.VISIBLE - binding.recordingSignal.visibility = View.GONE - binding.recordingPause.visibility = View.GONE - } - HMSRecordingState.RESUMED, HMSRecordingState.STARTED -> { - binding.recordingSignalProgress.visibility = View.GONE - binding.recordingSignal.visibility = View.VISIBLE - binding.recordingPause.visibility = View.GONE - } - HMSRecordingState.PAUSED -> { - binding.recordingSignalProgress.visibility = View.GONE - binding.recordingSignal.visibility = View.GONE - binding.recordingPause.visibility = View.VISIBLE - } - HMSRecordingState.FAILED, HMSRecordingState.NONE, HMSRecordingState.STOPPED -> { - binding.recordingSignalProgress.visibility = View.GONE - binding.recordingSignal.visibility = View.GONE - binding.recordingPause.visibility = View.GONE - } - } + updateRecordingViews(state) } - meetingViewModel.isRecording.observe( - viewLifecycleOwner, - Observer { - updateStreamingRecordingViews(it) - }) - + meetingViewModel.streamingState.observe(viewLifecycleOwner) { state -> + updateStreamingViews(state) + } meetingViewModel.isHandRaised.observe(viewLifecycleOwner) { isHandRaised -> if (isHandRaised) { @@ -432,23 +387,10 @@ class MeetingFragment : Fragment() { } } - meetingViewModel.isRecording.observe(viewLifecycleOwner) { - val isRecording = meetingViewModel.isRecordingState() - binding.recordingSignal.visibility = if (isRecording) View.VISIBLE else View.GONE - } - - meetingViewModel.isScreenShare.observe(viewLifecycleOwner) { meetingViewModel.triggerScreenShareNotification(it) } - meetingViewModel.hlsToggleUpdateLiveData.observe(viewLifecycleOwner) { - when(it) { - true -> binding.meetingFragmentProgress.visibility = View.VISIBLE - false -> binding.meetingFragmentProgress.visibility = View.GONE - } - } - meetingViewModel.meetingViewMode.observe(viewLifecycleOwner) { updateMeetingViewMode(it) Log.d(TAG, "Meeting view mode changed to $it") @@ -686,6 +628,14 @@ class MeetingFragment : Fragment() { } + private fun startHLSStreamingIfRequired() { + if (args.startHlsStream && meetingViewModel.isAllowedToHlsStream()) { + binding.meetingFragmentProgress.visibility = View.VISIBLE + hasStartedHls = true + meetingViewModel.startHls(settings.lastUsedMeetingUrl, HMSHlsRecordingConfig(true, false)) + } + } + private val pipReceiver by lazy { PipBroadcastReceiver( toogleLocalAudio = meetingViewModel::toggleLocalAudio, @@ -1044,9 +994,7 @@ class MeetingFragment : Fragment() { if (activity?.isInPictureInPictureMode?.not() == true && (meetingViewModel.meetingViewMode.value is MeetingViewMode.HLS_VIEWER).not()){ binding.bottomControls.visibility = View.VISIBLE } - binding.progressBar.root.visibility = View.GONE - binding.meetingFragmentProgress.visibility = View.GONE } private fun showProgressBar() { @@ -1068,10 +1016,15 @@ class MeetingFragment : Fragment() { } } + binding.iconSend.setOnSingleClickListener { + val messageStr = binding.editTextMessage.text.toString().trim() + if (messageStr.isNotEmpty()) { + chatViewModel.sendMessage(messageStr) + binding.editTextMessage.setText("") + } + } - - - binding.buttonSettingsMenu?.apply { + binding.buttonSettingsMenu.apply { setOnSingleClickListener(200L) { Log.v(TAG, "buttonSettingsMenu.onClick()") @@ -1108,7 +1061,11 @@ class MeetingFragment : Fragment() { onNameChange = { }, showPolls = { findNavController().navigate(MeetingFragmentDirections.actionMeetingFragmentToPollsCreationFragment()) }, onRecordingClicked = { - if (meetingViewModel.isRecordingState().not()) { + val isBrowserRecordingRunning = meetingViewModel.hmsSDK.getRoom()?.browserRecordingState?.state in listOf( + HMSRecordingState.STARTING, HMSRecordingState.STARTED, + HMSRecordingState.RESUMED, HMSRecordingState.PAUSED + ) + if (isBrowserRecordingRunning.not()) { meetingViewModel.recordMeeting(true, runnable = it) } else { StopRecordingBottomSheet { @@ -1120,11 +1077,9 @@ class MeetingFragment : Fragment() { StopRecordingBottomSheet.TAG ) } - - }, ).show( - childFragmentManager, MeetingFragment.AudioSwitchBottomSheetTAG + childFragmentManager, AudioSwitchBottomSheetTAG ) } else { @@ -1187,7 +1142,7 @@ class MeetingFragment : Fragment() { updatePipEndCall() - binding.iconOutputDevice?.apply { + binding.iconOutputDevice.apply { setOnSingleClickListener(200L) { Log.v(TAG, "iconOutputDevice.onClick()") @@ -1201,7 +1156,7 @@ class MeetingFragment : Fragment() { updateActionVolumeMenuIcon(meetingViewModel.getAudioOutputRouteType()) - binding.buttonSwitchCamera?.setOnSingleClickListener(200L) { + binding.buttonSwitchCamera.setOnSingleClickListener(200L) { meetingViewModel.flipCamera() if (it.isEnabled) meetingViewModel.flipCamera() } @@ -1209,8 +1164,8 @@ class MeetingFragment : Fragment() { if (meetingViewModel.getHmsRoomLayout()?.data?.getOrNull(0)?.logo?.url.isNullOrEmpty()) { binding.logoIv?.visibility = View.GONE } else { - binding.logoIv?.visibility = View.VISIBLE - binding.logoIv?.let { + binding.logoIv.visibility = View.VISIBLE + binding.logoIv.let { Glide.with(this) .load(meetingViewModel.getHmsRoomLayout()?.data?.getOrNull(0)?.logo?.url) .into(it) diff --git a/room-kit/src/main/java/live/hms/roomkit/ui/meeting/MeetingViewModel.kt b/room-kit/src/main/java/live/hms/roomkit/ui/meeting/MeetingViewModel.kt index 9871db0c9..8b39d98d9 100644 --- a/room-kit/src/main/java/live/hms/roomkit/ui/meeting/MeetingViewModel.kt +++ b/room-kit/src/main/java/live/hms/roomkit/ui/meeting/MeetingViewModel.kt @@ -288,14 +288,12 @@ class MeetingViewModel( private val previewErrorData: MutableLiveData = MutableLiveData() private val previewUpdateData: MutableLiveData>> = MutableLiveData() - private val hlsToggleUpdateData: MutableLiveData = MutableLiveData() val statsToggleData: MutableLiveData = MutableLiveData(false) val previewRoomStateLiveData: LiveData> = roomState val previewPeerLiveData: LiveData> = previewPeerData val previewErrorLiveData: LiveData = previewErrorData val previewUpdateLiveData: LiveData>> = previewUpdateData - val hlsToggleUpdateLiveData: LiveData = hlsToggleUpdateData val statsToggleLiveData: LiveData = statsToggleData val isScreenShare: MutableLiveData = MutableLiveData(false) val hmsNotificationEvent = SingleLiveEvent() @@ -348,13 +346,15 @@ class MeetingViewModel( val isLocalVideoEnabled = MutableLiveData(settings.publishVideo) private val _isRecording = MutableLiveData(StreamingRecordingState.NOT_RECORDING_OR_STREAMING) - val isRecording: LiveData = _isRecording private var hmsRoom: HMSRoom? = null // Live data for enabling/disabling mute buttons val isLocalAudioPresent = MutableLiveData(false) val isLocalVideoPresent = MutableLiveData(false) + + //Live data to show ui for recording and streaming states val recordingState = MutableLiveData(HMSRecordingState.NONE) + val streamingState = MutableLiveData(HMSStreamingState.NONE) // Live data containing all the current tracks in a meeting private val _liveDataTracks = MutableLiveData(_tracks) @@ -489,8 +489,7 @@ class MeetingViewModel( override fun onRoomUpdate(type: HMSRoomUpdate, hmsRoom: HMSRoom) { roomState.postValue(Pair(type, hmsRoom)) - // This will keep the isRecording value updated correctly in preview. It will not be called after join. - _isRecording.postValue(getStreamingRecordingState(hmsRoom)) + if (type == HMSRoomUpdate.ROOM_PEER_COUNT_UPDATED) { peerCount.postValue(hmsRoom.peerCount) } @@ -713,11 +712,9 @@ class MeetingViewModel( Log.d(TAG, "Room started at: ${room.startedAt}") // get the hls URL from the Room, if it exists - val hlsUrl = room.hlsStreamingState?.variants?.get(0)?.hlsStreamUrl + val hlsUrl = room.hlsStreamingState.variants?.get(0)?.hlsStreamUrl switchToHlsViewIfRequired(room.localPeer?.hmsRole, hlsUrl) - _isRecording.postValue( - getStreamingRecordingState(room) - ) + sessionMetadataUseCase.setPinnedMessageUpdateListener( { message -> _sessionMetadata.postValue(message) }, object : HMSActionResultListener { @@ -836,49 +833,40 @@ class MeetingViewModel( Log.d(TAG, "join:onRoomUpdate type=$type, room=$hmsRoom") when (type) { - HMSRoomUpdate.ROOM_PEER_COUNT_UPDATED -> peerCount.postValue(hmsRoom.peerCount) + HMSRoomUpdate.ROOM_PEER_COUNT_UPDATED -> { + peerCount.postValue(hmsRoom.peerCount) + } + HMSRoomUpdate.SERVER_RECORDING_STATE_UPDATED -> { - _isRecording.postValue( - getStreamingRecordingState(hmsRoom) - ) showServerInfo(hmsRoom) } HMSRoomUpdate.RTMP_STREAMING_STATE_UPDATED -> { - _isRecording.postValue( - getStreamingRecordingState(hmsRoom) - ) showRtmpInfo(hmsRoom) + streamingState.postValue(hmsRoom.rtmpHMSRtmpStreamingState.state) } HMSRoomUpdate.BROWSER_RECORDING_STATE_UPDATED -> { - _isRecording.postValue( - getStreamingRecordingState(hmsRoom) - ) showRecordInfo(hmsRoom) - recordingState.postValue(hmsRoom.browserRecordingState.state) - } HMSRoomUpdate.HLS_STREAMING_STATE_UPDATED -> { - _isRecording.postValue( - getStreamingRecordingState(hmsRoom) - ) switchToHlsViewIfRequired() showHlsInfo(hmsRoom) + streamingState.postValue(hmsRoom.hlsStreamingState.state) } HMSRoomUpdate.HLS_RECORDING_STATE_UPDATED -> { - _isRecording.postValue( - getStreamingRecordingState(hmsRoom) - ) showHlsRecordingInfo(hmsRoom) - recordingState.postValue(hmsRoom.hlsRecordingState.state) } - else -> { + HMSRoomUpdate.ROOM_MUTED -> { + + } + HMSRoomUpdate.ROOM_UNMUTED -> { + } } } @@ -1111,26 +1099,6 @@ class MeetingViewModel( return room.serverRecordingState.state == HMSRecordingState.STARTED } - private fun getStreamingRecordingState(room: HMSRoom): StreamingRecordingState { - - val runningRecordingStates = listOf(HMSRecordingState.STARTING, HMSRecordingState.STARTED, HMSRecordingState.PAUSED, HMSRecordingState.RESUMED) - val runningStreamingStates = listOf(HMSStreamingState.STARTING, HMSStreamingState.STARTED) - val recording = (room.browserRecordingState.state in runningRecordingStates) || - (room.hlsRecordingState.state in runningRecordingStates) - val streaming = (room.rtmpHMSRtmpStreamingState.state in runningStreamingStates) || - (room.hlsStreamingState.state in runningStreamingStates) - - return if (recording && streaming) { - StreamingRecordingState.STREAMING_AND_RECORDING - } else if (recording) { - StreamingRecordingState.RECORDING - } else if (streaming) { - StreamingRecordingState.STREAMING - } else { - StreamingRecordingState.NOT_RECORDING_OR_STREAMING - } - } - fun isHlsRunning() = hmsSDK.getRoom()?.hlsStreamingState?.state == HMSStreamingState.STARTED fun isRTMPRunning() = hmsSDK.getRoom()?.rtmpHMSRtmpStreamingState?.state == HMSStreamingState.STARTED @@ -1845,13 +1813,12 @@ class MeetingViewModel( override fun onError(error: HMSException) { viewModelScope.launch { _events.emit(Event.Hls.HlsError(error)) - hlsToggleUpdateData.postValue(false) + streamingState.postValue(HMSStreamingState.FAILED) } } override fun onSuccess() { Log.d(TAG, "Hls streaming started successfully") - hlsToggleUpdateData.postValue(true) } }) } @@ -2150,10 +2117,6 @@ class MeetingViewModel( } } - fun isRecordingState(): Boolean { - return isRecording.value == StreamingRecordingState.RECORDING || isRecording.value == StreamingRecordingState.STREAMING_AND_RECORDING - } - fun requestBringOnStage(handRaisePeer: HMSPeer, onStageRole: String) { changeRole(handRaisePeer.peerID, onStageRole, false) } diff --git a/room-kit/src/main/java/live/hms/roomkit/ui/meeting/SessionOptionBottomSheet.kt b/room-kit/src/main/java/live/hms/roomkit/ui/meeting/SessionOptionBottomSheet.kt index 028e0ef41..aa2d82eba 100644 --- a/room-kit/src/main/java/live/hms/roomkit/ui/meeting/SessionOptionBottomSheet.kt +++ b/room-kit/src/main/java/live/hms/roomkit/ui/meeting/SessionOptionBottomSheet.kt @@ -159,8 +159,11 @@ class SessionOptionBottomSheet( - meetingViewModel.isRecording.observe(viewLifecycleOwner) { - val isRecording = meetingViewModel.isRecordingState() + meetingViewModel.recordingState.observe(viewLifecycleOwner) { state -> + + val isRecording = state in listOf(HMSRecordingState.STARTED, HMSRecordingState.PAUSED, + HMSRecordingState.RESUMED) + recordingOption.setSelectedButton(isRecording) recordingOption.setText(if (isRecording) resources.getString(R.string.stop_recording) else resources.getString(R.string.start_record_meeting)) } diff --git a/room-kit/src/main/java/live/hms/roomkit/ui/theme/ThemeExt.kt b/room-kit/src/main/java/live/hms/roomkit/ui/theme/ThemeExt.kt index a1395fc84..da8f428d8 100644 --- a/room-kit/src/main/java/live/hms/roomkit/ui/theme/ThemeExt.kt +++ b/room-kit/src/main/java/live/hms/roomkit/ui/theme/ThemeExt.kt @@ -433,14 +433,14 @@ internal fun FragmentMeetingBinding.applyTheme() { // ) // ) - tvRecordingTime?.setTextColor( + tvStreamingTime.setTextColor( getColorOrDefault( HMSPrebuiltTheme.getColours()?.onSurfaceHigh, HMSPrebuiltTheme.getDefaults().onsurface_med_emp ) ) - tvViewersCount?.setTextColor( + tvViewersCount.setTextColor( getColorOrDefault( HMSPrebuiltTheme.getColours()?.onSurfaceHigh, HMSPrebuiltTheme.getDefaults().onsurface_high_emp diff --git a/room-kit/src/main/res/layout/fragment_meeting.xml b/room-kit/src/main/res/layout/fragment_meeting.xml index 9a3f056d1..a87cf8dd8 100644 --- a/room-kit/src/main/res/layout/fragment_meeting.xml +++ b/room-kit/src/main/res/layout/fragment_meeting.xml @@ -213,7 +213,7 @@ Date: Fri, 10 Nov 2023 12:25:09 +0530 Subject: [PATCH 05/13] Fix: Streaming and recording updates not being shown on joining room Fix: RTMP streaming not being shown on preview --- .../hms/roomkit/ui/meeting/MeetingFragment.kt | 8 +-- .../roomkit/ui/meeting/MeetingViewModel.kt | 13 ++++- .../hms/roomkit/ui/meeting/PreviewFragment.kt | 55 +++++++------------ 3 files changed, 36 insertions(+), 40 deletions(-) diff --git a/room-kit/src/main/java/live/hms/roomkit/ui/meeting/MeetingFragment.kt b/room-kit/src/main/java/live/hms/roomkit/ui/meeting/MeetingFragment.kt index 106285894..f60a06c92 100644 --- a/room-kit/src/main/java/live/hms/roomkit/ui/meeting/MeetingFragment.kt +++ b/room-kit/src/main/java/live/hms/roomkit/ui/meeting/MeetingFragment.kt @@ -782,7 +782,7 @@ class MeetingFragment : Fragment() { - binding.topMenu?.setBackgroundColor( + binding.topMenu.setBackgroundColor( getColorOrDefault( HMSPrebuiltTheme.getColours()?.backgroundDim, HMSPrebuiltTheme.getDefaults().background_default @@ -794,7 +794,7 @@ class MeetingFragment : Fragment() { HMSPrebuiltTheme.getDefaults().background_default ) ) - binding.buttonRaiseHand?.visibility = View.GONE + binding.buttonRaiseHand.visibility = View.GONE WindowCompat.setDecorFitsSystemWindows(activity!!.window, true) @@ -830,7 +830,7 @@ class MeetingFragment : Fragment() { ) , Color.TRANSPARENT, GradientDrawable.Orientation.BOTTOM_TOP) - binding.buttonRaiseHand?.visibility = View.VISIBLE + binding.buttonRaiseHand.visibility = View.VISIBLE binding.fragmentContainer.setOnSingleClickListener(500L) { if (controlBarsVisible) @@ -874,7 +874,7 @@ class MeetingFragment : Fragment() { } override fun onAnimationCancel(animation: Animator) { - binding.topMenu?.visibility = View.VISIBLE + binding.topMenu.visibility = View.VISIBLE controlBarsVisible = true } diff --git a/room-kit/src/main/java/live/hms/roomkit/ui/meeting/MeetingViewModel.kt b/room-kit/src/main/java/live/hms/roomkit/ui/meeting/MeetingViewModel.kt index 8b39d98d9..a94eb243d 100644 --- a/room-kit/src/main/java/live/hms/roomkit/ui/meeting/MeetingViewModel.kt +++ b/room-kit/src/main/java/live/hms/roomkit/ui/meeting/MeetingViewModel.kt @@ -289,6 +289,7 @@ class MeetingViewModel( private val previewUpdateData: MutableLiveData>> = MutableLiveData() val statsToggleData: MutableLiveData = MutableLiveData(false) + val peerCount = MutableLiveData(0) val previewRoomStateLiveData: LiveData> = roomState val previewPeerLiveData: LiveData> = previewPeerData @@ -305,7 +306,6 @@ class MeetingViewModel( if (mode != meetingViewMode.value) { meetingViewMode.postValue(mode) } - } fun isAutoSimulcastEnabled() = settings.disableAutoSimulcast @@ -497,7 +497,7 @@ class MeetingViewModel( }) } - val peerCount = MutableLiveData(0) + fun setLocalVideoEnabled(enabled: Boolean) { hmsSDK.getLocalPeer()?.videoTrack?.apply { @@ -715,6 +715,15 @@ class MeetingViewModel( val hlsUrl = room.hlsStreamingState.variants?.get(0)?.hlsStreamUrl switchToHlsViewIfRequired(room.localPeer?.hmsRole, hlsUrl) + if (room.hlsStreamingState.state != HMSStreamingState.NONE) + streamingState.postValue(room.hlsStreamingState.state) + if (room.rtmpHMSRtmpStreamingState.state != HMSStreamingState.NONE) + streamingState.postValue(room.rtmpHMSRtmpStreamingState.state) + if (room.browserRecordingState.state != HMSRecordingState.NONE) + recordingState.postValue(room.browserRecordingState.state) + if (room.hlsRecordingState.state != HMSRecordingState.NONE) + recordingState.postValue(HMSRecordingState.NONE) + sessionMetadataUseCase.setPinnedMessageUpdateListener( { message -> _sessionMetadata.postValue(message) }, object : HMSActionResultListener { diff --git a/room-kit/src/main/java/live/hms/roomkit/ui/meeting/PreviewFragment.kt b/room-kit/src/main/java/live/hms/roomkit/ui/meeting/PreviewFragment.kt index 056f657cd..0d9bc0059 100644 --- a/room-kit/src/main/java/live/hms/roomkit/ui/meeting/PreviewFragment.kt +++ b/room-kit/src/main/java/live/hms/roomkit/ui/meeting/PreviewFragment.kt @@ -253,7 +253,6 @@ class PreviewFragment : Fragment() { binding.descriptionTv.startBounceAnimationUpwards() } - if (meetingViewModel.getHmsRoomLayout()?.getCurrentRoleData(roleName)?.logo?.url.isNullOrEmpty()) { binding.logoIv.visibility = View.INVISIBLE } else { @@ -265,9 +264,6 @@ class PreviewFragment : Fragment() { binding.logoIv.startBounceAnimationUpwards() } - - - } private fun setupKeyboardAnimation() { @@ -327,25 +323,6 @@ class PreviewFragment : Fragment() { private fun initButtons() { - meetingViewModel.previewRoomStateLiveData.observe(viewLifecycleOwner) { - if (it.second.peerCount != null) { - binding.iconParticipants.visibility = View.VISIBLE - binding.participantCountText.text = it.second.peerCount.formatNames().orEmpty() - binding.iconParticipants.startBounceAnimationUpwards() - } - isHlsRunning = it.second.hlsStreamingState.state == HMSStreamingState.STARTED - updateJoinButtonTextIfHlsIsEnabled(it?.second?.localPeer?.hmsRole?.name) - - if (it.second.hlsStreamingState.state == HMSStreamingState.STARTED) { - binding.liveHlsGroup.visibility = View.VISIBLE - binding.hlsSession.startBounceAnimationUpwards() - } else { - binding.liveHlsGroup.visibility = View.GONE - } - - - } - binding.closeBtn.setOnSingleClickListener(300L) { contextSafe { context, activity -> meetingViewModel.leaveMeeting() @@ -353,7 +330,6 @@ class PreviewFragment : Fragment() { } } - binding.iconOutputDevice.apply { setOnSingleClickListener(200L) { Log.v(TAG, "iconOutputDevice.onClick()") @@ -499,13 +475,7 @@ class PreviewFragment : Fragment() { } - private fun goToHomePage() {/*Intent(requireContext(), HomeActivity::class.java).apply { - crashlyticsLog( - TAG, - "MeetingActivity.finish() -> going to HomeActivity :: $this" - ) - startActivity(this) - }*/ + private fun goToHomePage() { requireActivity().finish() } @@ -540,6 +510,25 @@ class PreviewFragment : Fragment() { } } + meetingViewModel.previewRoomStateLiveData.observe(viewLifecycleOwner) { + if (it.second.peerCount != null) { + binding.iconParticipants.visibility = View.VISIBLE + binding.participantCountText.text = it.second.peerCount.formatNames().orEmpty() + binding.iconParticipants.startBounceAnimationUpwards() + } + isHlsRunning = it.second.hlsStreamingState.state == HMSStreamingState.STARTED + updateJoinButtonTextIfHlsIsEnabled(it?.second?.localPeer?.hmsRole?.name) + + val isLiveWithHLSOrRTMP = it.second.hlsStreamingState.state == HMSStreamingState.STARTED || + it.second.rtmpHMSRtmpStreamingState.state == HMSStreamingState.STARTED + if (isLiveWithHLSOrRTMP) { + binding.liveHlsGroup.visibility = View.VISIBLE + binding.hlsSession.startBounceAnimationUpwards() + } else { + binding.liveHlsGroup.visibility = View.GONE + } + } + meetingViewModel.previewErrorLiveData.observe(viewLifecycleOwner) { error -> if (error.isTerminal) { isPreviewLoaded = false @@ -638,7 +627,7 @@ class PreviewFragment : Fragment() { if (settings.lastUsedMeetingUrl.contains("/streaming/").not()) { - updateJoinButtonTextIfHlsIsEnabled(room?.localPeer?.hmsRole?.name) + updateJoinButtonTextIfHlsIsEnabled(room.localPeer?.hmsRole?.name) enableDisableJoinNowButton() binding.buttonJoinMeeting.visibility = View.VISIBLE updateActionVolumeMenuIcon(meetingViewModel.getAudioOutputRouteType()) @@ -665,8 +654,6 @@ class PreviewFragment : Fragment() { private fun updateUiBasedOnPublishParams(publishParams: PublishParams?) { if (publishParams == null) return - - if (publishParams.allowed.contains("audio")) { binding.buttonToggleAudio.visibility = View.VISIBLE binding.buttonToggleAudio.startBounceAnimationUpwards() From 6b08d66da552031db77dc419ff27ee2b1ee8bec7 Mon Sep 17 00:00:00 2001 From: Gulzar Date: Fri, 10 Nov 2023 15:43:34 +0530 Subject: [PATCH 06/13] added changes --- .../live/hms/roomkit/ui/meeting/MeetingFragment.kt | 14 ++++++++------ .../live/hms/roomkit/ui/settings/SettingsStore.kt | 2 +- 2 files changed, 9 insertions(+), 7 deletions(-) diff --git a/room-kit/src/main/java/live/hms/roomkit/ui/meeting/MeetingFragment.kt b/room-kit/src/main/java/live/hms/roomkit/ui/meeting/MeetingFragment.kt index 44048a738..414ede601 100644 --- a/room-kit/src/main/java/live/hms/roomkit/ui/meeting/MeetingFragment.kt +++ b/room-kit/src/main/java/live/hms/roomkit/ui/meeting/MeetingFragment.kt @@ -735,6 +735,14 @@ class MeetingFragment : Fragment() { .addToBackStack(null) .commit() + binding.root.setOnClickListener { + if (controlBarsVisible && meetingViewModel.prebuiltInfoContainer.isChatOverlay()) + hideControlBars() + else + showControlBars(true) + } + + if(modeEnteredOrExitedHls) { val overlayIsVisible = isOverlayChatVisible() if (meetingViewModel.prebuiltInfoContainer.isChatEnabled()) { @@ -1196,12 +1204,6 @@ class MeetingFragment : Fragment() { } } binding.chatMessages.visibility = binding.chatView.visibility - binding.chatMessages.setOnClickListener { - if (controlBarsVisible) - hideControlBars() - else - showControlBars(true) - } // Scroll to the latest message if it's visible if (binding.chatMessages.visibility == View.VISIBLE) { val position = chatAdapter.itemCount - 1 diff --git a/room-kit/src/main/java/live/hms/roomkit/ui/settings/SettingsStore.kt b/room-kit/src/main/java/live/hms/roomkit/ui/settings/SettingsStore.kt index 95723c296..66dcd81bc 100644 --- a/room-kit/src/main/java/live/hms/roomkit/ui/settings/SettingsStore.kt +++ b/room-kit/src/main/java/live/hms/roomkit/ui/settings/SettingsStore.kt @@ -132,7 +132,7 @@ class SettingsStore(context: Context) { set(value) = putBoolean(USE_HARDWARE_AEC, value) var showStats: Boolean - get() = sharedPreferences.getBoolean(SHOW_STATS, true) + get() = sharedPreferences.getBoolean(SHOW_STATS, false) set(value) = putBoolean(SHOW_STATS, value) var disableAutoResize: Boolean From a046af85acbb5f68ebc7806b08540a22304f6296 Mon Sep 17 00:00:00 2001 From: Gulzar Date: Fri, 10 Nov 2023 16:06:06 +0530 Subject: [PATCH 07/13] bottom sheet full on landscape --- .../hms/roomkit/ui/meeting/MeetingFragment.kt | 17 ++++++++++------- .../ui/meeting/SessionOptionBottomSheet.kt | 6 ++++++ .../meeting/bottomsheets/EndCallBottomSheet.kt | 7 ++++++- .../bottomsheets/LeaveCallBottomSheet.kt | 7 ++++++- .../MultipleLeaveOptionBottomSheet.kt | 6 ++++++ .../hms/roomkit/ui/meeting/chat/ChatAdapter.kt | 5 ++++- 6 files changed, 38 insertions(+), 10 deletions(-) diff --git a/room-kit/src/main/java/live/hms/roomkit/ui/meeting/MeetingFragment.kt b/room-kit/src/main/java/live/hms/roomkit/ui/meeting/MeetingFragment.kt index 414ede601..b0b7760f5 100644 --- a/room-kit/src/main/java/live/hms/roomkit/ui/meeting/MeetingFragment.kt +++ b/room-kit/src/main/java/live/hms/roomkit/ui/meeting/MeetingFragment.kt @@ -84,7 +84,9 @@ val LEAVE_INFORMATION_REASON = "bundle-leave-information-reason" val LEAVE_INFROMATION_WAS_END_ROOM = "bundle-leave-information-end-room" class MeetingFragment : Fragment() { - private val chatAdapter = ChatAdapter() + private val chatAdapter = ChatAdapter({ + onChatClick() + }) companion object { private const val TAG = "MeetingFragment" const val AudioSwitchBottomSheetTAG = "audioSwitchBottomSheet" @@ -144,6 +146,12 @@ class MeetingFragment : Fragment() { cancelCallback() } + private fun onChatClick() { + if (controlBarsVisible && meetingViewModel.prebuiltInfoContainer.isChatOverlay()) + hideControlBars() + else + showControlBars(true) + } private fun cancelCallback() = handler.removeCallbacks(hideRunnable) var resultLauncher = @@ -735,12 +743,7 @@ class MeetingFragment : Fragment() { .addToBackStack(null) .commit() - binding.root.setOnClickListener { - if (controlBarsVisible && meetingViewModel.prebuiltInfoContainer.isChatOverlay()) - hideControlBars() - else - showControlBars(true) - } + if(modeEnteredOrExitedHls) { diff --git a/room-kit/src/main/java/live/hms/roomkit/ui/meeting/SessionOptionBottomSheet.kt b/room-kit/src/main/java/live/hms/roomkit/ui/meeting/SessionOptionBottomSheet.kt index aa2d82eba..26e738578 100644 --- a/room-kit/src/main/java/live/hms/roomkit/ui/meeting/SessionOptionBottomSheet.kt +++ b/room-kit/src/main/java/live/hms/roomkit/ui/meeting/SessionOptionBottomSheet.kt @@ -9,6 +9,8 @@ import android.view.View import android.view.ViewGroup import androidx.fragment.app.activityViewModels import androidx.recyclerview.widget.GridLayoutManager +import com.google.android.material.bottomsheet.BottomSheetBehavior +import com.google.android.material.bottomsheet.BottomSheetDialog import com.google.android.material.bottomsheet.BottomSheetDialogFragment import com.xwray.groupie.Group import com.xwray.groupie.GroupieAdapter @@ -59,6 +61,10 @@ class SessionOptionBottomSheet( override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) applyTheme() + dialog?.let { + val sheet = it as BottomSheetDialog + sheet.behavior.state = BottomSheetBehavior.STATE_EXPANDED + } binding.closeBtn.setOnClickListener { dismissAllowingStateLoss() diff --git a/room-kit/src/main/java/live/hms/roomkit/ui/meeting/bottomsheets/EndCallBottomSheet.kt b/room-kit/src/main/java/live/hms/roomkit/ui/meeting/bottomsheets/EndCallBottomSheet.kt index 5401cf57d..1de7b5f7c 100644 --- a/room-kit/src/main/java/live/hms/roomkit/ui/meeting/bottomsheets/EndCallBottomSheet.kt +++ b/room-kit/src/main/java/live/hms/roomkit/ui/meeting/bottomsheets/EndCallBottomSheet.kt @@ -5,6 +5,8 @@ import android.view.LayoutInflater import android.view.View import android.view.ViewGroup import androidx.fragment.app.activityViewModels +import com.google.android.material.bottomsheet.BottomSheetBehavior +import com.google.android.material.bottomsheet.BottomSheetDialog import com.google.android.material.bottomsheet.BottomSheetDialogFragment import live.hms.roomkit.R import live.hms.roomkit.databinding.EndSessionBottomSheetBinding @@ -43,7 +45,10 @@ class EndCallBottomSheet : BottomSheetDialogFragment() { override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) binding.applyTheme() - + dialog?.let { + val sheet = it as BottomSheetDialog + sheet.behavior.state = BottomSheetBehavior.STATE_EXPANDED + } val canEndRoom = meetingViewModel.isAllowedToEndMeeting() diff --git a/room-kit/src/main/java/live/hms/roomkit/ui/meeting/bottomsheets/LeaveCallBottomSheet.kt b/room-kit/src/main/java/live/hms/roomkit/ui/meeting/bottomsheets/LeaveCallBottomSheet.kt index 5632f1e1c..04dd55093 100644 --- a/room-kit/src/main/java/live/hms/roomkit/ui/meeting/bottomsheets/LeaveCallBottomSheet.kt +++ b/room-kit/src/main/java/live/hms/roomkit/ui/meeting/bottomsheets/LeaveCallBottomSheet.kt @@ -5,6 +5,8 @@ import android.view.LayoutInflater import android.view.View import android.view.ViewGroup import androidx.fragment.app.activityViewModels +import com.google.android.material.bottomsheet.BottomSheetBehavior +import com.google.android.material.bottomsheet.BottomSheetDialog import com.google.android.material.bottomsheet.BottomSheetDialogFragment import live.hms.roomkit.R import live.hms.roomkit.databinding.EndSessionBottomSheetBinding @@ -43,7 +45,10 @@ class LeaveCallBottomSheet : BottomSheetDialogFragment() { override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) binding.applyTheme() - + dialog?.let { + val sheet = it as BottomSheetDialog + sheet.behavior.state = BottomSheetBehavior.STATE_EXPANDED + } binding.endSessionTitle.text = "Leave Session" binding.endSessionDescription.text = diff --git a/room-kit/src/main/java/live/hms/roomkit/ui/meeting/bottomsheets/MultipleLeaveOptionBottomSheet.kt b/room-kit/src/main/java/live/hms/roomkit/ui/meeting/bottomsheets/MultipleLeaveOptionBottomSheet.kt index 6dd53401f..4904f2e59 100644 --- a/room-kit/src/main/java/live/hms/roomkit/ui/meeting/bottomsheets/MultipleLeaveOptionBottomSheet.kt +++ b/room-kit/src/main/java/live/hms/roomkit/ui/meeting/bottomsheets/MultipleLeaveOptionBottomSheet.kt @@ -5,6 +5,8 @@ import android.view.LayoutInflater import android.view.View import android.view.ViewGroup import androidx.fragment.app.activityViewModels +import com.google.android.material.bottomsheet.BottomSheetBehavior +import com.google.android.material.bottomsheet.BottomSheetDialog import com.google.android.material.bottomsheet.BottomSheetDialogFragment import live.hms.roomkit.R import live.hms.roomkit.databinding.ExitBottomSheetBinding @@ -45,6 +47,10 @@ class MultipleLeaveOptionBottomSheet() : BottomSheetDialogFragment() { super.onViewCreated(view, savedInstanceState) binding.applyTheme() + dialog?.let { + val sheet = it as BottomSheetDialog + sheet.behavior.state = BottomSheetBehavior.STATE_EXPANDED + } binding.leaveTitle.text = "Leave" binding.leaveDescription.text = "Others will continue after you leave. You can join the session again." diff --git a/room-kit/src/main/java/live/hms/roomkit/ui/meeting/chat/ChatAdapter.kt b/room-kit/src/main/java/live/hms/roomkit/ui/meeting/chat/ChatAdapter.kt index b18f70dc0..f3719a1ea 100644 --- a/room-kit/src/main/java/live/hms/roomkit/ui/meeting/chat/ChatAdapter.kt +++ b/room-kit/src/main/java/live/hms/roomkit/ui/meeting/chat/ChatAdapter.kt @@ -14,7 +14,7 @@ import java.text.SimpleDateFormat import java.util.* -class ChatAdapter : ListAdapter(DIFFUTIL_CALLBACK) { +class ChatAdapter(val onClick: () -> Unit = {}) : ListAdapter(DIFFUTIL_CALLBACK) { private val formatter = SimpleDateFormat("h:mm a", Locale.getDefault()) companion object { private val DIFFUTIL_CALLBACK = object : DiffUtil.ItemCallback() { @@ -31,6 +31,9 @@ class ChatAdapter : ListAdapter( RecyclerView.ViewHolder(binding.root) { init { binding.applyTheme() + binding.root.setOnClickListener { + onClick() + } } From 737589db816c337eb7c903d0e4016d2ef2809352 Mon Sep 17 00:00:00 2001 From: Gulzar Date: Fri, 10 Nov 2023 16:14:56 +0530 Subject: [PATCH 08/13] added fixes --- .../meeting/AudioOutputSwitchBottomSheet.kt | 7 +++- .../ui/meeting/ChangeNameDialogFragment.kt | 7 ++++ .../HlsVideoQualitySelectorBottomSheet.kt | 7 +++- .../src/main/res/layout/fragment_meeting.xml | 34 +++++++++++++------ 4 files changed, 43 insertions(+), 12 deletions(-) diff --git a/room-kit/src/main/java/live/hms/roomkit/ui/meeting/AudioOutputSwitchBottomSheet.kt b/room-kit/src/main/java/live/hms/roomkit/ui/meeting/AudioOutputSwitchBottomSheet.kt index fd67eaa75..528ab7e6a 100644 --- a/room-kit/src/main/java/live/hms/roomkit/ui/meeting/AudioOutputSwitchBottomSheet.kt +++ b/room-kit/src/main/java/live/hms/roomkit/ui/meeting/AudioOutputSwitchBottomSheet.kt @@ -6,6 +6,8 @@ import android.view.LayoutInflater import android.view.View import android.view.ViewGroup import androidx.fragment.app.activityViewModels +import com.google.android.material.bottomsheet.BottomSheetBehavior +import com.google.android.material.bottomsheet.BottomSheetDialog import com.google.android.material.bottomsheet.BottomSheetDialogFragment import live.hms.roomkit.R import live.hms.roomkit.databinding.BottomSheetAudioSwitchBinding @@ -47,7 +49,10 @@ class AudioOutputSwitchBottomSheet( override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) - + dialog?.let { + val sheet = it as BottomSheetDialog + sheet.behavior.state = BottomSheetBehavior.STATE_EXPANDED + } binding.root.background = resources.getDrawable(R.drawable.gray_shape_round_dialog) .apply { diff --git a/room-kit/src/main/java/live/hms/roomkit/ui/meeting/ChangeNameDialogFragment.kt b/room-kit/src/main/java/live/hms/roomkit/ui/meeting/ChangeNameDialogFragment.kt index 93d929110..62fa8de43 100644 --- a/room-kit/src/main/java/live/hms/roomkit/ui/meeting/ChangeNameDialogFragment.kt +++ b/room-kit/src/main/java/live/hms/roomkit/ui/meeting/ChangeNameDialogFragment.kt @@ -7,6 +7,8 @@ import android.view.View import android.view.ViewGroup import android.view.inputmethod.InputMethodManager import androidx.fragment.app.activityViewModels +import com.google.android.material.bottomsheet.BottomSheetBehavior +import com.google.android.material.bottomsheet.BottomSheetDialog import com.google.android.material.bottomsheet.BottomSheetDialogFragment import live.hms.roomkit.R import live.hms.roomkit.databinding.ChangeNameFragmentBinding @@ -41,6 +43,11 @@ class ChangeNameDialogFragment : BottomSheetDialogFragment() { override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) binding.applyTheme() + + dialog?.let { + val sheet = it as BottomSheetDialog + sheet.behavior.state = BottomSheetBehavior.STATE_EXPANDED + } val newName = binding.newName val submitButton = binding.changeName val cancelButton = binding.closeBtn diff --git a/room-kit/src/main/java/live/hms/roomkit/ui/meeting/HlsVideoQualitySelectorBottomSheet.kt b/room-kit/src/main/java/live/hms/roomkit/ui/meeting/HlsVideoQualitySelectorBottomSheet.kt index 31ea9299d..483f5a9c9 100644 --- a/room-kit/src/main/java/live/hms/roomkit/ui/meeting/HlsVideoQualitySelectorBottomSheet.kt +++ b/room-kit/src/main/java/live/hms/roomkit/ui/meeting/HlsVideoQualitySelectorBottomSheet.kt @@ -7,6 +7,8 @@ import android.view.View import android.view.ViewGroup import android.widget.RadioButton import android.widget.TextView +import com.google.android.material.bottomsheet.BottomSheetBehavior +import com.google.android.material.bottomsheet.BottomSheetDialog import com.google.android.material.bottomsheet.BottomSheetDialogFragment import live.hms.roomkit.R import live.hms.roomkit.databinding.DialogTrackSelectionBinding @@ -32,7 +34,10 @@ class HlsVideoQualitySelectorBottomSheet( override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) - + dialog?.let { + val sheet = it as BottomSheetDialog + sheet.behavior.state = BottomSheetBehavior.STATE_EXPANDED + } binding.closeBtn.setOnClickListener { dismiss() } diff --git a/room-kit/src/main/res/layout/fragment_meeting.xml b/room-kit/src/main/res/layout/fragment_meeting.xml index a87cf8dd8..c2ad48042 100644 --- a/room-kit/src/main/res/layout/fragment_meeting.xml +++ b/room-kit/src/main/res/layout/fragment_meeting.xml @@ -255,18 +255,32 @@ - - + android:layout_height="wrap_content"> + + + + + + Date: Fri, 10 Nov 2023 16:55:30 +0530 Subject: [PATCH 09/13] Fix: recording updates not being shown on joining room --- .../main/java/live/hms/roomkit/ui/meeting/MeetingViewModel.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/room-kit/src/main/java/live/hms/roomkit/ui/meeting/MeetingViewModel.kt b/room-kit/src/main/java/live/hms/roomkit/ui/meeting/MeetingViewModel.kt index a94eb243d..777072c03 100644 --- a/room-kit/src/main/java/live/hms/roomkit/ui/meeting/MeetingViewModel.kt +++ b/room-kit/src/main/java/live/hms/roomkit/ui/meeting/MeetingViewModel.kt @@ -722,7 +722,7 @@ class MeetingViewModel( if (room.browserRecordingState.state != HMSRecordingState.NONE) recordingState.postValue(room.browserRecordingState.state) if (room.hlsRecordingState.state != HMSRecordingState.NONE) - recordingState.postValue(HMSRecordingState.NONE) + recordingState.postValue(room.hlsRecordingState.state) sessionMetadataUseCase.setPinnedMessageUpdateListener( { message -> _sessionMetadata.postValue(message) }, From c7141c12b8948a073a91e736fec903315a70e6cc Mon Sep 17 00:00:00 2001 From: pratim Date: Fri, 10 Nov 2023 18:35:01 +0530 Subject: [PATCH 10/13] Fix: recording updates not being shown on joining room --- .../live/hms/roomkit/ui/meeting/MeetingViewModel.kt | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/room-kit/src/main/java/live/hms/roomkit/ui/meeting/MeetingViewModel.kt b/room-kit/src/main/java/live/hms/roomkit/ui/meeting/MeetingViewModel.kt index 777072c03..8529dcfa9 100644 --- a/room-kit/src/main/java/live/hms/roomkit/ui/meeting/MeetingViewModel.kt +++ b/room-kit/src/main/java/live/hms/roomkit/ui/meeting/MeetingViewModel.kt @@ -715,13 +715,16 @@ class MeetingViewModel( val hlsUrl = room.hlsStreamingState.variants?.get(0)?.hlsStreamUrl switchToHlsViewIfRequired(room.localPeer?.hmsRole, hlsUrl) - if (room.hlsStreamingState.state != HMSStreamingState.NONE) + val runningStreamingStates = listOf(HMSStreamingState.STARTED, HMSStreamingState.STARTING) + val runningRecordingStates = listOf(HMSRecordingState.STARTING, HMSRecordingState.STARTED, HMSRecordingState.PAUSED, HMSRecordingState.RESUMED) + + if (room.hlsStreamingState.state in runningStreamingStates) streamingState.postValue(room.hlsStreamingState.state) - if (room.rtmpHMSRtmpStreamingState.state != HMSStreamingState.NONE) + if (room.rtmpHMSRtmpStreamingState.state in runningStreamingStates) streamingState.postValue(room.rtmpHMSRtmpStreamingState.state) - if (room.browserRecordingState.state != HMSRecordingState.NONE) + if (room.browserRecordingState.state in runningRecordingStates) recordingState.postValue(room.browserRecordingState.state) - if (room.hlsRecordingState.state != HMSRecordingState.NONE) + if (room.hlsRecordingState.state in runningRecordingStates ) recordingState.postValue(room.hlsRecordingState.state) sessionMetadataUseCase.setPinnedMessageUpdateListener( From ff40eb3a7e129c02276d3d88d871b1dfe7c2e259 Mon Sep 17 00:00:00 2001 From: pratim Date: Fri, 10 Nov 2023 18:38:38 +0530 Subject: [PATCH 11/13] Fix: Show joinNow if beam is running --- .../java/live/hms/roomkit/ui/meeting/PreviewFragment.kt | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/room-kit/src/main/java/live/hms/roomkit/ui/meeting/PreviewFragment.kt b/room-kit/src/main/java/live/hms/roomkit/ui/meeting/PreviewFragment.kt index 0d9bc0059..247788c00 100644 --- a/room-kit/src/main/java/live/hms/roomkit/ui/meeting/PreviewFragment.kt +++ b/room-kit/src/main/java/live/hms/roomkit/ui/meeting/PreviewFragment.kt @@ -57,6 +57,7 @@ import live.hms.video.sdk.models.HMSLocalPeer import live.hms.video.sdk.models.HMSPeer import live.hms.video.sdk.models.HMSRoom import live.hms.video.sdk.models.enums.HMSPeerUpdate +import live.hms.video.sdk.models.enums.HMSRecordingState import live.hms.video.sdk.models.enums.HMSStreamingState import live.hms.video.sdk.models.role.PublishParams import live.hms.videoview.VideoViewStateChangeListener @@ -90,7 +91,7 @@ class PreviewFragment : Fragment() { private var setTextOnce = false private var isPreviewLoaded = false private var nameEditText: String? = null - private var isHlsRunning = false + private var isBeamRunning = false private var isFirstRender : Boolean = true private var startHlsStream : Boolean = false @@ -100,7 +101,7 @@ class PreviewFragment : Fragment() { val hlsJoinButtonFromLayoutConfig = meetingViewModel.getHmsRoomLayout() ?.getPreviewLayout(roleName)?.default?.elements?.joinForm?.joinBtnType == "JOIN_BTN_TYPE_JOIN_AND_GO_LIVE" - if (isHlsRunning.not() && hlsJoinButtonFromLayoutConfig) { + if (isBeamRunning.not() && hlsJoinButtonFromLayoutConfig) { if (binding.buttonJoinMeeting.drawableStart == null) { binding.buttonJoinMeeting.setDrawables( start = ContextCompat.getDrawable( @@ -516,7 +517,9 @@ class PreviewFragment : Fragment() { binding.participantCountText.text = it.second.peerCount.formatNames().orEmpty() binding.iconParticipants.startBounceAnimationUpwards() } - isHlsRunning = it.second.hlsStreamingState.state == HMSStreamingState.STARTED + isBeamRunning = it.second.hlsStreamingState.state == HMSStreamingState.STARTED || + it.second.rtmpHMSRtmpStreamingState.state == HMSStreamingState.STARTED || + it.second.browserRecordingState.state == HMSRecordingState.STARTED updateJoinButtonTextIfHlsIsEnabled(it?.second?.localPeer?.hmsRole?.name) val isLiveWithHLSOrRTMP = it.second.hlsStreamingState.state == HMSStreamingState.STARTED || From 8812dc82aeb9f1c52c667f4e8ea946b2d0a58fec Mon Sep 17 00:00:00 2001 From: Aniket Kadam Date: Thu, 16 Nov 2023 14:09:57 +0530 Subject: [PATCH 12/13] Update gradle.properties --- gradle.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle.properties b/gradle.properties index d96b4501f..a86a815ad 100644 --- a/gradle.properties +++ b/gradle.properties @@ -22,5 +22,5 @@ kotlin.code.style=official 100MS_APP_VERSION_CODE=643 100MS_APP_VERSION_NAME=5.8.872 hmsRoomKitGroup=live.100ms -HMS_ROOM_KIT_VERSION=1.1.3 +HMS_ROOM_KIT_VERSION=1.1.4 android.suppressUnsupportedCompileSdk=33 From 923a6eb07ef923ee27f1cde198cc43c2f50e2685 Mon Sep 17 00:00:00 2001 From: Aniket Kadam Date: Thu, 16 Nov 2023 14:20:08 +0530 Subject: [PATCH 13/13] Update build.gradle --- room-kit/build.gradle | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/room-kit/build.gradle b/room-kit/build.gradle index fae3ec8f8..887f48ad9 100644 --- a/room-kit/build.gradle +++ b/room-kit/build.gradle @@ -69,7 +69,7 @@ dependencies { implementation 'androidx.constraintlayout:constraintlayout:2.1.4' implementation 'androidx.percentlayout:percentlayout:1.0.0' - def hmsVersion = "2.8.0" + def hmsVersion = "2.8.1" // To add dependencies of specific module implementation "live.100ms:android-sdk:$hmsVersion" implementation "live.100ms:video-view:$hmsVersion" @@ -158,4 +158,4 @@ afterEvaluate { } } } -} \ No newline at end of file +}