This commit is contained in:
zhongchao
2021-02-07 17:57:57 +08:00
9 changed files with 160 additions and 264 deletions

View File

@@ -2,12 +2,9 @@ package com.mogo.cloud;
import android.os.Bundle;
import com.mogo.cloud.live.manager.CameraFrameManager;
import com.mogo.cloud.live.manager.ILiveStreamManager;
import com.mogo.cloud.live.manager.LiveStreamManagerImpl;
import com.mogo.cloud.live.server.PushService;
import com.mogo.cloud.passport.MoGoAiCloudClientConfig;
import com.mogo.cloud.util.Devices;
/**
@@ -16,20 +13,22 @@ import com.mogo.cloud.util.Devices;
public class LivePushActivity extends BaseLiveActivity {
public static final String TAG = "PushActivity";
private boolean isLive = false;
ILiveStreamManager liveStreamManager;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// 初始化直播流管理
ILiveStreamManager liveStreamManager = LiveStreamManagerImpl.getInstance(this, MoGoAiCloudClientConfig.getInstance().getSn());
liveStreamManager = LiveStreamManagerImpl.getInstance(this, MoGoAiCloudClientConfig.getInstance().getSn());
liveStreamManager.uploadCamStatus(1, 1);
}
@Override
public void onVideoFrame(byte[] bytes, int bytesLength) {
//Log.i(TAG, "onVideoFrame byte length: " + bytesLength);
CameraFrameManager.getInstance().notifyYUVData(bytes, 1280, 720, 3);
if (liveStreamManager != null) {
liveStreamManager.notifyYUVData(bytes, 1280, 720, 3);
}
}
@Override
@@ -40,6 +39,8 @@ public class LivePushActivity extends BaseLiveActivity {
@Override
protected void onDestroy() {
super.onDestroy();
PushService.startService(this, PushService.ACTION_STOP_RTMP_PUSH, null);
if (liveStreamManager != null) {
liveStreamManager.stopLiveStream();
}
}
}

View File

@@ -8,13 +8,13 @@ public interface ILiveProgressListener {
/**
* 开始
*/
default void onStart() {
default void onEngineStart() {
}
/**
* 结束
*/
default void onStop() {
default void onEngineStop() {
}
/**
@@ -34,6 +34,11 @@ public interface ILiveProgressListener {
*/
void onDisConnect();
/**
* 房间在线人数变化
*/
void onRoomOnlineUserCountUpdate(int count);
/**
* 调试错误信息回调
*

View File

@@ -1,8 +1,6 @@
package com.mogo.cloud.live.manager;
import com.mogo.cloud.live.listener.ILiveStatusListener;
public interface ILiveStreamManager {
/**
* 开始直播
@@ -37,13 +35,6 @@ public interface ILiveStreamManager {
*/
void notifyYUVData(byte[] data, int width, int height, int type);
/**
* 直播状态改变时回调
*
* @param changeCallback live status change callback
*/
void setLiveStatusChangeCallback(ILiveStatusListener changeCallback);
/**
* 释放资源
*/

View File

@@ -1,10 +1,16 @@
package com.mogo.cloud.live.manager;
import android.content.Context;
import android.os.Handler;
import android.os.SystemClock;
import android.util.Log;
import com.mogo.cloud.live.listener.ILiveStatusListener;
import com.mogo.cloud.live.model.CommandModel;
import com.mogo.cloud.live.server.PushService;
import com.mogo.cloud.live.utils.LiveStreamUtils;
import com.mogo.cloud.live.socket.SocketMsgUtils;
import com.mogo.cloud.live.socket.SocketRequestUtils;
import com.mogo.cloud.socket.IMogoCloudSocketOnMessageListener;
import com.mogo.cloud.socket.MsgBody;
import com.mogo.utils.logger.Logger;
@@ -20,7 +26,17 @@ public class LiveStreamManagerImpl implements ILiveStreamManager {
public static volatile String mDevicesId;
private final Context mContext;
private final LiveStreamUtils mLiveStreamUtils;
// 循环上报摄像头可直播状态间隔时间
private static final int PUSH_CAM_TIME = 10 * 60 * 1000;
private static volatile int sCam1LiveStatus = 0, sCam2LiveStatus = 0;
private static volatile int sCam1AvailableStatus = 0, sCam2AvailableStatus = 0;
private static final int PUSH_START = 0; // 开始
private static final int PUSH_STOP = 1; // 结束
private static final String C1 = "C_1"; //前置摄像头
private static final String C2 = "C_2"; //后置摄像头
private Handler mHandler; // 循环上报摄像头状态
private SocketMsgUtils mSocketMsgUtils; // Socket 长链接
public static ILiveStreamManager getInstance(Context context, String devicesId) {
if (sInstance == null) {
@@ -33,15 +49,37 @@ public class LiveStreamManagerImpl implements ILiveStreamManager {
return sInstance;
}
private LiveStreamManagerImpl(Context context, String devicesId) {
mContext = context;
mDevicesId = devicesId;
mLiveStreamUtils = LiveStreamUtils.getInstance(mContext);
mHandler = new Handler();
// 初始化Socket长连接通道
mSocketMsgUtils = SocketMsgUtils.getInstance(mContext,
new IMogoCloudSocketOnMessageListener<CommandModel>() {
@Override
public Class<CommandModel> target() {
return CommandModel.class;
}
@Override
public void onMsgReceived(CommandModel obj) {
Log.i(TAG, "onMsgReceived: obj=" + obj);
Logger.i(TAG, "onMsgReceived: obj=" + obj + " systemClock :" + SystemClock.elapsedRealtime() + " SystemTime : " + System.currentTimeMillis());
livePushHandler(obj.getType(), obj.getVideoChannel());
}
});
// 初始化查询摄像头状态
restartCamStatusLoop();
}
/**
* 获取前置摄像头直播状态
*/
@Override
public int getLiveStatus() {
return mLiveStreamUtils.getCam1LiveStatus();
return sCam1LiveStatus;
}
@Override
@@ -59,7 +97,13 @@ public class LiveStreamManagerImpl implements ILiveStreamManager {
@Override
public void uploadCamStatus(int frontStatus, int backStatus) {
Logger.d(TAG, "uploadCamStatus frontStatus is:" + frontStatus + " backStatus is:" + backStatus);
mLiveStreamUtils.uploadCamStatus(frontStatus, backStatus);
sCam1AvailableStatus = frontStatus;
sCam2AvailableStatus = backStatus;
MsgBody msgBody = new MsgBody();
msgBody.msgType(196614);
msgBody.content(SocketRequestUtils.buildDeviceData(frontStatus, backStatus));
mSocketMsgUtils.uploadCamInfo(msgBody);
}
@Override
@@ -68,12 +112,62 @@ public class LiveStreamManagerImpl implements ILiveStreamManager {
}
@Override
public void setLiveStatusChangeCallback(ILiveStatusListener callback) {
mLiveStreamUtils.setLiveStatusChangeCallback(callback);
public void release() {
try {
mSocketMsgUtils.release();
sCam1LiveStatus = 0;
sCam2LiveStatus = 0;
} catch (Exception e) {
e.printStackTrace();
}
}
@Override
public void release() {
mLiveStreamUtils.release();
/**
* 开启摄像头状态循环
*/
private void restartCamStatusLoop() {
Log.i(TAG, "开启摄像头状态循环");
if (mHandler != null) {
mHandler.removeCallbacks(mCamStatusRun);
mHandler.postDelayed(mCamStatusRun, PUSH_CAM_TIME);
}
}
/**
* 循环同步摄像头状态
*/
private Runnable mCamStatusRun = () -> {
Log.i(TAG, "循环同步摄像头状态");
uploadCamStatus(sCam1AvailableStatus, sCam2AvailableStatus);
restartCamStatusLoop();
};
/**
* 接收到长连接指令
*
* @param videoChannel 指令数据
*/
public void livePushHandler(int status, String videoChannel) {
try {
// 前置摄像头
if (C1.equals(videoChannel)) {
// 停止直播
if (status == PUSH_STOP) {
PushService.startService(mContext, PushService.ACTION_STOP_RTMP_PUSH, LiveStreamManagerImpl.mDevicesId);
// 释放资源
CameraFrameManager.getInstance().release();
}
// 开始直播
else if (status == PUSH_START) {
PushService.startService(mContext, PushService.ACTION_START_RTMP_PUSH, LiveStreamManagerImpl.mDevicesId);
}
sCam1LiveStatus = status;
} else {
Log.d(TAG, "目前只支持前置行车记录仪");
}
} catch (Exception e) {
e.printStackTrace();
}
}
}

View File

@@ -103,6 +103,10 @@ public class MoGoLiveManager {
* 播放状态true-播放中false-没有播放
*/
private boolean isPlaying;
/**
* 当前在直播间的人数,只剩下一个人的时候需要停掉直播推送
*/
private int onlineNumber;
private static final class Holder {
private static final MoGoLiveManager manager = new MoGoLiveManager();
@@ -181,13 +185,11 @@ public class MoGoLiveManager {
public void onEngineStateUpdate(ZegoEngineState state) {
super.onEngineStateUpdate(state);
Logger.i(TAG, "onEngineStateUpdate state : " + state.name());
if (state == ZegoEngineState.START) {
if (listener != null) {
listener.onStart();
}
} else {
if (listener != null) {
listener.onStop();
if (listener != null) {
if (state == ZegoEngineState.START) {
listener.onEngineStart();
} else {
listener.onEngineStop();
}
}
}
@@ -198,16 +200,12 @@ public class MoGoLiveManager {
super.onRoomStateUpdate(roomID, state, errorCode, extendedData);
Logger.i(TAG, "onRoomStateUpdate roomID : " + roomID + " state:" + state + " errorCode:" + errorCode);
//房间状态更新
if (state == ZegoRoomState.CONNECTING) {
if (listener != null) {
if (listener != null) {
if (state == ZegoRoomState.CONNECTING) {
listener.onConnecting();
}
} else if (state == ZegoRoomState.CONNECTED) {
if (listener != null) {
} else if (state == ZegoRoomState.CONNECTED) {
listener.onConnected(roomID);
}
} else {
if (listener != null) {
} else {
listener.onDisConnect();
}
}
@@ -218,6 +216,10 @@ public class MoGoLiveManager {
public void onRoomOnlineUserCountUpdate(String roomID, int count) {
super.onRoomOnlineUserCountUpdate(roomID, count);
Logger.i(TAG, "onRoomOnlineUserCountUpdate roomID : " + roomID + " , count : " + count);
onlineNumber = count;
if (listener != null) {
listener.onRoomOnlineUserCountUpdate(count);
}
}
// 房间内其他用户增加或减少的通知回调
@@ -261,7 +263,9 @@ public class MoGoLiveManager {
* 销毁即构引擎
*/
private void destroyEngine() {
ZegoExpressEngine.destroyEngine(null);
ZegoExpressEngine.destroyEngine(() -> {
Logger.d(TAG, "销毁ZeGo引擎");
});
}
/**
@@ -312,7 +316,7 @@ public class MoGoLiveManager {
Logger.i(TAG, "setCustomVideoCaptureHandler onStart");
isCaptureStatus = true;
if (listener != null) {
listener.onStart();
listener.onEngineStart();
}
}
@@ -322,7 +326,7 @@ public class MoGoLiveManager {
Logger.i(TAG, "setCustomVideoCaptureHandler onStop");
isCaptureStatus = false;
if (listener != null) {
listener.onStop();
listener.onEngineStop();
}
}
});

View File

@@ -15,7 +15,8 @@ import com.mogo.cloud.live.manager.MoGoLiveManager;
import com.mogo.cloud.live.utils.ByteUtils;
public class PushService extends Service implements IYUVDataListener {
public class PushService extends Service
implements IYUVDataListener {
public static final String ACTION_START_RTMP_PUSH = "action_start_rtmp_push";
public static final String ACTION_STOP_RTMP_PUSH = "action_stop_rtmp_push";
@@ -139,7 +140,7 @@ public class PushService extends Service implements IYUVDataListener {
if (mLivePusher != null && mLivePusher.isCaptureStatus()
&& mLivePusher.isPushing() && data != null) {
// 将YUV数据发布到即构
MoGoLiveManager.getInstance().startPublishingStream(
mLivePusher.startPublishingStream(
ByteUtils.getBuffer(data, data.length), data.length,
SystemClock.elapsedRealtime());
}

View File

@@ -50,6 +50,14 @@ public class SocketMsgUtils implements IMogoCloudSocketMsgAckListener {
mSocketManager.registerOnMessageListener(401017, listener);
}
/**
* 释放资源
*/
public void release() {
mSocketManager.release();
mSocketManager.unregisterOnMessageListener(401017, mMessageListener);
}
/**
* 上传相机信息
*
@@ -59,14 +67,6 @@ public class SocketMsgUtils implements IMogoCloudSocketMsgAckListener {
mSocketManager.sendMsg(appId, headerType, body, this);
}
/**
* 释放资源
*/
public void release() {
mSocketManager.release();
mSocketManager.unregisterOnMessageListener(401017, mMessageListener);
}
@Override
public void onAck(long msgId) {
Log.i(TAG, "msgId=" + msgId);

View File

@@ -1,205 +0,0 @@
package com.mogo.cloud.live.utils;
import android.content.Context;
import android.os.Handler;
import android.os.SystemClock;
import android.util.Log;
import com.mogo.cloud.live.listener.ILiveStatusListener;
import com.mogo.cloud.live.manager.CameraFrameManager;
import com.mogo.cloud.live.manager.LiveStreamManagerImpl;
import com.mogo.cloud.live.model.CommandModel;
import com.mogo.cloud.live.server.PushService;
import com.mogo.cloud.live.socket.SocketMsgUtils;
import com.mogo.cloud.live.socket.SocketRequestUtils;
import com.mogo.cloud.socket.IMogoCloudSocketOnMessageListener;
import com.mogo.cloud.socket.MsgBody;
import com.mogo.utils.logger.Logger;
public class LiveStreamUtils implements IMogoCloudSocketOnMessageListener<CommandModel> {
private static final String TAG = "LiveStreamUtils";
private static final int POLL_TIME = 30 * 1000;
// 循环上报摄像头可直播状态间隔时间
private static final int PUSH_CAM_TIME = 10 * 60 * 1000;
// 开始
private static final int PUSH_START = 0;
// 结束
private static final int PUSH_STOP = 1;
private static final String C1 = "C_1"; //前置摄像头
private static final String C2 = "C_2"; //后置摄像头
private static volatile LiveStreamUtils sInstance;
private static volatile int sCam1LiveStatus = 0, sCam2LiveStatus = 0;
private static volatile int sCam1AvailableStatus = 0, sCam2AvailableStatus = 0;
private ILiveStatusListener mLiveStatusCallback;
private Context mContext;
private Handler mHandler;
private SocketMsgUtils mSocketMsgUtils;
public static LiveStreamUtils getInstance(Context context) {
if (sInstance == null) {
synchronized (LiveStreamUtils.class) {
if (sInstance == null) {
sInstance = new LiveStreamUtils(context.getApplicationContext());
}
}
}
return sInstance;
}
private LiveStreamUtils(Context context) {
mContext = context;
mHandler = new Handler();
init();
initPoll();
}
/**
* 初始化
*/
private void init() {
// 初始化Socket长连接通道
mSocketMsgUtils = SocketMsgUtils.getInstance(mContext, this);
}
/**
* 初始化查询摄像头状态
*/
private void initPoll() {
restartCamStatusLoop();
}
/**
* 获取前置摄像头直播状态
*/
public int getCam1LiveStatus() {
return sCam1LiveStatus;
}
/**
* 后置摄像头直播状态
*/
public int getCam2LiveStatus() {
return sCam2LiveStatus;
}
/**
* 上传摄像头状态
*
* @param cam1Status 前置摄像头可直播状态
* @param cam2Status 后置摄像头可直播状态
*/
public void uploadCamStatus(int cam1Status, int cam2Status) {
Log.i(TAG, "上传摄像头状态");
sCam1AvailableStatus = cam1Status;
sCam2AvailableStatus = cam2Status;
MsgBody msgBody = new MsgBody();
msgBody.msgType(196614);
msgBody.content(SocketRequestUtils.buildDeviceData(cam1Status, cam2Status));
mSocketMsgUtils.uploadCamInfo(msgBody);
}
/**
* 接收到长连接指令
*
* @param videoChannel 指令数据
*/
private void rtmpPushHandler(int status, String videoChannel) {
try {
// 前置摄像头
if (C1.equals(videoChannel)) {
// 停止直播
if (status == PUSH_STOP) {
//PushService.startService(mContext, PushService.ACTION_STOP_RTMP_PUSH, LiveStreamManagerImpl.mDevicesId);
}
// 开始直播
else {
PushService.startService(mContext, PushService.ACTION_START_RTMP_PUSH, LiveStreamManagerImpl.mDevicesId);
}
// 同步状态
if (sCam1LiveStatus != PUSH_STOP) {
liveStatusCallbackOnChange(C1, PUSH_STOP);
CameraFrameManager.getInstance().release();
} else {
liveStatusCallbackOnChange(C1, PUSH_START);
}
sCam1LiveStatus = status;
} else {
Log.d(TAG, "目前只支持前置行车记录仪");
}
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 直播状态回调
*
* @param camId 摄像头ID
* @param status 状态
*/
private void liveStatusCallbackOnChange(String camId, int status) {
if (mLiveStatusCallback != null) {
mLiveStatusCallback.onChange(camId, status);
}
}
/**
* 开启摄像头状态循环
*/
private void restartCamStatusLoop() {
Log.i(TAG, "开启摄像头状态循环");
if (mHandler != null) {
mHandler.removeCallbacks(mCamStatusRun);
mHandler.postDelayed(mCamStatusRun, PUSH_CAM_TIME);
}
}
/**
* 循环同步摄像头状态
*/
private Runnable mCamStatusRun = () -> {
Log.i(TAG, "循环同步摄像头状态");
uploadCamStatus(sCam1AvailableStatus, sCam2AvailableStatus);
restartCamStatusLoop();
};
/**
* 设置直播状态回调用
*
* @param changeCallback 回调接口对象
*/
public void setLiveStatusChangeCallback(ILiveStatusListener changeCallback) {
mLiveStatusCallback = changeCallback;
}
public void release() {
try {
sCam1LiveStatus = 0;
sCam2LiveStatus = 0;
mSocketMsgUtils.release();
} catch (Exception e) {
e.printStackTrace();
}
}
@Override
public Class<CommandModel> target() {
return CommandModel.class;
}
@Override
public void onMsgReceived(CommandModel obj) {
Log.i(TAG, "onMsgReceived: obj=" + obj);
Logger.i(TAG, "onMsgReceived: obj=" + obj + " systemClock :" + SystemClock.elapsedRealtime() + " SystemTime : " + System.currentTimeMillis());
rtmpPushHandler(obj.getType(), obj.getVideoChannel());
}
}

View File

@@ -108,12 +108,12 @@ public class TrafficLiveManager implements ILiveProgressListener {
}
@Override
public void onStart() {
public void onEngineStart() {
callBack.onLiveStart();
}
@Override
public void onStop() {
public void onEngineStop() {
callBack.onLiveStop();
}
@@ -134,6 +134,11 @@ public class TrafficLiveManager implements ILiveProgressListener {
callBack.onDisConnect();
}
@Override
public void onRoomOnlineUserCountUpdate(int count) {
}
@Override
public void onDebugError(int errorCode, String funcName, String errorInfo) {
Logger.e(TAG, "onDebugError errorCode : " + errorCode + " funcName : " + funcName + " errorInfo : " + errorInfo);