Hi There,
We are facing issue with video preview, when we join meeting first time in app, everything works fine but when we close meeting and join same or another meeting again, there is no video preview there, I have checked in logs, i can see video preview is enabled but i cannot see any video on screen.
here is screenshot from app.
as you can see in screenshot, there is no camera priew
to exit meeting, we have added code as below
inMeetingService?.leaveCurrentMeeting(true)
we have made custom screen for meetings. and below is code for this screen.
class MyMeetingActivity: MeetingActivity(), OnGestureListener {
private var inMeetingService: InMeetingService? = null
companion object {
private const val TAG = "MyMeetingActivity"
var isRunning = false
fun start(context: Context) {
val intent = Intent(context, MyMeetingActivity::class.java)
context.startActivity(intent)
}
}
override fun isAlwaysFullScreen(): Boolean {
return false
}
override fun isSensorOrientationEnabled(): Boolean {
return false
}
private lateinit var btnAudio: ImageView
private lateinit var btnVideo: ImageView
private lateinit var btnParticipants: ImageView
private lateinit var btnChat: ImageView
private lateinit var btnLeave: ImageView
private lateinit var zoomSdk: ZoomSDK
private lateinit var context: Context
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
context = this
zoomSdk = ZoomSDK.getInstance()
if (!zoomSdk.isInitialized) {
finish()
return
}
if (checkSelfPermission(Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(
this@MyMeetingActivity,
arrayOf(Manifest.permission.CAMERA),
1001
)
}
inMeetingService = zoomSdk.inMeetingService
btnAudio = findViewById(R.id.btnAudio)
btnVideo = findViewById(R.id.btnVideo)
btnChat = findViewById(R.id.btnChat)
btnParticipants = findViewById(R.id.btnParticipants)
btnLeave = findViewById(R.id.btnLeaveZoomMeeting)
initListeners()
}
override fun getLayout(): Int {
return R.layout.activity_meeting
}
override fun onResume() {
super.onResume()
updateButtonsStatus()
// disable animation
overridePendingTransition(0, 0)
}
private fun initListeners() {
btnLeave.setOnClickListener {
inMeetingService?.leaveCurrentMeeting(true)
Log.e(TAG,"Leave meeting")
finish()
}
btnAudio.setOnClickListener {
val audioController = zoomSdk.inMeetingService.inMeetingAudioController
val result = audioController.muteMyAudio(!audioController.isMyAudioMuted)
Log.e(TAG,"Audio > ${result.name} / ${result.ordinal} / ${result.declaringClass.simpleName}")
if (audioController.isMyAudioMuted) {
btnAudio.setImageResource(R.drawable.ic_mic_focus)
}else {
btnAudio.setImageResource(R.drawable.ic_mic_mute_focus)
}
}
btnVideo.setOnClickListener {
val videoController = zoomSdk.inMeetingService.inMeetingVideoController
// videoController.switchToNextCamera()
val result = videoController.muteMyVideo(!videoController.isMyVideoMuted)
Log.e(TAG,"Video > ${result.name} / ${result.ordinal} / ${result.declaringClass.simpleName}")
if (videoController.isMyVideoMuted) {
btnVideo.setImageResource(R.drawable.ic_videocam_on_focus)
}else {
btnVideo.setImageResource(R.drawable.ic_videocam_off_focus)
}
}
btnChat.setOnClickListener {
MyMessage.showToast(context,"This function is not ready yet!")
return@setOnClickListener
}
btnParticipants.setOnClickListener {
MyMessage.showToast(context,"This function is not ready yet!")
return@setOnClickListener
}
zoomSdk.meetingService.addListener { meetingStatus, i, i1 ->
Log.e(TAG,"meetingService ${meetingStatus.name}")
if (meetingStatus == MeetingStatus.MEETING_STATUS_INMEETING) {
updateButtonsStatus()
val videoController = zoomSdk.inMeetingService.inMeetingVideoController
Log.e(TAG,"videoController > ${videoController.selectedCameraId} / ${videoController.isMyVideoMuted}")
Log.d(TAG,"videoController > ${videoController.cameraDeviceList.size}")
for (camera in videoController.cameraDeviceList) {
Log.d(TAG,"Camera >>> ${camera.deviceId} / ${camera.isSelectedDevice} ${camera.deviceName}")
}
}
}
zoomSdk.inMeetingService.addListener(object : InMeetingServiceListener {
override fun onMeetingNeedPasswordOrDisplayName(
b: Boolean,
b1: Boolean,
inMeetingEventHandler: InMeetingEventHandler
) {
}
override fun onWebinarNeedRegister() {
}
override fun onJoinWebinarNeedUserNameAndEmail(inMeetingEventHandler: InMeetingEventHandler) {}
override fun onMeetingNeedColseOtherMeeting(p0: InMeetingEventHandler?) {}
override fun onMeetingFail(i: Int, i1: Int) {}
override fun onMeetingLeaveComplete(l: Long) {
Log.e(TAG,"onMeetingLeaveComplete > $l")
}
override fun onMeetingUserJoin(list: List<Long>) {
Log.e(TAG,"onMeetingUserJoin > ${list.size}")
val service = zoomSdk.inMeetingService
for (id in list) {
Log.d(TAG,"Participant > $id")
try {
val info = service.getUserInfoById(id)
Log.e(TAG,"User > ${info.userName} / ${info.inMeetingUserRole} / ${info.avatarPath} ")
}catch (e: Exception) {
e.printStackTrace()
}
}
}
override fun onMeetingUserLeave(list: List<Long>) {
Log.e(TAG,"onMeetingUserLeave > ${list.size}")
val service = zoomSdk.inMeetingService
for (id in list) {
Log.d(TAG,"Participant > $id")
try {
val info = service.getUserInfoById(id)
Log.e(TAG,"User > ${info.userName} / ${info.inMeetingUserRole} / ${info.avatarPath} ")
}catch (e: Exception) {
e.printStackTrace()
}
}
}
override fun onMeetingUserUpdated(l: Long) {}
override fun onMeetingHostChanged(l: Long) {}
override fun onMeetingCoHostChanged(l: Long) {}
override fun onActiveVideoUserChanged(l: Long) {}
override fun onActiveSpeakerVideoUserChanged(l: Long) {}
override fun onSpotlightVideoChanged(b: Boolean) {}
override fun onUserVideoStatusChanged(p0: Long) {}
override fun onUserNetworkQualityChanged(l: Long) {}
override fun onMicrophoneStatusError(mobileRTCMicrophoneError: MobileRTCMicrophoneError) {
Log.e(TAG,"onMicrophoneStatusError >> ${mobileRTCMicrophoneError.name}")
}
override fun onUserAudioStatusChanged(p0: Long) {}
override fun onHostAskUnMute(l: Long) {}
override fun onHostAskStartVideo(l: Long) {}
override fun onUserAudioTypeChanged(l: Long) {}
override fun onMyAudioSourceTypeChanged(i: Int) {
Log.e(TAG,"onMyAudioSourceTypeChanged >> $i")
}
override fun onLowOrRaiseHandStatusChanged(l: Long, b: Boolean) {}
override fun onMeetingSecureKeyNotification(p0: ByteArray?) {}
override fun onChatMessageReceived(inMeetingChatMessage: InMeetingChatMessage) {}
override fun onSilentModeChanged(b: Boolean) {
updateButtonsStatus()
}
override fun onFreeMeetingReminder(b: Boolean, b1: Boolean, b2: Boolean) {}
override fun onMeetingActiveVideo(l: Long) {}
override fun onSinkAttendeeChatPriviledgeChanged(i: Int) {}
override fun onSinkAllowAttendeeChatNotification(i: Int) {}
override fun onUserNameChanged(l: Long, s: String) {}
})
}
private fun updateButtonsStatus() {
val enabled = inMeetingService?.isMeetingConnected ?: false
Log.e(TAG,"updateButtonsStatus $enabled")
btnAudio.isEnabled = enabled
btnVideo.isEnabled = enabled
btnChat.isEnabled = enabled
btnParticipants.isEnabled = enabled
val videoController = zoomSdk.inMeetingService.inMeetingVideoController
if (videoController.isMyVideoMuted) {
btnVideo.setImageResource(R.drawable.ic_videocam_on)
}else {
btnVideo.setImageResource(R.drawable.ic_videocam_off)
}
val audioController = zoomSdk.inMeetingService.inMeetingAudioController
if (audioController.isMyAudioMuted) {
btnAudio.setImageResource(R.drawable.ic_mic)
}else {
btnAudio.setImageResource(R.drawable.ic_mic_mute)
}
}
override fun onContentChanged() {
super.onContentChanged()
disableFullScreenMode()
}
private fun disableFullScreenMode() {
window.setFlags(
WindowManager.LayoutParams.FLAG_FULLSCREEN.inv(),
WindowManager.LayoutParams.FLAG_FULLSCREEN
)
}
@Subscribe(threadMode = ThreadMode.MAIN)
fun onMessageEvent(myEvent: MyEvent) {
Log.e(TAG, "Event >> ${myEvent.event} / ${myEvent.msg}")
if (myEvent.event == Events.GESTURE) {
myEvent.motionEvent?.let {
onGesture(it)
}
}
}
override fun onStart() {
super.onStart()
isRunning = true
EventBus.getDefault().register(this)
}
override fun onStop() {
super.onStop()
isRunning = false
EventBus.getDefault().unregister(this)
}
private var currentSelection: ImageView? = null
private var cursor = 0
override fun onGesture(gesture: Gesture): Boolean {
return when(gesture) {
Gesture.TAP -> {
currentSelection?.performClick()
true
}
Gesture.SWIPE_BACKWARD -> {
if (cursor > 0) {
cursor -= 1
}
showSelectedButton()
return true
}
Gesture.SWIPE_FORWARD -> {
if (cursor < 4) {
cursor += 1
}
showSelectedButton()
return true
}
Gesture.SWIPE_DOWN -> {
btnLeave.performClick()
return true
}
Gesture.TAP_AND_HOLD -> {
GestureService.stopGestureService(this)
return true
}
else -> {
false
}
}
}
private fun showSelectedButton() {
Log.e(TAG,"Swipe > $ $cursor")
currentSelection?.let {
when (it.id) {
btnAudio.id -> {
val audioController = zoomSdk.inMeetingService.inMeetingAudioController
if (audioController.isMyAudioMuted) {
btnAudio.setImageResource(R.drawable.ic_mic)
}else {
btnAudio.setImageResource(R.drawable.ic_mic_mute)
}
}
btnVideo.id ->{
val videoController = zoomSdk.inMeetingService.inMeetingVideoController
if (videoController.isMyVideoMuted) {
btnVideo.setImageResource(R.drawable.ic_videocam_on)
}else {
btnVideo.setImageResource(R.drawable.ic_videocam_off)
}
}
btnChat.id -> {
btnChat.setImageResource(R.drawable.ic_chat)
}
btnParticipants.id -> {
btnParticipants.setImageResource(R.drawable.ic_group)
}
btnLeave.id -> {
btnLeave.setImageResource(R.drawable.ic_exit)
}
}
}
currentSelection = when(cursor) {
0 -> {
val audioController = zoomSdk.inMeetingService.inMeetingAudioController
if (audioController.isMyAudioMuted) {
btnAudio.setImageResource(R.drawable.ic_mic_focus)
}else {
btnAudio.setImageResource(R.drawable.ic_mic_mute_focus)
}
btnAudio
}
1 -> {
val videoController = zoomSdk.inMeetingService.inMeetingVideoController
if (videoController.isMyVideoMuted) {
btnVideo.setImageResource(R.drawable.ic_videocam_on_focus)
}else {
btnVideo.setImageResource(R.drawable.ic_videocam_off_focus)
}
btnVideo
}
2 -> {
btnChat.setImageResource(R.drawable.ic_chat_focus)
btnChat
}
3 -> {
btnParticipants.setImageResource(R.drawable.ic_group_focus)
btnParticipants
}
else -> {
btnLeave.setImageResource(R.drawable.ic_exit_focus)
btnLeave
}
}
}
}
also i’m sharing encrypted logs from app for reference.
here are logs
please check and let me know about this issue.
thanks.