Android接入容联 云通讯 音视频通话功能

好久没有写博客,最近公司项目上需要实现音视频通话的功能,基于某些原因,选择了接入容联 云通讯。

这个平台的SDK基础版是可以免费接入的,限制注册人数2000人,IM基础功能基本上都有,这里主要接入音视频通话功能。

而官网提供的源码是没有专门针对音视频功能的,功能涵盖很多,需要用户自己去抽离出来,所以这儿写一篇博文记录一下。

1、首先需要去平台注册账号,https://www.yuntongxun.com/

官网源码下载地址:https://www.yuntongxun.com/doc/ready/demo/1_4_1_1.html

我会在后边给出我的源码地址。

2、进入控制台,按照接入流程,一步一步的创建应用,选择音视频通话,获取appkey和apptoken 。

3、点击项目上线,为项目开通IM功能,在IM管理中申请音视频功能(点击上线以后才能选择开通)

[图片]

4、在IM管理中点击开发文档,下载必要的so文件和jar包,选择必要的权限,配置gradle等。

5、基础工作做完以后就开始初始化sdk,登陆服务等。(注意登陆,登陆监听,来电消息等都要放在初始化成功以后的

onInitialized()方法中)
 if(!ECDevice.isInitialized()) {
 /*  initial: ECSDK 初始化接口
            * 参数:
            *     inContext - Android应用上下文对象
            *     inListener - SDK初始化结果回调接口,ECDevice.InitListener
            *
            * 说明:示例在应用程序创建时初始化 SDK引用的是Application的上下文,
            *       开发者可根据开发需要调整。
            */
            ECDevice.initial(getApplicationContext(), new ECDevice.InitListener() {
                @Override
                public void onInitialized() {
                    // SDK已经初始化成功
                    Log.i("info","初始化SDK成功");

                    // 设置接收VoIP来电事件通知Intent
                    // 呼入界面activity、开发者需修改该类
                    Intent intent = new Intent(context, VedioActivity.class);
                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                    PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
                    ECDevice.setPendingIntent(pendingIntent);
                    //设置登录参数,可分为自定义方式和VoIP验密方式。
                    //设置通知回调监听包含登录状态监听,接收消息监听,VoIP呼叫事件回调监听和设置接收VoIP来电事件通知Intent等。
                    //验证参数是否正确,登陆SDK。
                   
                     //初始化成功以后先注册登陆回调监听和voip通话监听,然后再进行登陆
//                    setListener();
//                    login();
                }
                @Override
                public void onError(Exception exception) {
                    //在初始化错误的方法中打印错误原因
                    Log.i("info","初始化SDK失败"+exception.getMessage());
                }
            });}
        // 已经初始化成功,后续开发业务代码。
        Log.i(TAG, "初始化SDK及登陆代码完成");
private void setListener() {

        Log.i("info","==执行连接操作==");
        // 设置SDK注册结果回调通知,当第一次初始化注册成功或者失败会通过该引用回调
        // 通知应用SDK注册状态
        // 当网络断开导致SDK断开连接或者重连成功也会通过该设置回调
        ECDevice.setOnDeviceConnectListener(new ECDevice.OnECDeviceConnectListener() {
            @Override
            public void onConnect() {
                Log.i("info","==连接==");
            }

            @Override
            public void onDisconnect(ECError ecError) {
                Log.i("info","==断开连接==");
            }

            @Override
            public void onConnectState(ECDevice.ECConnectState ecConnectState, ECError ecError) {
                Log.i("info","====ecConnectState===" + ecConnectState + "==ecError==="+ecError.toString());
                if(ecConnectState == ECDevice.ECConnectState.CONNECT_FAILED ){
                    if(ecError.errorCode == SdkErrorCode.SDK_KICKED_OFF) {
                        Log.i("","==帐号异地登陆");
                    }
                    else {
                        Log.i("","==其他登录失败,错误码:"+ ecError.errorCode);
                    }
                    return ;
                }
                else if(ecConnectState == ECDevice.ECConnectState.CONNECT_SUCCESS) {
                    Log.i("","==登陆成功");
                }
            }
        });
        //通话监听
        ECDevice.getECVoIPCallManager().setOnVoIPCallListener(new ECVoIPCallManager.OnVoIPListener() {
            @Override
            public void onDtmfReceived(String s, char c) {
                Log.i("info","=====onDtmfReceived======"+s.toString());
            }

            @Override
            public void onCallEvents(ECVoIPCallManager.VoIPCall voIPCall) {
                Log.i("info","=====onCallEvents======"+voIPCall.callId);
                Log.i("info","=====onCallEvents======"+voIPCall.callType);
                if(voIPCall==null) return;

                switch(voIPCall. callState){

                    case ECCALL_ALERTING:

                        Log.i("","对方振铃");

                        break;

                    case ECCALL_PROCEEDING:
                        Log.i("","呼叫中");

                        break;

                    case ECCALL_ANSWERED:
                        Log.i("","John接受了呼叫应答");

                        break;

                    case ECCALL_FAILED://
                        Log.i("","呼叫失败");

                        break;

                    case ECCALL_RELEASED:

                        //无论是Tony还是John主动结束通话,双方都会进入到此回调
                        Log.i("","结束当前通话");

                        break;

                    default:

                        break;
                }
            }

            @Override
            public void onMediaDestinationChanged(VoipMediaChangedInfo voipMediaChangedInfo) {
                Log.i("info","=====onMediaDestinationChanged======"+voipMediaChangedInfo.toString());
            }

            @Override
            public void onSwitchCallMediaTypeRequest(String s, ECVoIPCallManager.CallType callType) {
                Log.i("info","=====onSwitchCallMediaTypeRequest======"+s.toString());
                Log.i("info","=====onSwitchCallMediaTypeRequest======"+callType.toString());
            }

            @Override
            public void onSwitchCallMediaTypeResponse(String s, ECVoIPCallManager.CallType callType) {
                Log.i("info","=====onSwitchCallMediaTypeResponse======"+s.toString());
                Log.i("info","=====onSwitchCallMediaTypeResponse======"+callType.toString());
            }

            @Override
            public void onVideoRatioChanged(VideoRatio videoRatio) {
                Log.i("info","=====onVideoRatioChanged======"+videoRatio.toString());
            }
        });
//接收发送到的txt消息
ECDevice.setOnChatReceiveListener(new OnChatReceiveListener() {
    @Override
    public void OnReceivedMessage(ECMessage ecMessage) {
        Log.d("", "[OnReceivedMessage] show notice true");
        if (ecMessage == null) {
            return;
        }

        if(ecMessage.getType()== ECMessage.Type.TXT){
            ECTextMessageBody textMessageBody = (ECTextMessageBody) ecMessage.getBody();
            String message = textMessageBody.getMessage();
            String[] arr =  message.split(",");
            ECSuperActivity.EXTRA_CALL_NUMBER = arr[0];
            ECSuperActivity.EXTRA_CALL_NAME = arr[1];
            ECSuperActivity.EXTRA_CALL_TYPE = arr[2];
            Log.i("aaaaaaaaa","aa====="+message);
        }
    }

    @Override
    public void onReceiveMessageNotify(ECMessageNotify ecMessageNotify) {

    }

    @Override
    public void OnReceiveGroupNoticeMessage(ECGroupNoticeMessage ecGroupNoticeMessage) {

    }

    @Override
    public void onOfflineMessageCount(int i) {

    }

    @Override
    public int onGetOfflineMessage() {
        return 0;
    }

    @Override
    public void onReceiveOfflineMessage(List<ECMessage> list) {

    }

    @Override
    public void onReceiveOfflineMessageCompletion() {

    }

    @Override
    public void onServicePersonVersion(int i) {

    }

    @Override
    public void onReceiveDeskMessage(ECMessage ecMessage) {

    }

    @Override
    public void onSoftVersion(String s, int i) {

    }
});
    }

    private void login() {

        //创建登录参数对象
        ECInitParams params = ECInitParams.createParams();
        //设置用户登录账号
        params.setUserid(Constents.id);
        //设置AppId
        params.setAppKey(Constents.appKey);
        //设置AppToken
        params.setToken(Constents.appToken);
        //设置登陆验证模式:自定义登录方式
        params.setAuthType(ECInitParams.LoginAuthType.NORMAL_AUTH);
        //LoginMode(强制上线:FORCE_LOGIN  默认登录:AUTO。使用方式详见注意事项)
        params.setMode(ECInitParams.LoginMode.AUTO);

        //验证参数是否正确
        if(params.validate()) {
            // 登录函数
            ECDevice.login(params);
        }
    }

