音视频通信

作为独立开发者或想缩短音视频开发周期的公司来说,想要在Android平台下实现音视频通信,最快捷的方法是寻找开源项目或调用其他公司API。之所以这么说是因为音视频通信技术涉及到底层音视频采集、解码、 FFmpeg(音视频处理解决方案)、媒体流传输协议等太多太多相关技术知识点。试了 几个开源项目,视频差强人意,语音与视频不同步等不稳定因素。因此我把目光放到其他公司的API上(点击下载demo程序)。demo程序API提供了一系列纯Java语言的调用接口,通过JNI即可调用内核共享库(.so 类似win32 的dll),根据官方开发文档我很快就实现音视频通信,下面是我在调用其API的经验总结。视频效果图如下:

调用API在Android平台下实现音视频通信_第1张图片

Android通信平台相关API方法

   
   
   
   
  1. // 初始化SDK  
  2.     public native int InitSDK(int osver, int flags);  
  3.     // 连接服务器  
  4.     public native int Connect(String serverip, int port);  
  5.     // 登录系统  
  6.     public native int Login(String username, String password);  
  7.     // 进入房间(房间ID)  
  8.     public native int EnterRoom(int roomid, String password);  
  9.     // 进入房间(房间名称)  
  10.     public native int EnterRoomEx(String roomname, String password);  
  11.     // 退出房间  
  12.     public native int LeaveRoom(int roomid);  
  13.     // 设置视频显示位置  
  14.     public native int SetVideoPos(int userid, Surface surface, int lef,  
  15.             int top, int right, int bottom);  
  16.     /**  
  17.      * 功能: 设置视频显示位置,或是刷新视频显示 返回值:0表示成功,否则为出错代码   
  18.      * 参数:   
  19.      * userid  用户ID   
  20.      * surface 视频显示界面,android客户端只需提供SurfaceView控件,内核自动将视频显示在控件上  
  21.      * lef,top,right,bottom视频显示位置信息  
  22.      */ 
  23.     // 注销登录  
  24.     public native int Logout();  
  25.     // 释放资源  
  26.     public native int Release(); 

一、初始化SDK

初始化SDK是首先要完成的,用于设置SDK的一些行为,包括设置对应的回调函数。代码如下:

   
   
   
   
  1. //初始化SDK  
  2.     private void InitialSDK() {  
  3.         if (anychat == null) {  
  4.             anychat = new AnyChatCoreSDK();  
  5.             //设置基本事件回调函数  
  6.             anychat.SetBaseEvent(this);  
  7.             if (configEntity.useARMv6Lib != 0)  
  8.                 anychat.SetSDKOptionInt(AnyChatDefine.  
  9.                         BRAC_SO_CORESDK_USEARMV6LIB, 1);            //使用ARMv6指令集  
  10.             anychat.InitSDK(android.os.Build.VERSION.SDK_INT, 0);   //初始化SDK 的一个参数是android API版本  
  11.             bNeedRelease = true;  
  12.         }  
  13.     } 

二、登录系统

当初始化SDK完成之后,便可以实现连接服务器、验证用户身份、用户登录等。

   
   
   
   
  1. //连接服务器  
  2.         anychat.Connect("211.155.25.90"8906);  
  3.         //登录系统  
  4.         anychat.Login("android",""); 

连接服务器和登录系统都是一个异步的过程,调用后会立即返回。在回调函数中根据返回代码判断服务器是否连接成功和登录成功。

三、进入房间

登录成功后就可进入相应的房间,只有在相同房间的用户才能进行音视频通信。代码如下

1、进入房间

   
   
   
   
  1. //进入1号房间  
  2. anychat.EnterRoom(1"");    

进入房间后系统会将该房间在线用户发送给客户端,只有在同一个房间用户才能进行音视频互交、文字聊天、文件传输等。当新用户进入房间或用户下线,都会触发异步消息通知上层应用更改状态。

2、文字聊天

成功进入房间后,便可调用API接口向指定用户或房间中所有在线用户发送文字 聊天消息。

   
   
   
   
  1. //发送文字聊天消息  
  2.         String message = messageEditText.getText().toString();  
  3.         anychat.SendTextMessage(-10,message); 

其他用户收到文字聊天消息会触发相应的回调函数并将聊天消息显示在界面上。

3、请求其他用户的音视频

   
   
   
   
  1. // 请求对方的视频流   
  2.         anychat.UserCameraControl(userID, 1);  
  3.         // 请求对方的音频流   
  4.         anychat.UserSpeakControl(userID, 1); 

4、音视频的显示与播放

   
   
   
   
  1. //判断远程用户视频是否已打开  
  2.         if (!bOtherVideoOpened) {  
  3.             if (anychat.GetCameraState(userID) == 2 
  4.                     && anychat.GetUserVideoWidth(userID) != 0) {  
  5.                 SurfaceHolder holder = otherView.getHolder();   //获得SurfaceView控件  
  6.                 holder.setFormat(PixelFormat.RGB_565);          //设置显示格式  
  7.                 holder.setFixedSize(anychat.GetUserVideoWidth(userID),  
  8.                         anychat.GetUserVideoHeight(userID));    //设置视频显示宽高  
  9.                 Surface s = holder.getSurface();                //获得视频画面  
  10.                 anychat.SetVideoPos(userID, s, 0000);     //调用API显示视频画面  
  11.                 bOtherVideoOpened = true;  
  12.             }  
  13.         }  
  14.         //判断本地视频是否已打开  
  15.         if (!bSelfVideoOpened) {  
  16.             if (anychat.GetCameraState(-1) == 2 
  17.                     && anychat.GetUserVideoWidth(-1) != 0) {  
  18.                 SurfaceHolder holder = myView.getHolder();      //获得SurfaceView控件  
  19.                 holder.setFormat(PixelFormat.RGB_565);          //设置显示格式  
  20.                 holder.setFixedSize(anychat.GetUserVideoWidth(-1),  
  21.                         anychat.GetUserVideoHeight(-1));        //设置视频显示宽高  
  22.                 Surface s = holder.getSurface();                //获得视频画面  
  23.                 anychat.SetVideoPos(-1, s, 0000);         //调用API显示视频画面  
  24.                 bSelfVideoOpened = true;  
  25.             }  
  26.         } 

Android程序中,当收到用户的媒体流数据时,Android客户端只需提供一个SurfaceView控件,内核自动将视频媒体流数据显示在该控件上并播放声音。

四、释放资源

与前面讲的连接服务器、登录系统、进入房间对应的的是离开房间、注销系统、释放资源。代码如下:

   
   
   
   
  1. protected void onDestroy() {  
  2.     //离开房间  
  3.     anychat.LeaveRoom(-1);  
  4.     //注销登录  
  5.     anychat.Logout();  
  6.     //释放资源 关闭SDK 不再返回登录界面  
  7.     anychat.Release(); 
  8. }

离开房间后可再进入房间,但是注销登录和释放资源后,SDK将不再工作。在Activity生命周期结束的时候可以将占用资源释放,程序退出。

总结:还有其他诸如发送文件、P2P连接、对Android设备设置、获取在线用户等非常实用功能等待你们去挖掘。用java我们也能快速实现音视频通信。如有不懂可以联系我QQ:992139738讨论或到官网下载demo程序参考。