video-straming-android-changes
parent
95b00dd67d
commit
e76ecf172f
@ -0,0 +1,385 @@
|
||||
package com.hmg.hmgDr.ui.fragment
|
||||
|
||||
import android.Manifest
|
||||
import android.annotation.SuppressLint
|
||||
import android.app.Activity
|
||||
import android.content.Intent
|
||||
import android.opengl.GLSurfaceView
|
||||
import android.os.Bundle
|
||||
import android.os.CountDownTimer
|
||||
import android.os.Handler
|
||||
import android.os.Looper
|
||||
import android.util.Log
|
||||
import android.view.LayoutInflater
|
||||
import android.view.MotionEvent
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.widget.*
|
||||
import androidx.fragment.app.Fragment
|
||||
import com.hmg.hmgDr.Model.ChangeCallStatusRequestModel
|
||||
import com.hmg.hmgDr.Model.GetSessionStatusModel
|
||||
import com.hmg.hmgDr.Model.SessionStatusModel
|
||||
import com.hmg.hmgDr.R
|
||||
import com.hmg.hmgDr.ui.VideoCallActivity
|
||||
import com.hmg.hmgDr.ui.VideoCallContract.VideoCallPresenter
|
||||
import com.hmg.hmgDr.ui.VideoCallContract.VideoCallView
|
||||
import com.hmg.hmgDr.ui.VideoCallPresenterImpl
|
||||
import com.opentok.android.*
|
||||
import com.opentok.android.PublisherKit.PublisherListener
|
||||
import pub.devrel.easypermissions.AfterPermissionGranted
|
||||
import pub.devrel.easypermissions.AppSettingsDialog
|
||||
import pub.devrel.easypermissions.EasyPermissions
|
||||
import pub.devrel.easypermissions.EasyPermissions.PermissionCallbacks
|
||||
import java.util.*
|
||||
|
||||
class VideoCallFragment : Fragment(), PermissionCallbacks, Session.SessionListener, PublisherListener,
|
||||
SubscriberKit.VideoListener, VideoCallView {
|
||||
|
||||
lateinit var videoCallPresenter: VideoCallPresenter
|
||||
|
||||
private var mSession: Session? = null
|
||||
private var mPublisher: Publisher? = null
|
||||
private var mSubscriber: Subscriber? = null
|
||||
|
||||
private var mVolHandler: Handler? = null
|
||||
private var mConnectedHandler: Handler? = null
|
||||
private var mVolRunnable: Runnable? = null
|
||||
private var mConnectedRunnable: Runnable? = null
|
||||
|
||||
private var mPublisherViewContainer: FrameLayout? = null
|
||||
private var mSubscriberViewContainer: RelativeLayout? = null
|
||||
private var controlPanel: RelativeLayout? = null
|
||||
|
||||
private var apiKey: String? = null
|
||||
private var sessionId: String? = null
|
||||
private var token: String? = null
|
||||
private var appLang: String? = null
|
||||
private var baseUrl: String? = null
|
||||
|
||||
private var isSwitchCameraClicked = false
|
||||
private var isCameraClicked = false
|
||||
private var isSpeckerClicked = false
|
||||
private var isMicClicked = false
|
||||
|
||||
private var mCallBtn: ImageView? = null
|
||||
private var mCameraBtn: ImageView? = null
|
||||
private var mSwitchCameraBtn: ImageView? = null
|
||||
private var mspeckerBtn: ImageView? = null
|
||||
private var mMicBtn: ImageView? = null
|
||||
|
||||
private val progressBar: ProgressBar? = null
|
||||
private val countDownTimer: CountDownTimer? = null
|
||||
private val progressBarTextView: TextView? = null
|
||||
private val progressBarLayout: RelativeLayout? = null
|
||||
|
||||
private var isConnected = false
|
||||
|
||||
private var sessionStatusModel: GetSessionStatusModel? = null
|
||||
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
requireActivity().setTheme(R.style.AppTheme)
|
||||
super.onCreate(savedInstanceState)
|
||||
|
||||
requestPermissions()
|
||||
}
|
||||
|
||||
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
|
||||
savedInstanceState: Bundle?): View? {
|
||||
|
||||
val view = inflater.inflate(R.layout.activity_video_call, container, false)
|
||||
|
||||
Objects.requireNonNull(requireActivity().actionBar)!!.hide()
|
||||
initUI(view)
|
||||
|
||||
return view
|
||||
}
|
||||
|
||||
override fun onPause() {
|
||||
super.onPause()
|
||||
if (mSession == null) {
|
||||
return
|
||||
}
|
||||
mSession!!.onPause()
|
||||
if (requireActivity().isFinishing) {
|
||||
disconnectSession()
|
||||
}
|
||||
}
|
||||
|
||||
override fun onResume() {
|
||||
super.onResume()
|
||||
if (mSession == null) {
|
||||
return
|
||||
}
|
||||
mSession!!.onResume()
|
||||
}
|
||||
|
||||
override fun onDestroy() {
|
||||
disconnectSession()
|
||||
super.onDestroy()
|
||||
}
|
||||
|
||||
@SuppressLint("ClickableViewAccessibility")
|
||||
private fun initUI(view: View) {
|
||||
mPublisherViewContainer = view.findViewById<FrameLayout>(R.id.local_video_view_container)
|
||||
mSubscriberViewContainer = view.findViewById<RelativeLayout>(R.id.remote_video_view_container)
|
||||
|
||||
arguments?.run {
|
||||
apiKey = getString("apiKey")
|
||||
sessionId = getString("sessionId")
|
||||
token = getString("token")
|
||||
appLang = getString("appLang")
|
||||
baseUrl = getString("baseUrl")
|
||||
sessionStatusModel = getParcelable("sessionStatusModel")
|
||||
}
|
||||
|
||||
controlPanel = view.findViewById<RelativeLayout>(R.id.control_panel)
|
||||
videoCallPresenter = VideoCallPresenterImpl(this, baseUrl)
|
||||
mCallBtn = view.findViewById<ImageView>(R.id.btn_call)
|
||||
mCameraBtn = view.findViewById<ImageView>(R.id.btn_camera)
|
||||
mSwitchCameraBtn = view.findViewById<ImageView>(R.id.btn_switch_camera)
|
||||
mspeckerBtn = view.findViewById<ImageView>(R.id.btn_specker)
|
||||
mMicBtn = view.findViewById<ImageView>(R.id.btn_mic)
|
||||
|
||||
// progressBarLayout=findViewById(R.id.progressBar);
|
||||
// progressBar=findViewById(R.id.progress_bar);
|
||||
// progressBarTextView=findViewById(R.id.progress_bar_text);
|
||||
// progressBar.setVisibility(View.GONE);
|
||||
hiddenButtons()
|
||||
checkClientConnected()
|
||||
mSubscriberViewContainer!!.setOnTouchListener { v: View?, event: MotionEvent? ->
|
||||
controlPanel!!.visibility = View.VISIBLE
|
||||
mVolHandler!!.removeCallbacks(mVolRunnable!!)
|
||||
mVolHandler!!.postDelayed(mVolRunnable!!, (5 * 1000).toLong())
|
||||
true
|
||||
}
|
||||
if (appLang == "ar") {
|
||||
progressBarLayout!!.layoutDirection = View.LAYOUT_DIRECTION_RTL
|
||||
}
|
||||
}
|
||||
|
||||
private fun checkClientConnected() {
|
||||
mConnectedHandler = Handler((Looper.getMainLooper()))
|
||||
mConnectedRunnable = Runnable {
|
||||
if (!isConnected) {
|
||||
videoCallPresenter.callClintConnected(sessionStatusModel)
|
||||
}
|
||||
}
|
||||
mConnectedHandler!!.postDelayed(mConnectedRunnable!!, (55 * 1000).toLong())
|
||||
}
|
||||
|
||||
private fun hiddenButtons() {
|
||||
mVolHandler = Handler()
|
||||
mVolRunnable = Runnable { controlPanel!!.visibility = View.GONE }
|
||||
mVolHandler!!.postDelayed(mVolRunnable!!, (5 * 1000).toLong())
|
||||
}
|
||||
|
||||
override fun onRequestPermissionsResult(requestCode: Int, permissions: Array<String?>, grantResults: IntArray) {
|
||||
super.onRequestPermissionsResult(requestCode, permissions, grantResults)
|
||||
EasyPermissions.onRequestPermissionsResult(requestCode, permissions, grantResults, this)
|
||||
}
|
||||
|
||||
override fun onPermissionsGranted(requestCode: Int, perms: List<String?>) {
|
||||
Log.d(TAG, "onPermissionsGranted:" + requestCode + ":" + perms.size)
|
||||
}
|
||||
|
||||
override fun onPermissionsDenied(requestCode: Int, perms: List<String?>) {
|
||||
Log.d(TAG, "onPermissionsDenied:" + requestCode + ":" + perms.size)
|
||||
if (EasyPermissions.somePermissionPermanentlyDenied(this, perms)) {
|
||||
AppSettingsDialog.Builder(this)
|
||||
.setTitle(getString(R.string.title_settings_dialog))
|
||||
.setRationale(getString(R.string.rationale_ask_again))
|
||||
.setPositiveButton(getString(R.string.setting))
|
||||
.setNegativeButton(getString(R.string.cancel))
|
||||
.setRequestCode(RC_SETTINGS_SCREEN_PERM)
|
||||
.build()
|
||||
.show()
|
||||
}
|
||||
}
|
||||
|
||||
@AfterPermissionGranted(RC_VIDEO_APP_PERM)
|
||||
private fun requestPermissions() {
|
||||
val perms = arrayOf(Manifest.permission.INTERNET, Manifest.permission.CAMERA)
|
||||
if (EasyPermissions.hasPermissions(requireContext(), *perms)) {
|
||||
try {
|
||||
mSession = Session.Builder(context, apiKey, sessionId).build()
|
||||
mSession!!.setSessionListener(this)
|
||||
mSession!!.connect(token)
|
||||
} catch (e: Exception) {
|
||||
e.printStackTrace()
|
||||
}
|
||||
} else {
|
||||
EasyPermissions.requestPermissions(this, getString(R.string.remaining_ar), RC_VIDEO_APP_PERM, *perms)
|
||||
}
|
||||
}
|
||||
|
||||
override fun onConnected(session: Session?) {
|
||||
Log.i(TAG, "Session Connected")
|
||||
mPublisher = Publisher.Builder(requireContext()).build()
|
||||
mPublisher!!.setPublisherListener(this)
|
||||
mPublisherViewContainer!!.addView(mPublisher!!.view)
|
||||
if (mPublisher!!.getView() is GLSurfaceView) {
|
||||
(mPublisher!!.getView() as GLSurfaceView).setZOrderOnTop(true)
|
||||
}
|
||||
mSession!!.publish(mPublisher)
|
||||
}
|
||||
|
||||
override fun onDisconnected(session: Session) {
|
||||
Log.d(TAG, "onDisconnected: disconnected from session " + session.sessionId)
|
||||
mSession = null
|
||||
}
|
||||
|
||||
override fun onError(session: Session, opentokError: OpentokError) {
|
||||
Log.d(TAG, "onError: Error (" + opentokError.message + ") in session " + session.sessionId)
|
||||
Toast.makeText(requireContext(), "Session error. See the logcat please.", Toast.LENGTH_LONG).show()
|
||||
requireActivity().finish()
|
||||
}
|
||||
|
||||
override fun onStreamReceived(session: Session, stream: Stream) {
|
||||
Log.d(TAG, "onStreamReceived: New stream " + stream.streamId + " in session " + session.sessionId)
|
||||
if (mSubscriber != null) {
|
||||
isConnected = true
|
||||
return
|
||||
}
|
||||
isConnected = true
|
||||
subscribeToStream(stream)
|
||||
videoCallPresenter.callChangeCallStatus(ChangeCallStatusRequestModel(3, sessionStatusModel!!.doctorId, sessionStatusModel!!.generalid, token, sessionStatusModel!!.vcid))
|
||||
}
|
||||
|
||||
override fun onStreamDropped(session: Session, stream: Stream) {
|
||||
Log.d(TAG, "onStreamDropped: Stream " + stream.streamId + " dropped from session " + session.sessionId)
|
||||
if (mSubscriber == null) {
|
||||
return
|
||||
}
|
||||
if (mSubscriber!!.stream == stream) {
|
||||
mSubscriberViewContainer!!.removeView(mSubscriber!!.view)
|
||||
mSubscriber!!.destroy()
|
||||
mSubscriber = null
|
||||
}
|
||||
disconnectSession()
|
||||
}
|
||||
|
||||
override fun onStreamCreated(publisherKit: PublisherKit?, stream: Stream) {
|
||||
Log.d(TAG, "onStreamCreated: Own stream " + stream.streamId + " created")
|
||||
}
|
||||
|
||||
override fun onStreamDestroyed(publisherKit: PublisherKit?, stream: Stream) {
|
||||
Log.d(TAG, "onStreamDestroyed: Own stream " + stream.streamId + " destroyed")
|
||||
}
|
||||
|
||||
override fun onError(publisherKit: PublisherKit?, opentokError: OpentokError) {
|
||||
Log.d(VideoCallFragment.TAG, "onError: Error (" + opentokError.message + ") in publisher")
|
||||
Toast.makeText(requireContext(), "Session error. See the logcat please.", Toast.LENGTH_LONG).show()
|
||||
requireActivity().finish()
|
||||
}
|
||||
|
||||
override fun onVideoDataReceived(subscriberKit: SubscriberKit?) {
|
||||
mSubscriber!!.setStyle(BaseVideoRenderer.STYLE_VIDEO_SCALE, BaseVideoRenderer.STYLE_VIDEO_FILL)
|
||||
mSubscriberViewContainer!!.addView(mSubscriber!!.view)
|
||||
}
|
||||
|
||||
override fun onVideoDisabled(subscriberKit: SubscriberKit?, s: String?) {}
|
||||
|
||||
override fun onVideoEnabled(subscriberKit: SubscriberKit?, s: String?) {}
|
||||
|
||||
override fun onVideoDisableWarning(subscriberKit: SubscriberKit?) {}
|
||||
|
||||
override fun onVideoDisableWarningLifted(subscriberKit: SubscriberKit?) {}
|
||||
|
||||
private fun subscribeToStream(stream: Stream) {
|
||||
mSubscriber = Subscriber.Builder(requireContext(), stream).build()
|
||||
mSubscriber!!.setVideoListener(this)
|
||||
mSession!!.subscribe(mSubscriber)
|
||||
}
|
||||
|
||||
private fun disconnectSession() {
|
||||
if (mSession == null) {
|
||||
requireActivity().setResult(Activity.RESULT_CANCELED)
|
||||
requireActivity().finish()
|
||||
return
|
||||
}
|
||||
if (mSubscriber != null) {
|
||||
mSubscriberViewContainer!!.removeView(mSubscriber!!.view)
|
||||
mSession!!.unsubscribe(mSubscriber)
|
||||
mSubscriber!!.destroy()
|
||||
mSubscriber = null
|
||||
}
|
||||
if (mPublisher != null) {
|
||||
mPublisherViewContainer!!.removeView(mPublisher!!.view)
|
||||
mSession!!.unpublish(mPublisher)
|
||||
mPublisher!!.destroy()
|
||||
mPublisher = null
|
||||
}
|
||||
mSession!!.disconnect()
|
||||
countDownTimer?.cancel()
|
||||
videoCallPresenter.callChangeCallStatus(ChangeCallStatusRequestModel(16, sessionStatusModel!!.doctorId, sessionStatusModel!!.generalid, token, sessionStatusModel!!.vcid))
|
||||
requireActivity().finish()
|
||||
}
|
||||
|
||||
fun onSwitchCameraClicked(view: View?) {
|
||||
if (mPublisher != null) {
|
||||
isSwitchCameraClicked = !isSwitchCameraClicked
|
||||
mPublisher!!.cycleCamera()
|
||||
val res = if (isSwitchCameraClicked) R.drawable.flip_disapled else R.drawable.flip_enabled
|
||||
mSwitchCameraBtn!!.setImageResource(res)
|
||||
}
|
||||
}
|
||||
|
||||
fun onCameraClicked(view: View?) {
|
||||
if (mPublisher != null) {
|
||||
isCameraClicked = !isCameraClicked
|
||||
mPublisher!!.publishVideo = !isCameraClicked
|
||||
val res = if (isCameraClicked) R.drawable.video_disanabled else R.drawable.video_enabled
|
||||
mCameraBtn!!.setImageResource(res)
|
||||
}
|
||||
}
|
||||
|
||||
fun onSpeckerClicked(view: View?) {
|
||||
if (mSubscriber != null) {
|
||||
isSpeckerClicked = !isSpeckerClicked
|
||||
mSubscriber!!.subscribeToAudio = !isSpeckerClicked
|
||||
val res = if (isSpeckerClicked) R.drawable.audio_disabled else R.drawable.audio_enabled
|
||||
mspeckerBtn!!.setImageResource(res)
|
||||
}
|
||||
}
|
||||
|
||||
fun onMicClicked(view: View?) {
|
||||
if (mPublisher != null) {
|
||||
isMicClicked = !isMicClicked
|
||||
mPublisher!!.publishAudio = !isMicClicked
|
||||
val res = if (isMicClicked) R.drawable.mic_disabled else R.drawable.mic_enabled
|
||||
mMicBtn!!.setImageResource(res)
|
||||
}
|
||||
}
|
||||
|
||||
fun onCallClicked(view: View?) {
|
||||
disconnectSession()
|
||||
}
|
||||
|
||||
override fun onCallSuccessful(sessionStatusModel: SessionStatusModel) {
|
||||
if (sessionStatusModel.sessionStatus == 2 || sessionStatusModel.sessionStatus == 3) {
|
||||
val returnIntent = Intent()
|
||||
returnIntent.putExtra("sessionStatusNotRespond", sessionStatusModel)
|
||||
requireActivity().setResult(Activity.RESULT_OK, returnIntent)
|
||||
requireActivity().finish()
|
||||
}
|
||||
}
|
||||
|
||||
override fun onCallChangeCallStatusSuccessful(sessionStatusModel: SessionStatusModel?) {}
|
||||
|
||||
override fun onFailure() {}
|
||||
|
||||
companion object {
|
||||
@JvmStatic
|
||||
fun newInstance(args: Bundle) =
|
||||
VideoCallFragment().apply {
|
||||
arguments = args
|
||||
}
|
||||
|
||||
private val TAG = VideoCallActivity::class.java.simpleName
|
||||
|
||||
private const val RC_SETTINGS_SCREEN_PERM = 123
|
||||
private const val RC_VIDEO_APP_PERM = 124
|
||||
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue