Some time ago, I developed a small function demo of voice connecting with the MAC. I usually play with my friends and voice connecting with the MAC. It is very easy to use, ha ha ha. Also use anyRTC API function. Cut the crap and turn it on!

Do not know anyRTC, you can click here to understand the official website, Android documentation!

Download the demo

  • Click on the download

  • The code has not been uploaded to GitHub, and will be uploaded to update the demo in the future.

The demo presentation

See wave video ~ save to give you screenshots, video to the real, simple and clear

Anchor end: Click to watch

Visitor: Click to watch

The Nuggets don’t have an online video feature yet, hope to support @nuggets sauce soon

Code implementation

This is combined with anyRTC background service, this service is also open to the outside world

1. Register and log in

I use the HTTP package of Yang Zhenjie on my side:

Implementation 'com. Yanzhenjie: okalle: 0.1.7'Copy the code
  • registered

    public void signUp(){
    	JSONObject params = new JSONObject();
    	try {
    		params.put("sex",0);
    		params.put("userName", Build.MODEL);
    	} catch (JSONException e) {
    		e.printStackTrace();
    	}
    	Kalle.post(String.format(Constants.SERVER,"user/signUp"))
    			.addHeader(Constants.CONTENT_TYPE,"application/json")
    			.body(new JsonBody(params.toString()))
    			.perform(new SimpleCallback<String>() {
    				@Override
    				public void onResponse(SimpleResponse<String, String> response) {
    					Log.i(TAG, "onResponse:signUp  response ="+response.succeed());
    					if (response.succeed().contains("success")){
    						signUpBean =gson.fromJson(response.succeed(),SignUpBean.class);
    						if (signUpBean !=null){
    							String uid =signUpBean.getData().getUid();
    							SpUtil.putString(Constants.UID,uid);
    							signIn(uid);
    						}
    					}
    				}
        
    				@Override
    				public void onException(Exception e) {
    					super.onException(e);
    					e.printStackTrace();
    				}
    			});
    }
    Copy the code
  • The login

    public void signIn(String uid){
    	JSONObject params = new JSONObject();
    	try {
    		params.put("cType",1);
    		params.put("pkg",ARApplication.the().getApplicationContext().getPackageName());
    		params.put("uid",uid);
    	} catch (JSONException e) {
    		e.printStackTrace();
    	}
    	Kalle.post(String.format(Constants.SERVER,"user/signIn"))
    			.addHeader(Constants.CONTENT_TYPE,"application/json")
    			.body(new JsonBody(params.toString()))
    			.perform(new SimpleCallback<String>() {
    				@Override
    				public void onResponse(SimpleResponse<String, String> response) {
    					Log.i(TAG, "onResponse: signIn success ="+response.succeed());
    					if (response.succeed().contains("success")){
    						signInBean =gson.fromJson(response.succeed(),SignInBean.class);
    						getRoomList(signInBean);
    						if (loginListener !=null){
    							loginListener.loginSuccess(signInBean);
    						}
    					}
    				}
        
    				@Override
    				public void onException(Exception e) {
    					super.onException(e);
    					e.printStackTrace();
    				}
    			});
    }
    Copy the code

2. Host creates and obtains rooms

  • Create a room

A. Initialize Rtc and Rtm instances

MRtcEngine =RtcEngine. Create (mContext, appID,mEventHandler); MRtmClient = rtmClient.createInstance (mContext, appID,mClientListener);Copy the code

B. Log in to AR RTM

public void login(String rtmToken,String userId, final ResultCallback<Void> callback){ if (mRtmClient ! =null){ if (mIsLogin) { if (callback ! = null) callback.onSuccess(null); return; } mRtmClient.login(rtmToken, String.valueOf(userId), new ResultCallback<Void>() { @Override public void onSuccess(Void aVoid) { Log.d(TAG, "rtm login success"); mIsLogin = true; if (callback ! = null) callback.onSuccess(aVoid); } @Override public void onFailure(ErrorInfo errorInfo) { Log.e(TAG, String.format("rtm join %s", errorInfo.getErrorDescription())); mIsLogin = false; if (callback ! = null) callback.onFailure(errorInfo); }}); }}Copy the code

