日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

如何实现一套可切换的声网+阿里的直播引擎

發布時間:2024/4/15 编程问答 37 豆豆
生活随笔 收集整理的這篇文章主要介紹了 如何实现一套可切换的声网+阿里的直播引擎 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

前言

小盒的直播業務一開始是打算用兩套引擎切換使用的,所以需要封裝一下。而且因為聲網和阿里的直播sdk的官方文檔都不是很全面,甚至有的還有錯誤(可能是文檔沒及時更新)導致無法正常運行,接入時問題多多,所以同時記錄一下的接入過程中的問題及處理。

定義接口

首先因為需要兩個引擎切換使用,所以定義了接口,定義常用的行為

public interface RtcEngine {void init(Context context, RtcInfo config);void join();void leave();void setRtcListener(RtcListener rtcListener); }

這里RtcInfo是兩個sdk需要用到的參數,由服務端提供。我們是初始化時一次性提供,當然也可以實時提供,如果實時提供,join函數也需要一些添加必要參數。

RtcInfo的定義如下:

public class RtcInfo {public AgoraConfig agoraConfig;public AliConfig aliConfig;public String rtcType; } public class AgoraConfig {public String liveChannel;public String appId;public int avatarUID;public int liveUID;public String liveToken; } public class AliConfig {public String liveChannel;public String appId;public String avatarUID;public String liveUID;public String liveToken;... }

另外還有一個監聽RtcListener,統一了兩個sdk的回調,可以自行豐富

