技术

技术

2
评论

基于环信sdk在uni-app框架中快速开发一款多平台社交Demo SDK uni_app 环信

beyond 发表了文章 • 524 次浏览 • 2020-05-11 11:34 • 来自相关话题

说在前面:此款 demo 是基于 环信sdk 开发的一款具有单聊、群聊、聊天室、音视频等功能的应用。在此之前我们已经开发完 Vue、react(web端)、微信小程序。这三个热门领域的版本,如有需要源码可以后台留言索取。





 
安装开发工具

我们选用微信小程序来用做示例(如果选择百度、支付宝安装对应开发者工具即可)、

微信开发者工具建议还是安装最新版的。uni-app的开发也必须安装HBuilderX工具,这个是捆绑的,没得选择。要用uni-app,你必须得装!

工具安装:

微信开发者工具

HBuilderX

项目demo介绍:






项目demo启动预览:





 
快速集成环信 sdk:

1、复制整个utils文件






如果你想具体了解主要配置文件 请看这个链接:

http://docs-im.easemob.com/im/web/intro/start

2、如何使用环信的appkey ,可以在环信 console 后台注册一个 账号申请appkey ,可以参考这里 ,获取到  appkey 以后添加到配置文件中 ,如下图所示:






以上两个重要的配置准备完成之后就可以进行一系列的操作了(收发消息、好友申请、进群入群通知等)

在uni-app中 使用环信 sdk 实现添加、删除好友:

1、在全局 App.vue 文件 钩子函数 onLaunch() 中监听各种事件 (好友申请、收到各类消息等)如图:






发送好友请求:






在onPresence(message)事件中接收到好友消息申请:






同意好友请求:






拒绝好友请求:






实现收发消息:

1、给好友发送消息:






2、接收到消息:

在onTextMessage(message)事件中接收到好友消息,然后做消息上屏处理(具体消息上屏逻辑可看demo中代码示例):





以上展示的仅仅为基本业务场景,更多的业务逻辑详情请看demo示例。api具体详情可以查看 环信sdk 文档

最后结语:基于uni-app这个框架可实现多平台, 虽然目前一期集成环信sdk的版本仅支持微信小程序版本,但二期我们将加入头条、支付宝等小程序,敬请期待。PS:对于安卓、ios移动端,我们建议使用针对移动端开发的sdk版本。

基于uni-app的开发其中也趟了不少坑,在这里就不多赘述了。回归到框架的选型来讲,选用uni-app开发小程序,可同时并行多端小程序,这点是真香,一次开发多端发布。至于审核嘛~ 时快时慢。 查看全部
说在前面:此款 demo 是基于 环信sdk 开发的一款具有单聊、群聊、聊天室、音视频等功能的应用。在此之前我们已经开发完 Vue、react(web端)、微信小程序。这三个热门领域的版本,如有需要源码可以后台留言索取。

1.jpg

 
安装开发工具

我们选用微信小程序来用做示例(如果选择百度、支付宝安装对应开发者工具即可)、

微信开发者工具建议还是安装最新版的。uni-app的开发也必须安装HBuilderX工具,这个是捆绑的,没得选择。要用uni-app,你必须得装!

工具安装:

微信开发者工具

HBuilderX

项目demo介绍:

2.jpg


项目demo启动预览:

3.jpg

 
快速集成环信 sdk:

1、复制整个utils文件

4.jpg


如果你想具体了解主要配置文件 请看这个链接:

http://docs-im.easemob.com/im/web/intro/start

2、如何使用环信的appkey ,可以在环信 console 后台注册一个 账号申请appkey ,可以参考这里 ,获取到  appkey 以后添加到配置文件中 ,如下图所示:

5.jpg


以上两个重要的配置准备完成之后就可以进行一系列的操作了(收发消息、好友申请、进群入群通知等)

在uni-app中 使用环信 sdk 实现添加、删除好友:

1、在全局 App.vue 文件 钩子函数 onLaunch() 中监听各种事件 (好友申请、收到各类消息等)如图:

6.jpg


发送好友请求:

7.jpg


在onPresence(message)事件中接收到好友消息申请:

8.jpg


同意好友请求:

9.jpg


拒绝好友请求:

10.jpg


实现收发消息:

1、给好友发送消息:

11.jpg


2、接收到消息:

在onTextMessage(message)事件中接收到好友消息,然后做消息上屏处理(具体消息上屏逻辑可看demo中代码示例):

12.jpg

以上展示的仅仅为基本业务场景,更多的业务逻辑详情请看demo示例。api具体详情可以查看 环信sdk 文档

最后结语:基于uni-app这个框架可实现多平台, 虽然目前一期集成环信sdk的版本仅支持微信小程序版本,但二期我们将加入头条、支付宝等小程序,敬请期待。PS:对于安卓、ios移动端,我们建议使用针对移动端开发的sdk版本。

基于uni-app的开发其中也趟了不少坑,在这里就不多赘述了。回归到框架的选型来讲,选用uni-app开发小程序,可同时并行多端小程序,这点是真香,一次开发多端发布。至于审核嘛~ 时快时慢。
1
评论

手把手教程:4小时开发一个视频会议APP【附开源代码】 环信 开源 视频会议

fat1 发表了文章 • 1027 次浏览 • 2020-04-17 00:29 • 来自相关话题

今年是不平凡的一年,没错,就是因为疫情,因为疫情原因 ,大家只能呆着家里,严重影响了我们正常的学习 生活 工作,在这种情况下,只能在家办公,这时候大家就会想到线上视频会议,目前很多互联网公司有这个产品,比较出名的就比如 腾讯会议 钉钉 zoom等,用这些是很方便,但是如果能开发自己的视频会议,那会不会更好或者是更有成就感,下面简单介绍这个这个项目,和大概的开发过程。本项目基于环信音视频云来完成,实现的主要功能有:
  创建会议、删除会议、获取指定会议室详情、加入会议室、退出会议室等关于会议的管理 ;  获取会议室参会人名列表、踢人,设置观众为主播,设置主播为观众等关于会议室的人员管理;  共享桌面(web端);
 三个端的实现:Android,iOS,Web

上面这些功能在项目中都已经实现。还有水印 ,变声等高级功能在环信音视频SDK的接口内部都已经封装好,本项目没有实现 ,大家可以自行去实现。有关多人音视频功能更详细的介绍大家可以参考:这儿。多人音视频实现的实现主要有以下一些场景:社交交友,远程心理咨询、远程医疗、一对一在线教育、远程视频辅助等。咳咳 ,接下来就是纯干货了,给大家介绍我是如何一步步开发出一个完整的多人音视频app。
 
项目截图
 
首先给大家展示下项目运行的效果图,会议界面 主窗口是一个大的 RelativeLayout ,最下面的那一排排小窗口是的实现方法是HorizontalScrollView加上一个开源的组件 com.jaouan.compoundlayout.RadioLayoutGroup 实现的,点击下面的小窗口后,可以 把小窗口的视频流显示在大屏上,具体是调用 updateRemoteSurfaceView(String streamId, EMCallSurfaceView remoteView)来更新SurfaceView,具体的细节大家可以看看代码里面的实现 最后会公布代码开源地址。
















准备工作
    大家得下载安装Android Studio,配置好Android 开发环境,怎么详细配置我就在这不再细说了 网上有很多的教程,大家自己可以找找看,然后大家可以看看环信多人音视频会议的主要功能和一些基本概念介绍。
集成 
  1. 首先大家会想问怎么调用环信的SDK ,大家可以使用 远程依赖SDK包,建议大家用最新版本的远程依赖:
     com.hyphenate:hyphenate-sdk:3.6.6 ,依赖包可以放在 build.gradle里面的 dependencies 选项下面,如下图所示





2.其次怎么使用环信的appkey ,可以在环信音视频云后台注册一个 账号申请appkey ,可以参考这里 ,获取到  appkey 以后添加到AndroidManifest.xml中 ,如下图所示:






3.经过以上两个重要的前期配置准备 ,接下来我们就可以开始进行代码开发了,首先我们先创建一个项目的DemoApplication类和      DemoHelper类,DemoApplication 类和DemoHelper类都是一个单例类 ,DemoApplication 主要功能就是进行DemoHelper 的初始化,而DemoHelper里面主要是主要有一些option 配置和EMClient 进行初始化,代码如下所示:public void init(Context context) {
EMOptions options = initChatOptions(context);
EMClient.getInstance().init(context, options);
PreferenceManager.init(context);
}
  DemoHelper还有一个重要的功能就是设置  EMConferenceListener 进行会议监听,有关 EMConferenceListener的类的详细介绍 ,通过这个监听可以再加入会议的时候获取到已经在会议中的流和主播信息,分别是通过其中以下两个回调获取:@Override
public void onMemberJoined(EMConferenceMember member){

}

@Override
public void onStreamAdded(EMConferenceStream stream){

}
4.DemoApplication类完成以后,接下来就是怎么去登陆 环信IM 账号和 创建加入会议房间了,首次安装的时候都没有账号,我们使用的办法是自动注册一个账号 在本地进行保存,然后进行登录 ,注册 登录详细接口请看 这儿,  注册 登录的调用大概如下所示: 
 try {
        //注册一个环信ID
        EMClient.getInstance().createAccount(username, password);
            
        //注册成功进行登录
        PreferenceManager.getInstance().setCurrentUserName(username);
        PreferenceManager.getInstance().setCurrentuserPassword(password);
        login();
    } catch (final HyphenateException e) {
       runOnUiThread(new Runnable() {
               public void run() {
                  int errorCode=e.getErrorCode();
                   if(errorCode==EMError.NETWORK_ERROR){
                    Toast.makeText(getApplicationContext(), getResources().getString(R.string.network_anomalies), Toast.LENGTH_SHORT).show();
      }
   }   
}
 
  public void login() {
 
        //登录已经注册成功的环信ID
        EMClient.getInstance().login(username, password, new EMCallBack() {
            @Override
            public void onSuccess() {
                Log.d(TAG, "login: onSuccess");
                //登录成功进入会议房间
                joinRoom();
            }
            @Override
            public void onProgress(int progress, String status) {
                Log.d(TAG, "login: onProgress");
            }
            @Override
            public void onError(final int code, final String message) {
                Log.d(TAG, "login: onError: " + code);
                runOnUiThread(new Runnable() {
                    public void run() {
                        Toast.makeText(getApplicationContext(), getString(R.string.Login_failed) + message,Toast.LENGTH_SHORT).show();
                    }
                });
            }
        });
    }
登录完成以后,我们可以根据房间名创建并加入房间,主要代码大概如下: EMClient.getInstance().conferenceManager().joinRoom(currentRoomname, currentPassword, conferenceRole,roomConfig, new EMValueCallBack<EMConference>(){
@Override
public void onSuccess(EMConference value) {
EMLog.i(TAG, "join conference success");
Intent intent = new Intent(MainActivity.this, ConferenceActivity.class);
startActivity(intent);
finish();
}
@Override
public void onError(final int error, final String errorMsg) {
EMLog.e(TAG, "join conference failed error " + error + ", msg " + errorMsg);
runOnUiThread(new Runnable() {
@Override
public void run() {
setBtnEnable(true);
if(error == CALL_TALKER_ISFULL) {
takerFullDialogDisplay();
}else{
Toast.makeText(getApplicationContext(), "Join conference failed " + error + " " + errorMsg, Toast.LENGTH_SHORT).show();
}
}
});
}
});
EMClient.getInstance().conferenceManager().joinRoom() API可以根据房间名创建指定会议,当以该房间名命名的会议不存在时候,会直接创建,当会议已经创建好 可以根据正确的房间名和密码加入房间 ,到这一步为止,我们已经成功的创建 并加入会议。
5.加入会议以后我们进入到会议界面,展示从DemoHelper类 EMConferenceListener 中的 onStreamAdded 回调 和 onMemberJoined 获取到的流和主播列表 ,在ConferenceActivity 中实现 EMConferenceListener ,然后直接把 ConferenceActivity 注册监听,用以下方法  EMClient.getInstance().conferenceManager().addConferenceListener(this); 这样就可实现 EMConferenceListener 事件的处理,比如
 主播 进出房间 :
public void onMemberJoined(final EMConferenceMember member);
public void onMemberExited(final EMConferenceMember member);

增加流 移除流:
public void onStreamAdded(final EMConferenceStream stream)
 public void onStreamRemoved(final EMConferenceStream stream)

管理员变更: 
public void onAdminAdded(String streamId) ;  
public void onAdminRemoved(String streamId)

角色变更  用户被踢  谁在说话等各种回调,可以处理各种业务逻辑 ,详细的请参考 项目中的实现 ,最后会附上项目的开源地址。

6 进入会议房间以后如果用户角色为主播可以进行发布视频流 ,观众只能订阅视频流 不能发布视频流 ,可以调用SDK的publish接口发布流,该接口用到了EMStreamParam参数,你可以自由配置,比如是否上传视频,是否上传音频,使用前置或后置摄像头,视频码率,显示视频页面等等,具体实现可以参考 中发布 订阅视频流的内容, 关于以上的代码逻辑如以 如以下: //发布视频流
normalParam = new EMStreamParam();
normalParam.setStreamType(EMConferenceStream.StreamType.NORMAL);
normalParam.setVideoOff(true);
normalParam.setAudioOff(true);

EMClient.getInstance().conferenceManager().publish(normalParam, new EMValueCallBack<String>() {
@Override
public void onSuccess(String value) {
conference.setPubStreamId(value, EMConferenceStream.StreamType.NORMAL);
addOrUpdateStreamList("local-stream", value);

PhoneStateManager.get(ConferenceActivity.this).addStateCallback(phoneStateCallback);
}

@Override
public void onError(int error, String errorMsg) {
EMLog.i(TAG, "publish failed: error=" + error + ", msg=" + errorMsg);
}
});
//订阅其他主播的视频流
private void subscribe(EMConferenceStream stream, EMCallSurfaceView surfaceView) {
EMClient.getInstance().conferenceManager().subscribe(stream, surfaceView, new EMValueCallBack<String>() {
@Override
public void onSuccess(String value) {
}

@Override
public void onError(int error, String errorMsg) {

}
});
}
7.有关上麦 下麦 的逻辑处理,观众可以请求上麦成为主播,主播可以下麦成为观众,上麦 下麦 是利用 EMConferenceAttribute进行处理 ,EMConferenceAttribute  是一个事件广播,广播事件是一个key-value格式,key-value 可以由开发者进行自行定义,增添事件以后 ,服务器会把事件进行广播。会议中成员会收到 onAttributesUpdated回调。例如本项目中的会议上麦 下麦 代码如下所示://上麦申请

EMClient.getInstance().conferenceManager().setConferenceAttribute(
EMClient.getInstance().getCurrentUser(),
"request_tobe_speaker",
new EMValueCallBack<Void>() {
@Override
public void onSuccess(Void value) {
EMLog.i(TAG, "request_tobe_speaker scuessed");

}

@Override
public void onError(int error, String errorMsg) {
EMLog.i(TAG, "request_tobe_speaker failed: error=" + error

}
});

//下麦申请
EMClient.getInstance().conferenceManager().setConferenceAttribute(EMClient.getInstance().getCurrentUser()
, "request_tobe_audience", new EMValueCallBack<Void>() {
@Override
public void onSuccess(Void value) {
EMLog.i(TAG, "request_tobe_audience scuessed");
}

@Override
public void onError(int error, String errorMsg) {
EMLog.i(TAG, "request_tobe_audience failed: error=" + error + ", msg=" + errorMsg);
}
});
 上麦 下麦 请求发出以后 只能由主持人去处理,处理在 EMConferenceListener  的回调 onAttributesUpdated(EMConferenceAttribute attributes) 去处理 ,收到回调以后 解析attributes 然后进行处理请求,处理的过程代码大概如下: EMClient.getInstance().conferenceManager().grantRole(conference.getConferenceId()
, new EMConferenceMember(memName, null, null,null)
, EMConferenceManager.EMConferenceRole.Talker, new EMValueCallBack<String>() {
@Override
public void onSuccess(String value) {
EMLog.i(TAG, " requestTalkerDisplay request_tobe_speaker changeRole success, result: " + value);
dialog.dismiss();
}
@Override
public void onError(int error, String errorMsg) {
EMLog.i(TAG, " requestTalkerDisplay request_tobe_speaker changeRole failed, error: " + error + " - " + errorMsg);

}
});
下麦也是和上麦一样是利用 EMConferenceAttribute进行处理。

9.有关退出会议 销毁会议 普通主播  观众只能退出会议 ,主持人还可以 销毁会议 正在进行中的会议可以进行销毁,退出会议 销毁会议 具体代码如下: EMClient.getInstance().conferenceManager().exitConference(new EMValueCallBack() {
@Override
public void onSuccess(Object value) {
runOnUiThread(new Runnable() {
@Override
public void run() {
Toast.makeText(getApplicationContext(), "您已成功退出当前会议!", Toast.LENGTH_SHORT).show();
}
});
}

@Override
public void onError(int error, String errorMsg) {
EMLog.i(TAG, "exit conference failed " + error + ", " + errorMsg);
}
});

EMClient.getInstance().conferenceManager().destroyConference(new EMValueCallBack() {
@Override
public void onSuccess(Object value) {
runOnUiThread(new Runnable() {
@Override
public void run() {
Toast.makeText(getApplicationContext(), "您已成功销毁当前会议!", Toast.LENGTH_SHORT).show();
}
});
EMLog.i(TAG, "finish ConferenceActivity");
finish();
}

尾语
至此 整个 多人音视频会议开发的详细步骤 已经完成 ,虽然比较麻烦 但是每个步骤都很清晰 ,有不太清楚的欢迎大家积极讨论, 附上本项目的github地址:https://github.com/easemob/videocall-android  欢迎大家积极参与 ,谢谢支持。
Demo下载 二维码如下 欢迎大家体验(iOS版和web版下载地址请见:https://www.easemob.com/download/rtc)






  查看全部
今年是不平凡的一年,没错,就是因为疫情,因为疫情原因 ,大家只能呆着家里,严重影响了我们正常的学习 生活 工作,在这种情况下,只能在家办公,这时候大家就会想到线上视频会议,目前很多互联网公司有这个产品,比较出名的就比如 腾讯会议 钉钉 zoom等,用这些是很方便,但是如果能开发自己的视频会议,那会不会更好或者是更有成就感,下面简单介绍这个这个项目,和大概的开发过程。本项目基于环信音视频云来完成,实现的主要功能有:
  •   创建会议、删除会议、获取指定会议室详情、加入会议室、退出会议室等关于会议的管理 ;
  •   获取会议室参会人名列表、踢人,设置观众为主播,设置主播为观众等关于会议室的人员管理;
  •   共享桌面(web端);

 三个端的实现:Android,iOS,Web

上面这些功能在项目中都已经实现。还有水印 ,变声等高级功能在环信音视频SDK的接口内部都已经封装好,本项目没有实现 ,大家可以自行去实现。有关多人音视频功能更详细的介绍大家可以参考:这儿。多人音视频实现的实现主要有以下一些场景:社交交友,远程心理咨询、远程医疗、一对一在线教育、远程视频辅助等。咳咳 ,接下来就是纯干货了,给大家介绍我是如何一步步开发出一个完整的多人音视频app。
 
项目截图
 
首先给大家展示下项目运行的效果图,会议界面 主窗口是一个大的 RelativeLayout ,最下面的那一排排小窗口是的实现方法是HorizontalScrollView加上一个开源的组件 com.jaouan.compoundlayout.RadioLayoutGroup 实现的,点击下面的小窗口后,可以 把小窗口的视频流显示在大屏上,具体是调用 updateRemoteSurfaceView(String streamId, EMCallSurfaceView remoteView)来更新SurfaceView,具体的细节大家可以看看代码里面的实现 最后会公布代码开源地址。

20200410140627956.jpg


20200410140855852.jpg


20200410141055394.jpg


准备工作
    大家得下载安装Android Studio,配置好Android 开发环境,怎么详细配置我就在这不再细说了 网上有很多的教程,大家自己可以找找看,然后大家可以看看环信多人音视频会议的主要功能和一些基本概念介绍。
集成 
  1. 首先大家会想问怎么调用环信的SDK ,大家可以使用 远程依赖SDK包,建议大家用最新版本的远程依赖:
     com.hyphenate:hyphenate-sdk:3.6.6 ,依赖包可以放在 build.gradle里面的 dependencies 选项下面,如下图所示
2020040917363212.png


2.其次怎么使用环信的appkey ,可以在环信音视频云后台注册一个 账号申请appkey ,可以参考这里 ,获取到  appkey 以后添加到AndroidManifest.xml中 ,如下图所示:

20200409213959916.png


3.经过以上两个重要的前期配置准备 ,接下来我们就可以开始进行代码开发了,首先我们先创建一个项目的DemoApplication类和      DemoHelper类,DemoApplication 类和DemoHelper类都是一个单例类 ,DemoApplication 主要功能就是进行DemoHelper 的初始化,而DemoHelper里面主要是主要有一些option 配置和EMClient 进行初始化,代码如下所示:
public void init(Context context) {
EMOptions options = initChatOptions(context);
EMClient.getInstance().init(context, options);
PreferenceManager.init(context);
}

  DemoHelper还有一个重要的功能就是设置  EMConferenceListener 进行会议监听,有关 EMConferenceListener的类的详细介绍 ,通过这个监听可以再加入会议的时候获取到已经在会议中的流和主播信息,分别是通过其中以下两个回调获取:
@Override 
public void onMemberJoined(EMConferenceMember member){

}

@Override
public void onStreamAdded(EMConferenceStream stream){

}

4.DemoApplication类完成以后,接下来就是怎么去登陆 环信IM 账号和 创建加入会议房间了,首次安装的时候都没有账号,我们使用的办法是自动注册一个账号 在本地进行保存,然后进行登录 ,注册 登录详细接口请看 这儿,  注册 登录的调用大概如下所示: 
 try {
        //注册一个环信ID
        EMClient.getInstance().createAccount(username, password);
            
        //注册成功进行登录
        PreferenceManager.getInstance().setCurrentUserName(username);
        PreferenceManager.getInstance().setCurrentuserPassword(password);
        login();
    } catch (final HyphenateException e) {
       runOnUiThread(new Runnable() {
               public void run() {
                  int errorCode=e.getErrorCode();
                   if(errorCode==EMError.NETWORK_ERROR){
                    Toast.makeText(getApplicationContext(), getResources().getString(R.string.network_anomalies), Toast.LENGTH_SHORT).show();
      }
   }   
}
 
  public void login() {
 
        //登录已经注册成功的环信ID
        EMClient.getInstance().login(username, password, new EMCallBack() {
            @Override
            public void onSuccess() {
                Log.d(TAG, "login: onSuccess");
                //登录成功进入会议房间
                joinRoom();
            }
            @Override
            public void onProgress(int progress, String status) {
                Log.d(TAG, "login: onProgress");
            }
            @Override
            public void onError(final int code, final String message) {
                Log.d(TAG, "login: onError: " + code);
                runOnUiThread(new Runnable() {
                    public void run() {
                        Toast.makeText(getApplicationContext(), getString(R.string.Login_failed) + message,Toast.LENGTH_SHORT).show();
                    }
                });
            }
        });
    }
登录完成以后,我们可以根据房间名创建并加入房间,主要代码大概如下:
 EMClient.getInstance().conferenceManager().joinRoom(currentRoomname, currentPassword, conferenceRole,roomConfig, new EMValueCallBack<EMConference>(){
@Override
public void onSuccess(EMConference value) {
EMLog.i(TAG, "join conference success");
Intent intent = new Intent(MainActivity.this, ConferenceActivity.class);
startActivity(intent);
finish();
}
@Override
public void onError(final int error, final String errorMsg) {
EMLog.e(TAG, "join conference failed error " + error + ", msg " + errorMsg);
runOnUiThread(new Runnable() {
@Override
public void run() {
setBtnEnable(true);
if(error == CALL_TALKER_ISFULL) {
takerFullDialogDisplay();
}else{
Toast.makeText(getApplicationContext(), "Join conference failed " + error + " " + errorMsg, Toast.LENGTH_SHORT).show();
}
}
});
}
});

EMClient.getInstance().conferenceManager().joinRoom() API可以根据房间名创建指定会议,当以该房间名命名的会议不存在时候,会直接创建,当会议已经创建好 可以根据正确的房间名和密码加入房间 ,到这一步为止,我们已经成功的创建 并加入会议。
5.加入会议以后我们进入到会议界面,展示从DemoHelper类 EMConferenceListener 中的 onStreamAdded 回调 和 onMemberJoined 获取到的流和主播列表 ,在ConferenceActivity 中实现 EMConferenceListener ,然后直接把 ConferenceActivity 注册监听,用以下方法  EMClient.getInstance().conferenceManager().addConferenceListener(this); 这样就可实现 EMConferenceListener 事件的处理,比如
 主播 进出房间 :
public void onMemberJoined(final EMConferenceMember member);
public void onMemberExited(final EMConferenceMember member);

增加流 移除流:
public void onStreamAdded(final EMConferenceStream stream)
 public void onStreamRemoved(final EMConferenceStream stream)

管理员变更: 
public void onAdminAdded(String streamId) ;  
public void onAdminRemoved(String streamId)

角色变更  用户被踢  谁在说话等各种回调,可以处理各种业务逻辑 ,详细的请参考 项目中的实现 ,最后会附上项目的开源地址。

6 进入会议房间以后如果用户角色为主播可以进行发布视频流 ,观众只能订阅视频流 不能发布视频流 ,可以调用SDK的publish接口发布流,该接口用到了EMStreamParam参数,你可以自由配置,比如是否上传视频,是否上传音频,使用前置或后置摄像头,视频码率,显示视频页面等等,具体实现可以参考 中发布 订阅视频流的内容, 关于以上的代码逻辑如以 如以下:
 //发布视频流
normalParam = new EMStreamParam();
normalParam.setStreamType(EMConferenceStream.StreamType.NORMAL);
normalParam.setVideoOff(true);
normalParam.setAudioOff(true);

EMClient.getInstance().conferenceManager().publish(normalParam, new EMValueCallBack<String>() {
@Override
public void onSuccess(String value) {
conference.setPubStreamId(value, EMConferenceStream.StreamType.NORMAL);
addOrUpdateStreamList("local-stream", value);

PhoneStateManager.get(ConferenceActivity.this).addStateCallback(phoneStateCallback);
}

@Override
public void onError(int error, String errorMsg) {
EMLog.i(TAG, "publish failed: error=" + error + ", msg=" + errorMsg);
}
});
//订阅其他主播的视频流
private void subscribe(EMConferenceStream stream, EMCallSurfaceView surfaceView) {
EMClient.getInstance().conferenceManager().subscribe(stream, surfaceView, new EMValueCallBack<String>() {
@Override
public void onSuccess(String value) {
}

@Override
public void onError(int error, String errorMsg) {

}
});
}

7.有关上麦 下麦 的逻辑处理,观众可以请求上麦成为主播,主播可以下麦成为观众,上麦 下麦 是利用 EMConferenceAttribute进行处理 ,EMConferenceAttribute  是一个事件广播,广播事件是一个key-value格式,key-value 可以由开发者进行自行定义,增添事件以后 ,服务器会把事件进行广播。会议中成员会收到 onAttributesUpdated回调。例如本项目中的会议上麦 下麦 代码如下所示:
//上麦申请  

EMClient.getInstance().conferenceManager().setConferenceAttribute(
EMClient.getInstance().getCurrentUser(),
"request_tobe_speaker",
new EMValueCallBack<Void>() {
@Override
public void onSuccess(Void value) {
EMLog.i(TAG, "request_tobe_speaker scuessed");

}

@Override
public void onError(int error, String errorMsg) {
EMLog.i(TAG, "request_tobe_speaker failed: error=" + error

}
});

//下麦申请
EMClient.getInstance().conferenceManager().setConferenceAttribute(EMClient.getInstance().getCurrentUser()
, "request_tobe_audience", new EMValueCallBack<Void>() {
@Override
public void onSuccess(Void value) {
EMLog.i(TAG, "request_tobe_audience scuessed");
}

@Override
public void onError(int error, String errorMsg) {
EMLog.i(TAG, "request_tobe_audience failed: error=" + error + ", msg=" + errorMsg);
}
});

 上麦 下麦 请求发出以后 只能由主持人去处理,处理在 EMConferenceListener  的回调 onAttributesUpdated(EMConferenceAttribute attributes) 去处理 ,收到回调以后 解析attributes 然后进行处理请求,处理的过程代码大概如下:
   EMClient.getInstance().conferenceManager().grantRole(conference.getConferenceId()
, new EMConferenceMember(memName, null, null,null)
, EMConferenceManager.EMConferenceRole.Talker, new EMValueCallBack<String>() {
@Override
public void onSuccess(String value) {
EMLog.i(TAG, " requestTalkerDisplay request_tobe_speaker changeRole success, result: " + value);
dialog.dismiss();
}
@Override
public void onError(int error, String errorMsg) {
EMLog.i(TAG, " requestTalkerDisplay request_tobe_speaker changeRole failed, error: " + error + " - " + errorMsg);

}
});

下麦也是和上麦一样是利用 EMConferenceAttribute进行处理。

9.有关退出会议 销毁会议 普通主播  观众只能退出会议 ,主持人还可以 销毁会议 正在进行中的会议可以进行销毁,退出会议 销毁会议 具体代码如下:
 EMClient.getInstance().conferenceManager().exitConference(new EMValueCallBack() {
@Override
public void onSuccess(Object value) {
runOnUiThread(new Runnable() {
@Override
public void run() {
Toast.makeText(getApplicationContext(), "您已成功退出当前会议!", Toast.LENGTH_SHORT).show();
}
});
}

@Override
public void onError(int error, String errorMsg) {
EMLog.i(TAG, "exit conference failed " + error + ", " + errorMsg);
}
});

EMClient.getInstance().conferenceManager().destroyConference(new EMValueCallBack() {
@Override
public void onSuccess(Object value) {
runOnUiThread(new Runnable() {
@Override
public void run() {
Toast.makeText(getApplicationContext(), "您已成功销毁当前会议!", Toast.LENGTH_SHORT).show();
}
});
EMLog.i(TAG, "finish ConferenceActivity");
finish();
}

尾语
至此 整个 多人音视频会议开发的详细步骤 已经完成 ,虽然比较麻烦 但是每个步骤都很清晰 ,有不太清楚的欢迎大家积极讨论, 附上本项目的github地址:https://github.com/easemob/videocall-android  欢迎大家积极参与 ,谢谢支持。
Demo下载 二维码如下 欢迎大家体验(iOS版和web版下载地址请见:https://www.easemob.com/download/rtc)


20200410142228530.png

 
0
评论

如何用 30 天入门年薪 30 万的技术领域? 技术 深度学习

sunshine123 发表了文章 • 567 次浏览 • 2019-10-08 17:18 • 来自相关话题

2016年3月15日,人机大战第五场在韩国首尔进行,经过长达5个小时搏杀,李世石认输,最终李世石与AlphaGo总比分定格在1比4。
值得注意的是:李世石仅在3月15日结束的第四场对战中取得了唯一的一场胜利。而支撑机器取胜的核心技术,就是深度学习。
自此之后,深度学习开始逐渐进入大家的视野。

01
什么是深度学习?

深度学习其实是机器学习(Machine Learning)的一个分支学科,而机器学习主要是研究数据之言的关系的,比如它可以用来分析性别、年龄、学历、职业等因素之间的数学关系。
显而易见,这些因果关系并不是一个简单的线性关系就能解决的。但是深度学习通过多非线性模型表示数据之间的关系,从而确定数据之间的相互关系是什么。

02
深度学习已经融入到了人们的日常生活中

现在汽车的自动驾驶、短信邮件的自动回复、扫地机器人,以及在围棋中击败最优秀人类选手的软件,都应用到了深度学习。甚至骚扰电话,也有很多是AI机器人打过来的,可能电话那头和你聊得正酣、声音甜美的客服妹子只是一串代码。
因此,阿里达摩院的工程师们,受不了骚扰骚扰电话的骚扰,发起了“二哈”AI,让机器人与骚扰电话自动聊天。
大家感受一下这对话画风





 
总之,AI机器人的骚扰电话,正在用AI进行解决。

03

可能是编程领域薪资最高的岗位

而与此同时学习深度学习的人也开始变得多了起来,但由于深度学习涉及面比较广,很多学者会对此望而却步。然而如果学好深度学习,不仅仅可以给你带来高薪资,也有可能会给你带来很多的荣誉!因为在此领域还是非常缺乏人才的!
大家可以看一份数据





 
平均月薪已达到3w,年薪36w。





 
就应届生深度学习岗的薪资,都已经达到了很多其他互联网职业3年工作经验都难以企及的水平。
现在各个大厂,也都有深度学习相关的项目,而且待遇方面也是极其的诱人。
百度推出“少帅计划”,针对30岁以下的深度学习科学家,开出100万以上年薪
阿里巴巴对外宣布将通过校园招聘组建一支规模达数百人的 NASA“青年军”
华为更是开出200万年薪招聘应届毕业生,其专业均为最前沿的人工智能领域
作为一个有追求的程序员,相信你在脑海中闪过无数次这样的疑问:如何掌握深度学习?

04

如何掌握深度学习?

目前市场对于深度学习的需求,早已出现供不应求的现象,但太多工程师想入门或者转行却不知从何开始,很多初学者都会有这样的困惑:
一边要熟练掌握线性代数、矩阵计算,一边还要搞概率论
一边要去研究各种库与框架,一边学习如何在用编程语言实现算法
一边学习如何制作数据集、特征提取,一边微调参数,选择合适的算法
这样一轮下来,深度学习还没有开始就已经走上了放弃之路。
放眼网上现有的一些深度学习课程,经常会发现有些知识点覆盖不全,或者学习门槛较高,研究性的问题不多,或者说只关注面试,而忽略了底层的逻辑以及真实案例的实操。
因此,我们通上百名深度学习用户的调研,与老师花费上千小时的时间,提炼了102节精华课程。
我们希望通过“从零开始深度学习”这门课程,让你0基础入门深度学习,建立起完整的学习路径,同时通过“智能问答模型”的实战案例,将所学知识学以致用。
#购课即送王海良老师在京东原价69的《智能问答与深度学习》实体书一本#

讲师介绍
王海良:Chatopera联合创始人&CEO,微软人工智能最有价值专家,先后工作于IBM软件开发实验室和创新中心。
李卓桓:25年编程经验,曾任优酷网首席科学家、叽歪网创始人,水木清华BBS站长,紫霞BBS站长。
林旭鸣:北京邮电大学模式识别实验室研究生,任职阿里巴巴的阿里小蜜团队。
陈可心:香港大学硕士,任职经历包括:微软中国、今日头条研发中心,联想香港人工智能中心以及联合国亚太分部。
李思珍:现任职今日头条,主要工作实现人机交互系统的意图识别和关键词优化。

#课程介绍#
相信很多小伙伴,在入门深度学习的路上,会被一些数据基础搞得犯怵,搭建环境的时候也许会遇到很多坑。
因此,我们把课程分为五个模块:数学基础、Python编程语言基础、深度学习初步、深度学习深化、智能问答模型实践,带你一探深度学习的究竟,希望你通过此次学习,不仅掌握原理更能动手实操。
除了上述102节视频课程,我们还为这次课程搭配了书籍《深度学习与智能问答》,一边跟着视频实操,一边阅读书籍巩固,学习效果double~





 
如何保证你的学习效果?
由基础的数学学习开始,逐渐建立完整的深度学习知识体系
五大模块,由知识学习到真实案例的实践
购课送原价69元深度学习实体书,边学边读,加深记忆
建立一个互助、监督的高效学习社群,随时交流问题

购课须知
本课程包含哪些内容?
包含102节视频课(20+小时)+实体书(京东原价69)

上课形式是怎样的?
课程授课形式为:视频+群答疑

#如何报名#
限时特惠:99元(原价199元)
拼团特惠69元~
图书(含邮寄) + 100+节视频课程,每课仅需6毛钱

扫码立即抢购!
平均一天2元,就是一瓶水钱
坚持30天,换你一次进入高薪技术领域的机会
如果对课程有疑问
欢迎扫码回复“1”进课程咨询群





 
 
  查看全部
2016年3月15日,人机大战第五场在韩国首尔进行,经过长达5个小时搏杀,李世石认输,最终李世石与AlphaGo总比分定格在1比4。
值得注意的是:李世石仅在3月15日结束的第四场对战中取得了唯一的一场胜利。而支撑机器取胜的核心技术,就是深度学习。
自此之后,深度学习开始逐渐进入大家的视野。

01
什么是深度学习?


深度学习其实是机器学习(Machine Learning)的一个分支学科,而机器学习主要是研究数据之言的关系的,比如它可以用来分析性别、年龄、学历、职业等因素之间的数学关系。
显而易见,这些因果关系并不是一个简单的线性关系就能解决的。但是深度学习通过多非线性模型表示数据之间的关系,从而确定数据之间的相互关系是什么。

02
深度学习已经融入到了人们的日常生活中


现在汽车的自动驾驶、短信邮件的自动回复、扫地机器人,以及在围棋中击败最优秀人类选手的软件,都应用到了深度学习。甚至骚扰电话,也有很多是AI机器人打过来的,可能电话那头和你聊得正酣、声音甜美的客服妹子只是一串代码。
因此,阿里达摩院的工程师们,受不了骚扰骚扰电话的骚扰,发起了“二哈”AI,让机器人与骚扰电话自动聊天。
大家感受一下这对话画风

1.gif

 
总之,AI机器人的骚扰电话,正在用AI进行解决。

03

可能是编程领域薪资最高的岗位


而与此同时学习深度学习的人也开始变得多了起来,但由于深度学习涉及面比较广,很多学者会对此望而却步。然而如果学好深度学习,不仅仅可以给你带来高薪资,也有可能会给你带来很多的荣誉!因为在此领域还是非常缺乏人才的!
大家可以看一份数据

2.png

 
平均月薪已达到3w,年薪36w。

4.png

 
就应届生深度学习岗的薪资,都已经达到了很多其他互联网职业3年工作经验都难以企及的水平。
现在各个大厂,也都有深度学习相关的项目,而且待遇方面也是极其的诱人。
百度推出“少帅计划”,针对30岁以下的深度学习科学家,开出100万以上年薪
阿里巴巴对外宣布将通过校园招聘组建一支规模达数百人的 NASA“青年军”
华为更是开出200万年薪招聘应届毕业生,其专业均为最前沿的人工智能领域
作为一个有追求的程序员,相信你在脑海中闪过无数次这样的疑问:如何掌握深度学习?

04

如何掌握深度学习?


目前市场对于深度学习的需求,早已出现供不应求的现象,但太多工程师想入门或者转行却不知从何开始,很多初学者都会有这样的困惑:
一边要熟练掌握线性代数、矩阵计算,一边还要搞概率论
一边要去研究各种库与框架,一边学习如何在用编程语言实现算法
一边学习如何制作数据集、特征提取,一边微调参数,选择合适的算法
这样一轮下来,深度学习还没有开始就已经走上了放弃之路。
放眼网上现有的一些深度学习课程,经常会发现有些知识点覆盖不全,或者学习门槛较高,研究性的问题不多,或者说只关注面试,而忽略了底层的逻辑以及真实案例的实操。
因此,我们通上百名深度学习用户的调研,与老师花费上千小时的时间,提炼了102节精华课程。
我们希望通过“从零开始深度学习”这门课程,让你0基础入门深度学习,建立起完整的学习路径,同时通过“智能问答模型”的实战案例,将所学知识学以致用。
#购课即送王海良老师在京东原价69的《智能问答与深度学习》实体书一本#

讲师介绍
王海良:Chatopera联合创始人&CEO,微软人工智能最有价值专家,先后工作于IBM软件开发实验室和创新中心。
李卓桓:25年编程经验,曾任优酷网首席科学家、叽歪网创始人,水木清华BBS站长,紫霞BBS站长。
林旭鸣:北京邮电大学模式识别实验室研究生,任职阿里巴巴的阿里小蜜团队。
陈可心:香港大学硕士,任职经历包括:微软中国、今日头条研发中心,联想香港人工智能中心以及联合国亚太分部。
李思珍:现任职今日头条,主要工作实现人机交互系统的意图识别和关键词优化。

#课程介绍#
相信很多小伙伴,在入门深度学习的路上,会被一些数据基础搞得犯怵,搭建环境的时候也许会遇到很多坑。
因此,我们把课程分为五个模块:数学基础、Python编程语言基础、深度学习初步、深度学习深化、智能问答模型实践,带你一探深度学习的究竟,希望你通过此次学习,不仅掌握原理更能动手实操。
除了上述102节视频课程,我们还为这次课程搭配了书籍《深度学习与智能问答》,一边跟着视频实操,一边阅读书籍巩固,学习效果double~

5.jpg

 
如何保证你的学习效果?
由基础的数学学习开始,逐渐建立完整的深度学习知识体系
五大模块,由知识学习到真实案例的实践
购课送原价69元深度学习实体书,边学边读,加深记忆
建立一个互助、监督的高效学习社群,随时交流问题

购课须知
本课程包含哪些内容?
包含102节视频课(20+小时)+实体书(京东原价69)

上课形式是怎样的?
课程授课形式为:视频+群答疑

#如何报名#
限时特惠:99元(原价199元)
拼团特惠69元~
图书(含邮寄) + 100+节视频课程,每课仅需6毛钱

扫码立即抢购!
平均一天2元,就是一瓶水钱
坚持30天,换你一次进入高薪技术领域的机会
如果对课程有疑问
欢迎扫码回复“1”进课程咨询群

6.jpg

 
 
 
2
评论

基于环信sdk在uni-app框架中快速开发一款多平台社交Demo SDK uni_app 环信

beyond 发表了文章 • 524 次浏览 • 2020-05-11 11:34 • 来自相关话题

说在前面:此款 demo 是基于 环信sdk 开发的一款具有单聊、群聊、聊天室、音视频等功能的应用。在此之前我们已经开发完 Vue、react(web端)、微信小程序。这三个热门领域的版本,如有需要源码可以后台留言索取。





 
安装开发工具

我们选用微信小程序来用做示例(如果选择百度、支付宝安装对应开发者工具即可)、

微信开发者工具建议还是安装最新版的。uni-app的开发也必须安装HBuilderX工具,这个是捆绑的,没得选择。要用uni-app,你必须得装!

工具安装:

微信开发者工具

HBuilderX

项目demo介绍:






项目demo启动预览:





 
快速集成环信 sdk:

1、复制整个utils文件






如果你想具体了解主要配置文件 请看这个链接:

http://docs-im.easemob.com/im/web/intro/start

2、如何使用环信的appkey ,可以在环信 console 后台注册一个 账号申请appkey ,可以参考这里 ,获取到  appkey 以后添加到配置文件中 ,如下图所示:






以上两个重要的配置准备完成之后就可以进行一系列的操作了(收发消息、好友申请、进群入群通知等)

在uni-app中 使用环信 sdk 实现添加、删除好友:

1、在全局 App.vue 文件 钩子函数 onLaunch() 中监听各种事件 (好友申请、收到各类消息等)如图:






发送好友请求:






在onPresence(message)事件中接收到好友消息申请:






同意好友请求:






拒绝好友请求:






实现收发消息:

1、给好友发送消息:






2、接收到消息:

在onTextMessage(message)事件中接收到好友消息,然后做消息上屏处理(具体消息上屏逻辑可看demo中代码示例):





以上展示的仅仅为基本业务场景,更多的业务逻辑详情请看demo示例。api具体详情可以查看 环信sdk 文档

最后结语:基于uni-app这个框架可实现多平台, 虽然目前一期集成环信sdk的版本仅支持微信小程序版本,但二期我们将加入头条、支付宝等小程序,敬请期待。PS:对于安卓、ios移动端,我们建议使用针对移动端开发的sdk版本。

基于uni-app的开发其中也趟了不少坑,在这里就不多赘述了。回归到框架的选型来讲,选用uni-app开发小程序,可同时并行多端小程序,这点是真香,一次开发多端发布。至于审核嘛~ 时快时慢。 查看全部
说在前面:此款 demo 是基于 环信sdk 开发的一款具有单聊、群聊、聊天室、音视频等功能的应用。在此之前我们已经开发完 Vue、react(web端)、微信小程序。这三个热门领域的版本,如有需要源码可以后台留言索取。

1.jpg

 
安装开发工具

我们选用微信小程序来用做示例(如果选择百度、支付宝安装对应开发者工具即可)、

微信开发者工具建议还是安装最新版的。uni-app的开发也必须安装HBuilderX工具,这个是捆绑的,没得选择。要用uni-app,你必须得装!

工具安装:

微信开发者工具

HBuilderX

项目demo介绍:

2.jpg


项目demo启动预览:

3.jpg

 
快速集成环信 sdk:

1、复制整个utils文件

4.jpg


如果你想具体了解主要配置文件 请看这个链接:

http://docs-im.easemob.com/im/web/intro/start

2、如何使用环信的appkey ,可以在环信 console 后台注册一个 账号申请appkey ,可以参考这里 ,获取到  appkey 以后添加到配置文件中 ,如下图所示:

5.jpg


以上两个重要的配置准备完成之后就可以进行一系列的操作了(收发消息、好友申请、进群入群通知等)

在uni-app中 使用环信 sdk 实现添加、删除好友:

1、在全局 App.vue 文件 钩子函数 onLaunch() 中监听各种事件 (好友申请、收到各类消息等)如图:

6.jpg


发送好友请求:

7.jpg


在onPresence(message)事件中接收到好友消息申请:

8.jpg


同意好友请求:

9.jpg


拒绝好友请求:

10.jpg


实现收发消息:

1、给好友发送消息:

11.jpg


2、接收到消息:

在onTextMessage(message)事件中接收到好友消息,然后做消息上屏处理(具体消息上屏逻辑可看demo中代码示例):

12.jpg

以上展示的仅仅为基本业务场景,更多的业务逻辑详情请看demo示例。api具体详情可以查看 环信sdk 文档

最后结语:基于uni-app这个框架可实现多平台, 虽然目前一期集成环信sdk的版本仅支持微信小程序版本,但二期我们将加入头条、支付宝等小程序,敬请期待。PS:对于安卓、ios移动端,我们建议使用针对移动端开发的sdk版本。

基于uni-app的开发其中也趟了不少坑,在这里就不多赘述了。回归到框架的选型来讲,选用uni-app开发小程序,可同时并行多端小程序,这点是真香,一次开发多端发布。至于审核嘛~ 时快时慢。
1
评论

手把手教程:4小时开发一个视频会议APP【附开源代码】 环信 开源 视频会议

fat1 发表了文章 • 1027 次浏览 • 2020-04-17 00:29 • 来自相关话题

今年是不平凡的一年,没错,就是因为疫情,因为疫情原因 ,大家只能呆着家里,严重影响了我们正常的学习 生活 工作,在这种情况下,只能在家办公,这时候大家就会想到线上视频会议,目前很多互联网公司有这个产品,比较出名的就比如 腾讯会议 钉钉 zoom等,用这些是很方便,但是如果能开发自己的视频会议,那会不会更好或者是更有成就感,下面简单介绍这个这个项目,和大概的开发过程。本项目基于环信音视频云来完成,实现的主要功能有:
  创建会议、删除会议、获取指定会议室详情、加入会议室、退出会议室等关于会议的管理 ;  获取会议室参会人名列表、踢人,设置观众为主播,设置主播为观众等关于会议室的人员管理;  共享桌面(web端);
 三个端的实现:Android,iOS,Web

上面这些功能在项目中都已经实现。还有水印 ,变声等高级功能在环信音视频SDK的接口内部都已经封装好,本项目没有实现 ,大家可以自行去实现。有关多人音视频功能更详细的介绍大家可以参考:这儿。多人音视频实现的实现主要有以下一些场景:社交交友,远程心理咨询、远程医疗、一对一在线教育、远程视频辅助等。咳咳 ,接下来就是纯干货了,给大家介绍我是如何一步步开发出一个完整的多人音视频app。
 
项目截图
 
首先给大家展示下项目运行的效果图,会议界面 主窗口是一个大的 RelativeLayout ,最下面的那一排排小窗口是的实现方法是HorizontalScrollView加上一个开源的组件 com.jaouan.compoundlayout.RadioLayoutGroup 实现的,点击下面的小窗口后,可以 把小窗口的视频流显示在大屏上,具体是调用 updateRemoteSurfaceView(String streamId, EMCallSurfaceView remoteView)来更新SurfaceView,具体的细节大家可以看看代码里面的实现 最后会公布代码开源地址。
















准备工作
    大家得下载安装Android Studio,配置好Android 开发环境,怎么详细配置我就在这不再细说了 网上有很多的教程,大家自己可以找找看,然后大家可以看看环信多人音视频会议的主要功能和一些基本概念介绍。
集成 
  1. 首先大家会想问怎么调用环信的SDK ,大家可以使用 远程依赖SDK包,建议大家用最新版本的远程依赖:
     com.hyphenate:hyphenate-sdk:3.6.6 ,依赖包可以放在 build.gradle里面的 dependencies 选项下面,如下图所示





2.其次怎么使用环信的appkey ,可以在环信音视频云后台注册一个 账号申请appkey ,可以参考这里 ,获取到  appkey 以后添加到AndroidManifest.xml中 ,如下图所示:






3.经过以上两个重要的前期配置准备 ,接下来我们就可以开始进行代码开发了,首先我们先创建一个项目的DemoApplication类和      DemoHelper类,DemoApplication 类和DemoHelper类都是一个单例类 ,DemoApplication 主要功能就是进行DemoHelper 的初始化,而DemoHelper里面主要是主要有一些option 配置和EMClient 进行初始化,代码如下所示:public void init(Context context) {
EMOptions options = initChatOptions(context);
EMClient.getInstance().init(context, options);
PreferenceManager.init(context);
}
  DemoHelper还有一个重要的功能就是设置  EMConferenceListener 进行会议监听,有关 EMConferenceListener的类的详细介绍 ,通过这个监听可以再加入会议的时候获取到已经在会议中的流和主播信息,分别是通过其中以下两个回调获取:@Override
public void onMemberJoined(EMConferenceMember member){

}

@Override
public void onStreamAdded(EMConferenceStream stream){

}
4.DemoApplication类完成以后,接下来就是怎么去登陆 环信IM 账号和 创建加入会议房间了,首次安装的时候都没有账号,我们使用的办法是自动注册一个账号 在本地进行保存,然后进行登录 ,注册 登录详细接口请看 这儿,  注册 登录的调用大概如下所示: 
 try {
        //注册一个环信ID
        EMClient.getInstance().createAccount(username, password);
            
        //注册成功进行登录
        PreferenceManager.getInstance().setCurrentUserName(username);
        PreferenceManager.getInstance().setCurrentuserPassword(password);
        login();
    } catch (final HyphenateException e) {
       runOnUiThread(new Runnable() {
               public void run() {
                  int errorCode=e.getErrorCode();
                   if(errorCode==EMError.NETWORK_ERROR){
                    Toast.makeText(getApplicationContext(), getResources().getString(R.string.network_anomalies), Toast.LENGTH_SHORT).show();
      }
   }   
}
 
  public void login() {
 
        //登录已经注册成功的环信ID
        EMClient.getInstance().login(username, password, new EMCallBack() {
            @Override
            public void onSuccess() {
                Log.d(TAG, "login: onSuccess");
                //登录成功进入会议房间
                joinRoom();
            }
            @Override
            public void onProgress(int progress, String status) {
                Log.d(TAG, "login: onProgress");
            }
            @Override
            public void onError(final int code, final String message) {
                Log.d(TAG, "login: onError: " + code);
                runOnUiThread(new Runnable() {
                    public void run() {
                        Toast.makeText(getApplicationContext(), getString(R.string.Login_failed) + message,Toast.LENGTH_SHORT).show();
                    }
                });
            }
        });
    }
登录完成以后,我们可以根据房间名创建并加入房间,主要代码大概如下: EMClient.getInstance().conferenceManager().joinRoom(currentRoomname, currentPassword, conferenceRole,roomConfig, new EMValueCallBack<EMConference>(){
@Override
public void onSuccess(EMConference value) {
EMLog.i(TAG, "join conference success");
Intent intent = new Intent(MainActivity.this, ConferenceActivity.class);
startActivity(intent);
finish();
}
@Override
public void onError(final int error, final String errorMsg) {
EMLog.e(TAG, "join conference failed error " + error + ", msg " + errorMsg);
runOnUiThread(new Runnable() {
@Override
public void run() {
setBtnEnable(true);
if(error == CALL_TALKER_ISFULL) {
takerFullDialogDisplay();
}else{
Toast.makeText(getApplicationContext(), "Join conference failed " + error + " " + errorMsg, Toast.LENGTH_SHORT).show();
}
}
});
}
});
EMClient.getInstance().conferenceManager().joinRoom() API可以根据房间名创建指定会议,当以该房间名命名的会议不存在时候,会直接创建,当会议已经创建好 可以根据正确的房间名和密码加入房间 ,到这一步为止,我们已经成功的创建 并加入会议。
5.加入会议以后我们进入到会议界面,展示从DemoHelper类 EMConferenceListener 中的 onStreamAdded 回调 和 onMemberJoined 获取到的流和主播列表 ,在ConferenceActivity 中实现 EMConferenceListener ,然后直接把 ConferenceActivity 注册监听,用以下方法  EMClient.getInstance().conferenceManager().addConferenceListener(this); 这样就可实现 EMConferenceListener 事件的处理,比如
 主播 进出房间 :
public void onMemberJoined(final EMConferenceMember member);
public void onMemberExited(final EMConferenceMember member);

增加流 移除流:
public void onStreamAdded(final EMConferenceStream stream)
 public void onStreamRemoved(final EMConferenceStream stream)

管理员变更: 
public void onAdminAdded(String streamId) ;  
public void onAdminRemoved(String streamId)

角色变更  用户被踢  谁在说话等各种回调,可以处理各种业务逻辑 ,详细的请参考 项目中的实现 ,最后会附上项目的开源地址。

6 进入会议房间以后如果用户角色为主播可以进行发布视频流 ,观众只能订阅视频流 不能发布视频流 ,可以调用SDK的publish接口发布流,该接口用到了EMStreamParam参数,你可以自由配置,比如是否上传视频,是否上传音频,使用前置或后置摄像头,视频码率,显示视频页面等等,具体实现可以参考 中发布 订阅视频流的内容, 关于以上的代码逻辑如以 如以下: //发布视频流
normalParam = new EMStreamParam();
normalParam.setStreamType(EMConferenceStream.StreamType.NORMAL);
normalParam.setVideoOff(true);
normalParam.setAudioOff(true);

EMClient.getInstance().conferenceManager().publish(normalParam, new EMValueCallBack<String>() {
@Override
public void onSuccess(String value) {
conference.setPubStreamId(value, EMConferenceStream.StreamType.NORMAL);
addOrUpdateStreamList("local-stream", value);

PhoneStateManager.get(ConferenceActivity.this).addStateCallback(phoneStateCallback);
}

@Override
public void onError(int error, String errorMsg) {
EMLog.i(TAG, "publish failed: error=" + error + ", msg=" + errorMsg);
}
});
//订阅其他主播的视频流
private void subscribe(EMConferenceStream stream, EMCallSurfaceView surfaceView) {
EMClient.getInstance().conferenceManager().subscribe(stream, surfaceView, new EMValueCallBack<String>() {
@Override
public void onSuccess(String value) {
}

@Override
public void onError(int error, String errorMsg) {

}
});
}
7.有关上麦 下麦 的逻辑处理,观众可以请求上麦成为主播,主播可以下麦成为观众,上麦 下麦 是利用 EMConferenceAttribute进行处理 ,EMConferenceAttribute  是一个事件广播,广播事件是一个key-value格式,key-value 可以由开发者进行自行定义,增添事件以后 ,服务器会把事件进行广播。会议中成员会收到 onAttributesUpdated回调。例如本项目中的会议上麦 下麦 代码如下所示://上麦申请

EMClient.getInstance().conferenceManager().setConferenceAttribute(
EMClient.getInstance().getCurrentUser(),
"request_tobe_speaker",
new EMValueCallBack<Void>() {
@Override
public void onSuccess(Void value) {
EMLog.i(TAG, "request_tobe_speaker scuessed");

}

@Override
public void onError(int error, String errorMsg) {
EMLog.i(TAG, "request_tobe_speaker failed: error=" + error

}
});

//下麦申请
EMClient.getInstance().conferenceManager().setConferenceAttribute(EMClient.getInstance().getCurrentUser()
, "request_tobe_audience", new EMValueCallBack<Void>() {
@Override
public void onSuccess(Void value) {
EMLog.i(TAG, "request_tobe_audience scuessed");
}

@Override
public void onError(int error, String errorMsg) {
EMLog.i(TAG, "request_tobe_audience failed: error=" + error + ", msg=" + errorMsg);
}
});
 上麦 下麦 请求发出以后 只能由主持人去处理,处理在 EMConferenceListener  的回调 onAttributesUpdated(EMConferenceAttribute attributes) 去处理 ,收到回调以后 解析attributes 然后进行处理请求,处理的过程代码大概如下: EMClient.getInstance().conferenceManager().grantRole(conference.getConferenceId()
, new EMConferenceMember(memName, null, null,null)
, EMConferenceManager.EMConferenceRole.Talker, new EMValueCallBack<String>() {
@Override
public void onSuccess(String value) {
EMLog.i(TAG, " requestTalkerDisplay request_tobe_speaker changeRole success, result: " + value);
dialog.dismiss();
}
@Override
public void onError(int error, String errorMsg) {
EMLog.i(TAG, " requestTalkerDisplay request_tobe_speaker changeRole failed, error: " + error + " - " + errorMsg);

}
});
下麦也是和上麦一样是利用 EMConferenceAttribute进行处理。

9.有关退出会议 销毁会议 普通主播  观众只能退出会议 ,主持人还可以 销毁会议 正在进行中的会议可以进行销毁,退出会议 销毁会议 具体代码如下: EMClient.getInstance().conferenceManager().exitConference(new EMValueCallBack() {
@Override
public void onSuccess(Object value) {
runOnUiThread(new Runnable() {
@Override
public void run() {
Toast.makeText(getApplicationContext(), "您已成功退出当前会议!", Toast.LENGTH_SHORT).show();
}
});
}

@Override
public void onError(int error, String errorMsg) {
EMLog.i(TAG, "exit conference failed " + error + ", " + errorMsg);
}
});

EMClient.getInstance().conferenceManager().destroyConference(new EMValueCallBack() {
@Override
public void onSuccess(Object value) {
runOnUiThread(new Runnable() {
@Override
public void run() {
Toast.makeText(getApplicationContext(), "您已成功销毁当前会议!", Toast.LENGTH_SHORT).show();
}
});
EMLog.i(TAG, "finish ConferenceActivity");
finish();
}

尾语
至此 整个 多人音视频会议开发的详细步骤 已经完成 ,虽然比较麻烦 但是每个步骤都很清晰 ,有不太清楚的欢迎大家积极讨论, 附上本项目的github地址:https://github.com/easemob/videocall-android  欢迎大家积极参与 ,谢谢支持。
Demo下载 二维码如下 欢迎大家体验(iOS版和web版下载地址请见:https://www.easemob.com/download/rtc)






  查看全部
今年是不平凡的一年,没错,就是因为疫情,因为疫情原因 ,大家只能呆着家里,严重影响了我们正常的学习 生活 工作,在这种情况下,只能在家办公,这时候大家就会想到线上视频会议,目前很多互联网公司有这个产品,比较出名的就比如 腾讯会议 钉钉 zoom等,用这些是很方便,但是如果能开发自己的视频会议,那会不会更好或者是更有成就感,下面简单介绍这个这个项目,和大概的开发过程。本项目基于环信音视频云来完成,实现的主要功能有:
  •   创建会议、删除会议、获取指定会议室详情、加入会议室、退出会议室等关于会议的管理 ;
  •   获取会议室参会人名列表、踢人,设置观众为主播,设置主播为观众等关于会议室的人员管理;
  •   共享桌面(web端);

 三个端的实现:Android,iOS,Web

上面这些功能在项目中都已经实现。还有水印 ,变声等高级功能在环信音视频SDK的接口内部都已经封装好,本项目没有实现 ,大家可以自行去实现。有关多人音视频功能更详细的介绍大家可以参考:这儿。多人音视频实现的实现主要有以下一些场景:社交交友,远程心理咨询、远程医疗、一对一在线教育、远程视频辅助等。咳咳 ,接下来就是纯干货了,给大家介绍我是如何一步步开发出一个完整的多人音视频app。
 
项目截图
 
首先给大家展示下项目运行的效果图,会议界面 主窗口是一个大的 RelativeLayout ,最下面的那一排排小窗口是的实现方法是HorizontalScrollView加上一个开源的组件 com.jaouan.compoundlayout.RadioLayoutGroup 实现的,点击下面的小窗口后,可以 把小窗口的视频流显示在大屏上,具体是调用 updateRemoteSurfaceView(String streamId, EMCallSurfaceView remoteView)来更新SurfaceView,具体的细节大家可以看看代码里面的实现 最后会公布代码开源地址。

20200410140627956.jpg


20200410140855852.jpg


20200410141055394.jpg


准备工作
    大家得下载安装Android Studio,配置好Android 开发环境,怎么详细配置我就在这不再细说了 网上有很多的教程,大家自己可以找找看,然后大家可以看看环信多人音视频会议的主要功能和一些基本概念介绍。
集成 
  1. 首先大家会想问怎么调用环信的SDK ,大家可以使用 远程依赖SDK包,建议大家用最新版本的远程依赖:
     com.hyphenate:hyphenate-sdk:3.6.6 ,依赖包可以放在 build.gradle里面的 dependencies 选项下面,如下图所示
2020040917363212.png


2.其次怎么使用环信的appkey ,可以在环信音视频云后台注册一个 账号申请appkey ,可以参考这里 ,获取到  appkey 以后添加到AndroidManifest.xml中 ,如下图所示:

20200409213959916.png


3.经过以上两个重要的前期配置准备 ,接下来我们就可以开始进行代码开发了,首先我们先创建一个项目的DemoApplication类和      DemoHelper类,DemoApplication 类和DemoHelper类都是一个单例类 ,DemoApplication 主要功能就是进行DemoHelper 的初始化,而DemoHelper里面主要是主要有一些option 配置和EMClient 进行初始化,代码如下所示:
public void init(Context context) {
EMOptions options = initChatOptions(context);
EMClient.getInstance().init(context, options);
PreferenceManager.init(context);
}

  DemoHelper还有一个重要的功能就是设置  EMConferenceListener 进行会议监听,有关 EMConferenceListener的类的详细介绍 ,通过这个监听可以再加入会议的时候获取到已经在会议中的流和主播信息,分别是通过其中以下两个回调获取:
@Override 
public void onMemberJoined(EMConferenceMember member){

}

@Override
public void onStreamAdded(EMConferenceStream stream){

}

4.DemoApplication类完成以后,接下来就是怎么去登陆 环信IM 账号和 创建加入会议房间了,首次安装的时候都没有账号,我们使用的办法是自动注册一个账号 在本地进行保存,然后进行登录 ,注册 登录详细接口请看 这儿,  注册 登录的调用大概如下所示: 
 try {
        //注册一个环信ID
        EMClient.getInstance().createAccount(username, password);
            
        //注册成功进行登录
        PreferenceManager.getInstance().setCurrentUserName(username);
        PreferenceManager.getInstance().setCurrentuserPassword(password);
        login();
    } catch (final HyphenateException e) {
       runOnUiThread(new Runnable() {
               public void run() {
                  int errorCode=e.getErrorCode();
                   if(errorCode==EMError.NETWORK_ERROR){
                    Toast.makeText(getApplicationContext(), getResources().getString(R.string.network_anomalies), Toast.LENGTH_SHORT).show();
      }
   }   
}
 
  public void login() {
 
        //登录已经注册成功的环信ID
        EMClient.getInstance().login(username, password, new EMCallBack() {
            @Override
            public void onSuccess() {
                Log.d(TAG, "login: onSuccess");
                //登录成功进入会议房间
                joinRoom();
            }
            @Override
            public void onProgress(int progress, String status) {
                Log.d(TAG, "login: onProgress");
            }
            @Override
            public void onError(final int code, final String message) {
                Log.d(TAG, "login: onError: " + code);
                runOnUiThread(new Runnable() {
                    public void run() {
                        Toast.makeText(getApplicationContext(), getString(R.string.Login_failed) + message,Toast.LENGTH_SHORT).show();
                    }
                });
            }
        });
    }
登录完成以后,我们可以根据房间名创建并加入房间,主要代码大概如下:
 EMClient.getInstance().conferenceManager().joinRoom(currentRoomname, currentPassword, conferenceRole,roomConfig, new EMValueCallBack<EMConference>(){
@Override
public void onSuccess(EMConference value) {
EMLog.i(TAG, "join conference success");
Intent intent = new Intent(MainActivity.this, ConferenceActivity.class);
startActivity(intent);
finish();
}
@Override
public void onError(final int error, final String errorMsg) {
EMLog.e(TAG, "join conference failed error " + error + ", msg " + errorMsg);
runOnUiThread(new Runnable() {
@Override
public void run() {
setBtnEnable(true);
if(error == CALL_TALKER_ISFULL) {
takerFullDialogDisplay();
}else{
Toast.makeText(getApplicationContext(), "Join conference failed " + error + " " + errorMsg, Toast.LENGTH_SHORT).show();
}
}
});
}
});

EMClient.getInstance().conferenceManager().joinRoom() API可以根据房间名创建指定会议,当以该房间名命名的会议不存在时候,会直接创建,当会议已经创建好 可以根据正确的房间名和密码加入房间 ,到这一步为止,我们已经成功的创建 并加入会议。
5.加入会议以后我们进入到会议界面,展示从DemoHelper类 EMConferenceListener 中的 onStreamAdded 回调 和 onMemberJoined 获取到的流和主播列表 ,在ConferenceActivity 中实现 EMConferenceListener ,然后直接把 ConferenceActivity 注册监听,用以下方法  EMClient.getInstance().conferenceManager().addConferenceListener(this); 这样就可实现 EMConferenceListener 事件的处理,比如
 主播 进出房间 :
public void onMemberJoined(final EMConferenceMember member);
public void onMemberExited(final EMConferenceMember member);

增加流 移除流:
public void onStreamAdded(final EMConferenceStream stream)
 public void onStreamRemoved(final EMConferenceStream stream)

管理员变更: 
public void onAdminAdded(String streamId) ;  
public void onAdminRemoved(String streamId)

角色变更  用户被踢  谁在说话等各种回调,可以处理各种业务逻辑 ,详细的请参考 项目中的实现 ,最后会附上项目的开源地址。

6 进入会议房间以后如果用户角色为主播可以进行发布视频流 ,观众只能订阅视频流 不能发布视频流 ,可以调用SDK的publish接口发布流,该接口用到了EMStreamParam参数,你可以自由配置,比如是否上传视频,是否上传音频,使用前置或后置摄像头,视频码率,显示视频页面等等,具体实现可以参考 中发布 订阅视频流的内容, 关于以上的代码逻辑如以 如以下:
 //发布视频流
normalParam = new EMStreamParam();
normalParam.setStreamType(EMConferenceStream.StreamType.NORMAL);
normalParam.setVideoOff(true);
normalParam.setAudioOff(true);

EMClient.getInstance().conferenceManager().publish(normalParam, new EMValueCallBack<String>() {
@Override
public void onSuccess(String value) {
conference.setPubStreamId(value, EMConferenceStream.StreamType.NORMAL);
addOrUpdateStreamList("local-stream", value);

PhoneStateManager.get(ConferenceActivity.this).addStateCallback(phoneStateCallback);
}

@Override
public void onError(int error, String errorMsg) {
EMLog.i(TAG, "publish failed: error=" + error + ", msg=" + errorMsg);
}
});
//订阅其他主播的视频流
private void subscribe(EMConferenceStream stream, EMCallSurfaceView surfaceView) {
EMClient.getInstance().conferenceManager().subscribe(stream, surfaceView, new EMValueCallBack<String>() {
@Override
public void onSuccess(String value) {
}

@Override
public void onError(int error, String errorMsg) {

}
});
}

7.有关上麦 下麦 的逻辑处理,观众可以请求上麦成为主播,主播可以下麦成为观众,上麦 下麦 是利用 EMConferenceAttribute进行处理 ,EMConferenceAttribute  是一个事件广播,广播事件是一个key-value格式,key-value 可以由开发者进行自行定义,增添事件以后 ,服务器会把事件进行广播。会议中成员会收到 onAttributesUpdated回调。例如本项目中的会议上麦 下麦 代码如下所示:
//上麦申请  

EMClient.getInstance().conferenceManager().setConferenceAttribute(
EMClient.getInstance().getCurrentUser(),
"request_tobe_speaker",
new EMValueCallBack<Void>() {
@Override
public void onSuccess(Void value) {
EMLog.i(TAG, "request_tobe_speaker scuessed");

}

@Override
public void onError(int error, String errorMsg) {
EMLog.i(TAG, "request_tobe_speaker failed: error=" + error

}
});

//下麦申请
EMClient.getInstance().conferenceManager().setConferenceAttribute(EMClient.getInstance().getCurrentUser()
, "request_tobe_audience", new EMValueCallBack<Void>() {
@Override
public void onSuccess(Void value) {
EMLog.i(TAG, "request_tobe_audience scuessed");
}

@Override
public void onError(int error, String errorMsg) {
EMLog.i(TAG, "request_tobe_audience failed: error=" + error + ", msg=" + errorMsg);
}
});

 上麦 下麦 请求发出以后 只能由主持人去处理,处理在 EMConferenceListener  的回调 onAttributesUpdated(EMConferenceAttribute attributes) 去处理 ,收到回调以后 解析attributes 然后进行处理请求,处理的过程代码大概如下:
   EMClient.getInstance().conferenceManager().grantRole(conference.getConferenceId()
, new EMConferenceMember(memName, null, null,null)
, EMConferenceManager.EMConferenceRole.Talker, new EMValueCallBack<String>() {
@Override
public void onSuccess(String value) {
EMLog.i(TAG, " requestTalkerDisplay request_tobe_speaker changeRole success, result: " + value);
dialog.dismiss();
}
@Override
public void onError(int error, String errorMsg) {
EMLog.i(TAG, " requestTalkerDisplay request_tobe_speaker changeRole failed, error: " + error + " - " + errorMsg);

}
});

下麦也是和上麦一样是利用 EMConferenceAttribute进行处理。

9.有关退出会议 销毁会议 普通主播  观众只能退出会议 ,主持人还可以 销毁会议 正在进行中的会议可以进行销毁,退出会议 销毁会议 具体代码如下:
 EMClient.getInstance().conferenceManager().exitConference(new EMValueCallBack() {
@Override
public void onSuccess(Object value) {
runOnUiThread(new Runnable() {
@Override
public void run() {
Toast.makeText(getApplicationContext(), "您已成功退出当前会议!", Toast.LENGTH_SHORT).show();
}
});
}

@Override
public void onError(int error, String errorMsg) {
EMLog.i(TAG, "exit conference failed " + error + ", " + errorMsg);
}
});

EMClient.getInstance().conferenceManager().destroyConference(new EMValueCallBack() {
@Override
public void onSuccess(Object value) {
runOnUiThread(new Runnable() {
@Override
public void run() {
Toast.makeText(getApplicationContext(), "您已成功销毁当前会议!", Toast.LENGTH_SHORT).show();
}
});
EMLog.i(TAG, "finish ConferenceActivity");
finish();
}

尾语
至此 整个 多人音视频会议开发的详细步骤 已经完成 ,虽然比较麻烦 但是每个步骤都很清晰 ,有不太清楚的欢迎大家积极讨论, 附上本项目的github地址:https://github.com/easemob/videocall-android  欢迎大家积极参与 ,谢谢支持。
Demo下载 二维码如下 欢迎大家体验(iOS版和web版下载地址请见:https://www.easemob.com/download/rtc)


20200410142228530.png

 
2
评论

基于环信sdk在uni-app框架中快速开发一款多平台社交Demo SDK uni_app 环信

beyond 发表了文章 • 524 次浏览 • 2020-05-11 11:34 • 来自相关话题

说在前面:此款 demo 是基于 环信sdk 开发的一款具有单聊、群聊、聊天室、音视频等功能的应用。在此之前我们已经开发完 Vue、react(web端)、微信小程序。这三个热门领域的版本,如有需要源码可以后台留言索取。





 
安装开发工具

我们选用微信小程序来用做示例(如果选择百度、支付宝安装对应开发者工具即可)、

微信开发者工具建议还是安装最新版的。uni-app的开发也必须安装HBuilderX工具,这个是捆绑的,没得选择。要用uni-app,你必须得装!

工具安装:

微信开发者工具

HBuilderX

项目demo介绍:






项目demo启动预览:





 
快速集成环信 sdk:

1、复制整个utils文件






如果你想具体了解主要配置文件 请看这个链接:

http://docs-im.easemob.com/im/web/intro/start

2、如何使用环信的appkey ,可以在环信 console 后台注册一个 账号申请appkey ,可以参考这里 ,获取到  appkey 以后添加到配置文件中 ,如下图所示:






以上两个重要的配置准备完成之后就可以进行一系列的操作了(收发消息、好友申请、进群入群通知等)

在uni-app中 使用环信 sdk 实现添加、删除好友:

1、在全局 App.vue 文件 钩子函数 onLaunch() 中监听各种事件 (好友申请、收到各类消息等)如图:






发送好友请求:






在onPresence(message)事件中接收到好友消息申请:






同意好友请求:






拒绝好友请求:






实现收发消息:

1、给好友发送消息:






2、接收到消息:

在onTextMessage(message)事件中接收到好友消息,然后做消息上屏处理(具体消息上屏逻辑可看demo中代码示例):





以上展示的仅仅为基本业务场景,更多的业务逻辑详情请看demo示例。api具体详情可以查看 环信sdk 文档

最后结语:基于uni-app这个框架可实现多平台, 虽然目前一期集成环信sdk的版本仅支持微信小程序版本,但二期我们将加入头条、支付宝等小程序,敬请期待。PS:对于安卓、ios移动端,我们建议使用针对移动端开发的sdk版本。

基于uni-app的开发其中也趟了不少坑,在这里就不多赘述了。回归到框架的选型来讲,选用uni-app开发小程序,可同时并行多端小程序,这点是真香,一次开发多端发布。至于审核嘛~ 时快时慢。 查看全部
说在前面:此款 demo 是基于 环信sdk 开发的一款具有单聊、群聊、聊天室、音视频等功能的应用。在此之前我们已经开发完 Vue、react(web端)、微信小程序。这三个热门领域的版本,如有需要源码可以后台留言索取。

1.jpg

 
安装开发工具

我们选用微信小程序来用做示例(如果选择百度、支付宝安装对应开发者工具即可)、

微信开发者工具建议还是安装最新版的。uni-app的开发也必须安装HBuilderX工具,这个是捆绑的,没得选择。要用uni-app,你必须得装!

工具安装:

微信开发者工具

HBuilderX

项目demo介绍:

2.jpg


项目demo启动预览:

3.jpg

 
快速集成环信 sdk:

1、复制整个utils文件

4.jpg


如果你想具体了解主要配置文件 请看这个链接:

http://docs-im.easemob.com/im/web/intro/start

2、如何使用环信的appkey ,可以在环信 console 后台注册一个 账号申请appkey ,可以参考这里 ,获取到  appkey 以后添加到配置文件中 ,如下图所示:

5.jpg


以上两个重要的配置准备完成之后就可以进行一系列的操作了(收发消息、好友申请、进群入群通知等)

在uni-app中 使用环信 sdk 实现添加、删除好友:

1、在全局 App.vue 文件 钩子函数 onLaunch() 中监听各种事件 (好友申请、收到各类消息等)如图:

6.jpg


发送好友请求:

7.jpg


在onPresence(message)事件中接收到好友消息申请:

8.jpg


同意好友请求:

9.jpg


拒绝好友请求:

10.jpg


实现收发消息:

1、给好友发送消息:

11.jpg


2、接收到消息:

在onTextMessage(message)事件中接收到好友消息,然后做消息上屏处理(具体消息上屏逻辑可看demo中代码示例):

12.jpg

以上展示的仅仅为基本业务场景,更多的业务逻辑详情请看demo示例。api具体详情可以查看 环信sdk 文档

最后结语:基于uni-app这个框架可实现多平台, 虽然目前一期集成环信sdk的版本仅支持微信小程序版本,但二期我们将加入头条、支付宝等小程序,敬请期待。PS:对于安卓、ios移动端,我们建议使用针对移动端开发的sdk版本。

基于uni-app的开发其中也趟了不少坑,在这里就不多赘述了。回归到框架的选型来讲,选用uni-app开发小程序,可同时并行多端小程序,这点是真香,一次开发多端发布。至于审核嘛~ 时快时慢。
1
评论

手把手教程:4小时开发一个视频会议APP【附开源代码】 环信 开源 视频会议

fat1 发表了文章 • 1027 次浏览 • 2020-04-17 00:29 • 来自相关话题

今年是不平凡的一年,没错,就是因为疫情,因为疫情原因 ,大家只能呆着家里,严重影响了我们正常的学习 生活 工作,在这种情况下,只能在家办公,这时候大家就会想到线上视频会议,目前很多互联网公司有这个产品,比较出名的就比如 腾讯会议 钉钉 zoom等,用这些是很方便,但是如果能开发自己的视频会议,那会不会更好或者是更有成就感,下面简单介绍这个这个项目,和大概的开发过程。本项目基于环信音视频云来完成,实现的主要功能有:
  创建会议、删除会议、获取指定会议室详情、加入会议室、退出会议室等关于会议的管理 ;  获取会议室参会人名列表、踢人,设置观众为主播,设置主播为观众等关于会议室的人员管理;  共享桌面(web端);
 三个端的实现:Android,iOS,Web

上面这些功能在项目中都已经实现。还有水印 ,变声等高级功能在环信音视频SDK的接口内部都已经封装好,本项目没有实现 ,大家可以自行去实现。有关多人音视频功能更详细的介绍大家可以参考:这儿。多人音视频实现的实现主要有以下一些场景:社交交友,远程心理咨询、远程医疗、一对一在线教育、远程视频辅助等。咳咳 ,接下来就是纯干货了,给大家介绍我是如何一步步开发出一个完整的多人音视频app。
 
项目截图
 
首先给大家展示下项目运行的效果图,会议界面 主窗口是一个大的 RelativeLayout ,最下面的那一排排小窗口是的实现方法是HorizontalScrollView加上一个开源的组件 com.jaouan.compoundlayout.RadioLayoutGroup 实现的,点击下面的小窗口后,可以 把小窗口的视频流显示在大屏上,具体是调用 updateRemoteSurfaceView(String streamId, EMCallSurfaceView remoteView)来更新SurfaceView,具体的细节大家可以看看代码里面的实现 最后会公布代码开源地址。
















准备工作
    大家得下载安装Android Studio,配置好Android 开发环境,怎么详细配置我就在这不再细说了 网上有很多的教程,大家自己可以找找看,然后大家可以看看环信多人音视频会议的主要功能和一些基本概念介绍。
集成 
  1. 首先大家会想问怎么调用环信的SDK ,大家可以使用 远程依赖SDK包,建议大家用最新版本的远程依赖:
     com.hyphenate:hyphenate-sdk:3.6.6 ,依赖包可以放在 build.gradle里面的 dependencies 选项下面,如下图所示





2.其次怎么使用环信的appkey ,可以在环信音视频云后台注册一个 账号申请appkey ,可以参考这里 ,获取到  appkey 以后添加到AndroidManifest.xml中 ,如下图所示:






3.经过以上两个重要的前期配置准备 ,接下来我们就可以开始进行代码开发了,首先我们先创建一个项目的DemoApplication类和      DemoHelper类,DemoApplication 类和DemoHelper类都是一个单例类 ,DemoApplication 主要功能就是进行DemoHelper 的初始化,而DemoHelper里面主要是主要有一些option 配置和EMClient 进行初始化,代码如下所示:public void init(Context context) {
EMOptions options = initChatOptions(context);
EMClient.getInstance().init(context, options);
PreferenceManager.init(context);
}
  DemoHelper还有一个重要的功能就是设置  EMConferenceListener 进行会议监听,有关 EMConferenceListener的类的详细介绍 ,通过这个监听可以再加入会议的时候获取到已经在会议中的流和主播信息,分别是通过其中以下两个回调获取:@Override
public void onMemberJoined(EMConferenceMember member){

}

@Override
public void onStreamAdded(EMConferenceStream stream){

}
4.DemoApplication类完成以后,接下来就是怎么去登陆 环信IM 账号和 创建加入会议房间了,首次安装的时候都没有账号,我们使用的办法是自动注册一个账号 在本地进行保存,然后进行登录 ,注册 登录详细接口请看 这儿,  注册 登录的调用大概如下所示: 
 try {
        //注册一个环信ID
        EMClient.getInstance().createAccount(username, password);
            
        //注册成功进行登录
        PreferenceManager.getInstance().setCurrentUserName(username);
        PreferenceManager.getInstance().setCurrentuserPassword(password);
        login();
    } catch (final HyphenateException e) {
       runOnUiThread(new Runnable() {
               public void run() {
                  int errorCode=e.getErrorCode();
                   if(errorCode==EMError.NETWORK_ERROR){
                    Toast.makeText(getApplicationContext(), getResources().getString(R.string.network_anomalies), Toast.LENGTH_SHORT).show();
      }
   }   
}
 
  public void login() {
 
        //登录已经注册成功的环信ID
        EMClient.getInstance().login(username, password, new EMCallBack() {
            @Override
            public void onSuccess() {
                Log.d(TAG, "login: onSuccess");
                //登录成功进入会议房间
                joinRoom();
            }
            @Override
            public void onProgress(int progress, String status) {
                Log.d(TAG, "login: onProgress");
            }
            @Override
            public void onError(final int code, final String message) {
                Log.d(TAG, "login: onError: " + code);
                runOnUiThread(new Runnable() {
                    public void run() {
                        Toast.makeText(getApplicationContext(), getString(R.string.Login_failed) + message,Toast.LENGTH_SHORT).show();
                    }
                });
            }
        });
    }
登录完成以后,我们可以根据房间名创建并加入房间,主要代码大概如下: EMClient.getInstance().conferenceManager().joinRoom(currentRoomname, currentPassword, conferenceRole,roomConfig, new EMValueCallBack<EMConference>(){
@Override
public void onSuccess(EMConference value) {
EMLog.i(TAG, "join conference success");
Intent intent = new Intent(MainActivity.this, ConferenceActivity.class);
startActivity(intent);
finish();
}
@Override
public void onError(final int error, final String errorMsg) {
EMLog.e(TAG, "join conference failed error " + error + ", msg " + errorMsg);
runOnUiThread(new Runnable() {
@Override
public void run() {
setBtnEnable(true);
if(error == CALL_TALKER_ISFULL) {
takerFullDialogDisplay();
}else{
Toast.makeText(getApplicationContext(), "Join conference failed " + error + " " + errorMsg, Toast.LENGTH_SHORT).show();
}
}
});
}
});
EMClient.getInstance().conferenceManager().joinRoom() API可以根据房间名创建指定会议,当以该房间名命名的会议不存在时候,会直接创建,当会议已经创建好 可以根据正确的房间名和密码加入房间 ,到这一步为止,我们已经成功的创建 并加入会议。
5.加入会议以后我们进入到会议界面,展示从DemoHelper类 EMConferenceListener 中的 onStreamAdded 回调 和 onMemberJoined 获取到的流和主播列表 ,在ConferenceActivity 中实现 EMConferenceListener ,然后直接把 ConferenceActivity 注册监听,用以下方法  EMClient.getInstance().conferenceManager().addConferenceListener(this); 这样就可实现 EMConferenceListener 事件的处理,比如
 主播 进出房间 :
public void onMemberJoined(final EMConferenceMember member);
public void onMemberExited(final EMConferenceMember member);

增加流 移除流:
public void onStreamAdded(final EMConferenceStream stream)
 public void onStreamRemoved(final EMConferenceStream stream)

管理员变更: 
public void onAdminAdded(String streamId) ;  
public void onAdminRemoved(String streamId)

角色变更  用户被踢  谁在说话等各种回调,可以处理各种业务逻辑 ,详细的请参考 项目中的实现 ,最后会附上项目的开源地址。

6 进入会议房间以后如果用户角色为主播可以进行发布视频流 ,观众只能订阅视频流 不能发布视频流 ,可以调用SDK的publish接口发布流,该接口用到了EMStreamParam参数,你可以自由配置,比如是否上传视频,是否上传音频,使用前置或后置摄像头,视频码率,显示视频页面等等,具体实现可以参考 中发布 订阅视频流的内容, 关于以上的代码逻辑如以 如以下: //发布视频流
normalParam = new EMStreamParam();
normalParam.setStreamType(EMConferenceStream.StreamType.NORMAL);
normalParam.setVideoOff(true);
normalParam.setAudioOff(true);

EMClient.getInstance().conferenceManager().publish(normalParam, new EMValueCallBack<String>() {
@Override
public void onSuccess(String value) {
conference.setPubStreamId(value, EMConferenceStream.StreamType.NORMAL);
addOrUpdateStreamList("local-stream", value);

PhoneStateManager.get(ConferenceActivity.this).addStateCallback(phoneStateCallback);
}

@Override
public void onError(int error, String errorMsg) {
EMLog.i(TAG, "publish failed: error=" + error + ", msg=" + errorMsg);
}
});
//订阅其他主播的视频流
private void subscribe(EMConferenceStream stream, EMCallSurfaceView surfaceView) {
EMClient.getInstance().conferenceManager().subscribe(stream, surfaceView, new EMValueCallBack<String>() {
@Override
public void onSuccess(String value) {
}

@Override
public void onError(int error, String errorMsg) {

}
});
}
7.有关上麦 下麦 的逻辑处理,观众可以请求上麦成为主播,主播可以下麦成为观众,上麦 下麦 是利用 EMConferenceAttribute进行处理 ,EMConferenceAttribute  是一个事件广播,广播事件是一个key-value格式,key-value 可以由开发者进行自行定义,增添事件以后 ,服务器会把事件进行广播。会议中成员会收到 onAttributesUpdated回调。例如本项目中的会议上麦 下麦 代码如下所示://上麦申请

EMClient.getInstance().conferenceManager().setConferenceAttribute(
EMClient.getInstance().getCurrentUser(),
"request_tobe_speaker",
new EMValueCallBack<Void>() {
@Override
public void onSuccess(Void value) {
EMLog.i(TAG, "request_tobe_speaker scuessed");

}

@Override
public void onError(int error, String errorMsg) {
EMLog.i(TAG, "request_tobe_speaker failed: error=" + error

}
});

//下麦申请
EMClient.getInstance().conferenceManager().setConferenceAttribute(EMClient.getInstance().getCurrentUser()
, "request_tobe_audience", new EMValueCallBack<Void>() {
@Override
public void onSuccess(Void value) {
EMLog.i(TAG, "request_tobe_audience scuessed");
}

@Override
public void onError(int error, String errorMsg) {
EMLog.i(TAG, "request_tobe_audience failed: error=" + error + ", msg=" + errorMsg);
}
});
 上麦 下麦 请求发出以后 只能由主持人去处理,处理在 EMConferenceListener  的回调 onAttributesUpdated(EMConferenceAttribute attributes) 去处理 ,收到回调以后 解析attributes 然后进行处理请求,处理的过程代码大概如下: EMClient.getInstance().conferenceManager().grantRole(conference.getConferenceId()
, new EMConferenceMember(memName, null, null,null)
, EMConferenceManager.EMConferenceRole.Talker, new EMValueCallBack<String>() {
@Override
public void onSuccess(String value) {
EMLog.i(TAG, " requestTalkerDisplay request_tobe_speaker changeRole success, result: " + value);
dialog.dismiss();
}
@Override
public void onError(int error, String errorMsg) {
EMLog.i(TAG, " requestTalkerDisplay request_tobe_speaker changeRole failed, error: " + error + " - " + errorMsg);

}
});
下麦也是和上麦一样是利用 EMConferenceAttribute进行处理。

9.有关退出会议 销毁会议 普通主播  观众只能退出会议 ,主持人还可以 销毁会议 正在进行中的会议可以进行销毁,退出会议 销毁会议 具体代码如下: EMClient.getInstance().conferenceManager().exitConference(new EMValueCallBack() {
@Override
public void onSuccess(Object value) {
runOnUiThread(new Runnable() {
@Override
public void run() {
Toast.makeText(getApplicationContext(), "您已成功退出当前会议!", Toast.LENGTH_SHORT).show();
}
});
}

@Override
public void onError(int error, String errorMsg) {
EMLog.i(TAG, "exit conference failed " + error + ", " + errorMsg);
}
});

EMClient.getInstance().conferenceManager().destroyConference(new EMValueCallBack() {
@Override
public void onSuccess(Object value) {
runOnUiThread(new Runnable() {
@Override
public void run() {
Toast.makeText(getApplicationContext(), "您已成功销毁当前会议!", Toast.LENGTH_SHORT).show();
}
});
EMLog.i(TAG, "finish ConferenceActivity");
finish();
}

尾语
至此 整个 多人音视频会议开发的详细步骤 已经完成 ,虽然比较麻烦 但是每个步骤都很清晰 ,有不太清楚的欢迎大家积极讨论, 附上本项目的github地址:https://github.com/easemob/videocall-android  欢迎大家积极参与 ,谢谢支持。
Demo下载 二维码如下 欢迎大家体验(iOS版和web版下载地址请见:https://www.easemob.com/download/rtc)






  查看全部
今年是不平凡的一年,没错,就是因为疫情,因为疫情原因 ,大家只能呆着家里,严重影响了我们正常的学习 生活 工作,在这种情况下,只能在家办公,这时候大家就会想到线上视频会议,目前很多互联网公司有这个产品,比较出名的就比如 腾讯会议 钉钉 zoom等,用这些是很方便,但是如果能开发自己的视频会议,那会不会更好或者是更有成就感,下面简单介绍这个这个项目,和大概的开发过程。本项目基于环信音视频云来完成,实现的主要功能有:
  •   创建会议、删除会议、获取指定会议室详情、加入会议室、退出会议室等关于会议的管理 ;
  •   获取会议室参会人名列表、踢人,设置观众为主播,设置主播为观众等关于会议室的人员管理;
  •   共享桌面(web端);

 三个端的实现:Android,iOS,Web

上面这些功能在项目中都已经实现。还有水印 ,变声等高级功能在环信音视频SDK的接口内部都已经封装好,本项目没有实现 ,大家可以自行去实现。有关多人音视频功能更详细的介绍大家可以参考:这儿。多人音视频实现的实现主要有以下一些场景:社交交友,远程心理咨询、远程医疗、一对一在线教育、远程视频辅助等。咳咳 ,接下来就是纯干货了,给大家介绍我是如何一步步开发出一个完整的多人音视频app。
 
项目截图
 
首先给大家展示下项目运行的效果图,会议界面 主窗口是一个大的 RelativeLayout ,最下面的那一排排小窗口是的实现方法是HorizontalScrollView加上一个开源的组件 com.jaouan.compoundlayout.RadioLayoutGroup 实现的,点击下面的小窗口后,可以 把小窗口的视频流显示在大屏上,具体是调用 updateRemoteSurfaceView(String streamId, EMCallSurfaceView remoteView)来更新SurfaceView,具体的细节大家可以看看代码里面的实现 最后会公布代码开源地址。

20200410140627956.jpg


20200410140855852.jpg


20200410141055394.jpg


准备工作
    大家得下载安装Android Studio,配置好Android 开发环境,怎么详细配置我就在这不再细说了 网上有很多的教程,大家自己可以找找看,然后大家可以看看环信多人音视频会议的主要功能和一些基本概念介绍。
集成 
  1. 首先大家会想问怎么调用环信的SDK ,大家可以使用 远程依赖SDK包,建议大家用最新版本的远程依赖:
     com.hyphenate:hyphenate-sdk:3.6.6 ,依赖包可以放在 build.gradle里面的 dependencies 选项下面,如下图所示
2020040917363212.png


2.其次怎么使用环信的appkey ,可以在环信音视频云后台注册一个 账号申请appkey ,可以参考这里 ,获取到  appkey 以后添加到AndroidManifest.xml中 ,如下图所示:

20200409213959916.png


3.经过以上两个重要的前期配置准备 ,接下来我们就可以开始进行代码开发了,首先我们先创建一个项目的DemoApplication类和      DemoHelper类,DemoApplication 类和DemoHelper类都是一个单例类 ,DemoApplication 主要功能就是进行DemoHelper 的初始化,而DemoHelper里面主要是主要有一些option 配置和EMClient 进行初始化,代码如下所示:
public void init(Context context) {
EMOptions options = initChatOptions(context);
EMClient.getInstance().init(context, options);
PreferenceManager.init(context);
}

  DemoHelper还有一个重要的功能就是设置  EMConferenceListener 进行会议监听,有关 EMConferenceListener的类的详细介绍 ,通过这个监听可以再加入会议的时候获取到已经在会议中的流和主播信息,分别是通过其中以下两个回调获取:
@Override 
public void onMemberJoined(EMConferenceMember member){

}

@Override
public void onStreamAdded(EMConferenceStream stream){

}

4.DemoApplication类完成以后,接下来就是怎么去登陆 环信IM 账号和 创建加入会议房间了,首次安装的时候都没有账号,我们使用的办法是自动注册一个账号 在本地进行保存,然后进行登录 ,注册 登录详细接口请看 这儿,  注册 登录的调用大概如下所示: 
 try {
        //注册一个环信ID
        EMClient.getInstance().createAccount(username, password);
            
        //注册成功进行登录
        PreferenceManager.getInstance().setCurrentUserName(username);
        PreferenceManager.getInstance().setCurrentuserPassword(password);
        login();
    } catch (final HyphenateException e) {
       runOnUiThread(new Runnable() {
               public void run() {
                  int errorCode=e.getErrorCode();
                   if(errorCode==EMError.NETWORK_ERROR){
                    Toast.makeText(getApplicationContext(), getResources().getString(R.string.network_anomalies), Toast.LENGTH_SHORT).show();
      }
   }   
}
 
  public void login() {
 
        //登录已经注册成功的环信ID
        EMClient.getInstance().login(username, password, new EMCallBack() {
            @Override
            public void onSuccess() {
                Log.d(TAG, "login: onSuccess");
                //登录成功进入会议房间
                joinRoom();
            }
            @Override
            public void onProgress(int progress, String status) {
                Log.d(TAG, "login: onProgress");
            }
            @Override
            public void onError(final int code, final String message) {
                Log.d(TAG, "login: onError: " + code);
                runOnUiThread(new Runnable() {
                    public void run() {
                        Toast.makeText(getApplicationContext(), getString(R.string.Login_failed) + message,Toast.LENGTH_SHORT).show();
                    }
                });
            }
        });
    }
登录完成以后,我们可以根据房间名创建并加入房间,主要代码大概如下:
 EMClient.getInstance().conferenceManager().joinRoom(currentRoomname, currentPassword, conferenceRole,roomConfig, new EMValueCallBack<EMConference>(){
@Override
public void onSuccess(EMConference value) {
EMLog.i(TAG, "join conference success");
Intent intent = new Intent(MainActivity.this, ConferenceActivity.class);
startActivity(intent);
finish();
}
@Override
public void onError(final int error, final String errorMsg) {
EMLog.e(TAG, "join conference failed error " + error + ", msg " + errorMsg);
runOnUiThread(new Runnable() {
@Override
public void run() {
setBtnEnable(true);
if(error == CALL_TALKER_ISFULL) {
takerFullDialogDisplay();
}else{
Toast.makeText(getApplicationContext(), "Join conference failed " + error + " " + errorMsg, Toast.LENGTH_SHORT).show();
}
}
});
}
});

EMClient.getInstance().conferenceManager().joinRoom() API可以根据房间名创建指定会议,当以该房间名命名的会议不存在时候,会直接创建,当会议已经创建好 可以根据正确的房间名和密码加入房间 ,到这一步为止,我们已经成功的创建 并加入会议。
5.加入会议以后我们进入到会议界面,展示从DemoHelper类 EMConferenceListener 中的 onStreamAdded 回调 和 onMemberJoined 获取到的流和主播列表 ,在ConferenceActivity 中实现 EMConferenceListener ,然后直接把 ConferenceActivity 注册监听,用以下方法  EMClient.getInstance().conferenceManager().addConferenceListener(this); 这样就可实现 EMConferenceListener 事件的处理,比如
 主播 进出房间 :
public void onMemberJoined(final EMConferenceMember member);
public void onMemberExited(final EMConferenceMember member);

增加流 移除流:
public void onStreamAdded(final EMConferenceStream stream)
 public void onStreamRemoved(final EMConferenceStream stream)

管理员变更: 
public void onAdminAdded(String streamId) ;  
public void onAdminRemoved(String streamId)

角色变更  用户被踢  谁在说话等各种回调,可以处理各种业务逻辑 ,详细的请参考 项目中的实现 ,最后会附上项目的开源地址。

6 进入会议房间以后如果用户角色为主播可以进行发布视频流 ,观众只能订阅视频流 不能发布视频流 ,可以调用SDK的publish接口发布流,该接口用到了EMStreamParam参数,你可以自由配置,比如是否上传视频,是否上传音频,使用前置或后置摄像头,视频码率,显示视频页面等等,具体实现可以参考 中发布 订阅视频流的内容, 关于以上的代码逻辑如以 如以下:
 //发布视频流
normalParam = new EMStreamParam();
normalParam.setStreamType(EMConferenceStream.StreamType.NORMAL);
normalParam.setVideoOff(true);
normalParam.setAudioOff(true);

EMClient.getInstance().conferenceManager().publish(normalParam, new EMValueCallBack<String>() {
@Override
public void onSuccess(String value) {
conference.setPubStreamId(value, EMConferenceStream.StreamType.NORMAL);
addOrUpdateStreamList("local-stream", value);

PhoneStateManager.get(ConferenceActivity.this).addStateCallback(phoneStateCallback);
}

@Override
public void onError(int error, String errorMsg) {
EMLog.i(TAG, "publish failed: error=" + error + ", msg=" + errorMsg);
}
});
//订阅其他主播的视频流
private void subscribe(EMConferenceStream stream, EMCallSurfaceView surfaceView) {
EMClient.getInstance().conferenceManager().subscribe(stream, surfaceView, new EMValueCallBack<String>() {
@Override
public void onSuccess(String value) {
}

@Override
public void onError(int error, String errorMsg) {

}
});
}

7.有关上麦 下麦 的逻辑处理,观众可以请求上麦成为主播,主播可以下麦成为观众,上麦 下麦 是利用 EMConferenceAttribute进行处理 ,EMConferenceAttribute  是一个事件广播,广播事件是一个key-value格式,key-value 可以由开发者进行自行定义,增添事件以后 ,服务器会把事件进行广播。会议中成员会收到 onAttributesUpdated回调。例如本项目中的会议上麦 下麦 代码如下所示:
//上麦申请  

EMClient.getInstance().conferenceManager().setConferenceAttribute(
EMClient.getInstance().getCurrentUser(),
"request_tobe_speaker",
new EMValueCallBack<Void>() {
@Override
public void onSuccess(Void value) {
EMLog.i(TAG, "request_tobe_speaker scuessed");

}

@Override
public void onError(int error, String errorMsg) {
EMLog.i(TAG, "request_tobe_speaker failed: error=" + error

}
});

//下麦申请
EMClient.getInstance().conferenceManager().setConferenceAttribute(EMClient.getInstance().getCurrentUser()
, "request_tobe_audience", new EMValueCallBack<Void>() {
@Override
public void onSuccess(Void value) {
EMLog.i(TAG, "request_tobe_audience scuessed");
}

@Override
public void onError(int error, String errorMsg) {
EMLog.i(TAG, "request_tobe_audience failed: error=" + error + ", msg=" + errorMsg);
}
});

 上麦 下麦 请求发出以后 只能由主持人去处理,处理在 EMConferenceListener  的回调 onAttributesUpdated(EMConferenceAttribute attributes) 去处理 ,收到回调以后 解析attributes 然后进行处理请求,处理的过程代码大概如下:
   EMClient.getInstance().conferenceManager().grantRole(conference.getConferenceId()
, new EMConferenceMember(memName, null, null,null)
, EMConferenceManager.EMConferenceRole.Talker, new EMValueCallBack<String>() {
@Override
public void onSuccess(String value) {
EMLog.i(TAG, " requestTalkerDisplay request_tobe_speaker changeRole success, result: " + value);
dialog.dismiss();
}
@Override
public void onError(int error, String errorMsg) {
EMLog.i(TAG, " requestTalkerDisplay request_tobe_speaker changeRole failed, error: " + error + " - " + errorMsg);

}
});

下麦也是和上麦一样是利用 EMConferenceAttribute进行处理。

9.有关退出会议 销毁会议 普通主播  观众只能退出会议 ,主持人还可以 销毁会议 正在进行中的会议可以进行销毁,退出会议 销毁会议 具体代码如下:
 EMClient.getInstance().conferenceManager().exitConference(new EMValueCallBack() {
@Override
public void onSuccess(Object value) {
runOnUiThread(new Runnable() {
@Override
public void run() {
Toast.makeText(getApplicationContext(), "您已成功退出当前会议!", Toast.LENGTH_SHORT).show();
}
});
}

@Override
public void onError(int error, String errorMsg) {
EMLog.i(TAG, "exit conference failed " + error + ", " + errorMsg);
}
});

EMClient.getInstance().conferenceManager().destroyConference(new EMValueCallBack() {
@Override
public void onSuccess(Object value) {
runOnUiThread(new Runnable() {
@Override
public void run() {
Toast.makeText(getApplicationContext(), "您已成功销毁当前会议!", Toast.LENGTH_SHORT).show();
}
});
EMLog.i(TAG, "finish ConferenceActivity");
finish();
}

尾语
至此 整个 多人音视频会议开发的详细步骤 已经完成 ,虽然比较麻烦 但是每个步骤都很清晰 ,有不太清楚的欢迎大家积极讨论, 附上本项目的github地址:https://github.com/easemob/videocall-android  欢迎大家积极参与 ,谢谢支持。
Demo下载 二维码如下 欢迎大家体验(iOS版和web版下载地址请见:https://www.easemob.com/download/rtc)


20200410142228530.png

 
0
评论

如何用 30 天入门年薪 30 万的技术领域? 技术 深度学习

sunshine123 发表了文章 • 567 次浏览 • 2019-10-08 17:18 • 来自相关话题

2016年3月15日,人机大战第五场在韩国首尔进行,经过长达5个小时搏杀,李世石认输,最终李世石与AlphaGo总比分定格在1比4。
值得注意的是:李世石仅在3月15日结束的第四场对战中取得了唯一的一场胜利。而支撑机器取胜的核心技术,就是深度学习。
自此之后,深度学习开始逐渐进入大家的视野。

01
什么是深度学习?

深度学习其实是机器学习(Machine Learning)的一个分支学科,而机器学习主要是研究数据之言的关系的,比如它可以用来分析性别、年龄、学历、职业等因素之间的数学关系。
显而易见,这些因果关系并不是一个简单的线性关系就能解决的。但是深度学习通过多非线性模型表示数据之间的关系,从而确定数据之间的相互关系是什么。

02
深度学习已经融入到了人们的日常生活中

现在汽车的自动驾驶、短信邮件的自动回复、扫地机器人,以及在围棋中击败最优秀人类选手的软件,都应用到了深度学习。甚至骚扰电话,也有很多是AI机器人打过来的,可能电话那头和你聊得正酣、声音甜美的客服妹子只是一串代码。
因此,阿里达摩院的工程师们,受不了骚扰骚扰电话的骚扰,发起了“二哈”AI,让机器人与骚扰电话自动聊天。
大家感受一下这对话画风





 
总之,AI机器人的骚扰电话,正在用AI进行解决。

03

可能是编程领域薪资最高的岗位

而与此同时学习深度学习的人也开始变得多了起来,但由于深度学习涉及面比较广,很多学者会对此望而却步。然而如果学好深度学习,不仅仅可以给你带来高薪资,也有可能会给你带来很多的荣誉!因为在此领域还是非常缺乏人才的!
大家可以看一份数据





 
平均月薪已达到3w,年薪36w。





 
就应届生深度学习岗的薪资,都已经达到了很多其他互联网职业3年工作经验都难以企及的水平。
现在各个大厂,也都有深度学习相关的项目,而且待遇方面也是极其的诱人。
百度推出“少帅计划”,针对30岁以下的深度学习科学家,开出100万以上年薪
阿里巴巴对外宣布将通过校园招聘组建一支规模达数百人的 NASA“青年军”
华为更是开出200万年薪招聘应届毕业生,其专业均为最前沿的人工智能领域
作为一个有追求的程序员,相信你在脑海中闪过无数次这样的疑问:如何掌握深度学习?

04

如何掌握深度学习?

目前市场对于深度学习的需求,早已出现供不应求的现象,但太多工程师想入门或者转行却不知从何开始,很多初学者都会有这样的困惑:
一边要熟练掌握线性代数、矩阵计算,一边还要搞概率论
一边要去研究各种库与框架,一边学习如何在用编程语言实现算法
一边学习如何制作数据集、特征提取,一边微调参数,选择合适的算法
这样一轮下来,深度学习还没有开始就已经走上了放弃之路。
放眼网上现有的一些深度学习课程,经常会发现有些知识点覆盖不全,或者学习门槛较高,研究性的问题不多,或者说只关注面试,而忽略了底层的逻辑以及真实案例的实操。
因此,我们通上百名深度学习用户的调研,与老师花费上千小时的时间,提炼了102节精华课程。
我们希望通过“从零开始深度学习”这门课程,让你0基础入门深度学习,建立起完整的学习路径,同时通过“智能问答模型”的实战案例,将所学知识学以致用。
#购课即送王海良老师在京东原价69的《智能问答与深度学习》实体书一本#

讲师介绍
王海良:Chatopera联合创始人&CEO,微软人工智能最有价值专家,先后工作于IBM软件开发实验室和创新中心。
李卓桓:25年编程经验,曾任优酷网首席科学家、叽歪网创始人,水木清华BBS站长,紫霞BBS站长。
林旭鸣:北京邮电大学模式识别实验室研究生,任职阿里巴巴的阿里小蜜团队。
陈可心:香港大学硕士,任职经历包括:微软中国、今日头条研发中心,联想香港人工智能中心以及联合国亚太分部。
李思珍:现任职今日头条,主要工作实现人机交互系统的意图识别和关键词优化。

#课程介绍#
相信很多小伙伴,在入门深度学习的路上,会被一些数据基础搞得犯怵,搭建环境的时候也许会遇到很多坑。
因此,我们把课程分为五个模块:数学基础、Python编程语言基础、深度学习初步、深度学习深化、智能问答模型实践,带你一探深度学习的究竟,希望你通过此次学习,不仅掌握原理更能动手实操。
除了上述102节视频课程,我们还为这次课程搭配了书籍《深度学习与智能问答》,一边跟着视频实操,一边阅读书籍巩固,学习效果double~





 
如何保证你的学习效果?
由基础的数学学习开始,逐渐建立完整的深度学习知识体系
五大模块,由知识学习到真实案例的实践
购课送原价69元深度学习实体书,边学边读,加深记忆
建立一个互助、监督的高效学习社群,随时交流问题

购课须知
本课程包含哪些内容?
包含102节视频课(20+小时)+实体书(京东原价69)

上课形式是怎样的?
课程授课形式为:视频+群答疑

#如何报名#
限时特惠:99元(原价199元)
拼团特惠69元~
图书(含邮寄) + 100+节视频课程,每课仅需6毛钱

扫码立即抢购!
平均一天2元,就是一瓶水钱
坚持30天,换你一次进入高薪技术领域的机会
如果对课程有疑问
欢迎扫码回复“1”进课程咨询群





 
 
  查看全部
2016年3月15日,人机大战第五场在韩国首尔进行,经过长达5个小时搏杀,李世石认输,最终李世石与AlphaGo总比分定格在1比4。
值得注意的是:李世石仅在3月15日结束的第四场对战中取得了唯一的一场胜利。而支撑机器取胜的核心技术,就是深度学习。
自此之后,深度学习开始逐渐进入大家的视野。

01
什么是深度学习?


深度学习其实是机器学习(Machine Learning)的一个分支学科,而机器学习主要是研究数据之言的关系的,比如它可以用来分析性别、年龄、学历、职业等因素之间的数学关系。
显而易见,这些因果关系并不是一个简单的线性关系就能解决的。但是深度学习通过多非线性模型表示数据之间的关系,从而确定数据之间的相互关系是什么。

02
深度学习已经融入到了人们的日常生活中


现在汽车的自动驾驶、短信邮件的自动回复、扫地机器人,以及在围棋中击败最优秀人类选手的软件,都应用到了深度学习。甚至骚扰电话,也有很多是AI机器人打过来的,可能电话那头和你聊得正酣、声音甜美的客服妹子只是一串代码。
因此,阿里达摩院的工程师们,受不了骚扰骚扰电话的骚扰,发起了“二哈”AI,让机器人与骚扰电话自动聊天。
大家感受一下这对话画风

1.gif

 
总之,AI机器人的骚扰电话,正在用AI进行解决。

03

可能是编程领域薪资最高的岗位


而与此同时学习深度学习的人也开始变得多了起来,但由于深度学习涉及面比较广,很多学者会对此望而却步。然而如果学好深度学习,不仅仅可以给你带来高薪资,也有可能会给你带来很多的荣誉!因为在此领域还是非常缺乏人才的!
大家可以看一份数据

2.png

 
平均月薪已达到3w,年薪36w。

4.png

 
就应届生深度学习岗的薪资,都已经达到了很多其他互联网职业3年工作经验都难以企及的水平。
现在各个大厂,也都有深度学习相关的项目,而且待遇方面也是极其的诱人。
百度推出“少帅计划”,针对30岁以下的深度学习科学家,开出100万以上年薪
阿里巴巴对外宣布将通过校园招聘组建一支规模达数百人的 NASA“青年军”
华为更是开出200万年薪招聘应届毕业生,其专业均为最前沿的人工智能领域
作为一个有追求的程序员,相信你在脑海中闪过无数次这样的疑问:如何掌握深度学习?

04

如何掌握深度学习?


目前市场对于深度学习的需求,早已出现供不应求的现象,但太多工程师想入门或者转行却不知从何开始,很多初学者都会有这样的困惑:
一边要熟练掌握线性代数、矩阵计算,一边还要搞概率论
一边要去研究各种库与框架,一边学习如何在用编程语言实现算法
一边学习如何制作数据集、特征提取,一边微调参数,选择合适的算法
这样一轮下来,深度学习还没有开始就已经走上了放弃之路。
放眼网上现有的一些深度学习课程,经常会发现有些知识点覆盖不全,或者学习门槛较高,研究性的问题不多,或者说只关注面试,而忽略了底层的逻辑以及真实案例的实操。
因此,我们通上百名深度学习用户的调研,与老师花费上千小时的时间,提炼了102节精华课程。
我们希望通过“从零开始深度学习”这门课程,让你0基础入门深度学习,建立起完整的学习路径,同时通过“智能问答模型”的实战案例,将所学知识学以致用。
#购课即送王海良老师在京东原价69的《智能问答与深度学习》实体书一本#

讲师介绍
王海良:Chatopera联合创始人&CEO,微软人工智能最有价值专家,先后工作于IBM软件开发实验室和创新中心。
李卓桓:25年编程经验,曾任优酷网首席科学家、叽歪网创始人,水木清华BBS站长,紫霞BBS站长。
林旭鸣:北京邮电大学模式识别实验室研究生,任职阿里巴巴的阿里小蜜团队。
陈可心:香港大学硕士,任职经历包括:微软中国、今日头条研发中心,联想香港人工智能中心以及联合国亚太分部。
李思珍:现任职今日头条,主要工作实现人机交互系统的意图识别和关键词优化。

#课程介绍#
相信很多小伙伴,在入门深度学习的路上,会被一些数据基础搞得犯怵,搭建环境的时候也许会遇到很多坑。
因此,我们把课程分为五个模块:数学基础、Python编程语言基础、深度学习初步、深度学习深化、智能问答模型实践,带你一探深度学习的究竟,希望你通过此次学习,不仅掌握原理更能动手实操。
除了上述102节视频课程,我们还为这次课程搭配了书籍《深度学习与智能问答》,一边跟着视频实操,一边阅读书籍巩固,学习效果double~

5.jpg

 
如何保证你的学习效果?
由基础的数学学习开始,逐渐建立完整的深度学习知识体系
五大模块,由知识学习到真实案例的实践
购课送原价69元深度学习实体书,边学边读,加深记忆
建立一个互助、监督的高效学习社群,随时交流问题

购课须知
本课程包含哪些内容?
包含102节视频课(20+小时)+实体书(京东原价69)

上课形式是怎样的?
课程授课形式为:视频+群答疑

#如何报名#
限时特惠:99元(原价199元)
拼团特惠69元~
图书(含邮寄) + 100+节视频课程,每课仅需6毛钱

扫码立即抢购!
平均一天2元,就是一瓶水钱
坚持30天,换你一次进入高薪技术领域的机会
如果对课程有疑问
欢迎扫码回复“1”进课程咨询群

6.jpg