C. Then the anchor joins the room

Join RTC and RTM channels

RTC: Audio and video call

RTM: Real-time messages

// Join RTM channel, Public void joinChannel(final String channelId, ResultCallback< void > callback) {if (mRtmClient! = null) { leaveChannel(); Log.w(TAG, String.format("joinChannel %s", channelId)); try { final RtmChannel rtmChannel = mRtmClient.createChannel(channelId, mChannelListener); if (rtmChannel == null) return; rtmChannel.join(new ResultCallback<Void>() { @Override public void onSuccess(Void aVoid) { Log.d(TAG, "rtm join success"); mRtmChannel = rtmChannel; getMembers(); } @Override public void onFailure(ErrorInfo errorInfo) { Log.e(TAG, String.format("rtm join %s", errorInfo.getErrorDescription())); //AlertUtil.showToast("RTM login failed, see the log to get more info"); mRtmChannel = rtmChannel; }}); } catch (Exception ex) { ex.printStackTrace(); Public void joinChannel(String rtcToken,String channelId, String userId) {if (mRtcEngine! = null){ mRtcEngine.setClientRole(Constants.CLIENT_ROLE_BROADCASTER); mRtcEngine.joinChannel(rtcToken, channelId, null, userId); mRtcEngine.muteLocalAudioStream(false); //mRtcEngine.setEnableSpeakerphone(true); createStreamingInstance(); }}Copy the code
  • Get room list

    Public void getRoomList(SignInBean SignInBean){JSONObject params = new JSONObject(); try { params.put("count", Integer.MAX_VALUE); params.put("rType", Constants.R_TYPE_LIVE); } catch (JSONException e) { e.printStackTrace(); } Kalle.post(String.format(Constants.SERVER,"user/getRoomList")) .addHeader(Constants.CONTENT_TYPE,"application/json") .addHeader(Constants.AUTHORIZATION,"Bearer "+signInBean.getData().getUserToken()) .body(new JsonBody(params.toString()))  .perform(new SimpleCallback<String>() { @Override public void onResponse(SimpleResponse<String, String> response) { Log.i(TAG, "onResponse: getRoomList ="+response.succeed()); if (response.succeed().contains("success")){ roomListBean =gson.fromJson(response.succeed(), RoomListBean.class); if (roomListener ! =null){ roomListener.showRoomList(roomListBean); } } } @Override public void onException(Exception e) { super.onException(e); e.printStackTrace(); Log.i(TAG, "onException: ===> ="+e.getMessage()); }}); }Copy the code

Note: Part of the function of voice link is shown above. The anchor creates the room, and the visitor joins the room by pulling down the refresh button

3. Visitors join the room

The first step to join the room is to join the RTM channel, and then apply to join the RTC channel after the host agrees to join the RTC channel for voice calls.

  • To join the room

    // Call the service interface, join the room, Public void joinRoom(String roomId,String roomName,String pullRtmpUrl){JSONObject params = new JSONObject(); try { params.put("cType",1); params.put("pkg",ARApplication.the().getApplicationContext().getPackageName()); params.put("roomId",roomId); } catch (JSONException e) { e.printStackTrace(); } Kalle.post(String.format(Constants.SERVER,"user/joinRoom")) .addHeader(Constants.CONTENT_TYPE,"application/json") .addHeader(Constants.AUTHORIZATION,"Bearer "+signInBean.getData().getUserToken()) .body(new JsonBody(params.toString()))  .perform(new SimpleCallback<String>() { @Override public void onResponse(SimpleResponse<String, String> response) { Log.i(TAG, "onResponse: joinRoom data ="+response.succeed()); if (response.succeed().contains("success")){ joinRoomBean =gson.fromJson(response.succeed(),JoinRoomBean.class); if (roomListener ! =null){ roomListener.joinRoom(joinRoomBean,roomId,roomName,pullRtmpUrl); } } } @Override public void onException(Exception e) { super.onException(e); e.printStackTrace(); Log.i(TAG, "onException: e="+e.getMessage()); }}); }Copy the code

