目录

android-音视频通信Demo

目录

android 音视频通信Demo

最近学习Android平台下跨平台音视频通信开发,虽然网上有很多开源项目供我们参考学习,但音视频效果很一般,还有很多不稳定的因素,毕竟是开源嘛。在国内我找到了一个比较好音视频通信解决方案(百度下载官方Anychat demo),该案例提供了纯Java语言接口供我们调用,随后我参照官方android demo程序和开发文档并结合自己的见解写了一个android音频通信

,200行以内代码就搞定了(难以相信吧)。其实我只是调用其相关API即可实现。以下是我自己写的Java代码,以备大家互相学习:

  1. 1./**
      • Android**天
      • 1、初始化SDK 2、连接服务器、 3、用户登录;4、进入房间;5、打开本地视频;6、请求对方视频
    1. */
  2. 5.public class VideoChatActivity extends Activity implements AnyChatBaseEvent
  3. 6.{
  4. 7.    private AnyChatCoreSDK anychat;         // 核心SDK
  5. 8.    private SurfaceView remoteSurfaceView;  // 对方视频
  6. 9.    private SurfaceView localSurfaceView;   // 本地视频
  7. 10.    private ConfigEntity configEntity;
  8. 11.    private boolean bSelfVideoOpened = false;   // 本地视频是否已打开
  9. 12.    private boolean bOtherVideoOpened = false;  // 对方视频是否已打开
  10. 13.    private TimerTask mTimerTask;               // 定时器
  11. 14.    private Timer mTimer = new Timer(true);
  12. 15.    private Handler handler;                    // 用Handler来不间断刷新即时视频
  13. 16.    private List userlist = new ArrayList();//保存在线用户列表
  14. 17.    private int userid;                         // 用户ID
  15. 18.    @Override
  16. 19.    public void onCreate(Bundle savedInstanceState)
  17. 20.    {
  18. 21.        super.onCreate(savedInstanceState);
  19. 22.        setContentView(R.layout.activity_video_chat);
  20. 23.        remoteSurfaceView = (SurfaceView) findViewById(R.id.surface_remote);
  21. 24.        localSurfaceView = (SurfaceView) findViewById(R.id.surface_local);
  22. 25.        configEntity = ConfigService.LoadConfig(this);//加载视频通话设置
  23. 26.        loginSystem();// 初始化SDK 连接服务器
  24. 27.        mTimerTask = new TimerTask(){
  25. 28.            public void run(){
  26. 29.                Message mesasge = new Message();
  27. 30.                handler.sendMessage(mesasge);
  28. 31.            }
  29. 32.        };
  30. 33.        mTimer.schedule(mTimerTask, 1000, 100);
  31. 34.        handler = new Handler(){
  32. 35.            @Override
  33. 36.            public void handleMessage(Message msg){
  34. 37.                VideoChat();// 不间断显示即时视频通话画面
  35. 38.                super.handleMessage(msg);
  36. 39.            }
  37. 40.        };
  38. 41.    }
  39. 42.    // 初始化SDK 连接服务器
  40. 43.    private void loginSystem(){
  41. 44.        if (anychat == null){
  42. 45.            anychat = new AnyChatCoreSDK();
  43. 46.            anychat.SetBaseEvent(this);         // 设置基本事件回调函数
  44. 47.            if (configEntity.useARMv6Lib != 0)  // 使用ARMv6指令集
  45. 48.                anychat.SetSDKOptionInt(AnyChatDefine.
  46. 49.                        BRAC_SO_CORESDK_USEARMV6LIB, 1);
  47. 50.            anychat.InitSDK(android.os.Build.VERSION.SDK_INT, 0); // 初始化SDK
  48. 51.        }
  49. 52.        anychat.Connect(“demo.anychat.cn”, 8906);// 连接服务器
  50. 53.    }
  51. 54.    // 显示即时视频通话画面
  52. 55.    public void VideoChat(){
  53. 56.        if (!bOtherVideoOpened){
  54. 57.            if (anychat.GetCameraState(userid) == 2
  55. 58.                    && anychat.GetUserVideoWidth(userid) != 0){
  56. 59.                SurfaceHolder holder = remoteSurfaceView.getHolder();
  57. 60.                holder.setFormat(PixelFormat.RGB_565);
  58. 61.                holder.setFixedSize(anychat.GetUserVideoWidth(userid),
  59. 62.                        anychat.GetUserVideoHeight(userid));
  60. 63.                Surface s = holder.getSurface();            // 获得视频画面
  61. 64.                anychat.SetVideoPos(userid, s, 0, 0, 0, 0); // 调用API显示视频画面
  62. 65.                bOtherVideoOpened = true;
  63. 66.            }
  64. 67.        }
  65. 68.        if (!bSelfVideoOpened){
  66. 69.            if (anychat.GetCameraState(-1) == 2
  67. 70.                    && anychat.GetUserVideoWidth(-1) != 0){
  68. 71.                SurfaceHolder holder = localSurfaceView.getHolder();
  69. 72.                holder.setFormat(PixelFormat.RGB_565);
  70. 73.                holder.setFixedSize(anychat.GetUserVideoWidth(-1),
  71. 74.                        anychat.GetUserVideoHeight(-1));
  72. 75.                Surface s = holder.getSurface();
  73. 76.                anychat.SetVideoPos(-1, s, 0, 0, 0, 0);
  74. 77.                bSelfVideoOpened = true;
  75. 78.            }
  76. 79.        }
  77. 80.    }
  78. 81.    public void OnAnyChatConnectMessage(boolean bSuccess){
  79. 82.        if (!bSuccess){
  80. 83.            Toast.makeText(VideoChatActivity.this, “连接服务器失败,自动重连,请稍后…”, Toast.LENGTH_SHORT).show();
  81. 84.        }
  82. 85.        anychat.Login(“android”, “”);               // 服务器连接成功 用户登录
  83. 86.    }
  84. 87.    public void OnAnyChatLoginMessage(int dwUserId, int dwErrorCode){
  85. 88.        if (dwErrorCode == 0) {
  86. 89.            Toast.makeText(this, “登录成功!”, Toast.LENGTH_SHORT).show();
  87. 90.            anychat.EnterRoom(1, “”);               // 用户登录成功 进入房间
  88. 91.            ApplyVideoConfig();
  89. 92.        } else {
  90. 93.            Toast.makeText(this, “登录失败,错误代码:” + dwErrorCode, Toast.LENGTH_SHORT).show();
  91. 94.        }
  92. 95.    }
  93. 96.    public void OnAnyChatEnterRoomMessage(int dwRoomId, int dwErrorCode){
  94. 97.        if (dwErrorCode == 0) {                     // 进入房间成功  打开本地音视频
  95. 98.            Toast.makeText(this, “进入房间成功”, Toast.LENGTH_SHORT).show();
  96. 99.            anychat.UserCameraControl(-1, 1);       // 打开本地视频
  97. 100.            anychat.UserSpeakControl(-1, 1);        // 打开本地音频
  98. 101.        } else {
  99. 102.            Toast.makeText(this, “进入房间失败,错误代码:” + dwErrorCode, Toast.LENGTH_SHORT).show();
  100. 103.        }
  101. 104.    }
  102. 105.    public void OnAnyChatOnlineUserMessage(int dwUserNum, int dwRoomId){
  103. 106.        if (dwRoomId == 1){
  104. 107.            int user[] = anychat.GetOnlineUser();
  105. 108.            if (user.length != 0){
  106. 109.                for (int i = 0; i < user.length; i++){
  107. 110.                    userlist.add(user[i]+"");
  108. 111.                }
  109. 112.                String temp =userlist.get(0);
  110. 113.                userid = Integer.parseInt(temp);
  111. 114.                anychat.UserCameraControl(userid, 1);// 请求用户视频
  112. 115.                anychat.UserSpeakControl(userid, 1); // 请求用户音频
  113. 116.            }
  114. 117.            else {
  115. 118.                Toast.makeText(VideoChatActivity.this, “当前没有在线用户”, Toast.LENGTH_SHORT).show();
  116. 119.            }
  117. 120.        }
  118. 121.    }
  119. 122.    public void OnAnyChatUserAtRoomMessage(int dwUserId, boolean bEnter){
  120. 123.        if (bEnter) {//新用户进入房间
  121. 124.            userlist.add(dwUserId+"");
  122. 125.        }
  123. 126.        else {       //用户离开房间
  124. 127.            if (dwUserId == userid)
  125. 128.            {
  126. 129.                Toast.makeText(VideoChatActivity.this, “视频用户已下线”, Toast.LENGTH_SHORT).show();
  127. 130.                anychat.UserCameraControl(userid, 0);// 关闭用户视频
  128. 131.                anychat.UserSpeakControl(userid, 0); // 关闭用户音频
  129. 132.                userlist.remove(userid+"");          //移除该用户
  130. 133.                if (userlist.size() != 0)
  131. 134.                {
  132. 135.                    String temp =userlist.get(0);
  133. 136.                    userid = Integer.parseInt(temp);
  134. 137.                    anychat.UserCameraControl(userid, 1);// 请求其他用户视频
  135. 138.                    anychat.UserSpeakControl(userid, 1); // 请求其他用户音频
  136. 139.                }
  137. 140.            }
  138. 141.            else {
  139. 142.                userlist.remove(dwUserId+"");    //移除该用户
  140. 143.            }
  141. 144.        }
  142. 145.    }
  143. 146.    public void OnAnyChatLinkCloseMessage(int dwErrorCode){
  144. 147.        Toast.makeText(VideoChatActivity.this, “连接关闭,error:” + dwErrorCode, Toast.LENGTH_SHORT).show();
  145. 148.    }
  146. 149.    @Override
  147. 150.    protected void onDestroy(){ //程序退出
  148. 151.        anychat.LeaveRoom(-1);  //离开房间
  149. 152.        anychat.Logout();       //注销登录
  150. 153.        anychat.Release();      //释放资源
  151. 154.        mTimer.cancel();
  152. 155.        super.onDestroy();
  153. 156.    }
  154. 157.    // 根据配置文件配置视频参数
  155. 158.    private void ApplyVideoConfig(){
  156. 159.        if (configEntity.configMode == 1) // 自定义视频参数配置
  157. 160.        {
  158. 161.            // 设置本地视频编码的码率(如果码率为0,则表示使用质量优先模式)
  159. 162.            anychat.SetSDKOptionInt(AnyChatDefine.BRAC_SO_LOCALVIDEO_BITRATECTRL,configEntity.videoBitrate);
  160. 163.            if (configEntity.videoBitrate == 0)
  161. 164.            {
  162. 165.                // 设置本地视频编码的质量
  163. 166.                anychat.SetSDKOptionInt(AnyChatDefine.BRAC_SO_LOCALVIDEO_QUALITYCTRL,configEntity.videoQuality);
  164. 167.            }
  165. 168.            // 设置本地视频编码的帧率
  166. 169.            anychat.SetSDKOptionInt(AnyChatDefine.BRAC_SO_LOCALVIDEO_FPSCTRL,configEntity.videoFps);
  167. 170.            // 设置本地视频编码的关键帧间隔
  168. 171.            anychat.SetSDKOptionInt(AnyChatDefine.BRAC_SO_LOCALVIDEO_GOPCTRL,configEntity.videoFps * 4);
  169. 172.            // 设置本地视频采集分辨率
  170. 173.            anychat.SetSDKOptionInt(AnyChatDefine.BRAC_SO_LOCALVIDEO_WIDTHCTRL,configEntity.resolution_width);
  171. 174.            anychat.SetSDKOptionInt(AnyChatDefine.BRAC_SO_LOCALVIDEO_HEIGHTCTRL,configEntity.resolution_height);
  172. 175.            // 设置视频编码预设参数(值越大,编码质量越高,占用CPU资源也会越高)
  173. 176.            anychat.SetSDKOptionInt(AnyChatDefine.BRAC_SO_LOCALVIDEO_PRESETCTRL,configEntity.videoPreset);
  174. 177.        }
  175. 178.        // 让视频参数生效
  176. 179.        anychat.SetSDKOptionInt(AnyChatDefine.BRAC_SO_LOCALVIDEO_APPLYPARAM,configEntity.configMode);
  177. 180.        // P2P设置
  178. 181.        anychat.SetSDKOptionInt(AnyChatDefine.BRAC_SO_NETWORK_P2PPOLITIC,configEntity.enableP2P);
  179. 182.        // 本地视频Overlay模式设置
  180. 183.        anychat.SetSDKOptionInt(AnyChatDefine.BRAC_SO_LOCALVIDEO_OVERLAY,configEntity.videoOverlay);
  181. 184.        // 回音消除设置
  182. 185.        anychat.SetSDKOptionInt(AnyChatDefine.BRAC_SO_AUDIO_ECHOCTRL,configEntity.enableAEC);
  183. 186.        // 平台硬件编码设置
  184. 187.        anychat.SetSDKOptionInt(AnyChatDefine.BRAC_SO_CORESDK_USEHWCODEC,configEntity.useHWCodec);
  185. 188.        // 视频旋转模式设置
  186. 189.        anychat.SetSDKOptionInt(AnyChatDefine.BRAC_SO_LOCALVIDEO_ROTATECTRL,configEntity.videorotatemode);
  187. 190.        // 视频平滑播放模式设置
  188. 191.        anychat.SetSDKOptionInt(AnyChatDefine.BRAC_SO_STREAM_SMOOTHPLAYMODE,configEntity.smoothPlayMode);
  189. 192.        // 视频采集驱动设置
  190. 193.        anychat.SetSDKOptionInt(AnyChatDefine.BRAC_SO_LOCALVIDEO_CAPDRIVER,configEntity.videoCapDriver);
  191. 194.        // 本地视频采集偏色修正设置
  192. 195.        anychat.SetSDKOptionInt(AnyChatDefine.BRAC_SO_LOCALVIDEO_FIXCOLORDEVIA,configEntity.fixcolordeviation);
  193. 196.        // 视频显示驱动设置
  194. 197.        anychat.SetSDKOptionInt(AnyChatDefine.BRAC_SO_VIDEOSHOW_DRIVERCTRL,configEntity.videoShowDriver);
  195. 198.    }
  196. 199.}

复制代码

该Android音视频解决方案还有文字聊天、发送文件、P2P连接等非常实用的功能。对于开发者来说,能快速实现类似QQ聊天和音视频通信是令人振奋的事情。