diff --git a/app/src/main/java/com/mogo/cloud/LivePushActivity.java b/app/src/main/java/com/mogo/cloud/LivePushActivity.java index 3d8a479..2bb2843 100644 --- a/app/src/main/java/com/mogo/cloud/LivePushActivity.java +++ b/app/src/main/java/com/mogo/cloud/LivePushActivity.java @@ -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(); + } } } \ No newline at end of file diff --git a/foudations/mogo-live/src/main/java/com/mogo/cloud/live/listener/ILiveProgressListener.java b/foudations/mogo-live/src/main/java/com/mogo/cloud/live/listener/ILiveProgressListener.java index 781f628..a4c2e5b 100644 --- a/foudations/mogo-live/src/main/java/com/mogo/cloud/live/listener/ILiveProgressListener.java +++ b/foudations/mogo-live/src/main/java/com/mogo/cloud/live/listener/ILiveProgressListener.java @@ -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); + /** * 调试错误信息回调 * diff --git a/foudations/mogo-live/src/main/java/com/mogo/cloud/live/manager/ILiveStreamManager.java b/foudations/mogo-live/src/main/java/com/mogo/cloud/live/manager/ILiveStreamManager.java index bcb50ed..8d5ae0e 100644 --- a/foudations/mogo-live/src/main/java/com/mogo/cloud/live/manager/ILiveStreamManager.java +++ b/foudations/mogo-live/src/main/java/com/mogo/cloud/live/manager/ILiveStreamManager.java @@ -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); - /** * 释放资源 */ diff --git a/foudations/mogo-live/src/main/java/com/mogo/cloud/live/manager/LiveStreamManagerImpl.java b/foudations/mogo-live/src/main/java/com/mogo/cloud/live/manager/LiveStreamManagerImpl.java index 1939f9c..ec8503e 100644 --- a/foudations/mogo-live/src/main/java/com/mogo/cloud/live/manager/LiveStreamManagerImpl.java +++ b/foudations/mogo-live/src/main/java/com/mogo/cloud/live/manager/LiveStreamManagerImpl.java @@ -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() { + + @Override + public Class 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(); + } } } diff --git a/foudations/mogo-live/src/main/java/com/mogo/cloud/live/manager/MoGoLiveManager.java b/foudations/mogo-live/src/main/java/com/mogo/cloud/live/manager/MoGoLiveManager.java index c932f1b..35420b9 100644 --- a/foudations/mogo-live/src/main/java/com/mogo/cloud/live/manager/MoGoLiveManager.java +++ b/foudations/mogo-live/src/main/java/com/mogo/cloud/live/manager/MoGoLiveManager.java @@ -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(); } } }); diff --git a/foudations/mogo-live/src/main/java/com/mogo/cloud/live/server/PushService.java b/foudations/mogo-live/src/main/java/com/mogo/cloud/live/server/PushService.java index 79a549d..af72147 100644 --- a/foudations/mogo-live/src/main/java/com/mogo/cloud/live/server/PushService.java +++ b/foudations/mogo-live/src/main/java/com/mogo/cloud/live/server/PushService.java @@ -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()); } diff --git a/foudations/mogo-live/src/main/java/com/mogo/cloud/live/socket/SocketMsgUtils.java b/foudations/mogo-live/src/main/java/com/mogo/cloud/live/socket/SocketMsgUtils.java index 843aaa9..3a388a1 100644 --- a/foudations/mogo-live/src/main/java/com/mogo/cloud/live/socket/SocketMsgUtils.java +++ b/foudations/mogo-live/src/main/java/com/mogo/cloud/live/socket/SocketMsgUtils.java @@ -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); diff --git a/foudations/mogo-live/src/main/java/com/mogo/cloud/live/utils/LiveStreamUtils.java b/foudations/mogo-live/src/main/java/com/mogo/cloud/live/utils/LiveStreamUtils.java deleted file mode 100644 index 0027c2f..0000000 --- a/foudations/mogo-live/src/main/java/com/mogo/cloud/live/utils/LiveStreamUtils.java +++ /dev/null @@ -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 { - 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 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()); - } -} diff --git a/modules/mogo-trafficlive/src/main/java/com/mogo/cloud/trafficlive/core/TrafficLiveManager.java b/modules/mogo-trafficlive/src/main/java/com/mogo/cloud/trafficlive/core/TrafficLiveManager.java index c6a3027..76f834d 100644 --- a/modules/mogo-trafficlive/src/main/java/com/mogo/cloud/trafficlive/core/TrafficLiveManager.java +++ b/modules/mogo-trafficlive/src/main/java/com/mogo/cloud/trafficlive/core/TrafficLiveManager.java @@ -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);