Then RTM join the room, the same as above anchor join the room.

  • Application process

A. Visitors click on the mic and send an RTM message to the host to inform the host “I want to be on the MIC”.

Try {jsonObject.put(" CMD ","apply"); } catch (JSONException e) { e.printStackTrace(); } mChatRoomManager.getRtmManager().sendMessageToPeer(mAnchorId,jsonObject.toString(),null); Public void sendMessageToPeer(Final String userId, Final String Content, final ResultCallback<Void> callback) { if (TextUtils.isEmpty(userId)) return; if (mRtmClient ! = null) { RtmMessage message = mRtmClient.createMessage(content); mRtmClient.sendMessageToPeer(userId, message, null, new ResultCallback<Void>() { @Override public void onSuccess(Void aVoid) { Log.d(TAG, String.format("sendMessageToPeer %s %s", userId, content)); if (callback ! = null) callback.onSuccess(aVoid); } @Override public void onFailure(ErrorInfo errorInfo) { Log.e(TAG, String.format("sendMessageToPeer %s", errorInfo.getErrorDescription())); if (callback ! = null) callback.onFailure(errorInfo); }}); }}Copy the code

B. After receiving the message, a dialog box is displayed and the host confirms or rejects the operation.

// The host receives the message and performs the logical operation! McHanneldata.getname (userId) + McHanneldata.getname (userId) + McHanneldata.getname (userId) + McHanneldata.getname (userId) + McHanneldata.getname (userId) + McHanneldata.getname (userId) + McHanneldata.getname (userId); () -> { try { object.put("cmd",Constants.MIC_REJECT_LINE); } catch (JSONException e) { e.printStackTrace(); } mChatRoomManager.getRtmManager().sendMessageToPeer(userId,object.toString(),null); }, () -> { try { object.put("cmd",Constants.MIC_ACCEPT_LINE); } catch (JSONException e) { e.printStackTrace(); } mChatRoomManager.getRtmManager().sendMessageToPeer(userId,object.toString(),null); }); applyDialog.show();Copy the code

C. After the host agrees to be on the channel, the tourists join the RTC channel and connect to the channel.

MicState = MIC_STATE_DOWN; isJoinMic =true; AutoTipDialog =new autoTipDialog (this, r.davle.success_tip," Agree to buy "); autoTipDialog.show(); mJoinMic.setImageResource(R.drawable.down_mic); String rtcToken = Optional.ofNullable(serverManager) .map(ARServerManager::getJoinRoomBean) .map(JoinRoomBean::getData) .map(JoinRoomBean.DataBean::getRoom) .map(JoinRoomBean.DataBean.RoomBeans::getRtcToken) .orElse(""); Log.i(TAG, "onAcceptLineUpdated: rtcToken ="+rtcToken); mChatRoomManager.joinRtcChannel(rtcToken,roomId); Mute (true); // mute(true); if (isMic){ mChatMic.setImageResource(R.drawable.mic_close); }else { mChatMic.setImageResource(R.drawable.mic_open); } mChatRoomManager.getRtcManager().muteLocalAudioStream(isMic); if (isSpeaker){ mSpeaker.setImageResource(R.drawable.speaker_close); }else { mSpeaker.setImageResource(R.drawable.speaker_open); } mChatRoomManager.getRtcManager().getRtcEngine().setEnableSpeakerphone(! isSpeaker); rlMusic.setVisibility(View.VISIBLE); mChatMic.setVisibility(View.VISIBLE); mSpeaker.setVisibility(View.GONE); mFrameLayout.setVisibility(View.VISIBLE); rvGuestLog.setVisibility(View.GONE); MLogList. Add (new LogBean (R.d rawable. Circle, getDate (), wheat "success"));Copy the code

This time you can and your partner voice operation!

Finally release RTC and RTM resources, anchor exit delete room, tourists exit room can be!

If you don’t understand the place, welcome to leave a message.

Author: anyRTC- Dong Muyu