1. 程式人生 > >android視訊通話

android視訊通話

最近學習Android平臺下跨平臺音視訊通訊開發,雖然網上有很多開源專案供我們參考學習,但音視訊效果很一般,還有很多不穩定的因素,畢竟是開源嘛。在國內我找到了一個比較好音視訊通訊解決方案(點選下載官方demo),該案例提供了純Java語言介面供我們呼叫,隨後我參照官方android demo程式和開發文件並結合自己的見解寫了一個android音訊通訊軟體,200行以內程式碼就搞定了(難以相信吧)。其實我只是呼叫其相關API即可實現。以下是我自己寫的Java程式碼,以備大家互相學習:

Java程式碼
  1. /**  
  2.  * Android視訊聊天   
  3.  * 1、初始化SDK 2、連線伺服器、 3、使用者登入;4、進入房間;5、開啟本地視訊;6、請求對方視訊
     
  4.  */
  5. publicclass VideoChatActivity extends Activity implements AnyChatBaseEvent   
  6. {   
  7. private AnyChatCoreSDK anychat;         // 核心SDK
  8. private SurfaceView remoteSurfaceView;  // 對方視訊
  9. private SurfaceView localSurfaceView;   // 本地視訊
  10. private ConfigEntity configEntity;   
  11. privateboolean bSelfVideoOpened = false;   
    // 本地視訊是否已開啟
  12. privateboolean bOtherVideoOpened = false;  // 對方視訊是否已開啟
  13. private TimerTask mTimerTask;               // 定時器
  14. private Timer mTimer = new Timer(true);   
  15. private Handler handler;                    // 用Handler來不間斷重新整理即時視訊
  16. private List<String> userlist = new ArrayList<String>();//儲存線上使用者列表
  17. private
    int userid;                         // 使用者ID
  18. @Override
  19. publicvoid onCreate(Bundle savedInstanceState)   
  20.     {   
  21. super.onCreate(savedInstanceState);   
  22.         setContentView(R.layout.activity_video_chat);   
  23.         remoteSurfaceView = (SurfaceView) findViewById(R.id.surface_remote);   
  24.         localSurfaceView = (SurfaceView) findViewById(R.id.surface_local);   
  25.         configEntity = ConfigService.LoadConfig(this);//載入視訊通話設定
  26.         loginSystem();// 初始化SDK 連線伺服器
  27.         mTimerTask = new TimerTask(){   
  28. publicvoid run(){   
  29.                 Message mesasge = new Message();   
  30.                 handler.sendMessage(mesasge);   
  31.             }   
  32.         };   
  33.         mTimer.schedule(mTimerTask, 1000100);   
  34.         handler = new Handler(){   
  35. @Override
  36. publicvoid handleMessage(Message msg){   
  37.                 VideoChat();// 不間斷顯示即時視訊通話畫面
  38. super.handleMessage(msg);   
  39.             }   
  40.         };   
  41.     }   
  42. // 初始化SDK 連線伺服器
  43. privatevoid loginSystem(){   
  44. if (anychat == null){   
  45.             anychat = new AnyChatCoreSDK();   
  46.             anychat.SetBaseEvent(this);         // 設定基本事件回撥函式
  47. if (configEntity.useARMv6Lib != 0)  // 使用ARMv6指令集
  48.                 anychat.SetSDKOptionInt(AnyChatDefine.   
  49.                         BRAC_SO_CORESDK_USEARMV6LIB, 1);   
  50.             anychat.InitSDK(android.os.Build.VERSION.SDK_INT, 0); // 初始化SDK
  51.         }   
  52.         anychat.Connect("demo.anychat.cn"8906);// 連線伺服器
  53.     }   
  54. // 顯示即時視訊通話畫面
  55. publicvoid VideoChat(){   
  56. if (!bOtherVideoOpened){   
  57. if (anychat.GetCameraState(userid) == 2
  58.                     && anychat.GetUserVideoWidth(userid) != 0){   
  59.                 SurfaceHolder holder = remoteSurfaceView.getHolder();   
  60.                 holder.setFormat(PixelFormat.RGB_565);   
  61.                 holder.setFixedSize(anychat.GetUserVideoWidth(userid),   
  62.                         anychat.GetUserVideoHeight(userid));   
  63.                 Surface s = holder.getSurface();            // 獲得視訊畫面
  64.                 anychat.SetVideoPos(userid, s, 0000); // 呼叫API顯示視訊畫面
  65.                 bOtherVideoOpened = true;   
  66.             }   
  67.         }   
  68. if (!bSelfVideoOpened){   
  69. if (anychat.GetCameraState(-1) == 2
  70.                     && anychat.GetUserVideoWidth(-1) != 0){   
  71.                 SurfaceHolder holder = localSurfaceView.getHolder();   
  72.                 holder.setFormat(PixelFormat.RGB_565);   
  73.                 holder.setFixedSize(anychat.GetUserVideoWidth(-1),   
  74.                         anychat.GetUserVideoHeight(-1));   
  75.                 Surface s = holder.getSurface();   
  76.                 anychat.SetVideoPos(-1, s, 0000);   
  77.                 bSelfVideoOpened = true;   
  78.             }   
  79.         }   
  80.     }   
  81. publicvoid OnAnyChatConnectMessage(boolean bSuccess){   
  82. if (!bSuccess){   
  83.             Toast.makeText(VideoChatActivity.this"連線伺服器失敗,自動重連,請稍後...", Toast.LENGTH_SHORT).show();   
  84.         }   
  85.         anychat.Login("android""");               // 伺服器連線成功 使用者登入
  86.     }   
  87. publicvoid OnAnyChatLoginMessage(int dwUserId, int dwErrorCode){   
  88. if (dwErrorCode == 0) {   
  89.             Toast.makeText(this"登入成功!", Toast.LENGTH_SHORT).show();   
  90.             anychat.EnterRoom(1"");               // 使用者登入成功 進入房間
  91.             ApplyVideoConfig();   
  92.         } else {   
  93.             Toast.makeText(this"登入失敗,錯誤程式碼:" + dwErrorCode, Toast.LENGTH_SHORT).show();   
  94.         }   
  95.     }   
  96. publicvoid OnAnyChatEnterRoomMessage(int dwRoomId, int dwErrorCode){   
  97. if (dwErrorCode == 0) {                     // 進入房間成功  開啟本地音視訊
  98.             Toast.makeText(this"進入房間成功", Toast.LENGTH_SHORT).show();   
  99.             anychat.UserCameraControl(-11);       // 開啟本地視訊
  100.             anychat.UserSpeakControl(-11);        // 開啟本地音訊
  101.         } else {   
  102.             Toast.makeText(this"進入房間失敗,錯誤程式碼:" + dwErrorCode, Toast.LENGTH_SHORT).show();   
  103.         }   
  104.     }   
  105. publicvoid OnAnyChatOnlineUserMessage(int dwUserNum, int dwRoomId){   
  106. if (dwRoomId == 1){   
  107. int user[] = anychat.GetOnlineUser();   
  108. if (user.length != 0){   
  109. for (int i = 0; i < user.length; i++){   
  110.                     userlist.add(user[i]+"");   
  111.                 }   
  112.                 String temp =userlist.get(0);   
  113.                 userid = Integer.parseInt(temp);   
  114.                 anychat.UserCameraControl(userid, 1);// 請求使用者視訊
  115.                 anychat.UserSpeakControl(userid, 1); // 請求使用者音訊
  116.             }   
  117. else {   
  118.                 Toast.makeText(VideoChatActivity.this"當前沒有線上使用者", Toast.LENGTH_SHORT).show();   
  119.             }   
  120.         }   
  121.     }   
  122. publicvoid OnAnyChatUserAtRoomMessage(int dwUserId, boolean bEnter){   
  123. if (bEnter) {//新使用者進入房間
  124.             userlist.add(dwUserId+"");   
  125.         }   
  126. else {       //使用者離開房間
  127. if (dwUserId == userid)   
  128.             {   
  129.                 Toast.makeText(VideoChatActivity.this"視訊使用者已下線", Toast.LENGTH_SHORT).show();   
  130.                 anychat.UserCameraControl(userid, 0);// 關閉使用者視訊
  131.                 anychat.UserSpeakControl(userid, 0); // 關閉使用者音訊
  132.                 userlist.remove(userid+"");          //移除該使用者
  133. if (userlist.size() != 0)   
  134.                 {   
  135.                     String temp =userlist.get(0);   
  136.                     userid = Integer.parseInt(temp);   
  137.                     anychat.UserCameraControl(userid, 1);// 請求其他使用者視訊
  138.                     anychat.UserSpeakControl(userid, 1); // 請求其他使用者音訊
  139.                 }   
  140.             }   
  141. else {   
  142.                 userlist.remove(dwUserId+"");    //移除該使用者
  143.             }   
  144.         }   
  145.     }   
  146. publicvoid OnAnyChatLinkCloseMessage(int dwErrorCode){   
  147.         Toast.makeText(VideoChatActivity.this"連線關閉,error:" + dwErrorCode, Toast.LENGTH_SHORT).show();   
  148.     }   
  149. @Override
  150. protectedvoid onDestroy(){ //程式退出 
  151.         anychat.LeaveRoom(-1);  //離開房間 
  152.         anychat.Logout();       //登出登入 
  153.         anychat.Release();      //釋放資源
  154.         mTimer.cancel();   
  155. super.onDestroy();   
  156.     }   
  157. // 根據配置檔案配置視訊引數
  158. privatevoid ApplyVideoConfig(){   
  159. if (configEntity.configMode == 1// 自定義視訊引數配置
  160.         {   
  161. // 設定本地視訊編碼的位元速率(如果位元速率為0,則表示使用質量優先模式)
  162.             anychat.SetSDKOptionInt(AnyChatDefine.BRAC_SO_LOCALVIDEO_BITRATECTRL,configEntity.videoBitrate);   
  163. if (configEntity.videoBitrate == 0)   
  164.             {   
  165. // 設定本地視訊編碼的質量
  166.                 anychat.SetSDKOptionInt(AnyChatDefine.BRAC_SO_LOCALVIDEO_QUALITYCTRL,configEntity.videoQuality);   
  167.             }   
  168. // 設定本地視訊編碼的幀率
  169.             anychat.SetSDKOptionInt(AnyChatDefine.BRAC_SO_LOCALVIDEO_FPSCTRL,configEntity.videoFps);   
  170. // 設定本地視訊編碼的關鍵幀間隔
  171.             anychat.SetSDKOptionInt(AnyChatDefine.BRAC_SO_LOCALVIDEO_GOPCTRL,configEntity.videoFps * 4);   
  172. // 設定本地視訊採集解析度
  173.             anychat.SetSDKOptionInt(AnyChatDefine.BRAC_SO_LOCALVIDEO_WIDTHCTRL,configEntity.resolution_width);   
  174.             anychat.SetSDKOptionInt(AnyChatDefine.BRAC_SO_LOCALVIDEO_HEIGHTCTRL,configEntity.resolution_height);   
  175. // 設定視訊編碼預設引數(值越大,編碼質量越高,佔用CPU資源也會越高)
  176.             anychat.SetSDKOptionInt(AnyChatDefine.BRAC_SO_LOCALVIDEO_PRESETCTRL,configEntity.videoPreset);   
  177.         }   
  178. // 讓視訊引數生效
  179.         anychat.SetSDKOptionInt(AnyChatDefine.BRAC_SO_LOCALVIDEO_APPLYPARAM,configEntity.configMode);   
  180. // P2P設定
  181.         anychat.SetSDKOptionInt(AnyChatDefine.BRAC_SO_NETWORK_P2PPOLITIC,configEntity.enableP2P);   
  182. // 本地視訊Overlay模式設定
  183.         anychat.SetSDKOptionInt(AnyChatDefine.BRAC_SO_LOCALVIDEO_OVERLAY,configEntity.videoOverlay);   
  184. // 迴音消除設定
  185.         anychat.SetSDKOptionInt(AnyChatDefine.BRAC_SO_AUDIO_ECHOCTRL,configEntity.enableAEC);   
  186. // 平臺硬體編碼設定
  187.         anychat.SetSDKOptionInt(AnyChatDefine.BRAC_SO_CORESDK_USEHWCODEC,configEntity.useHWCodec);   
  188. // 視訊旋轉模式設定
  189.         anychat.SetSDKOptionInt(AnyChatDefine.BRAC_SO_LOCALVIDEO_ROTATECTRL,configEntity.videorotatemode);   
  190. // 視訊平滑播放模式設定
  191.         anychat.SetSDKOptionInt(AnyChatDefine.BRAC_SO_STREAM_SMOOTHPLAYMODE,configEntity.smoothPlayMode);   
  192. // 視訊採集驅動設定
  193.         anychat.SetSDKOptionInt(AnyChatDefine.BRAC_SO_LOCALVIDEO_CAPDRIVER,configEntity.videoCapDriver);   
  194. // 本地視訊採集偏色修正設定
  195.         anychat.SetSDKOptionInt(AnyChatDefine.BRAC_SO_LOCALVIDEO_FIXCOLORDEVIA,configEntity.fixcolordeviation);   
  196. // 視訊顯示驅動設定
  197.         anychat.SetSDKOptionInt(AnyChatDefine.BRAC_SO_VIDEOSHOW_DRIVERCTRL,configEntity.videoShowDriver);   
  198.     }   
  199. }    

詳細看了官方的開發文件你會發現,該Android音視訊解決方案還有文字聊天、傳送檔案、P2P連線等非常實用的功能。對於開發者來說,能快速實現類似QQ聊天和音視訊通訊是令人振奮的事情。如有不懂可以加QQ討論:992139738;附上我寫的demo程式供參考學習,效果圖檢視圖片附件