Last active
December 12, 2017 02:36
-
-
Save poberwong/35b698b72de88e382d8daff57d01649e to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package com.drr; | |
import android.content.pm.PackageManager; | |
import android.os.Build; | |
import android.support.v4.app.ActivityCompat; | |
import android.support.v4.content.ContextCompat; | |
import android.support.v7.app.AppCompatActivity; | |
import android.os.Bundle; | |
import android.text.Layout; | |
import android.util.Log; | |
import android.view.Surface; | |
import android.view.SurfaceView; | |
import android.view.View; | |
import android.view.ViewGroup; | |
import android.widget.FrameLayout; | |
import android.widget.ImageButton; | |
import android.widget.ImageView; | |
import android.widget.LinearLayout; | |
import com.netease.nimlib.sdk.NIMClient; | |
import com.netease.nimlib.sdk.Observer; | |
import com.netease.nimlib.sdk.RequestCallback; | |
import com.netease.nimlib.sdk.auth.AuthService; | |
import com.netease.nimlib.sdk.auth.LoginInfo; | |
import com.netease.nimlib.sdk.avchat.AVChatCallback; | |
import com.netease.nimlib.sdk.avchat.AVChatManager; | |
import com.netease.nimlib.sdk.avchat.AVChatManagerLite; | |
import com.netease.nimlib.sdk.avchat.model.AVChatExternalVideoRender; | |
import com.netease.nimlib.sdk.avchat.AVChatStateObserver; | |
import com.netease.nimlib.sdk.avchat.constant.AVChatEventType; | |
import com.netease.nimlib.sdk.avchat.constant.AVChatType; | |
import com.netease.nimlib.sdk.avchat.constant.AVChatVideoScalingType; | |
import com.netease.nimlib.sdk.avchat.model.AVChatAudioFrame; | |
import com.netease.nimlib.sdk.avchat.model.AVChatCalleeAckEvent; | |
import com.netease.nimlib.sdk.avchat.model.AVChatCameraCapturer; | |
import com.netease.nimlib.sdk.avchat.model.AVChatData; | |
import com.netease.nimlib.sdk.avchat.model.AVChatI420Frame; | |
import com.netease.nimlib.sdk.avchat.model.AVChatNetworkStats; | |
import com.netease.nimlib.sdk.avchat.model.AVChatNotifyOption; | |
import com.netease.nimlib.sdk.avchat.model.AVChatSessionStats; | |
import com.netease.nimlib.sdk.avchat.model.AVChatSurfaceViewRenderer; | |
import com.netease.nimlib.sdk.avchat.model.AVChatVideoCapturerFactory; | |
import com.netease.nimlib.sdk.avchat.model.AVChatVideoFrame; | |
import java.util.Map; | |
public class VideoChatActivity extends AppCompatActivity implements AVChatStateObserver{ | |
/** | |
* account info | |
*/ | |
private String account = null; | |
private String token = null; | |
private String aimAccount = null; | |
/** | |
* view info | |
*/ | |
private LinearLayout waitingView; | |
private LinearLayout surfaceRoot; | |
private LinearLayout localRoot; | |
private ImageButton bt; | |
private AVChatSurfaceViewRenderer largeRender; | |
private AVChatSurfaceViewRenderer miniRender; | |
/** | |
* component info | |
*/ | |
private CallStateEnum callingState = CallStateEnum.INVALID; | |
private AVChatCameraCapturer mVideoCapturer; | |
private AVChatData avChatData = null; | |
@Override | |
protected void onCreate(Bundle savedInstanceState) { | |
super.onCreate(savedInstanceState); | |
setContentView(R.layout.activity_video_chat); | |
bt = (ImageButton) findViewById(R.id.button); | |
waitingView = (LinearLayout) findViewById(R.id.waiting_screen); | |
surfaceRoot = (LinearLayout) findViewById(R.id.chatting_surface); | |
localRoot = (LinearLayout) findViewById(R.id.local_surface); | |
largeRender = new AVChatSurfaceViewRenderer(this); | |
miniRender = new AVChatSurfaceViewRenderer(this); | |
Bundle data = getIntent().getExtras(); | |
bt.setOnClickListener(new View.OnClickListener() { | |
@Override | |
public void onClick(View view) { | |
hangup(); | |
} | |
}); | |
account = data.getString("account"); | |
token = data.getString("token"); | |
aimAccount = data.getString("aimAccount"); | |
doLogin(); | |
getPermission(); | |
} | |
public void doLogin() { | |
LoginInfo info = new LoginInfo(account, token); // config... | |
RequestCallback<LoginInfo> callback = | |
new RequestCallback<LoginInfo>() { | |
@Override | |
public void onSuccess(LoginInfo param) { | |
Log.i("nim: ", param.getAccount()); | |
outGoingCalling(aimAccount, AVChatType.VIDEO); | |
} | |
@Override | |
public void onFailed(int code) { | |
} | |
@Override | |
public void onException(Throwable exception) { | |
} | |
// 可以在此保存LoginInfo到本地,下次启动APP做自动登录用 | |
}; | |
NIMClient.getService(AuthService.class).login(info) | |
.setCallback(callback); | |
} | |
public void logout () { | |
NIMClient.getService(AuthService.class).logout(); | |
} | |
public void hangup () { | |
if (avChatData == null) { | |
AVChatManager.getInstance().disableVideo(); | |
AVChatManager.getInstance().disableRtc(); | |
logout(); | |
finish(); | |
} else { | |
AVChatManager.getInstance().hangUp2(avChatData.getChatId(), new AVChatCallback<Void>() { | |
@Override | |
public void onSuccess(Void aVoid) { | |
AVChatManager.getInstance().disableRtc(); | |
logout(); | |
finish(); | |
} | |
@Override | |
public void onFailed(int code) { | |
} | |
@Override | |
public void onException(Throwable exception) { | |
} | |
}); | |
} | |
} | |
/** | |
* 拨打音视频 | |
*/ | |
public void outGoingCalling(String account, final AVChatType callTypeEnum) { | |
AVChatNotifyOption notifyOption = new AVChatNotifyOption(); | |
//附加字段 | |
notifyOption.extendMessage = "extra_data"; | |
//是否兼容WebRTC模式 | |
notifyOption.webRTCCompat = true; | |
//默认forceKeepCalling为true,开发者如果不需要离线持续呼叫功能可以将forceKeepCalling设为false | |
notifyOption.forceKeepCalling = false; | |
//打开Rtc模块 | |
AVChatManager.getInstance().enableRtc(); | |
this.callingState = (callTypeEnum == AVChatType.VIDEO ? CallStateEnum.VIDEO : CallStateEnum.AUDIO); | |
// //设置自己需要的可选参数 | |
// AVChatManager.getInstance().setParameters(avChatParameters); | |
//视频通话 | |
if (callTypeEnum == AVChatType.VIDEO) { | |
//打开视频模块 | |
AVChatManager.getInstance().enableVideo(); | |
AVChatManager.getInstance().startVideoPreview(); | |
//创建视频采集模块并且设置到系统中 | |
if (mVideoCapturer == null) { | |
mVideoCapturer = AVChatVideoCapturerFactory.createCameraCapturer(); | |
AVChatManager.getInstance().setupVideoCapturer(mVideoCapturer); | |
} | |
//设置本地预览画布 | |
// AVChatManager.getInstance().setupLocalVideoRender(textureViewRenderer, false, scalingType); | |
//开始视频预览 | |
// AVChatManager.getInstance().startVideoPreview(); | |
} | |
//呼叫 | |
AVChatManager.getInstance().call2(account, callTypeEnum, notifyOption, new AVChatCallback<AVChatData>() { | |
@Override | |
public void onSuccess(AVChatData data) { | |
avChatData = data; | |
//发起会话成功 | |
Log.i("call nim", "call success"); | |
} | |
@Override | |
public void onFailed(int code) { | |
Log.i("call nim", "call fail" + code); | |
} | |
@Override | |
public void onException(Throwable exception) { | |
Log.i("call nim", "call ex"); | |
} | |
}); | |
// 监听对方接听 | |
AVChatManager.getInstance().observeCalleeAckNotification(new Observer<AVChatCalleeAckEvent>() { | |
@Override | |
public void onEvent(AVChatCalleeAckEvent ackInfo) { | |
if (ackInfo.getEvent() == AVChatEventType.CALLEE_ACK_BUSY) { | |
// 对方正在忙 | |
} else if (ackInfo.getEvent() == AVChatEventType.CALLEE_ACK_REJECT) { | |
// 对方拒绝接听 | |
} else if (ackInfo.getEvent() == AVChatEventType.CALLEE_ACK_AGREE) { | |
// 对方同意接听 | |
} | |
} | |
}, true); | |
AVChatManager.getInstance().observeAVChatState(this, true); | |
} | |
@Override | |
public void onTakeSnapshotResult(String account, boolean success, String file) { | |
} | |
@Override | |
public void onAVRecordingCompletion(String account, String filePath) { | |
} | |
@Override | |
public void onAudioRecordingCompletion(String filePath) { | |
} | |
@Override | |
public void onLowStorageSpaceWarning(long availableSize) { | |
} | |
@Override | |
public void onAudioMixingEvent(int event) { | |
} | |
@Override | |
public void onJoinedChannel(int code, String audioFile, String videoFile, int elapsed) { | |
} | |
@Override | |
public void onUserJoined(String account) { | |
initLargeSurfaceView(); | |
} | |
@Override | |
public void onUserLeave(String account, int event) { | |
} | |
@Override | |
public void onLeaveChannel() { | |
} | |
@Override | |
public void onProtocolIncompatible(int status) { | |
} | |
@Override | |
public void onDisconnectServer() { | |
} | |
@Override | |
public void onNetworkQuality(String account, int quality, AVChatNetworkStats stats) { | |
} | |
@Override | |
public void onCallEstablished() { | |
Log.i("nim", "established"); | |
} | |
@Override | |
public void onDeviceEvent(int code, String desc) { | |
} | |
@Override | |
public void onConnectionTypeChanged(int netType) { | |
} | |
@Override | |
public void onFirstVideoFrameAvailable(String account) { | |
} | |
@Override | |
public void onFirstVideoFrameRendered(String account) { | |
} | |
@Override | |
public void onVideoFrameResolutionChanged(String account, int width, int height, int rotate) { | |
} | |
@Override | |
public void onVideoFpsReported(String account, int fps) { | |
} | |
@Override | |
public boolean onVideoFrameFilter(AVChatVideoFrame frame, boolean maybeDualInput) { | |
return false; | |
} | |
@Override | |
public boolean onAudioFrameFilter(AVChatAudioFrame frame) { | |
return false; | |
} | |
@Override | |
public void onAudioDeviceChanged(int device) { | |
} | |
@Override | |
public void onReportSpeaker(Map<String, Integer> speakers, int mixedEnergy) { | |
} | |
@Override | |
public void onSessionStats(AVChatSessionStats sessionStats) { | |
} | |
@Override | |
public void onLiveEvent(int event) { | |
} | |
/** 获取权限*/ | |
private void getPermission() { | |
if (Build.VERSION.SDK_INT>22){ | |
if (ContextCompat.checkSelfPermission(this, | |
android.Manifest.permission.CAMERA)!= PackageManager.PERMISSION_GRANTED){ | |
//先判断有没有权限 ,没有就在这里进行权限的申请 | |
ActivityCompat.requestPermissions(this,new String[]{ | |
android.Manifest.permission.CAMERA}, 1); | |
}else { | |
//说明已经获取到摄像头权限了 | |
Log.i("MainActivity","已经获取了权限"); | |
} | |
}else { | |
//这个说明系统版本在6.0之下,不需要动态获取权限。 | |
Log.i("MainActivity","这个说明系统版本在6.0之下,不需要动态获取权限。"); | |
} | |
} | |
/** | |
* 大图像surfaceview 初始化 | |
* | |
*/ | |
public void initLargeSurfaceView() { | |
/** | |
* 设置画布,加入到自己的布局中,用于呈现视频图像 | |
* account 要显示视频的用户帐号x | |
*/ | |
/** | |
* 应该是开启推流 | |
*/ | |
AVChatManager.getInstance().muteLocalVideo(false); | |
Log.i("muted", AVChatManager.getInstance().isLocalVideoMuted() + ""); | |
if (AVChatManager.getInstance().isLocalVideoMuted()) { | |
AVChatManager.getInstance().muteLocalVideo(false); | |
} | |
Log.i("call nim", aimAccount); | |
AVChatManager.getInstance().setupRemoteVideoRender(aimAccount, largeRender, false, AVChatVideoScalingType.SCALE_ASPECT_BALANCED); | |
AVChatManager.getInstance().setupLocalVideoRender(miniRender, false, AVChatVideoScalingType.SCALE_ASPECT_BALANCED); | |
addIntoRoot(largeRender); | |
} | |
private void addIntoRoot (SurfaceView surfaceView) { | |
if (surfaceView.getParent() != null) { | |
((ViewGroup) surfaceView.getParent()).removeView(surfaceView); | |
} | |
// surfaceView.setZOrderMediaOverlay(false); | |
waitingView.setVisibility(View.GONE); | |
localRoot.addView(miniRender); | |
surfaceRoot.addView(largeRender); | |
surfaceRoot.setVisibility(View.VISIBLE); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment