Android平臺下通過JNI快速實現音視頻通信

音視頻通信

作爲獨立開發者或想縮短音視頻開發週期的公司來說,想要在Android平臺下實現音視頻通信,最快捷的方法是尋找開源項目或調用其他公司API。之所以這麼說是因爲音視頻通信技術涉及到底層音視頻採集、解碼、 FFmpeg(音視頻處理解決方案)、媒體流傳輸協議等太多太多相關技術知識點。試了 幾個開源項目,視頻差強人意,語音與視頻不同步等不穩定因素。因此我把目光放到其他公司的API上(點擊下載demo程序)。demo程序API提供了一系列純Java語言的調用接口,通過JNI即可調用內核共享庫(.so 類似win32 的dll),根據官方開發文檔我很快就實現音視頻通信,下面是我在調用其API的經驗總結。視頻效果圖如下:

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程序參考。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章