java ilvmanagerview_Android 腾讯互动直播集成

最近刚用完互动直播sdk 做完直播,简单记录下。

一.旁路推流

首先先弄懂“旁路”的概念

凡是通过url观看的直播都是旁路直播,旁路直播要进行旁路推流,否则旁路直播无法观看直播。

向在app内我们是通过joinRoom() 加入的房间,所以不属于旁路直播。

二.主播方

大概流程是这个样子,根据自己需求进行变更

1.向服务器请求房间号。

2.根据房间号,创建房间。

public void createRoom() {

ILVLiveRoomOption hostOption = new ILVLiveRoomOption(”主播ID“)

.roomDisconnectListener(this)

.autoCamera(true)

.videoMode(ILiveConstants.VIDEOMODE_BSUPPORT)

.controlRole(CurLiveInfo.getCurRole())

//角色是主播 一定不能设置错 主播走核心机房 观众走边缘机房

// .controlRole("LiveMaster")

.videoRecvMode(AVRoomMulti.VIDEO_RECV_MODE_SEMI_AUTO_RECV_CAMERA_VIDEO);

int ret = ILVLiveManager.getInstance().createRoom(“房间ID”, hostOption, new ILiveCallBack() {

@Override

public void onSuccess(Object data) {

if (getView()!=null)

getView().enterRoomComplete(MySelfInfo.getInstance().getIdStatus(), true);

ILiveLog.d(TAG, "ILVB-SXB|startEnterRoom->create room sucess");

}

@Override

public void onError(String module, int errCode, String errMsg) {

if (getView()!=null)

getView().errRoomFail();

ILiveLog.d(TAG, "ILVB-SXB|createRoom->create room failed:" + module + "|" + errCode + "|" + errMsg);

}

});

}

4.创建房间成功后有旁路直播开启旁路推流。

public void pushStream() {

/**

* 旁路直播 退出房间时必须退出推流。否则会占用后台channel。

*/

ILivePushOption option = new ILivePushOption();

option.encode(ILivePushOption.Encode.HLS);

// option.setRecordFileType(ILivePushOption.RecordFileType.RECORD_HLS_FLV_MP4);

option.setRecordFileType(ILivePushOption.RecordFileType.RECORD_HLS_FLV_MP4);

// option.channelName("跟ios协商");

//推流格式 到时候跟ios统一

pushStream(option);

}

/**

* 开启推流

*

* @param option

*/

public void pushStream(ILivePushOption option) {

if (!isPushed) {

ILiveRoomManager.getInstance().startPushStream(option, new ILiveCallBack() {

@Override

public void onSuccess(ILivePushRes data) {

// List liveUrls = data.getUrls();

Log.i("pushStream", "推流成功!!!!!!!");

}

@Override

public void onError(String module, int errCode, String errMsg) {

Log.i("pushStream", "推流失败!!!!!!!");

}

});

}

}

5.退出房间前:在房间发送自定义消息告诉观众主播要退出房间,方便观众端切换主播已离开界面,并停止推流。

发送自定义消息退出房间

public void sendExitRoomMSG() {

ILVCustomCmd cmd = new ILVCustomCmd();

cmd.setCmd(Constans.AVIMCMD_EXITLIVE);

cmd.setParam(sendExitRoomJson());

cmd.setType(ILVText.ILVTextType.eGroupMsg);

ILVLiveManager.getInstance().sendCustomCmd(cmd, new ILiveCallBack() {

@Override

public void onSuccess(TIMMessage data) {

if (isPushed) {

stopStream();

}

callExitRoom();

}

@Override

public void onError(String module, int errCode, String errMsg) {

}

});

}

停止推流

/**

* 退出直播的时候关闭推流

*/

public void stopStream() {

ILiveRoomManager.getInstance().stopPushStream(streamChannelID, new ILiveCallBack() {

@Override

public void onSuccess(Object data) {

SxbLog.e(TAG, "stopPush->success");

isPushed = false;

}

@Override

public void onError(String module, int errCode, String errMsg) {

SxbLog.e(TAG, "stopPush->failed:" + module + "|" + errCode + "|" + errMsg);

}

});

}

6.退出房间。

private void callExitRoom() {

ILiveSDK.getInstance().getAvVideoCtrl().setLocalVideoPreProcessCallback(null);

quitLiveRoom();

}

三.观众方

大概流程是这个样子,根据自己需求进行变更。

1.向服务器请求房间号。

2.根据房间号加入房间。

//加入房间

public void joinRoom(int roomId) {

ILVLiveManager.getInstance().quitRoom(null);

this.rommId = roomId + "";

ILVLiveRoomOption memberOption = new ILVLiveRoomOption(ConfigUtils.getUid())

.autoCamera(false)

.roomDisconnectListener(this)

.videoMode(ILiveConstants.VIDEOMODE_BSUPPORT)

.controlRole("Guest")

.authBits(AVRoomMulti.AUTH_BITS_JOIN_ROOM | AVRoomMulti.AUTH_BITS_RECV_AUDIO | AVRoomMulti.AUTH_BITS_RECV_CAMERA_VIDEO | AVRoomMulti.AUTH_BITS_RECV_SCREEN_VIDEO)

.videoRecvMode(AVRoomMulti.VIDEO_RECV_MODE_SEMI_AUTO_RECV_CAMERA_VIDEO)

.autoMic(false);

int ret = ILVLiveManager.getInstance().joinRoom(roomId, memberOption, new ILiveCallBack() {

@Override

public void onSuccess(Object data) {

ILiveLog.d(TAG, "ILVB-Suixinbo|startEnterRoom->join room sucess");

if (null != mGuestLiveView)

mGuestLiveView.enterRoomComplete(true);

}

@Override

public void onError(String module, int errCode, String errMsg) {

LogUtils.d("suyan", "===========加入房间失败" + module + errCode + errMsg);

if (null != mGuestLiveView) {

mGuestLiveView.enterRoomComplete(false);

}

}

});

}

3.加入房间成功后,在房间发送自定义消息,告诉房间内有人加入,方便主播统计目前的房间人数。

/**

* 发送信令,点赞,进入房间

*/

public int sendGroupCmd(int cmd, String param) {

ILVCustomCmd customCmd = new ILVCustomCmd();

//1.传cmd

customCmd.setCmd(cmd);

//2.创建自定义数据

String json = sendCusJsn();

//3.传自定义数据

customCmd.setParam(json);

//4.设置自定义类型

customCmd.setType(ILVText.ILVTextType.eGroupMsg);

return sendCmd(customCmd);

}

4.退出房间前:发送房间自定义消息,告诉主播观众退出,方便主播统计目前的在线人数。

5.退出直播间。

public void startExitRoom() {

if (ILiveSDK.getInstance() != null && ILiveSDK.getInstance().getAvVideoCtrl() != null) {

ILiveSDK.getInstance().getAvVideoCtrl().setLocalVideoPreProcessCallback(null);

}

quitLiveRoom();

}

private void quitLiveRoom() {

ILVLiveManager.getInstance().quitRoom(new ILiveCallBack() {

@Override

public void onSuccess(Object data) {

//1.回调给页面

if (null != mGuestLiveView) {

LogUtils.d("suyan", "=========退出成功");

mGuestLiveView.quiteRoomComplete(true);

}

}

@Override

public void onError(String module, int errCode, String errMsg) {

if (null != mGuestLiveView) {

mGuestLiveView.quiteRoomComplete(false);

}

}

});

}

自己封装了一个观众端的使用类,也是根据互动直播demo改的

package com.jyjt.ydyl.txlive.presenters;

import android.app.Activity;

import android.content.Context;

import android.text.TextUtils;

import com.google.gson.Gson;

import com.google.gson.GsonBuilder;

import com.google.gson.JsonSyntaxException;

import com.jyjt.ydyl.Entity.LiveCusEntity;

import com.jyjt.ydyl.tools.ConfigUtils;

import com.jyjt.ydyl.tools.Constans;

import com.jyjt.ydyl.tools.LogUtils;

import com.jyjt.ydyl.tools.ToastUtil;

import com.jyjt.ydyl.txlive.LiveDetailActivity;

import com.jyjt.ydyl.txlive.event.LiveMessageEvent;

import com.jyjt.ydyl.txlive.views.GuestLiveView;

import com.tencent.TIMConversationType;

import com.tencent.TIMCustomElem;

import com.tencent.TIMElem;

import com.tencent.TIMElemType;

import com.tencent.TIMGroupSystemElem;

import com.tencent.TIMGroupSystemElemType;

import com.tencent.TIMMessage;

import com.tencent.av.sdk.AVRoomMulti;

import com.tencent.ilivesdk.ILiveCallBack;

import com.tencent.ilivesdk.ILiveConstants;

