怎么和小伙伴语音连麦,你造吗?

怎么和小伙伴语音连麦,你造吗?

Android小彩虹2021-08-25 2:31:04180A+A-

前段时间开发出一个语音连麦的小功能demo,平常自己玩玩,和小伙伴语音连麦,很好用,哈哈哈。使用的也是anyRTC的API功能。废话少说,开整!

不知道anyRTC的,可以点击这里了解官网Android文档!

demo下载

  • 点击下载

  • 代码还没有上传到GitHub,日后上传更新demo。

demo演示

看波视频~ 省的给大家截图,视频来的实在,简单明了

主播端:点击观看

游客端:点击观看

掘金还没有线上展示视频功能,希望赶快支持@掘金酱

代码实现

这个是结合anyRTC的后台服务的,这个也是服务也是对外开放的

1.注册登录

我这边使用的杨振杰封装的HTTP:

implementation 'com.yanzhenjie:okalle:0.1.7'                                       
  • 注册

    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();
    				}
    			});
    }
    
  • 登录

    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();
    				}
    			});
    }
    

2.主播创建和获取房间

  • 创建房间

a.首先需要初始化Rtc和Rtm实例

//创建RTC实例,appid 可以去anyRTC官网注册
mRtcEngine =RtcEngine.create(mContext, appId,mEventHandler);

//创建RTM实例,appid同上
mRtmClient =RtmClient.createInstance(mContext, appId,mClientListener);

b.然后登录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);
			}
		});
	}
}

c.然后主播加入房间

加入RTC和RTM频道

RTC:音视频通话

RTM:实时消息

//加入RTM频道,完成主播和游客实时消息的发送
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();
		}
	}
}

//加入RTC频道,实现主播和游客语音连麦
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();
	}
}
  • 获取房间列表

    //获取房间列表
    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());
    				}
    			});
    }
    

注:上面展示语音连麦的部分功能,创建房间的是主播,下拉刷新出来加入房间的是游客

3.游客加入房间

加入房间第一步就是加入RTM频道,然后申请上麦后,主播同意后,再加入RTC频道,进行语音通话。

  • 加入房间

    //调用服务接口,加入房间,接入有人进入房间
    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());
    				}
    			});
    }
    

然后进行RTM加入房间,和上面主播加入房间一样。

  • 申请上麦流程

a.游客点击上麦,给主播发一条RTM消息,通知主播“我要上麦”

//点击按钮事件,进行发送消息
try {
	jsonObject.put("cmd","apply");
} catch (JSONException e) {
	e.printStackTrace();
}
mChatRoomManager.getRtmManager().sendMessageToPeer(mAnchorId,jsonObject.toString(),null);

//发送P to P消息
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);
			}
		});
	}
}

b.主播收到消息,然后弹出对话框,然后进行:确定上麦、拒绝上麦的操作!

//主播收到消息,进行的逻辑操作!
applyDialog =new ApplyDialog(this, "连麦申请", 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();

c.主播同意上麦后,游客加入RTC频道,进行连麦。

//游客收到同意上麦的操作逻辑
micState = MIC_STATE_DOWN;
isJoinMic =true;
autoTipDialog =new AutoTipDialog(this,R.drawable.success_tip,"同意上麦");
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); //j加入RTC频道

mediaPlayerKit.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.drawable.circle,getDate(),"上麦成功"));

这个时候就可以和你的小伙伴进行语音操作啦!

最后释放RTC和RTM资源,主播退出删除房间,游客退出房间就可以啦!

如有不懂的地方,欢迎大家留言。

作者:anyRTC-东慕雨

点击这里复制本文地址 以上内容由权冠洲的博客整理呈现,请务必在转载分享时注明本文地址!如对内容有疑问,请联系我们,谢谢!

支持Ctrl+Enter提交

联系我们| 本站介绍| 留言建议 | 交换友链 | 域名展示
本站资源来自互联网收集,仅供用于学习和交流,请遵循相关法律法规,本站一切资源不代表本站立场,如有侵权、后门、不妥请联系本站删除

权冠洲的博客 © All Rights Reserved.  Copyright quanguanzhou.top All Rights Reserved
苏公网安备 32030302000848号   苏ICP备20033101号-1
本网站由 提供CDN/云存储服务

联系我们