6、登陆成功后就可以开始呼叫用户

//发起音频通话
String mCurrentCallId = VoIPCallHelper.makeCall(ECVoIPCallManager.CallType.VOICE,id,name);
if (TextUtils.isEmpty(mCurrentCallId)){
    Toast.makeText(this, "呼叫失败", Toast.LENGTH_SHORT).show();
}

//发起视频通话

ECDevice.getECVoIPSetupManager().setVideoView(mRemote_video_view, mLocalvideo_view);
String mCurrentCallId = ECDevice.getECVoIPCallManager().makeCall(ECVoIPCallManager.CallType.VIDEO, id);
if (TextUtils.isEmpty(mCurrentCallId)) {
    Toast.makeText(this, "呼叫失败", Toast.LENGTH_SHORT).show();
}

7、接收方的处理

//(1)如果视频呼叫,则在接受呼叫之前,需要先设置视频通话显示的view

ECDevice.getECVoIPSetupManager().setVideoView(view, localView);

//view 显示远端视频的surfaceview 

//localView本地显示视频的view

ECDevice.getECVoIpCallManager().acceptCall(mCurrentCallId);

//(2)John点击“拒绝”按钮,音视频拒绝的代码是一致的,调用的代码是:

ECDevice.getECVoIpCallManager().rejectCall(mCurrentCallId,”拒绝的原因,传入整型值”); 

 

8、进入音视频页面时,需要设置建立通话状态的监听

VoIPCallHelper.setOnCallEventNotifyListener(this);
/**
 * VoIP通话状态通知
 */
public interface OnCallEventNotifyListener {
    /**
     * 正在连接服务器
     * @param callId 通话的唯一标识
     */
    void onCallProceeding(String callId);

    void onMakeCallback(ECError arg0, String arg1, String arg2);

    /**
     * 对方正在振铃
     * @param callId 通话的唯一标识
     */
    void onCallAlerting(String callId);

    /**
     * 对方应答(通话完全建立)
     * @param callId 通话的唯一标识
     */
    void onCallAnswered(String callId);

    /**
     * 呼叫失败
     * @param callId 通话的唯一标识(有可能为Null)
     * @param reason 呼叫失败原因
     */
    void onMakeCallFailed(String callId, int reason);

    /**
     * VoIP通话结束
     * @param callId 通话的唯一标识
     */
    void onCallReleased(String callId);

    void onVideoRatioChanged(VideoRatio videoRatio);

}

在这些回调方法中处理通话任务就刷新通话双方的页面,建立通话时的页面,挂断通话的处理等。

这次实现音视频通话在网上找了好久,都么有找到比较适合的资源,也没有实现的demo可供参考,所以我写下这个篇文章,记录一下实现的过程,后边 会附上源码,希望能帮助到有需要的朋友。

 

github地址:https://github.com/XW837156540/RongyunDemo

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值