import com.tencent.ilivesdk.ILiveSDK;

import com.tencent.ilivesdk.core.ILiveLog;

import com.tencent.ilivesdk.core.ILiveRoomManager;

import com.tencent.ilivesdk.core.ILiveRoomOption;

import com.tencent.livesdk.ILVCustomCmd;

import com.tencent.livesdk.ILVLiveConstants;

import com.tencent.livesdk.ILVLiveManager;

import com.tencent.livesdk.ILVLiveRoomOption;

import com.tencent.livesdk.ILVText;

import com.tencent.openqq.protocol.imsdk.im_common;

import org.json.JSONObject;

import org.json.JSONTokener;

import java.util.Observable;

import java.util.Observer;

/**

* 观众端,直播帮助类

*

* 1.加入房间

* 2.离开房间

* 3.发送点赞,和加入房间指令

* 4.解析传过来的自定义消息(点赞,其他成员加入,用户退出直播, 达到上限,主播回来了)

* 5.房间链接断开监听

*

* 苏艳

*/

public class GuestLiveHelper implements ILiveRoomOption.onRoomDisconnectListener, Observer {

private final String TAG = "LiveHelper";

private GuestLiveView mGuestLiveView;

public Activity mContext;

private String rommId;

Gson gson;

public GuestLiveHelper(Activity context, GuestLiveView mGuestLiveView) {

mContext = context;

this.mGuestLiveView = mGuestLiveView;

LiveMessageEvent.getInstance().addObserver(this);

GsonBuilder builder = new GsonBuilder();

gson = builder.create();

}

//加入房间

public void joinRoom(int roomId) {

ILVLiveManager.getInstance().quitRoom(null);

this.rommId = roomId + "";

ILVLiveRoomOption memberOption = new ILVLiveRoomOption(ConfigUtils.getUid())

.autoCamera(false)

.roomDisconnectListener(this)

.videoMode(ILiveConstants.VIDEOMODE_BSUPPORT)

.controlRole("Guest")

.authBits(AVRoomMulti.AUTH_BITS_JOIN_ROOM | AVRoomMulti.AUTH_BITS_RECV_AUDIO | AVRoomMulti.AUTH_BITS_RECV_CAMERA_VIDEO | AVRoomMulti.AUTH_BITS_RECV_SCREEN_VIDEO)

.videoRecvMode(AVRoomMulti.VIDEO_RECV_MODE_SEMI_AUTO_RECV_CAMERA_VIDEO)

.autoMic(false);

int ret = ILVLiveManager.getInstance().joinRoom(roomId, memberOption, new ILiveCallBack() {

@Override

public void onSuccess(Object data) {

ILiveLog.d(TAG, "ILVB-Suixinbo|startEnterRoom->join room sucess");

if (null != mGuestLiveView)

mGuestLiveView.enterRoomComplete(true);

}

@Override

public void onError(String module, int errCode, String errMsg) {

LogUtils.d("suyan", "===========加入房间失败" + module + errCode + errMsg);

if (null != mGuestLiveView) {

mGuestLiveView.enterRoomComplete(false);

}

}

});

}

//退出房间

public void startExitRoom() {

if (ILiveSDK.getInstance() != null && ILiveSDK.getInstance().getAvVideoCtrl() != null) {

ILiveSDK.getInstance().getAvVideoCtrl().setLocalVideoPreProcessCallback(null);

}

quitLiveRoom();

}

private void quitLiveRoom() {

ILVLiveManager.getInstance().quitRoom(new ILiveCallBack() {

@Override

public void onSuccess(Object data) {

//1.回调给页面

if (null != mGuestLiveView) {

LogUtils.d("suyan", "=========退出成功");

mGuestLiveView.quiteRoomComplete(true);

}

}

@Override

public void onError(String module, int errCode, String errMsg) {

if (null != mGuestLiveView) {

mGuestLiveView.quiteRoomComplete(false);

}

}

});

}

/**

* 发送信令,点赞,进入房间

*/

public int sendGroupCmd(int cmd, String param) {

ILVCustomCmd customCmd = new ILVCustomCmd();

//1.传cmd

customCmd.setCmd(cmd);

//2.创建自定义数据

String json = sendCusJsn();

//3.传自定义数据

customCmd.setParam(json);

//4.设置自定义类型

customCmd.setType(ILVText.ILVTextType.eGroupMsg);

return sendCmd(customCmd);

}

//邀请上麦用的,暂时用不到

public int sendC2CCmd(final int cmd, String param, String destId) {

ILVCustomCmd customCmd = new ILVCustomCmd();

customCmd.setDestId(destId);

customCmd.setCmd(cmd);

customCmd.setParam(param);

customCmd.setType(ILVText.ILVTextType.eC2CMsg);

return sendCmd(customCmd);

}

private int sendCmd(final ILVCustomCmd cmd) {

return ILVLiveManager.getInstance().sendCustomCmd(cmd, new ILiveCallBack() {

@Override

public void onSuccess(Object data) {

LogUtils.d(TAG, "suyan" + cmd.getCmd() + "|" + cmd.getParam() + "====发送成功");

}

@Override

public void onError(String module, int errCode, String errMsg) {

// Toast.makeText(mContext, "sendCmd->failed:" + module + "|" + errCode + "|" + errMsg, Toast.LENGTH_SHORT).show();

}

});

}

@Override

public void onRoomDisconnect(int errCode, String errMsg) {

if (null != mGuestLiveView) {

//房间异常退出,通常指断网,或者没电

mGuestLiveView.roomDisconnect(errCode, errMsg);

}

}

// 解析文本消息

private void processTextMsg(LiveMessageEvent.SxbMsgInfo info) {

if (null == info.data || !(info.data instanceof ILVText)) {

return;

}

ILVText text = (ILVText) info.data;

if (text.getType() == ILVText.ILVTextType.eGroupMsg

&& !text.getDestId().equals(rommId)) {

if (TextUtils.isEmpty(rommId)) {

LogUtils.d("suyan","========当前的roomid为空");

}

return;

}

String name = info.senderId;

if (null != info.profile && !TextUtils.isEmpty(info.profile.getNickName())) {

name = info.profile.getNickName();

}

if (null != mGuestLiveView)

mGuestLiveView.refreshText(text.getText(), name);

}

// 解析自定义信令

private void processCmdMsg(LiveMessageEvent.SxbMsgInfo info) {

if (null == info.data || !(info.data instanceof ILVCustomCmd)) {

return;

}

ILVCustomCmd cmd = (ILVCustomCmd) info.data;

if (cmd.getType() == ILVText.ILVTextType.eGroupMsg

&& !cmd.getDestId().equals(rommId)) {

if (TextUtils.isEmpty(rommId)) {

LogUtils.d("suyan","========当前的roomid为空");

}

return;

}

String name = info.senderId;

if (null != info.profile && !TextUtils.isEmpty(info.profile.getNickName())) {

name = info.profile.getNickName();

}

handleCustomMsg(cmd.getCmd(), cmd.getParam(), info.senderId, name);

}

private void processOtherMsg(LiveMessageEvent.SxbMsgInfo info) {

if (null == info.data || !(info.data instanceof TIMMessage)) {

return;

}

TIMMessage currMsg = (TIMMessage) info.data;

// 过滤非当前群组消息

if (currMsg.getConversation() != null && currMsg.getConversation().getPeer() != null) {

if (currMsg.getConversation().getType() == TIMConversationType.Group

&& !rommId.equals(currMsg.getConversation().getPeer())) {

if (TextUtils.isEmpty(rommId)) {

LogUtils.d("suyan","========当前的roomid为空");

}

return;

}

}

for (int j = 0; j < currMsg.getElementCount(); j++) {

if (currMsg.getElement(j) == null)

continue;

TIMElem elem = currMsg.getElement(j);

TIMElemType type = elem.getType();

//系统消息

if (type == TIMElemType.GroupSystem) { // 群组解散消息

if (TIMGroupSystemElemType.TIM_GROUP_SYSTEM_DELETE_GROUP_TYPE == ((TIMGroupSystemElem) elem).getSubtype()) {

if (null != mGuestLiveView)

mGuestLiveView.dismissGroup("host", null);

}

} else if (type == TIMElemType.Custom) {

try {

final String strMagic = "__ACTION__";

String customText = new String(((TIMCustomElem) elem).getData(), "UTF-8");

if (!customText.startsWith(strMagic)) // 检测前缀

continue;

JSONTokener jsonParser = new JSONTokener(customText.substring(strMagic.length() + 1));

JSONObject json = (JSONObject) jsonParser.nextValue();

String action = json.optString("action", "");

if (action.equals("force_exit_room") || action.equals("force_disband_room")) {

JSONObject objData = json.getJSONObject("data");

String strRoomNum = objData.optString("room_num", "");

if (strRoomNum.equals(String.valueOf(ILiveRoomManager.getInstance().getRoomId()))) {

if (null != mGuestLiveView) {

mGuestLiveView.forceQuitRoom("管理员已将房间解散或将您踢出房间!");

}

}

}

} catch (Exception e) {

}

}

}

}

@Override

public void update(Observable observable, Object o) {

LiveMessageEvent.SxbMsgInfo info = (LiveMessageEvent.SxbMsgInfo) o;

LogUtils.d("suyan", "======收到消息" + info.msgType);

switch (info.msgType) {

case LiveMessageEvent.MSGTYPE_TEXT:

processTextMsg(info);

break;

case LiveMessageEvent.MSGTYPE_CMD:

processCmdMsg(info);

break;

case LiveMessageEvent.MSGTYPE_OTHER:

LogUtils.d("suyan", "=======其他消息");

processOtherMsg(info);

case LiveMessageEvent.MSGTYPE_DDETAIL:

LogUtils.d("suyan", "=======刷新房间数据");

processDetailMsg(info);

break;

}

}

// 解析自定义信令

private void processDetailMsg(LiveMessageEvent.SxbMsgInfo info) {

if (null != info && !TextUtils.isEmpty(info.senderId)) {

if (null != mGuestLiveView) {

mGuestLiveView.refreshData(info.senderId);

}

}

}

private void handleCustomMsg(int action, String param, String identifier, String nickname) {

LogUtils.d(TAG, "handleCustomMsg->action: " + action);

if (null == mGuestLiveView) {

return;

}

LiveCusEntity mliveCusEntity = updateGson(param);

if (mliveCusEntity != null) {

LogUtils.d("suyan", "===========解析后的数据" + mliveCusEntity.getContent().getLike_num() + "=" + mliveCusEntity.getContent().getOnline_num() + "=" + mliveCusEntity.getUser().getUid());

}

switch (action) {

case Constans.AVIMCMD_PRAISE://点赞

mGuestLiveView.refreshGoodLike();

break;

case Constans.AVIMCMD_ENTERLIVE://其他成员加入

mGuestLiveView.memberJoin(identifier, nickname);

break;

case Constans.AVIMCMD_EXITLIVE: //用户退出直播

mGuestLiveView.hostOffline(identifier, nickname);

break;

case ILVLiveConstants.ILVLIVE_CMD_LINKROOM_LIMIT: // 达到上限

LogUtils.d("suyan","========到达上限");

break;

case Constans.AVIMCMD_HOST_BACK://主播回来了

LogUtils.d("suyan","========主播回来了");

//昵称:nickname id:identifier

case Constans.AVIMCMD_PRAISE_TOTAL://观众进入房间,主播发送现在的总点赞数

try {

if (mliveCusEntity != null && !TextUtils.isEmpty(mliveCusEntity.getContent().getLike_num())) {

mGuestLiveView.refreshTotalGoodLike(Long.parseLong(mliveCusEntity.getContent().getLike_num()));

}

} catch (NumberFormatException e) {

e.printStackTrace();

}

default:

break;

}

}

//解析jsong

public LiveCusEntity updateGson(String jsonTest) {

if (!TextUtils.isEmpty(jsonTest)) {

LiveCusEntity mLiveCusEntity;

try {

mLiveCusEntity = gson.fromJson(jsonTest, LiveCusEntity.class);

return mLiveCusEntity;

} catch (JsonSyntaxException e) {

e.printStackTrace();

return null;

}

} else {

return null;

}

}

//发送json

public String sendCusJsn() {

LiveCusEntity liveCusEntity = new LiveCusEntity();

LiveCusEntity.LiveContent mLiveContent = new LiveCusEntity.LiveContent();

liveCusEntity.setContent(mLiveContent);

LiveCusEntity.User mUser = new LiveCusEntity.User();

mUser.setUid(ConfigUtils.getUid());

liveCusEntity.setUser(mUser);

String json = gson.toJson(liveCusEntity, LiveCusEntity.class);

LogUtils.d("suyan", "==========自定义数据" + json);

return json;

}

//销毁

public void onDestory() {

mGuestLiveView = null;

mContext = null;

LiveMessageEvent.getInstance().deleteObserver(this);

ILVLiveManager.getInstance().quitRoom(null);

ILiveRoomManager.getInstance().onDestory();

ILVLiveManager.getInstance().onDestory();

}

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值