661 lines
26 KiB
Java
661 lines
26 KiB
Java
package com.shayu.onetoone.manager;
|
||
|
||
import android.Manifest;
|
||
import android.os.Bundle;
|
||
import android.os.Handler;
|
||
import android.os.Looper;
|
||
import android.text.TextUtils;
|
||
import android.view.SurfaceView;
|
||
|
||
import com.blankj.utilcode.util.PermissionUtils;
|
||
import com.shayu.onetoone.AppContext;
|
||
import com.shayu.onetoone.R;
|
||
import com.shayu.onetoone.bean.SendConsumeBean;
|
||
import com.shayu.onetoone.listener.OnCallStatusListener;
|
||
import com.shayu.onetoone.listener.OnSendMessageListener;
|
||
import com.yunbao.common.CommonAppContext;
|
||
import com.yunbao.common.manager.IMLoginManager;
|
||
import com.yunbao.common.utils.StringUtil;
|
||
import com.yunbao.common.utils.ToastUtil;
|
||
import com.yunbao.faceunity.FaceManager;
|
||
|
||
import java.util.ArrayList;
|
||
import java.util.HashMap;
|
||
import java.util.List;
|
||
import java.util.Locale;
|
||
import java.util.Timer;
|
||
import java.util.TimerTask;
|
||
|
||
import io.rong.callkit.util.CallKitUtils;
|
||
import io.rong.calllib.CallUserProfile;
|
||
import io.rong.calllib.IRongCallListener;
|
||
import io.rong.calllib.IRongReceivedCallListener;
|
||
import io.rong.calllib.RongCallClient;
|
||
import io.rong.calllib.RongCallCommon;
|
||
import io.rong.calllib.RongCallSession;
|
||
import io.rong.calllib.StartCameraCallback;
|
||
import io.rong.calllib.message.CallSTerminateMessage;
|
||
import io.rong.common.RLog;
|
||
import io.rong.imkit.IMCenter;
|
||
import io.rong.imlib.RongIMClient;
|
||
import io.rong.imlib.model.Conversation;
|
||
|
||
public class CallClientManager {
|
||
public static final String VIDEO_RECEIVED_CALL = "receivedVideoCall";//接听
|
||
public static final String VIDEO_CALL = "callVideo";//拨打
|
||
public static final String VIDEO_FLOAT = "videoFloatWindow";//浮窗
|
||
public static final String AUDIO_RECEIVED_CALL = "receivedAudioCall";//接听
|
||
public static final String AUDIO_CALL = "callAudio";//拨打
|
||
public static final String AUDIO_FLOAT = "audioFloatWindow";//浮窗
|
||
private static CallClientManager manager;
|
||
private SurfaceView localVideo, remoteVideo;
|
||
private List<OnCallStatusListener> listeners;
|
||
private CallTimeTask timeTask = null;
|
||
|
||
public static CallClientManager getManager() {
|
||
if (manager == null) {
|
||
manager = new CallClientManager();
|
||
}
|
||
return manager;
|
||
}
|
||
|
||
private CallClientManager() {
|
||
listeners = new ArrayList<>();
|
||
init();
|
||
}
|
||
|
||
public SurfaceView getLocalVideo() {
|
||
return localVideo;
|
||
}
|
||
|
||
public SurfaceView getRemoteVideo() {
|
||
if (RongCallClient.getInstance() != null) {
|
||
for (CallUserProfile profile : RongCallClient.getInstance().getCallSession().getParticipantProfileList()) {
|
||
if (!profile.getUserId().equals(IMLoginManager.get(AppContext.getTopActivity()).getUserInfo().getId() + "")) {
|
||
return profile.getVideoView();
|
||
}
|
||
}
|
||
}
|
||
return remoteVideo;
|
||
}
|
||
|
||
private void init() {
|
||
RongCallClient.setReceivedCallListener(new CallMeListener());
|
||
}
|
||
|
||
public void addOnVoIPCallListener(OnCallStatusListener statusListener) {
|
||
listeners.add(statusListener);
|
||
RongCallClient.getInstance().setVoIPCallListener(new CallStatusListener(new OnCallStatusListener() {
|
||
@Override
|
||
public void onCallWait(SurfaceView localVideo) {
|
||
for (OnCallStatusListener listener : listeners) {
|
||
listener.onCallWait(localVideo);
|
||
}
|
||
}
|
||
|
||
@Override
|
||
public void onCallStart(String userId, SurfaceView remoteVideo) {
|
||
for (OnCallStatusListener listener : listeners) {
|
||
listener.onCallStart(userId, remoteVideo);
|
||
}
|
||
startTimer(null);
|
||
}
|
||
|
||
@Override
|
||
public void onCallEnd() {
|
||
for (OnCallStatusListener listener : listeners) {
|
||
listener.onCallEnd();
|
||
}
|
||
endTimer();
|
||
}
|
||
|
||
@Override
|
||
public void onStartFirstFrame() {
|
||
for (OnCallStatusListener listener : listeners) {
|
||
listener.onStartFirstFrame();
|
||
}
|
||
}
|
||
}));
|
||
}
|
||
|
||
public void removeOnVoIPCallListener(OnCallStatusListener statusListener) {
|
||
listeners.remove(statusListener);
|
||
}
|
||
|
||
public void checkMoney(String targetId, boolean video, OnSendMessageListener listener) {
|
||
if (video) {
|
||
SendMessageManager.checkVideoMessage(targetId, "1", listener);
|
||
} else {
|
||
SendMessageManager.checkAudioMessage(targetId, "1", listener);
|
||
}
|
||
}
|
||
|
||
private void startTimer(String targetId) {
|
||
if (timeTask != null) {
|
||
timeTask.cancel();
|
||
}
|
||
timeTask = new CallTimeTask(targetId);
|
||
new Timer().schedule(timeTask, 0, 1000);
|
||
}
|
||
|
||
private void endTimer() {
|
||
if (timeTask != null) {
|
||
timeTask.cancel();
|
||
}
|
||
timeTask = null;
|
||
}
|
||
|
||
public void callVideo(String targetId) {
|
||
RongCallClient.getInstance().setVoIPCallListener(new CallStatusListener(new OnCallStatusListener() {
|
||
@Override
|
||
public void onCallWait(SurfaceView localVideo) {
|
||
for (OnCallStatusListener listener : listeners) {
|
||
listener.onCallWait(localVideo);
|
||
}
|
||
ToastUtil.show(R.string.call_tips1);
|
||
}
|
||
|
||
@Override
|
||
public void onCallStart(String userId, SurfaceView remoteVideo) {
|
||
for (OnCallStatusListener listener : listeners) {
|
||
listener.onCallStart(userId, remoteVideo);
|
||
}
|
||
ToastUtil.show(R.string.call_tips2);
|
||
startTimer(targetId);
|
||
}
|
||
|
||
@Override
|
||
public void onCallEnd() {
|
||
for (OnCallStatusListener listener : listeners) {
|
||
listener.onCallEnd();
|
||
}
|
||
endTimer();
|
||
}
|
||
|
||
@Override
|
||
public void onStartFirstFrame() {
|
||
for (OnCallStatusListener listener : listeners) {
|
||
listener.onStartFirstFrame();
|
||
}
|
||
}
|
||
}));
|
||
List<String> userIds = new ArrayList<>();
|
||
userIds.add(targetId);
|
||
RongCallClient.getInstance().startCall(Conversation.ConversationType.PRIVATE, targetId, userIds, null, RongCallCommon.CallMediaType.VIDEO, null);
|
||
}
|
||
|
||
public void callAudio(String targetId) {
|
||
RongCallClient.getInstance().setVoIPCallListener(new CallStatusListener(new OnCallStatusListener() {
|
||
@Override
|
||
public void onCallWait(SurfaceView localVideo) {
|
||
for (OnCallStatusListener listener : listeners) {
|
||
listener.onCallWait(localVideo);
|
||
}
|
||
ToastUtil.show(R.string.call_tips1);
|
||
}
|
||
|
||
@Override
|
||
public void onCallStart(String userId, SurfaceView remoteVideo) {
|
||
for (OnCallStatusListener listener : listeners) {
|
||
listener.onCallStart(userId, remoteVideo);
|
||
}
|
||
ToastUtil.show(R.string.call_tips2);
|
||
startTimer(targetId);
|
||
}
|
||
|
||
@Override
|
||
public void onCallEnd() {
|
||
for (OnCallStatusListener listener : listeners) {
|
||
listener.onCallEnd();
|
||
}
|
||
endTimer();
|
||
}
|
||
|
||
@Override
|
||
public void onStartFirstFrame() {
|
||
for (OnCallStatusListener listener : listeners) {
|
||
listener.onStartFirstFrame();
|
||
}
|
||
}
|
||
}));
|
||
List<String> userIds = new ArrayList<>();
|
||
userIds.add(targetId);
|
||
RongCallClient.getInstance().startCall(Conversation.ConversationType.PRIVATE, targetId, userIds, null, RongCallCommon.CallMediaType.AUDIO, null);
|
||
}
|
||
|
||
public void acceptCall(String callId) {
|
||
RongCallClient.getInstance().acceptCall(callId);
|
||
}
|
||
|
||
public void endCall() {
|
||
if (RongCallClient.getInstance() != null && RongCallClient.getInstance().getCallSession() != null) {
|
||
RongCallClient.getInstance().hangUpCall(RongCallClient.getInstance().getCallSession().getCallId());
|
||
}
|
||
}
|
||
|
||
public boolean isCalling() {
|
||
return RongCallClient.getInstance() != null && RongCallClient.getInstance().getCallSession() != null;
|
||
}
|
||
|
||
public boolean isCallVideo(RongCallSession callSession) {
|
||
return callSession.getMediaType().equals(RongCallCommon.CallMediaType.VIDEO);
|
||
}
|
||
|
||
public long getTime(long activeTime) {
|
||
return activeTime == 0 ? 0 : (System.currentTimeMillis() - activeTime) / 1000;
|
||
}
|
||
|
||
private class CallTimeTask extends TimerTask {
|
||
Handler handler = new Handler(Looper.getMainLooper());
|
||
|
||
private String targetId;
|
||
private String sessionId;
|
||
private boolean isCallVideo = false;
|
||
long warningTime;
|
||
long activeTime;
|
||
|
||
public CallTimeTask(String targetId) {
|
||
this.targetId = targetId;
|
||
}
|
||
|
||
@Override
|
||
public boolean cancel() {
|
||
if(sessionId.equals(targetId)){
|
||
System.err.println("接听方不计费 结束");
|
||
return super.cancel();
|
||
}
|
||
long time = getTime(activeTime);
|
||
time = time % 10;
|
||
if (time == 0) {
|
||
time = 10;
|
||
}
|
||
if (isCallVideo) {
|
||
SendMessageManager.pingVideoMessage(targetId, time + "", new SendMessageListener());
|
||
} else {
|
||
SendMessageManager.pingAudioMessage(targetId, time + "", new SendMessageListener());
|
||
}
|
||
return super.cancel();
|
||
}
|
||
|
||
@Override
|
||
public void run() {
|
||
RongCallSession callSession = RongCallClient.getInstance().getCallSession();
|
||
if (callSession == null) {
|
||
cancel();
|
||
timeTask = null;
|
||
return;
|
||
}
|
||
isCallVideo = callSession.getMediaType() == RongCallCommon.CallMediaType.VIDEO;
|
||
activeTime = callSession.getActiveTime();
|
||
sessionId=callSession.getCallerUserId();
|
||
long time = getTime(activeTime);
|
||
checkTime(time);
|
||
String extra;
|
||
if (time > 0) {
|
||
if (time >= 3600) {
|
||
extra =
|
||
String.format(
|
||
Locale.ROOT,
|
||
"%d:%02d:%02d",
|
||
time / 3600,
|
||
(time % 3600) / 60,
|
||
(time % 60));
|
||
} else {
|
||
extra = String.format(Locale.ROOT, "%02d:%02d", (time % 3600) / 60, (time % 60));
|
||
}
|
||
handler.post(() -> {
|
||
for (OnCallStatusListener listener : listeners) {
|
||
listener.onTime(extra);
|
||
if (warningTime <= 60) {
|
||
listener.onTimeWarning(warningTime--);
|
||
}
|
||
}
|
||
});
|
||
|
||
}
|
||
}
|
||
|
||
private void checkTime(long time) {
|
||
if (StringUtil.isEmpty(targetId)) {
|
||
return;
|
||
}
|
||
if(sessionId.equals(targetId)){
|
||
System.err.println("接听方不计费");
|
||
return;
|
||
}
|
||
if(time==0){
|
||
return;
|
||
}
|
||
time = time % 10;
|
||
if (time == 0) {
|
||
time = 10;
|
||
} else {
|
||
return;
|
||
}
|
||
if (isCallVideo) {
|
||
SendMessageManager.pingVideoMessage(targetId, time + "", new SendMessageListener());
|
||
} else {
|
||
SendMessageManager.pingAudioMessage(targetId, time + "", new SendMessageListener());
|
||
}
|
||
}
|
||
|
||
private class SendMessageListener extends OnSendMessageListener {
|
||
@Override
|
||
public void onSuccess(String token, SendConsumeBean bean) {
|
||
super.onSuccess(token, bean);
|
||
|
||
if (isCallVideo) {
|
||
warningTime = bean.getVideoTime();
|
||
} else {
|
||
warningTime = bean.getMp3Time();
|
||
}
|
||
if (warningTime <= 60) {
|
||
for (OnCallStatusListener listener : listeners) {
|
||
listener.onTimeWarning(warningTime);
|
||
}
|
||
}
|
||
}
|
||
|
||
@Override
|
||
public void onError(int status, String msg) {
|
||
super.onError(status, msg);
|
||
if (status == OnSendMessageListener.STATUS_NOT_PRICE) {
|
||
for (OnCallStatusListener listener : listeners) {
|
||
listener.onErrorNotPrice(msg);
|
||
}
|
||
endCall();
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
private static class CallMeListener implements IRongReceivedCallListener {
|
||
|
||
@Override
|
||
public void onReceivedCall(RongCallSession callSession) {
|
||
Bundle bundle = new Bundle();
|
||
bundle.putString("targetId", callSession.getTargetId());
|
||
bundle.putString("callId", callSession.getCallId());
|
||
bundle.putString("sessionId", callSession.getSessionId());
|
||
if (callSession.getMediaType() == RongCallCommon.CallMediaType.VIDEO) {
|
||
bundle.putString("model", VIDEO_RECEIVED_CALL);
|
||
RouteManager.forwardActivity(RouteManager.ACTIVITY_CALL_VIDEO, bundle);
|
||
} else {
|
||
bundle.putString("model", AUDIO_RECEIVED_CALL);
|
||
RouteManager.forwardActivity(RouteManager.ACTIVITY_CALL_AUDIO, bundle);
|
||
}
|
||
}
|
||
|
||
@Override
|
||
public void onCheckPermission(RongCallSession callSession) {
|
||
ToastUtil.show(R.string.permission_request_title);
|
||
PermissionUtils.permission(Manifest.permission.CAMERA, Manifest.permission.RECORD_AUDIO).callback(new PermissionUtils.SimpleCallback() {
|
||
@Override
|
||
public void onGranted() {
|
||
RongCallClient.getInstance().onPermissionGranted();
|
||
}
|
||
|
||
@Override
|
||
public void onDenied() {
|
||
RongCallClient.getInstance().onPermissionDenied();
|
||
}
|
||
}).request();
|
||
}
|
||
}
|
||
|
||
private class CallStatusListener implements IRongCallListener {
|
||
OnCallStatusListener statusListener;
|
||
private long time = 0;
|
||
|
||
public CallStatusListener(OnCallStatusListener statusListener) {
|
||
this.statusListener = statusListener;
|
||
}
|
||
|
||
public long getTime(long activeTime) {
|
||
long tmpTime = activeTime == 0 ? 0 : (System.currentTimeMillis() - activeTime) / 1000;
|
||
time = tmpTime == 0 ? time : tmpTime;
|
||
return time;
|
||
}
|
||
|
||
@Override
|
||
public void onCallIncoming(RongCallSession callSession, SurfaceView localVideo) {
|
||
System.out.println("CallStatusListener.onCallIncoming");
|
||
}
|
||
|
||
/**
|
||
* 电话已拨出。
|
||
* 主叫端拨出电话后,通过回调 onCallOutgoing 通知当前 call 的详细信息。
|
||
*
|
||
* @param callSession 通话实体。
|
||
* @param localVideo 本地 camera 信息。
|
||
*/
|
||
@Override
|
||
public void onCallOutgoing(RongCallSession callSession, SurfaceView localVideo) {
|
||
if (isCallVideo(callSession)) {
|
||
localVideo.setZOrderOnTop(true);
|
||
localVideo.setZOrderMediaOverlay(true);
|
||
CallClientManager.this.localVideo = localVideo;
|
||
}
|
||
statusListener.onCallWait(localVideo);
|
||
System.out.println("CallStatusListener.onCallOutgoing");
|
||
}
|
||
|
||
/**
|
||
* 已建立通话。
|
||
* 通话接通时,通过回调 onCallConnected 通知当前 call 的详细信息。
|
||
*
|
||
* @param callSession 通话实体。
|
||
* @param localVideo 本地 camera 信息。
|
||
*/
|
||
@Override
|
||
public void onCallConnected(RongCallSession callSession, SurfaceView localVideo) {
|
||
if (isCallVideo(callSession)) {
|
||
localVideo.setZOrderOnTop(true);
|
||
localVideo.setZOrderMediaOverlay(true);
|
||
CallClientManager.this.localVideo = localVideo;
|
||
}
|
||
statusListener.onCallWait(localVideo);
|
||
}
|
||
|
||
/**
|
||
* 通话结束。
|
||
* 通话中,对方挂断,己方挂断,或者通话过程网络异常造成的通话中断,都会回调 onCallDisconnected。
|
||
*
|
||
* @param callSession 通话实体。
|
||
* @param reason 通话中断原因。
|
||
*/
|
||
@Override
|
||
public void onCallDisconnected(RongCallSession callSession, RongCallCommon.CallDisconnectedReason reason) {
|
||
System.out.println("CallStatusListener.onCallDisconnected");
|
||
|
||
String senderId;
|
||
String extra = "";
|
||
|
||
if (callSession == null) {
|
||
RLog.e("CallStatusListener", "onCallDisconnected. callSession is null!");
|
||
statusListener.onCallEnd();
|
||
return;
|
||
}
|
||
senderId = callSession.getInviterUserId();
|
||
long time = getTime(callSession.getActiveTime());
|
||
if (time > 0) {
|
||
if (time >= 3600) {
|
||
extra =
|
||
String.format(
|
||
Locale.ROOT,
|
||
"%d:%02d:%02d",
|
||
time / 3600,
|
||
(time % 3600) / 60,
|
||
(time % 60));
|
||
} else {
|
||
extra = String.format(Locale.ROOT, "%02d:%02d", (time % 3600) / 60, (time % 60));
|
||
}
|
||
}
|
||
|
||
if (!TextUtils.isEmpty(senderId)) {
|
||
CallSTerminateMessage message = new CallSTerminateMessage();
|
||
message.setReason(reason);
|
||
message.setMediaType(callSession.getMediaType());
|
||
message.setExtra(extra);
|
||
long serverTime =
|
||
System.currentTimeMillis() - RongIMClient.getInstance().getDeltaTime();
|
||
if (senderId.equals(callSession.getSelfUserId())) {
|
||
message.setDirection("MO");
|
||
IMCenter.getInstance()
|
||
.insertOutgoingMessage(
|
||
Conversation.ConversationType.PRIVATE,
|
||
callSession.getTargetId(),
|
||
io.rong.imlib.model.Message.SentStatus.SENT,
|
||
message,
|
||
serverTime,
|
||
null);
|
||
} else {
|
||
message.setDirection("MT");
|
||
IMCenter.getInstance()
|
||
.insertIncomingMessage(
|
||
Conversation.ConversationType.PRIVATE,
|
||
callSession.getTargetId(),
|
||
senderId,
|
||
CallKitUtils.getReceivedStatus(reason),
|
||
message,
|
||
serverTime,
|
||
null);
|
||
}
|
||
}
|
||
statusListener.onCallEnd();
|
||
CallClientManager.this.remoteVideo = null;
|
||
CallClientManager.this.localVideo = null;
|
||
}
|
||
|
||
@Override
|
||
public void onRemoteUserRinging(String userId) {
|
||
System.out.println("CallStatusListener.onRemoteUserRinging");
|
||
}
|
||
|
||
@Override
|
||
public void onRemoteUserAccept(String userId, RongCallCommon.CallMediaType mediaType) {
|
||
System.out.println("CallStatusListener.onRemoteUserAccept");
|
||
}
|
||
|
||
/**
|
||
* 被叫端加入通话。
|
||
* 主叫端拨出电话,被叫端收到请求后,加入通话,回调 onRemoteUserJoined。
|
||
*
|
||
* @param userId 加入用户的 id。<br />
|
||
* @param mediaType 加入用户的媒体类型,audio or video。<br />
|
||
* @param userType 加入用户的类型,1:正常用户,2:观察者。<br />
|
||
* @param remoteVideo 加入用户者的 camera 信息。如果 userType为2,remoteVideo对象为空;<br />
|
||
* 如果对端调用{@link RongCallClient#startCall(int, boolean, Conversation.ConversationType, String, List, List, RongCallCommon.CallMediaType, String, StartCameraCallback)} 或
|
||
* {@link RongCallClient#acceptCall(String, int, boolean, StartCameraCallback)}开始的音视频通话,则可以使用如下设置改变对端视频流的镜像显示:<br />
|
||
* <pre class="prettyprint">
|
||
* public void onRemoteUserJoined(String userId, RongCallCommon.CallMediaType mediaType, int userType, SurfaceView remoteVideo) {
|
||
* if (null != remoteVideo) {
|
||
* ((RongRTCVideoView) remoteVideo).setMirror( boolean);//观看对方视频流是否镜像处理
|
||
* }
|
||
* }
|
||
* </pre>
|
||
*/
|
||
@Override
|
||
public void onRemoteUserJoined(String userId, RongCallCommon.CallMediaType mediaType, int userType, SurfaceView remoteVideo) {
|
||
if (mediaType == RongCallCommon.CallMediaType.AUDIO) {
|
||
statusListener.onCallStart(userId, null);
|
||
return;
|
||
}
|
||
if (CallClientManager.this.remoteVideo != null) {
|
||
statusListener.onCallStart(userId, CallClientManager.this.remoteVideo);
|
||
return;
|
||
}
|
||
remoteVideo.setZOrderOnTop(false);
|
||
remoteVideo.setZOrderMediaOverlay(false);
|
||
CallClientManager.this.remoteVideo = remoteVideo;
|
||
statusListener.onCallStart(userId, remoteVideo);
|
||
System.out.println("CallStatusListener.onRemoteUserJoined");
|
||
}
|
||
|
||
@Override
|
||
public void onRemoteUserInvited(String userId, RongCallCommon.CallMediaType mediaType) {
|
||
System.out.println("CallStatusListener.onRemoteUserInvited");
|
||
}
|
||
|
||
/**
|
||
* 通话中的远端参与者离开。
|
||
* 回调 onRemoteUserLeft 通知状态更新。
|
||
*
|
||
* @param userId 远端参与者的 id。
|
||
* @param reason 远端参与者离开原因。
|
||
*/
|
||
@Override
|
||
public void onRemoteUserLeft(String userId, RongCallCommon.CallDisconnectedReason reason) {
|
||
System.out.println("CallStatusListener.onRemoteUserLeft");
|
||
if (statusListener != null) {
|
||
statusListener.onCallEnd();
|
||
}
|
||
}
|
||
|
||
@Override
|
||
public void onMediaTypeChanged(String userId, RongCallCommon.CallMediaType mediaType, SurfaceView video) {
|
||
System.out.println("CallStatusListener.onMediaTypeChanged");
|
||
}
|
||
|
||
@Override
|
||
public void onError(RongCallCommon.CallErrorCode errorCode) {
|
||
System.out.println("CallStatusListener.onError");
|
||
if (statusListener != null) {
|
||
statusListener.onCallEnd();
|
||
}
|
||
}
|
||
|
||
@Override
|
||
public void onRemoteCameraDisabled(String userId, boolean disabled) {
|
||
|
||
}
|
||
|
||
@Override
|
||
public void onRemoteMicrophoneDisabled(String userId, boolean disabled) {
|
||
|
||
}
|
||
|
||
@Override
|
||
public void onNetworkReceiveLost(String userId, int lossRate) {
|
||
|
||
}
|
||
|
||
@Override
|
||
public void onNetworkSendLost(int lossRate, int delay) {
|
||
|
||
}
|
||
|
||
@Override
|
||
public void onFirstRemoteVideoFrame(String userId, int height, int width) {
|
||
if (statusListener != null) {
|
||
statusListener.onStartFirstFrame();
|
||
}
|
||
}
|
||
|
||
@Override
|
||
public void onFirstRemoteAudioFrame(String userId) {
|
||
|
||
}
|
||
|
||
@Override
|
||
public void onAudioLevelSend(String audioLevel) {
|
||
|
||
}
|
||
|
||
@Override
|
||
public void onAudioLevelReceive(HashMap<String, String> audioLevel) {
|
||
|
||
}
|
||
|
||
@Override
|
||
public void onRemoteUserPublishVideoStream(String userId, String streamId, String tag, SurfaceView surfaceView) {
|
||
|
||
}
|
||
|
||
@Override
|
||
public void onRemoteUserUnpublishVideoStream(String userId, String streamId, String tag) {
|
||
|
||
}
|
||
}
|
||
}
|