• <strike id="fdgpu"><input id="fdgpu"></input></strike>
    <label id="fdgpu"></label>
    <s id="fdgpu"><code id="fdgpu"></code></s>

  • <label id="fdgpu"></label>
  • <span id="fdgpu"><u id="fdgpu"></u></span>

    <s id="fdgpu"><sub id="fdgpu"></sub></s>
    您當前的位置是:  首頁(yè) > 資訊 > 國內 >
     首頁(yè) > 資訊 > 國內 >

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

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


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

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

    專(zhuān)題

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

    亚洲精品网站在线观看不卡无广告,国产a不卡片精品免费观看,欧美亚洲一区二区三区在线,国产一区二区三区日韩 如东县| 嫩江县| 远安县| 济源市| 龙门县| 武陟县| 晴隆县| 高密市| 五华县| 沽源县| 新安县| 武功县| 大厂| 琼海市| 五大连池市| 昭平县| 清镇市| 夏河县| 屯留县| 海宁市| 乳山市| 昆山市| 彭泽县| 苏尼特左旗| 安远县| 贵南县| 竹山县| 江源县| 安岳县| 恩平市| 高淳县| 凉城县| 苍梧县| 南陵县| 东源县| 永昌县| 磐安县| 衢州市| 鹤峰县| 剑河县| 中卫市| http://444 http://444 http://444 http://444 http://444 http://444