中文字幕在线视频第一页,黄色毛片在线看,日本爱爱网站,亚洲系列中文字幕一区二区

您當(dāng)前的位置是:  首頁(yè) > 資訊 > 國(guó)內(nèi) >
 首頁(yè) > 資訊 > 國(guó)內(nèi) >

手把手教程:基于環(huán)信4小時(shí)開(kāi)發(fā)一個(gè)視頻會(huì)議APP【附源碼】

2020-04-17 10:09:17   作者:   來(lái)源:CTI論壇   評(píng)論:0  點(diǎn)擊:


  今年是不平凡的一年,因?yàn)橐咔樵?,大家只能呆著家里,作為一個(gè)開(kāi)發(fā)者,嚴(yán)重影響了我正常的學(xué)習(xí)、生活和工作,在這種情況下,只能宅在家辦公,這時(shí)候大家就會(huì)經(jīng)常用到線上視頻會(huì)議,目前很多互聯(lián)網(wǎng)公司提供這種服務(wù),比較出名的就比如:騰訊會(huì)議、釘釘、zoom等,用這些是很方便,但是如果能開(kāi)發(fā)自己的視頻會(huì)議APP,那會(huì)不會(huì)更好或者更有成就感呢?下面就簡(jiǎn)單介紹我這個(gè)項(xiàng)目和大概的開(kāi)發(fā)過(guò)程。
  01主要功能
  本項(xiàng)目基于環(huán)信音視頻云來(lái)完成,實(shí)現(xiàn)的主要功能有:
  • 創(chuàng)建會(huì)議、刪除會(huì)議、獲取指定會(huì)議室詳情、加入會(huì)議室、退出會(huì)議室等關(guān)于會(huì)議的管理 ;
  • 獲取會(huì)議室參會(huì)人名列表、踢人,設(shè)置觀眾為主播,設(shè)置主播為觀眾等關(guān)于會(huì)議室的人員管理;
  • 共享桌面(web端);
  • 三個(gè)端的實(shí)現(xiàn):Android,iOS,
  上面這些功能在項(xiàng)目中都已經(jīng)實(shí)現(xiàn)。還有水印 ,變聲等高級(jí)功能在環(huán)信音視頻SDK的接口內(nèi)部都已經(jīng)封裝好,本項(xiàng)目沒(méi)有實(shí)現(xiàn) ,大家可以自行去實(shí)現(xiàn)。有關(guān)多人音視頻功能更詳細(xì)的介紹大家可以參考:這兒。多人音視頻實(shí)現(xiàn)的實(shí)現(xiàn)主要有以下一些場(chǎng)景:社交交友,遠(yuǎn)程心理咨詢、遠(yuǎn)程醫(yī)療、一對(duì)一在線教育、遠(yuǎn)程視頻輔助等。咳咳 ,接下來(lái)就是純干貨了,給大家介紹我是如何一步步開(kāi)發(fā)出一個(gè)完整的多人音視頻app。
  02項(xiàng)目截圖
  首先給大家展示下項(xiàng)目運(yùn)行的效果圖,會(huì)議界面 主窗口是一個(gè)大的 RelativeLayout ,最下面的那一排排小窗口是的實(shí)現(xiàn)方法是HorizontalScrollView加上一個(gè)開(kāi)源的組件 com.jaouan.compoundlayout.RadioLayoutGroup 實(shí)現(xiàn)的,點(diǎn)擊下面的小窗口后,可以 把小窗口的視頻流顯示在大屏上,具體是調(diào)用 updateRemoteSurfaceView(String streamId, EMCallSurfaceView remoteView)來(lái)更新SurfaceView,具體的細(xì)節(jié)大家可以看看代碼里面的實(shí)現(xiàn) 最后會(huì)公布代碼開(kāi)源地址。
  03準(zhǔn)備工作
  大家得下載安裝Android Studio,配置好Android 開(kāi)發(fā)環(huán)境,怎么詳細(xì)配置我就在這不再細(xì)說(shuō)了 網(wǎng)上有很多的教程,大家自己可以找找看,然后大家可以看看環(huán)信多人音視頻會(huì)議的主要功能和一些基本概念介紹。
  04集成工作
  首先大家會(huì)想問(wèn)怎么調(diào)用環(huán)信的SDK ,大家可以使用 遠(yuǎn)程依賴SDK包,建議大家用最新版本的遠(yuǎn)程依賴:
  com.hyphenate:hyphenate-sdk:3.6.6 ,依賴包可以放在 build.gradle里面的 dependencies 選項(xiàng)下面,如下圖所示: 
  2.其次怎么使用環(huán)信的appkey ,可以在環(huán)信 console 后臺(tái)注冊(cè)一個(gè) 賬號(hào)申請(qǐng)appkey ,可以參考:這里 ,獲取到  appkey 以后添加到AndroidManifest.xml中 ,如下圖所示:
  3.經(jīng)過(guò)以上兩個(gè)重要的前期配置準(zhǔn)備 ,接下來(lái)我們就可以開(kāi)始進(jìn)行代碼開(kāi)發(fā)了,首先我們先創(chuàng)建一個(gè)項(xiàng)目的DemoApplication類和      DemoHelper類,DemoApplication 類和DemoHelper類都是一個(gè)單例類 ,DemoApplication 主要功能就是進(jìn)行DemoHelper      的初始化,而DemoHelper里面主要是主要有一些option 配置和EMClient 進(jìn)行初始化,代碼如下所示:
  DemoHelper還有一個(gè)重要的功能就是設(shè)置  EMConferenceListener 進(jìn)行會(huì)議監(jiān)聽(tīng),有關(guān) EMConferenceListener 的類的詳細(xì)介紹 ,通過(guò)這個(gè)監(jiān)聽(tīng)可以再加入會(huì)議的時(shí)候獲取到已經(jīng)在會(huì)議中的流和主播信息,分別是通過(guò)其中以下兩個(gè)回調(diào)獲取:
  @Overridepublic void onMemberJoined(EMConferenceMember member){}
  @Overridepublic void onStreamAdded(EMConferenceStream stream){}
  4.DemoApplication類完成以后,接下來(lái)就是怎么去登陸 環(huán)信IM 賬號(hào)和 創(chuàng)建加入會(huì)議房間了,首次安裝的時(shí)候都沒(méi)有賬號(hào),我們使用的辦法是自動(dòng)注冊(cè)一個(gè)賬號(hào) 在本地進(jìn)行保存,然后進(jìn)行登錄 ,注冊(cè) 登錄詳細(xì)接口請(qǐng)看 這兒,  注冊(cè) 登錄的調(diào)用大概如下所示:
  try {//注冊(cè)一個(gè)環(huán)信IDEMClient.getInstance()。createAccount(username, password);//注冊(cè)成功進(jìn)行登錄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();}
  }
  }
  EMClient.getInstance()。conferenceManager()。joinRoom(currentRoomname, currentPassword, conferenceRole,roomConfig, new EMValueCallBack(){@Overridepublic void onSuccess(EMConference value) {EMLog.i(TAG, "join  conference success");Intent intent = new Intent(MainActivity.this, ConferenceActivity.class);startActivity(intent);finish();}
  @Overridepublic void onError(final int error, final String errorMsg) {EMLog.e(TAG, "join conference failed error " + error + ", msg " + errorMsg);runOnUiThread(new Runnable() {@Overridepublic void run() {setBtnEnable(true);if(error == CALL_TALKER_ISFULL) {takerFullDialogDisplay();}else{Toast.makeText(getApplicationContext(), "Join conference failed " + error + " " + errorMsg, Toast.LENGTH_SHORT)。show();}
  }
  });}
  });
  登錄完成以后,我們可以根據(jù)房間名創(chuàng)建并加入房間,主要代碼大概如下:
  EMClient.getInstance()。conferenceManager()。joinRoom(currentRoomname, currentPassword, conferenceRole,roomConfig, new EMValueCallBack(){@Overridepublic void onSuccess(EMConference value) {EMLog.i(TAG, "join  conference success");Intent intent = new Intent(MainActivity.this, ConferenceActivity.class);startActivity(intent);finish();}
  @Overridepublic void onError(final int error, final String errorMsg) {EMLog.e(TAG, "join conference failed error " + error + ", msg " + errorMsg);runOnUiThread(new Runnable() {@Overridepublic 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可以根據(jù)房間名創(chuàng)建指定會(huì)議,當(dāng)以該房間名命名的會(huì)議不存在時(shí)候,會(huì)直接創(chuàng)建,當(dāng)會(huì)議已經(jīng)創(chuàng)建好 可以根據(jù)正確的房間名和密碼加入房間 ,到這一步為止,我們已經(jīng)成功的創(chuàng)建 并加入會(huì)議。
  5.加入會(huì)議以后我們進(jìn)入到會(huì)議界面,展示從DemoHelper類 EMConferenceListener 中的 onStreamAdded 回調(diào) 和 onMemberJoined 獲取到的流和主播列表 ,在ConferenceActivity 中實(shí)現(xiàn) EMConferenceListener ,然后直接把 ConferenceActivity 注冊(cè)監(jiān)聽(tīng),用以下方法  EMClient.getInstance().conferenceManager().addConferenceListener(this); 這樣就可實(shí)現(xiàn) EMConferenceListener 事件的處理,比如主播進(jìn)出房間 :
  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)角色變更、用戶被踢、誰(shuí)在說(shuō)話等各種回調(diào),可以處理各種業(yè)務(wù)邏輯 ,詳細(xì)的請(qǐng)參考 項(xiàng)目中的實(shí)現(xiàn) ,最后會(huì)附上項(xiàng)目的開(kāi)源地址。
  6 進(jìn)入會(huì)議房間以后如果用戶角色為主播可以進(jìn)行發(fā)布視頻流 ,觀眾只能訂閱視頻流 不能發(fā)布視頻流 ,可以調(diào)用SDK的publish接口發(fā)布流,該接口用到了EMStreamParam參數(shù),你可以自由配置,比如是否上傳視頻,是否上傳音頻,使用前置或后置攝像頭,視頻碼率,顯示視頻頁(yè)面等等,具體實(shí)現(xiàn)可以參考 中發(fā)布 訂閱視頻流的內(nèi)容, 關(guān)于以上的代碼邏輯如以 如以下:
  //發(fā)布視頻流
  normalParam = new EMStreamParam();normalParam.setStreamType(EMConferenceStream.StreamType.NORMAL);normalParam.setVideoOff(true);normalParam.setAudioOff(true);EMClient.getInstance().conferenceManager().publish(normalParam, new EMValueCallBack() {@Overridepublic void onSuccess(String value) {conference.setPubStreamId(value, EMConferenceStream.StreamType.NORMAL);addOrUpdateStreamList("local-stream", value);PhoneStateManager.get(ConferenceActivity.this).addStateCallback(phoneStateCallback);}
  @Overridepublic 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() {@Overridepublic void onSuccess(String value) {}
  @Overridepublic void onError(int error, String errorMsg) {}
  });}
  7.有關(guān)上麥 下麥 的邏輯處理,觀眾可以請(qǐng)求上麥成為主播,主播可以下麥成為觀眾,上麥 下麥 是利用 EMConferenceAttribute進(jìn)行處理 ,EMConferenceAttribute  是一個(gè)事件廣播,廣播事件是一個(gè)key-value格式,key-value 可以由開(kāi)發(fā)者進(jìn)行自行定義,增添事件以后 ,服務(wù)器會(huì)把事件進(jìn)行廣播。會(huì)議中成員會(huì)收到 onAttributesUpdated回調(diào)。例如本項(xiàng)目中的會(huì)議上麥 下麥 代碼如下所示:
  //上麥申請(qǐng)EMClient.getInstance()。conferenceManager()。setConferenceAttribute(EMClient.getInstance()。getCurrentUser(),"request_tobe_speaker",new EMValueCallBack() {@Overridepublic void onSuccess(Void value) {EMLog.i(TAG, "request_tobe_speaker scuessed");}
  @Overridepublic void onError(int error, String errorMsg) {EMLog.i(TAG, "request_tobe_speaker failed: error=" + error}
  });
  //下麥申請(qǐng)EMClient.getInstance()。conferenceManager()。setConferenceAttribute(EMClient.getInstance()。getCurrentUser(), "request_tobe_audience", new EMValueCallBack() {@Overridepublic void onSuccess(Void value) {EMLog.i(TAG, "request_tobe_audience scuessed");}
  @Overridepublic void onError(int error, String errorMsg) {EMLog.i(TAG, "request_tobe_audience failed: error=" + error + ", msg=" + errorMsg);}
  });
  上麥 下麥 請(qǐng)求發(fā)出以后 只能由主持人去處理,處理在 EMConferenceListener  的回調(diào) onAttributesUpdated(EMConferenceAttribute[] attributes) 去處理 ,收到回調(diào)以后 解析attributes 然后進(jìn)行處理請(qǐng)求,處理的過(guò)程代碼大概如下:
  EMClient.getInstance()。conferenceManager()。grantRole(conference.getConferenceId(), new EMConferenceMember(memName, null, null,null), EMConferenceManager.EMConferenceRole.Talker, new EMValueCallBack() {@Overridepublic void onSuccess(String value) {EMLog.i(TAG, " requestTalkerDisplay  request_tobe_speaker changeRole success, result: " + value);dialog.dismiss();}
  @Overridepublic void onError(int error, String errorMsg) {EMLog.i(TAG, " requestTalkerDisplay  request_tobe_speaker changeRole failed, error: " + error + " - " + errorMsg);}
  });
  下麥也是和上麥一樣是利用 EMConferenceAttribute進(jìn)行處理。
  9.有關(guān)退出會(huì)議 銷毀會(huì)議 普通主播  觀眾只能退出會(huì)議 ,主持人還可以 銷毀會(huì)議 正在進(jìn)行中的會(huì)議可以進(jìn)行銷毀,退出會(huì)議 銷毀會(huì)議 具體代碼如下:
  EMClient.getInstance()。conferenceManager()。exitConference(new EMValueCallBack() {@Overridepublic void onSuccess(Object value) {runOnUiThread(new Runnable() {@Overridepublic void run() {Toast.makeText(getApplicationContext(), "您已成功退出當(dāng)前會(huì)議!", Toast.LENGTH_SHORT)。show();}
  });}
  @Overridepublic void onError(int error, String errorMsg) {EMLog.i(TAG, "exit conference failed " + error + ", " + errorMsg);}
  });
  EMClient.getInstance()。conferenceManager()。destroyConference(new EMValueCallBack() {@Overridepublic void onSuccess(Object value) {runOnUiThread(new Runnable() {@Overridepublic void run() {Toast.makeText(getApplicationContext(), "您已成功銷毀當(dāng)前會(huì)議!", Toast.LENGTH_SHORT)。show();}
  });EMLog.i(TAG, "finish ConferenceActivity");finish();}
  05尾語(yǔ)至此整個(gè)多人音視頻會(huì)議APP開(kāi)發(fā)的詳細(xì)步驟已經(jīng)完成 ,雖然比較麻煩 但是每個(gè)步驟都很清晰 ,有不太清楚的歡迎大家積極討論, 附上本項(xiàng)目的github地址:點(diǎn)擊跳轉(zhuǎn)。 歡迎大家積極參與 ,謝謝支持。歡迎大家積極參與 ,謝謝支持。本人聯(lián)系方式:727402046@qq.com(本文首發(fā)CSDN博客,已得到原作者“不回頭的倔強(qiáng)”的授權(quán))

【免責(zé)聲明】本文僅代表作者本人觀點(diǎn),與CTI論壇無(wú)關(guān)。CTI論壇對(duì)文中陳述、觀點(diǎn)判斷保持中立,不對(duì)所包含內(nèi)容的準(zhǔn)確性、可靠性或完整性提供任何明示或暗示的保證。請(qǐng)讀者僅作參考,并請(qǐng)自行承擔(dān)全部責(zé)任。

專題

CTI論壇會(huì)員企業(yè)

上栗县| 根河市| 乌鲁木齐市| 香格里拉县| 安宁市| 陕西省| 兰西县| 镇远县| 台州市| 甘洛县| 彰化市| 朝阳区| 绵竹市| 衡水市| 汶川县| 泸溪县| 博乐市| 沂源县| 大关县| 泰顺县| 灌云县| 湘乡市| 犍为县| 乌兰浩特市| 喀喇沁旗| 梨树县| 靖边县| 西青区| 怀宁县| 赤峰市| 大庆市| 金阳县| 兰西县| 改则县| 晋中市| 天长市| 清新县| 彭水| 无极县| 泾源县| 双桥区|