|
@@ -0,0 +1,379 @@
|
|
|
+package com.wdkl.ncs.android.component.home.fragment
|
|
|
+
|
|
|
+import android.os.Handler
|
|
|
+import android.os.Looper
|
|
|
+import android.os.SystemClock
|
|
|
+import android.util.Log
|
|
|
+import android.view.View
|
|
|
+import android.view.ViewGroup
|
|
|
+import com.google.gson.Gson
|
|
|
+import com.wdkl.ncs.android.component.home.R
|
|
|
+import com.wdkl.ncs.android.component.home.util.AppUtils
|
|
|
+import com.wdkl.ncs.android.component.nursehome.common.Constants
|
|
|
+import com.wdkl.ncs.android.lib.utils.showMessage
|
|
|
+import com.wdkl.ncs.android.middleware.model.vo.InteractionVO
|
|
|
+import com.wdkl.ncs.android.middleware.tcp.channel.DeviceChannel
|
|
|
+import com.wdkl.ncs.android.middleware.tcp.channel.VideoUtil
|
|
|
+import com.wdkl.ncs.android.middleware.tcp.channel.VoiceUtil
|
|
|
+import com.wdkl.ncs.android.middleware.tcp.dto.TcpModel
|
|
|
+import com.wdkl.ncs.android.middleware.tcp.enums.TcpAction
|
|
|
+import com.wdkl.ncs.android.middleware.tcp.enums.TcpType
|
|
|
+import com.wdkl.ncs.android.middleware.utils.MessageEvent
|
|
|
+import com.wdkl.skywebrtc.CallSession
|
|
|
+import com.wdkl.skywebrtc.EnumType
|
|
|
+import com.wdkl.skywebrtc.SkyEngineKit
|
|
|
+import kotlinx.android.synthetic.main.sky_voice_call_layout.*
|
|
|
+import org.greenrobot.eventbus.Subscribe
|
|
|
+import org.greenrobot.eventbus.ThreadMode
|
|
|
+import org.webrtc.SurfaceViewRenderer
|
|
|
+import java.util.*
|
|
|
+
|
|
|
+class SkyCallFragment: BaseCallFragment(), CallSession.CallSessionCallback {
|
|
|
+
|
|
|
+ private var localSurfaceView: SurfaceViewRenderer? = null
|
|
|
+ private var remoteSurfaceView: SurfaceViewRenderer? = null
|
|
|
+
|
|
|
+ private val handler = Handler(Looper.getMainLooper())
|
|
|
+
|
|
|
+ private var callEnded: Boolean = false
|
|
|
+
|
|
|
+ override fun getLayId(): Int {
|
|
|
+ return R.layout.sky_voice_call_layout
|
|
|
+ }
|
|
|
+
|
|
|
+ override fun init() {
|
|
|
+ acceptCall()
|
|
|
+
|
|
|
+ when (callState) {
|
|
|
+ 0 -> {
|
|
|
+ //发起通话
|
|
|
+ }
|
|
|
+
|
|
|
+ 1 -> {
|
|
|
+ //接受通话
|
|
|
+ DeviceChannel.calling = true
|
|
|
+ val session = gEngineKit?.getCurrentSession()
|
|
|
+ if (session != null) {
|
|
|
+ session.setSessionCallback(this)
|
|
|
+ }
|
|
|
+ if (onlyAudio) {
|
|
|
+ Handler().postDelayed({
|
|
|
+ joinAudioCall()
|
|
|
+ }, 500)
|
|
|
+ } else {
|
|
|
+ Handler().postDelayed({
|
|
|
+ joinVideoCall()
|
|
|
+ }, 500)
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ override fun bindEvent() {
|
|
|
+ //通话挂断
|
|
|
+ sky_voice_call_hangup.setOnClickListener {
|
|
|
+ //结束sip通话
|
|
|
+ gEngineKit?.endCall()
|
|
|
+
|
|
|
+ if (Constants.visitHostId != -1) {
|
|
|
+ VideoUtil.handoffVideoCall(Constants.deviceId, Constants.visitHostId, Constants.interactionId)
|
|
|
+ }
|
|
|
+
|
|
|
+ DeviceChannel.calling = false
|
|
|
+ sky_voice_call_timer.stop()
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ override fun destroy() {
|
|
|
+ DeviceChannel.calling = false
|
|
|
+ if (sky_voice_call_timer != null) {
|
|
|
+ sky_voice_call_timer.stop()
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ //开始接听
|
|
|
+ private fun acceptCall() {
|
|
|
+ sky_voice_call_calling_text.text = "连接中..."
|
|
|
+ sky_voice_call_outgoing.visibility = View.VISIBLE
|
|
|
+ sky_voice_call_timer.visibility = View.GONE
|
|
|
+ }
|
|
|
+
|
|
|
+ //语音接通
|
|
|
+ private fun joinAudioCall() {
|
|
|
+ val session = gEngineKit?.getCurrentSession()
|
|
|
+ if (session != null) {
|
|
|
+ Log.e("dds", "audio call session state: " + session.state)
|
|
|
+
|
|
|
+ if (session.state == EnumType.CallState.Incoming) {
|
|
|
+ session.joinHome(session.roomId)
|
|
|
+ session.toggleSpeaker(true)
|
|
|
+ } else if (session.state == EnumType.CallState.Idle) {
|
|
|
+ callEnd()
|
|
|
+ return
|
|
|
+ }
|
|
|
+
|
|
|
+ Handler().postDelayed({
|
|
|
+ if (session.state == EnumType.CallState.Connected){
|
|
|
+ showCalling(onlyAudio)
|
|
|
+ } else {
|
|
|
+ gEngineKit?.endCall()
|
|
|
+ callEnd()
|
|
|
+ }
|
|
|
+ }, 1500)
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ //视频接通
|
|
|
+ private fun joinVideoCall() {
|
|
|
+ val session = gEngineKit?.getCurrentSession()
|
|
|
+ if (session != null) {
|
|
|
+ Log.e("dds", "video call session state: " + session.state)
|
|
|
+
|
|
|
+ if (session.state == EnumType.CallState.Incoming) {
|
|
|
+ val surfaceView = gEngineKit!!.currentSession.setupLocalVideo(false)
|
|
|
+ if (surfaceView != null) {
|
|
|
+ localSurfaceView = surfaceView as SurfaceViewRenderer
|
|
|
+ localSurfaceView!!.setZOrderMediaOverlay(false)
|
|
|
+ fullscreen_video_frame.addView(localSurfaceView)
|
|
|
+ }
|
|
|
+
|
|
|
+ session.joinHome(session.roomId)
|
|
|
+ session.toggleSpeaker(true)
|
|
|
+ } else if (session.state == EnumType.CallState.Idle) {
|
|
|
+ callEnd()
|
|
|
+ return
|
|
|
+ }
|
|
|
+
|
|
|
+ Handler().postDelayed({
|
|
|
+ if (session.state == EnumType.CallState.Connected){
|
|
|
+ showCalling(onlyAudio)
|
|
|
+ } else {
|
|
|
+ gEngineKit?.endCall()
|
|
|
+ callEnd()
|
|
|
+ }
|
|
|
+ }, 2000)
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ private fun showCalling(audioOnly: Boolean) {
|
|
|
+ if (audioOnly) {
|
|
|
+ //移除视频画面
|
|
|
+ fullscreen_video_frame.visibility = View.GONE
|
|
|
+ pip_video_frame.visibility = View.GONE
|
|
|
+ ll_voice_call.visibility = View.VISIBLE
|
|
|
+ } else {
|
|
|
+ //显示视频画面
|
|
|
+ fullscreen_video_frame.visibility = View.VISIBLE
|
|
|
+ pip_video_frame.visibility = View.VISIBLE
|
|
|
+ ll_voice_call.visibility = View.GONE
|
|
|
+ }
|
|
|
+
|
|
|
+ sky_voice_call_calling_text.text = "通话中..."
|
|
|
+ sky_voice_call_timer.visibility = View.VISIBLE
|
|
|
+ sky_voice_call_timer.base = SystemClock.elapsedRealtime()
|
|
|
+ sky_voice_call_timer.start()
|
|
|
+
|
|
|
+ if (Constants.hookOn) {
|
|
|
+ //手柄放下,免提模式
|
|
|
+ AppUtils.switchAudioMode(activity, true)
|
|
|
+ } else {
|
|
|
+ //手柄拿起,听筒模式
|
|
|
+ AppUtils.switchAudioMode(activity, false)
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ //创建会话
|
|
|
+ private fun startCall(targetId: String, audioOnly: Boolean): Boolean {
|
|
|
+ val room = UUID.randomUUID().toString() + System.currentTimeMillis()
|
|
|
+ val b = gEngineKit!!.startOutCall(baseActivity, room, targetId, audioOnly)
|
|
|
+ if (b) {
|
|
|
+ val session = gEngineKit!!.currentSession
|
|
|
+ if (session == null) {
|
|
|
+ return false
|
|
|
+ } else {
|
|
|
+ DeviceChannel.calling = true
|
|
|
+ session.setSessionCallback(this)
|
|
|
+ session.toggleSpeaker(true)
|
|
|
+
|
|
|
+ //3s还未连接上则判定为通话失败
|
|
|
+ Handler().postDelayed({
|
|
|
+ if (session.state == EnumType.CallState.Connected){
|
|
|
+ showCalling(onlyAudio)
|
|
|
+ } else {
|
|
|
+ gEngineKit?.endCall()
|
|
|
+ callEnd()
|
|
|
+ }
|
|
|
+ }, 3000)
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return b
|
|
|
+ }
|
|
|
+
|
|
|
+ //通话结束
|
|
|
+ private fun callEnd() {
|
|
|
+ Log.e("dds", "call end !!!!!!!!!!!!!!!!!!")
|
|
|
+ if (callEnded) {
|
|
|
+ return
|
|
|
+ }
|
|
|
+ callEnded = true
|
|
|
+
|
|
|
+ DeviceChannel.calling = false
|
|
|
+
|
|
|
+ if (sky_voice_call_timer != null) {
|
|
|
+ sky_voice_call_timer.stop()
|
|
|
+ }
|
|
|
+ if (gEngineKit != null && gEngineKit!!.currentSession != null && gEngineKit!!.currentSession.state != EnumType.CallState.Idle) {
|
|
|
+ gEngineKit!!.endCall()
|
|
|
+ }
|
|
|
+ backToMain()
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ /********************************************************
|
|
|
+ ********************* webrtc通话回调 ********************
|
|
|
+ * 注意: 如涉及到UI更新的需要在主线程处理,务必注意
|
|
|
+ *******************************************************/
|
|
|
+ override fun didChangeState(state: EnumType.CallState?) {
|
|
|
+ Log.e("dds", "didChangeState: " + state)
|
|
|
+ /*handler.post {
|
|
|
+ if (state == EnumType.CallState.Connected) {
|
|
|
+ //更新界面显示
|
|
|
+ showCalling(onlyAudio)
|
|
|
+ }
|
|
|
+ }*/
|
|
|
+ }
|
|
|
+
|
|
|
+ override fun didDisconnected(userId: String?) {
|
|
|
+ handler.post {
|
|
|
+ showMessage("断开连接")
|
|
|
+ callEnd()
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ override fun didError(error: String?) {
|
|
|
+ handler.post {
|
|
|
+ showMessage("通话错误")
|
|
|
+ callEnd()
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ //处理本地视频画面
|
|
|
+ override fun didCreateLocalVideoTrack() {
|
|
|
+ Log.e("dds", "didCreateLocalVideoTrack")
|
|
|
+ handler.post {
|
|
|
+ val session = gEngineKit!!.currentSession
|
|
|
+ if (session != null && !callEnded) {
|
|
|
+ if (localSurfaceView == null) {
|
|
|
+ val surfaceView = gEngineKit!!.currentSession.setupLocalVideo(true)
|
|
|
+ Log.e("dds", "didCreateLocalVideoTrack surfaceView: " + surfaceView)
|
|
|
+ if (surfaceView != null) {
|
|
|
+ localSurfaceView = surfaceView as SurfaceViewRenderer
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ //处理远端视频画面
|
|
|
+ override fun didReceiveRemoteVideoTrack(userId: String?) {
|
|
|
+ Log.e("dds", "didReceiveRemoteVideoTrack userId: " + userId)
|
|
|
+ handler.post {
|
|
|
+ val session = gEngineKit!!.currentSession
|
|
|
+ if (session != null && !callEnded) {
|
|
|
+ //本地画面
|
|
|
+ if (localSurfaceView != null) {
|
|
|
+ localSurfaceView!!.setZOrderMediaOverlay(true)
|
|
|
+ if (localSurfaceView!!.parent != null) {
|
|
|
+ (localSurfaceView!!.parent as ViewGroup).removeView(localSurfaceView)
|
|
|
+ }
|
|
|
+ pip_video_frame!!.addView(localSurfaceView)
|
|
|
+ }
|
|
|
+
|
|
|
+ //远端画面
|
|
|
+ val surfaceView = gEngineKit!!.currentSession.setupRemoteVideo(userId, false)
|
|
|
+ Log.e("dds", "didReceiveRemoteVideoTrack,surfaceView = $surfaceView")
|
|
|
+ if (surfaceView != null) {
|
|
|
+ remoteSurfaceView = surfaceView as SurfaceViewRenderer
|
|
|
+ fullscreen_video_frame.removeAllViews()
|
|
|
+ if (remoteSurfaceView!!.parent != null) {
|
|
|
+ (remoteSurfaceView!!.parent as ViewGroup).removeView(remoteSurfaceView)
|
|
|
+ }
|
|
|
+ fullscreen_video_frame.addView(remoteSurfaceView)
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ override fun didCallEndWithReason(callEndReason: EnumType.CallEndReason?) {
|
|
|
+ handler.post {
|
|
|
+ when (callEndReason) {
|
|
|
+ EnumType.CallEndReason.Busy -> {
|
|
|
+ showMessage("对方忙线中")
|
|
|
+ }
|
|
|
+ EnumType.CallEndReason.AcceptByOtherClient -> {
|
|
|
+ showMessage("通话中")
|
|
|
+ }
|
|
|
+ EnumType.CallEndReason.Hangup -> {
|
|
|
+ showMessage("通话结束")
|
|
|
+ }
|
|
|
+ EnumType.CallEndReason.MediaError -> {
|
|
|
+ showMessage("媒体错误")
|
|
|
+ }
|
|
|
+ EnumType.CallEndReason.OpenCameraFailure -> {
|
|
|
+ showMessage("打开摄像头错误")
|
|
|
+ }
|
|
|
+ EnumType.CallEndReason.RemoteHangup -> {
|
|
|
+ showMessage("对方挂断")
|
|
|
+ }
|
|
|
+ EnumType.CallEndReason.RemoteSignalError -> {
|
|
|
+ showMessage("对方网络断开")
|
|
|
+ }
|
|
|
+ EnumType.CallEndReason.SignalError -> {
|
|
|
+ showMessage("连接断开")
|
|
|
+ }
|
|
|
+ EnumType.CallEndReason.Timeout -> {
|
|
|
+ showMessage("对方未接听")
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ callEnd()
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ override fun didChangeMode(isAudioOnly: Boolean) {
|
|
|
+ handler.post {
|
|
|
+ //
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ override fun didUserLeave(userId: String?) {
|
|
|
+ handler.post {
|
|
|
+ showMessage("通话结束")
|
|
|
+ callEnd()
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ @Subscribe(threadMode = ThreadMode.MAIN)
|
|
|
+ fun onMoonEvent(messageEvent: MessageEvent) {
|
|
|
+ when (messageEvent.getType()) {
|
|
|
+ /*Constants.EVENT_TCP_MSG -> {
|
|
|
+ if (messageEvent.getMessage() is TcpModel) {
|
|
|
+ val curTcpModel = messageEvent.getMessage() as TcpModel
|
|
|
+ if (curTcpModel.getType() == TcpType.VOICE) {
|
|
|
+ val curInteractionVO = Gson().fromJson(curTcpModel.data.toString(), InteractionVO::class.java)
|
|
|
+ if (curTcpModel.getAction() == TcpAction.VoiceAction.HANDOFF) {
|
|
|
+ //对方挂断,不论我方呼出或呼入
|
|
|
+ if (Constants.interactionId == curInteractionVO.id) {
|
|
|
+ gEngineKit?.endCall()
|
|
|
+ callEnd()
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }*/
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+}
|