public interface RtcListener {void remoteOnline(View remoteView); //當收到流之后,將remoteView加入頁面中展示void remoteOffline(); }

接入聲網

聲網的封裝類,實現RtcEngine接口:

public class AgoraEngine implements RtcEngine {private final String TAG = this.getClass().getSimpleName();private Context mContext;private io.agora.rtc.RtcEngine engine;private RtcInfo mConfig;private RtcListener listener;private SurfaceView mRemoteView;private final IRtcEngineEventHandler iRtcEngineEventHandler = new IRtcEngineEventHandler() {@Overridepublic void onJoinChannelSuccess(String s, int i, int i1) {super.onJoinChannelSuccess(s, i, i1);}@Overridepublic void onLeaveChannel(RtcStats rtcStats) {super.onLeaveChannel(rtcStats);}@Overridepublic void onUserOffline(int i, int i1) {super.onUserOffline(i, i1);}@Overridepublic void onWarning(int i) {super.onWarning(i);}@Overridepublic void onError(int i) {super.onError(i);}@Overridepublic void onUserJoined(final int uid, int elapsed) {super.onUserJoined(uid, elapsed);//這里獲取到流,設置RemoteVideo并展示//因為有兩路流,我們只使用了一路,所以需要判斷一下,只展示老師的流if (uid != mConfig.agoraConfig.avatarUID && uid < xxxx) {...}if (uid == mConfig.agoraConfig.avatarUID) {//發現uid與老師id一致,創建設置RemoteVideo并展示mRemoteView.setActivated(true);mRemoteView.setEnabled(true);new Handler(mContext.getMainLooper()).post(new Runnable() {@Overridepublic void run() {mRemoteView = io.agora.rtc.RtcEngine.CreateRendererView(mContext);mRemoteView.setActivated(true);mRemoteView.setEnabled(true);if(listener != null){//交給頁面處理,一般是將播放器展示出來listener.joinSuccess(mRemoteView);}...}});}}@Overridepublic void onFirstRemoteVideoFrame(final int uid, int w, int h, int i3) {//官方文檔表明在這里會獲取第一禎流,然后設置RemoteVideo并展示。實際使用中發現這里根本不回調,而且在onUserJoined中處理RemoteVideo}};@Overridepublic void init(Context context, RtcInfo config) {mConfig = config;mContext = context.getApplicationContext();try {engine = io.agora.rtc.RtcEngine.create(mContext, config.agoraConfig.appId, iRtcEngineEventHandler);engine.setChannelProfile(Constants.CHANNEL_PROFILE_LIVE_BROADCASTING);engine.setVideoProfile(Constants.VIDEO_PROFILE_240P_4, false);engine.setClientRole(Constants.CLIENT_ROLE_AUDIENCE);engine.enableVideo();engine.setParameters("{\"che.audio.keep.audiosession\":true}");} catch (Exception e) {Log.e(TAG, TAG, e);engine = null;}}@Overridepublic void join() {if(engine != null){engine.joinChannel(mConfig.agoraConfig.liveToken, mConfig.agoraConfig.liveChannel, "", mConfig.agoraConfig.liveUID);}}@Overridepublic void leave() {if(engine != null){engine.leaveChannel();io.agora.rtc.RtcEngine.destroy();engine = null;}}@Overridepublic void setRtcListener(RtcListener rtcListener) {listener = rtcListener;} }

重點注意onFirstRemoteVideoFrame在官方文檔表明在這里會獲取第一禎流,然后設置RemoteVideo并展示。實際使用中發現這里根本不回調,而且在onUserJoined中處理RemoteVideo,在官方Demo里也是這么處理的,應該是文檔更新滯后了。(不知道現在更沒更新)。

代碼中我們沒有對onUserOffline進行處理,后續實際上是補充了相關功能,這里注意的是一定要校驗uid,否則可能導致問題。比如在老師退出直播間的時候我們需要做一些頁面調整,但是如果這里沒有校驗uid,那么其他人(特殊身份)在退出時也會執行這部分代碼。

接入阿里直播

阿里的封裝類,同樣實現RtcEngine接口:

public class AliEngine implements RtcEngine {private final String TAG = this.getClass().getSimpleName();private Context mContext;private AliRtcEngine mEngine;private RtcInfo mConfig;//private SophonSurfaceView mRemoteView;private AliRtcEngine.AliVideoCanvas mCanvas;private RtcListener listener;private AliRtcEngineEventListener aliRtcEngineEventListener = new AliRtcEngineEventListener() {...};private AliRtcEngineNotify aliRtcEngineNotify = new AliRtcEngineNotify() {...@Overridepublic void onRemoteTrackAvailableNotify(final String uid, AliRtcEngine.AliRtcAudioTrack audioTrack, final AliRtcEngine.AliRtcVideoTrack videoTrack) {super.onRemoteTrackAvailableNotify(uid, audioTrack, videoTrack);//收到流的第一禎,先判斷是不是老師的流if(uid.equals(mConfig.aliConfig.avatarUID)) { // mEngine.configRemoteAudio(mConfig.aliConfig.avatarUID, true); // mEngine.configRemoteScreenTrack(mConfig.aliConfig.avatarUID, true); // mEngine.configRemoteCameraTrack(mConfig.aliConfig.avatarUID, true, true); // mEngine.subscribe(mConfig.aliConfig.avatarUID);new Handler(mContext.getMainLooper()).post(new Runnable() {@Overridepublic void run() {if(mEngine == null){return;}AliRtcRemoteUserInfo info = mEngine.getUserInfo(uid);if(info == null){return;}AliRtcEngine.AliVideoCanvas cameraCanvas = info.getCameraCanvas();AliRtcEngine.AliVideoCanvas screenCanvas = info.getScreenCanvas();if(videoTrack == AliRtcEngine.AliRtcVideoTrack.AliRtcVideoTrackNo){screenCanvas = null;cameraCanvas = null;}else if(videoTrack == AliRtcEngine.AliRtcVideoTrack.AliRtcVideoTrackCamera){//我們只需要攝像頭的流。這里創建設置remoteView,并展示mCanvas = new AliRtcEngine.AliVideoCanvas();SophonSurfaceView mRemoteView = new SophonSurfaceView(mContext);if(listener != null){//交給頁面處理,一般是將播放器展示出來listener.joinSuccess(mRemoteView);}mRemoteView.setZOrderOnTop(true);mRemoteView.setZOrderMediaOverlay(true);mCanvas.view = mRemoteView;...screenCanvas = null;cameraCanvas = mCanvas;mEngine.setRemoteViewConfig(cameraCanvas, uid, AliRtcEngine.AliRtcVideoTrack.AliRtcVideoTrackCamera);}}});}}...};@Overridepublic void init(Context context, RtcInfo config) {mContext = context;mConfig = config;mEngine = AliRtcEngine.getInstance(context);mEngine.setRtcEngineEventListener(aliRtcEngineEventListener);mEngine.setRtcEngineNotify(aliRtcEngineNotify);mEngine.setClientRole(AliRtcEngine.AliRTCSDK_Client_Role.AliRTCSDK_live);mEngine.setChannelProfile(AliRtcEngine.AliRTCSDK_Channel_Profile.AliRTCSDK_Interactive_live);mEngine.setAutoPublishSubscribe(false, true);}@Overridepublic void join() {AliRtcAuthInfo info = new AliRtcAuthInfo();info.setConferenceId(mConfig.aliConfig.liveChannel);info.setAppid(mConfig.aliConfig.appId);info.setUserId(mConfig.aliConfig.liveUID);...info.setToken(mConfig.aliConfig.liveToken);if(mEngine != null){mEngine.joinChannel(info, "");}}@Overridepublic void leave() {if(mEngine != null){mEngine.leaveChannel();}mEngine = null;}@Overridepublic void setRtcListener(RtcListener rtcListener) {listener = rtcListener;} }

與聲網的很類似,注意事項也差不多,因為關鍵部分都有注釋,這里就不細說了。

總結

這樣在進入直播前,通過后臺獲取直播配置,根據類型初始化不同的引擎來使用即可。

源碼

關注公眾號:BennuCTech,發送“RtcEngine”獲取完整源碼。

總結

以上是生活随笔為你收集整理的如何实现一套可切换的声网+阿里的直播引擎的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。