迁移mogo-module-extensions到MoGoEagleEye.core.function-impl.mogo-core-function-monitoring

Signed-off-by: donghongyu <donghongyu@zhidaoauto.com>
This commit is contained in:
donghongyu
2022-03-02 18:32:39 +08:00
parent 1820610e42
commit fe79330014
71 changed files with 50 additions and 2450 deletions

View File

@@ -68,7 +68,6 @@ dependencies {
api rootProject.ext.dependencies.mogocommons
api rootProject.ext.dependencies.modulecommon
api rootProject.ext.dependencies.mogoservice
api rootProject.ext.dependencies.moduleextensions
api rootProject.ext.dependencies.callchat
api rootProject.ext.dependencies.callchatprovider
api rootProject.ext.dependencies.mapcustom
@@ -95,7 +94,6 @@ dependencies {
api project(':foudations:mogo-commons')
api project(':modules:mogo-module-common')
api project(':modules:mogo-module-service')
api project(':modules:mogo-module-extensions')
api project(':modules:mogo-module-carchatting')
api project(':modules:mogo-module-carchattingprovider')
api project(':libraries:map-custom')

View File

@@ -0,0 +1,171 @@
package com.mogo.eagle.core.function.live;
import android.content.Context;
import android.os.Bundle;
import android.text.TextUtils;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.ProgressBar;
import android.widget.TextView;
import androidx.constraintlayout.widget.ConstraintLayout;
import com.mogo.eagle.core.function.monitoring.R;
import com.mogo.eagle.core.utilcode.mogo.logger.Logger;
import com.mogo.eagle.core.widget.LiveRoundLayout;
import com.tencent.rtmp.ITXLivePlayListener;
import com.tencent.rtmp.TXLiveConstants;
import com.tencent.rtmp.TXLivePlayConfig;
import com.tencent.rtmp.TXLivePlayer;
import com.tencent.rtmp.ui.TXCloudVideoView;
/**
* V2XLiveGSYVideoView
*/
public class CameraLiveGSYVideoView extends LiveRoundLayout {
private static final String TAG = "CameraLiveGSYVideoView";
private TXCloudVideoView mTxcVideoView;
private ProgressBar mLoading;
private TXLivePlayer mLivePlayer;
private ConstraintLayout mClLoadError;
private TextView mTvRefreshButton;
private String mLiveUrl;
public CameraLiveGSYVideoView(Context context) {
this(context, null);
}
public CameraLiveGSYVideoView(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public CameraLiveGSYVideoView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
initView(context);
}
private void initView(Context context) {
LayoutInflater.from(context)
.inflate(R.layout.camera_view_video_layout_normal, this);
//mPlayerView 即 step1 中添加的界面 view
mTxcVideoView = findViewById(R.id.txcVideoView);
//创建 player 对象
mLivePlayer = new TXLivePlayer(context);
//关键 player 对象与界面 view
mLivePlayer.setPlayerView(mTxcVideoView);
mLivePlayer.setMute(true);
TXLivePlayConfig txLivePlayConfig = new TXLivePlayConfig();
// 增加重试次数
txLivePlayConfig.setConnectRetryCount(30);
mLivePlayer.setConfig(txLivePlayConfig);
mLivePlayer.enableHardwareDecode(true);
mLoading = findViewById(R.id.loading);
// mLoading.getIndeterminateDrawable().setColorFilter(ContextCompat.getColor(context, R.color.module_live_video_progress_bar_loading_color), PorterDuff.Mode.MULTIPLY);
mClLoadError = findViewById(R.id.clLoadError);
mTvRefreshButton = findViewById(R.id.tvRefreshButton);
mTvRefreshButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
mLoading.setVisibility(VISIBLE);
mClLoadError.setVisibility(GONE);
if (mLiveUrl != null) {
startLive(mLiveUrl);
}
}
});
}
/**
* 开始直播
*
* @param liveUrl 要直播的车机,如果没有直播的地址需要重新获取最新的直播地址
*/
public void startLive(String liveUrl) {
// 进行直播播放
if (mLivePlayer != null) {
if (!TextUtils.isEmpty(liveUrl)) {
mLiveUrl = liveUrl;
playLiveVideo(liveUrl);
}
}
}
/**
* 播放直播流,且开始心跳
*/
private void playLiveVideo(String liveUrl) {
try {
if (mLivePlayer != null) {
mLivePlayer.startPlay(liveUrl, TXLivePlayer.PLAY_TYPE_LIVE_RTMP);
mLivePlayer.setPlayListener(new ITXLivePlayListener() {
@Override
public void onPlayEvent(int event, Bundle bundle) {
Logger.w(TAG,
"直播信息= " +
"\n播放器onPlayEvent==" + event +
"\nbundle===" + bundle);
Logger.d(TAG, "liveUrl = " + liveUrl);
if (event == TXLiveConstants.PLAY_EVT_PLAY_LOADING) {
mLoading.setVisibility(VISIBLE);
mClLoadError.setVisibility(GONE);
} else if (event == TXLiveConstants.PLAY_EVT_PLAY_BEGIN) {
mLoading.setVisibility(GONE);
mClLoadError.setVisibility(GONE);
} else if (event < 0) {
stopLive(mLiveUrl);
mLoading.setVisibility(GONE);
mClLoadError.setVisibility(VISIBLE);
}
}
@Override
public void onNetStatus(Bundle bundle) {
Logger.w(TAG, "播放器onNetStatus===bundle===" + bundle);
}
});
}
} catch (Exception e) {
e.printStackTrace();
Logger.w(TAG, "播放器onNetStatus e = " + e);
mLoading.setVisibility(GONE);
mClLoadError.setVisibility(VISIBLE);
}
}
public void stopLive(String liveUrl) {
try {
Logger.w(TAG, "心跳:关闭直播...");
// 暂停
mLivePlayer.pause();
// true 代表清除最后一帧画面
mLivePlayer.stopPlay(true);
mTxcVideoView.onDestroy();
} catch (Exception e) {
e.printStackTrace();
}
}
@Override
protected void onAttachedToWindow() {
super.onAttachedToWindow();
if (mLiveUrl != null) {
startLive(mLiveUrl);
}
}
@Override
protected void onDetachedFromWindow() {
stopLive(mLiveUrl);
mLoading.setVisibility(VISIBLE);
super.onDetachedFromWindow();
}
}

View File

@@ -0,0 +1,117 @@
package com.mogo.eagle.core.function.live;
import android.util.Log;
import android.view.View;
import androidx.annotation.Nullable;
import com.mogo.cloud.socket.entity.SocketDownData;
import com.mogo.eagle.core.utilcode.mogo.logger.Logger;
import com.mogo.eagle.core.function.live.impl.AbsCameraScenario;
import com.mogo.service.windowview.IMogoTopViewStatusListener;
/**
* 路边摄像头直播控制 V2XPushLiveCarScenario
*/
public class CameraLiveManager extends AbsCameraScenario<SocketDownData.CloudRoadDataProto> implements IMogoTopViewStatusListener {
private static final String TAG = "CameraLiveManager";
private static CameraLiveManager mCameraLiveManager;
private boolean isShowWindow;
private CameraLiveManager() {
}
public static CameraLiveManager getInstance() {
if (mCameraLiveManager == null) {
synchronized (CameraLiveManager.class) {
if (mCameraLiveManager == null) {
mCameraLiveManager = new CameraLiveManager();
mCameraLiveManager.setV2XWindow(new PushCameraLiveWindow());
}
}
}
return mCameraLiveManager;
}
@Override
public void init(@Nullable SocketDownData.CloudRoadDataProto cloudRoadData) {
Log.d(TAG, "CameraLiveManager init -----> isShowWindow = " + isShowWindow);
if (isShowWindow) {
close();
}
setmCloudRoadData(cloudRoadData);
show();
}
@Override
public void show() {
showWindow();
}
@Override
public void showWindow() {
Log.d(TAG, "CameraLiveManager showWindow getV2XWindow = " + getV2XWindow());
if (getV2XWindow() != null) {
// ViewGroup.LayoutParams layoutParams =
// new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
// (int) AbsMogoApplication.getApp().getResources()
// .getDimension(R.dimen.module_video_window_height_content));
// TODO 这里需要替换展示方式
// MogoApisHandler.getInstance().getApis().getTopViewManager()
// .addViewNoLinkage(getV2XWindow().getView(), layoutParams, this);
// getV2XWindow().show(getmCloudRoadData());
isShowWindow = true;
}
}
@Override
public void closeWindow() {
if (getV2XWindow() != null) {
getV2XWindow().close();
}
isShowWindow = false;
}
@Override
public void showButton() {
}
@Override
public void closeButton() {
}
@Override
public void drawPOI() {
}
@Override
public void clearPOI() {
}
@Override
public void onViewAdded(View view) {
Logger.d(TAG, "展示 Window 动画结束");
}
@Override
public void onViewRemoved(View view) {
Logger.d(TAG, "关闭 Window 动画结束");
}
@Override
public void beforeViewAddAnim(View view) {
Logger.d(TAG, "展示 Window 开始");
}
@Override
public void beforeViewRemoveAnim(View view) {
}
}

View File

@@ -0,0 +1,182 @@
package com.mogo.eagle.core.function.live;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.text.TextUtils;
import android.util.Log;
import com.mogo.cloud.socket.entity.SocketDownData;
import com.mogo.commons.AbsMogoApplication;
import com.mogo.eagle.core.function.monitoring.R;
import com.mogo.eagle.core.utilcode.mogo.logger.Logger;
import com.mogo.eagle.core.utilcode.mogo.toast.TipToast;
import com.mogo.map.marker.IMogoMarker;
import com.mogo.map.marker.IMogoMarkerClickListener;
import com.mogo.map.marker.MogoMarkerOptions;
import com.mogo.module.common.MogoApisHandler;
import com.mogo.realtime.api.MoGoAiCloudRealTime;
import com.mogo.realtime.socket.IMogoCloudOnMsgListener;
/**
* vr模式下摄像头消息 CameraLiveNoticeHelper
*/
public class CameraLiveNoticeHelper implements IMogoCloudOnMsgListener {
private static final String TAG = "CameraLiveNoticeHelper";
private Context mContext;
private static IMogoMarker mMogoMarker;
private SocketDownData.CloudRoadDataProto mCloudRoadData;
private volatile boolean isVrMode;
private volatile boolean isVrModeMarker;
private volatile String mCurrentUuid;
public void init(Context context) {
Logger.d(TAG, "init ======= ");
mContext = context;
MoGoAiCloudRealTime.registerOnMsgListener(this);
MogoApisHandler.getInstance().getApis().getRegisterCenterApi().registerMogoMarkerClickListener(PushDataType.TYPE_PUSH_CAMERA_DATA, new IMogoMarkerClickListener() {
@Override
public boolean onMarkerClicked(IMogoMarker marker) {
//点击的marker的具体数据
if (mCloudRoadData != null && !TextUtils.isEmpty(mCloudRoadData.getRtmpUrl())) {
CameraLiveManager.getInstance().init(mCloudRoadData);
} else {
Logger.e(TAG, " onMarkerClicked mCloudRoadData == null ");
TipToast.shortTip("直播流地址为空");
}
return false;
}
});
}
public void release() {
MoGoAiCloudRealTime.unRegisterOnMsgListener(this);
MogoApisHandler.getInstance().getApis().getRegisterCenterApi().unregisterMogoMarkerClickListener(PushDataType.TYPE_PUSH_CAMERA_DATA);
mCloudRoadData = null;
mContext = null;
}
/**
* PushRoadConditionDrawer
* vr模式
*
* @param roadData 道路数据
*/
private void addVrCameraMarker(SocketDownData.CloudRoadDataProto roadData) {
Log.e(TAG, "addVrCameraMarker --lat = " + roadData.getLat() + "--lon =" + roadData.getLon() + "--uuid = " + roadData.getUuid() + "---rtmpUrl =" + roadData.getRtmpUrl());
if (!TextUtils.isEmpty(roadData.getRtmpUrl())) {
removeCameraMarker();
MogoMarkerOptions options = new MogoMarkerOptions()
.data(roadData)
.latitude(roadData.getLat())
.longitude(roadData.getLon());
options.anchor(0.5f, 0.5f);
Bitmap bitmap = BitmapFactory.decodeResource(mContext.getResources(), R.drawable.icon_space, null);
options.icon(bitmap);
mMogoMarker = MogoApisHandler.getInstance().getApis().getMapServiceApi().getMarkerManager(mContext)
.addMarker(PushDataType.TYPE_PUSH_CAMERA_DATA, options);
if (mMogoMarker != null) {
mMogoMarker.setInfoWindowAdapter(new CameraWindow3DAdapter(AbsMogoApplication.getApp(), options));
mMogoMarker.showInfoWindow();
mMogoMarker.setOwner(PushDataType.TYPE_PUSH_CAMERA_DATA);
}
}
}
/**
* 普通模式
*
* @param roadData 道路数据
*/
private void addNormalCameraMarker(SocketDownData.CloudRoadDataProto roadData) {
Log.e(TAG, "addNormalCameraMarker --lat = " + roadData.getLat() + " --lon =" + roadData.getLon() + "--uuid = " + roadData.getUuid() + "---rtmpUrl =" + roadData.getRtmpUrl());
if (!TextUtils.isEmpty(roadData.getRtmpUrl())) {
removeCameraMarker();
if (mMogoMarker != null) {
mMogoMarker.hideInfoWindow();
}
MogoMarkerOptions options = new MogoMarkerOptions()
.data(roadData)
.latitude(roadData.getLat())
.longitude(roadData.getLon());
options.anchor(0.5f, 0.5f);
Bitmap bitmap = BitmapFactory.decodeResource(mContext.getResources(), R.drawable.module_camera_normal_traffic, null);
options.icon(bitmap);
mMogoMarker = MogoApisHandler.getInstance().getApis().getMapServiceApi().getMarkerManager(mContext)
.addMarker(PushDataType.TYPE_PUSH_CAMERA_DATA, options);
if (mMogoMarker != null) {
mMogoMarker.setOwner(PushDataType.TYPE_PUSH_CAMERA_DATA);
}
}
}
private void removeCameraMarker() {
if (mMogoMarker != null) {
mMogoMarker.remove();
}
}
private void renderMarker(SocketDownData.LauncherSnapshotProto obj) {
if (obj != null) {
if (obj.getCamera() != null && !TextUtils.isEmpty(obj.getCamera().getRtmpUrl())) {
mCloudRoadData = obj.getCamera();
Log.d(TAG, "onMsgReceived getRtmpUrl = " + mCloudRoadData.getRtmpUrl() + "--- isVrMode = " + isVrMode + " ---isVrModeMarker = " + isVrModeMarker + ">>>>mCurrentUuid = " + mCurrentUuid + ">>>mCloudRoadData.getUuid() = " + mCloudRoadData.getUuid());
if (TextUtils.equals(mCurrentUuid, mCloudRoadData.getUuid())) {
if (isVrMode == isVrModeMarker) {
// do nothing.
Log.d(TAG, "-------------1------------");
} else {
if (isVrMode) {
Log.d(TAG, "-------------2------------");
addVrCameraMarker(mCloudRoadData);
isVrModeMarker = true;
} else {
Log.d(TAG, "-------------3------------");
addNormalCameraMarker(mCloudRoadData);
isVrModeMarker = false;
}
}
} else {
mCurrentUuid = mCloudRoadData.getUuid();
// 是否需要延迟
if (isVrMode) {
Log.d(TAG, "-------------4------------");
addVrCameraMarker(mCloudRoadData);
isVrModeMarker = true;
} else {
Log.d(TAG, "-------------5------------");
addNormalCameraMarker(mCloudRoadData);
isVrModeMarker = false;
}
}
} else {
//删除marker
if (obj.getCamera() != null) {
Log.e(TAG, "onMsgReceived RtmpUrl() = " + obj.getCamera().getRtmpUrl());
} else {
Log.e(TAG, "obj.getCamera() == null ----------- ");
}
removeCameraMarker();
}
} else {
Log.e(TAG, "onMsgReceived obj == null ");
}
}
@Override
public void onMsgSend(long id) {
//Logger.d(TAG, "onMsgSend id : " + id);
}
@Override
public void onMsgReceived(SocketDownData.LauncherSnapshotProto mogoSnapshotSetData) {
renderMarker(mogoSnapshotSetData);
}
}

View File

@@ -0,0 +1,29 @@
package com.mogo.eagle.core.function.live;
import android.content.Context;
import android.view.View;
import com.mogo.map.marker.IMogoInfoWindowAdapter;
import com.mogo.map.marker.IMogoMarker;
import com.mogo.map.marker.MogoMarkerOptions;
import com.mogo.module.common.drawer.marker.MapCameraInfoView;
/**
* @author lixiaopeng
* @since 2020/12/16
* 描述
*/
public class CameraWindow3DAdapter implements IMogoInfoWindowAdapter {
private Context mContext;
private MogoMarkerOptions mOptions;
public CameraWindow3DAdapter(Context context, MogoMarkerOptions options) {
this.mContext = context;
this.mOptions = options;
}
@Override
public View getInfoWindow(IMogoMarker marker) {
return new MapCameraInfoView(mContext, mOptions);
}
}

View File

@@ -0,0 +1,26 @@
package com.mogo.eagle.core.function.live;
import android.content.Context;
public class ExtensionServiceManager {
private static boolean isInit;
private static Context mContext;
private ExtensionServiceManager() {
}
public static void init(final Context context) {
if (!isInit) {
isInit = true;
mContext = context;
}
}
public static Context getContext() {
return mContext;
}
}

View File

@@ -0,0 +1,115 @@
package com.mogo.eagle.core.function.live;
import android.content.Context;
import android.os.Handler;
import android.text.TextUtils;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.ImageView;
import android.widget.RelativeLayout;
import com.mogo.cloud.socket.entity.SocketDownData;
import com.mogo.eagle.core.function.monitoring.R;
import com.mogo.eagle.core.utilcode.mogo.logger.Logger;
import com.mogo.module.common.MogoApisHandler;
import com.mogo.eagle.core.function.live.impl.ICameraWindow;
import com.mogo.service.imageloader.MogoImageView;
/**
* 点击摄像头 marker
* vr路边摄像头弹窗 V2XPushLiveCarWindow
*/
public class PushCameraLiveWindow extends RelativeLayout implements ICameraWindow<SocketDownData.CloudRoadDataProto> {
private static final String TAG = "PushCameraLiveWindow";
private CameraLiveGSYVideoView mLiveGSYVideoView;
private MogoImageView mIvReportHead;
private ImageView pushVideoClose;
// 直播30秒自动关闭
private static final Handler handlerV2XEvent = new Handler();
private static Runnable runnableV2XEvent;
public PushCameraLiveWindow() {
this(ExtensionServiceManager.getContext(), null);
}
public PushCameraLiveWindow(Context context) {
this(context, null);
}
public PushCameraLiveWindow(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public PushCameraLiveWindow(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
initView(context);
}
public void initView(Context context) {
Logger.w(TAG, "initView 。。。。。");
LayoutInflater.from(context).inflate(R.layout.camera_push_live_video, this);
// 详情列表
mLiveGSYVideoView = findViewById(R.id.videoPlayer);
mIvReportHead = findViewById(R.id.ivReportHead);
pushVideoClose = findViewById(R.id.pushVideoClose);
pushVideoClose.setOnClickListener(v -> {
//TODO 移除窗体
});
}
/**
* 展示直播Windows
*/
@Override
public void show(SocketDownData.CloudRoadDataProto entity) {
if (entity != null) {
Logger.w(TAG, "更新直播信息 show entity = " + entity);
if (!TextUtils.isEmpty(entity.getRtmpUrl())) {
Logger.w(TAG, "entity.getRtmpUrl() = " + entity.getRtmpUrl());
mIvReportHead.setVisibility(INVISIBLE);
MogoApisHandler.getInstance().getApis().getImageLoaderApi().displayImage(entity.getRtmpUrl(),
mIvReportHead);
mLiveGSYVideoView.startLive(entity.getRtmpUrl());
}
countDownV2XEvent();
}
}
@Override
public View getView() {
return this;
}
@Override
public void close() {
// 停止倒计时
if (runnableV2XEvent != null) {
handlerV2XEvent.removeCallbacks(runnableV2XEvent);
runnableV2XEvent = null;
}
//TODO 移除窗体
}
/**
* 窗体倒计时
*/
public void countDownV2XEvent() {
// 倒计时
if (runnableV2XEvent == null) {
runnableV2XEvent = () -> {
//Logger.d(MODULE_NAME, "V2X=== Window 30秒倒计时结束。。。");
//TODO 移除窗体
};
} else {
handlerV2XEvent.removeCallbacks(runnableV2XEvent);
}
Logger.d(TAG, "V2X=== Window 展示开始倒计时:" );
handlerV2XEvent.postDelayed(runnableV2XEvent, 20000);
}
}

View File

@@ -0,0 +1,13 @@
package com.mogo.eagle.core.function.live;
/**
* @author lixiaopeng
* @description
* @since 2020/12/13
*/
public class PushDataType {
/**
* Push 摄像头事件场景 VR
*/
public static final String TYPE_PUSH_CAMERA_DATA = "TYPE_PUSH_CAMERA_DATA";
}

View File

@@ -0,0 +1,38 @@
package com.mogo.eagle.core.function.live.impl;
import androidx.annotation.Nullable;
import com.mogo.cloud.socket.entity.SocketDownData;
public abstract class AbsCameraScenario<T> implements ICameraScenario {
protected String TAG = "AbsCameraScenario";
private ICameraWindow mV2XWindow;
private SocketDownData.CloudRoadDataProto mCloudRoadData;
public abstract void init(@Nullable SocketDownData.CloudRoadDataProto cloudRoadData);
@Override
public void close() {
closeButton();
closeWindow();
clearPOI();
}
public ICameraWindow getV2XWindow() {
return mV2XWindow;
}
public void setV2XWindow(@Nullable ICameraWindow mV2XWindow) {
this.mV2XWindow = mV2XWindow;
}
public SocketDownData.CloudRoadDataProto getmCloudRoadData() {
return mCloudRoadData;
}
public void setmCloudRoadData(SocketDownData.CloudRoadDataProto mCloudRoadData) {
this.mCloudRoadData = mCloudRoadData;
}
}

View File

@@ -0,0 +1,46 @@
package com.mogo.eagle.core.function.live.impl;
public interface ICameraScenario {
/**
* 展示场景
*/
void show();
/**
* 关闭场景
*/
void close();
/**
* 展示Window
*/
void showWindow();
/**
* 关闭Window
*/
void closeWindow();
/**
* 展示按钮
*/
void showButton();
/**
* 关闭按钮
*/
void closeButton();
/**
* 绘制POI
*/
void drawPOI();
/**
* 清除POI
*/
void clearPOI();
}

View File

@@ -0,0 +1,23 @@
package com.mogo.eagle.core.function.live.impl;
import android.view.View;
public interface ICameraWindow<T> {
/**
* 展示1/2窗口
*/
void show(T entity);
/**
* 关闭1/2窗口
*/
void close();
/**
* 返回窗体
*
* @return 当前窗体
*/
View getView();
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 163 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 163 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 163 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.1 KiB

View File

@@ -0,0 +1,14 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle"
>
<gradient
android:angle="180"
android:endColor="#3E7FFC"
android:startColor="#5CC1FF" />
<corners
android:bottomLeftRadius="@dimen/dp_20"
/>
</shape>

View File

@@ -0,0 +1,11 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle">
<gradient
android:angle="180"
android:endColor="#50526E"
android:startColor="#333F4057" />
<corners android:bottomRightRadius="@dimen/dp_20"/>
</shape>

View File

@@ -0,0 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<corners android:radius="@dimen/dp_20" />
<solid android:color="#3F4057" />
</shape>

View File

@@ -0,0 +1,38 @@
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<!---->
<item>
<shape android:shape="rectangle">
<padding
android:bottom="2dp"
android:left="2dp"
android:right="2dp"
android:top="3dp" />
<solid android:color="#00000000" />
<corners android:radius="@dimen/dp_26" />
</shape>
</item>
<item>
<shape android:shape="rectangle">
<padding
android:bottom="2dp"
android:left="2dp"
android:right="2dp"
android:top="2dp" />
<solid android:color="#00000000" />
<corners android:radius="@dimen/dp_26" />
</shape>
</item>
<!-- 中心背景 -->
<item>
<shape android:shape="rectangle">
<corners android:radius="@dimen/dp_26" />
<gradient
android:angle="135"
android:endColor="#3F4057"
android:startColor="#5E6079"
android:type="linear"
android:useLevel="true" />
</shape>
</item>
</layer-list>

View File

@@ -0,0 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:width="328dp" android:height="98dp">
<shape android:shape="rectangle">
<gradient android:angle="360" android:endColor="#ff616381" android:startColor="#ff48495e" />
<corners android:radius="@dimen/dp_20" />
</shape>
</item>
</selector>

View File

@@ -0,0 +1,36 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@drawable/v2x_alert_window_bg"
android:clipToPadding="false">
<com.mogo.eagle.core.function.live.CameraLiveGSYVideoView
android:id="@+id/videoPlayer"
android:layout_width="match_parent"
android:layout_height="@dimen/dp_300"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:roundLayoutRadius="@dimen/dp_30" />
<com.mogo.service.imageloader.MogoImageView
android:id="@+id/ivReportHead"
android:layout_width="@dimen/dp_80"
android:layout_height="@dimen/dp_80"
android:layout_marginEnd="@dimen/dp_31"
android:layout_marginBottom="@dimen/dp_14"
android:visibility="gone"
app:layout_constraintBottom_toBottomOf="@+id/videoPlayer"
app:layout_constraintEnd_toEndOf="@+id/videoPlayer"
app:miv_borderColor="#4cffffff"
app:miv_failureHolder="@drawable/icon_default_user_head"
app:miv_overlayImageId="@drawable/icon_default_user_head"
app:miv_placeHolder="@drawable/icon_default_user_head"
app:miv_shape="circle"
app:miv_shapeBorderWidth="@dimen/dp_4"
tools:visibility="invisible" />
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@@ -0,0 +1,22 @@
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/rlRoadEventDetail"
android:layout_width="match_parent"
android:layout_height="@dimen/dp_300"
android:clipToPadding="false">
<include
android:id="@+id/liveVideo"
layout="@layout/camera_item_v2x_live_video"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<ImageView
android:id="@+id/pushVideoClose"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="@dimen/dp_20"
android:layout_marginTop="@dimen/dp_20"
android:src="@drawable/module_common_close_selector" />
</RelativeLayout>

View File

@@ -0,0 +1,68 @@
<?xml version="1.0" encoding="utf-8"?>
<com.mogo.eagle.core.widget.LiveRoundLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent">
<com.tencent.rtmp.ui.TXCloudVideoView
android:id="@+id/txcVideoView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center" />
<androidx.core.widget.ContentLoadingProgressBar
android:id="@+id/loading"
style="?android:attr/progressBarStyleSmall"
android:layout_width="36dp"
android:layout_height="36dp"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true" />
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/clLoadError"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:visibility="gone"
tools:visibility="visible">
<ImageView
android:id="@+id/ivErrorIcon"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/icon_live_load_error"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/tvErrorContent"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="@dimen/dp_20"
android:text="直播获取失败"
android:textColor="@color/v2x_FFF_333"
android:textSize="@dimen/dp_20"
app:layout_constraintBottom_toBottomOf="@+id/ivErrorIcon"
app:layout_constraintStart_toEndOf="@+id/ivErrorIcon"
app:layout_constraintTop_toTopOf="@+id/ivErrorIcon" />
<TextView
android:id="@+id/tvRefreshButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/dp_40"
android:background="@drawable/v2x_refresh_button_bg"
android:paddingStart="@dimen/dp_135"
android:paddingTop="@dimen/dp_25"
android:paddingEnd="@dimen/dp_135"
android:paddingBottom="@dimen/dp_25"
android:text="重试"
android:textColor="@color/v2x_FFF_333"
android:textSize="@dimen/dp_20"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/ivErrorIcon" />
</androidx.constraintlayout.widget.ConstraintLayout>
</com.mogo.eagle.core.widget.LiveRoundLayout>

View File

@@ -0,0 +1,48 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="@dimen/dp_790"
android:layout_height="@dimen/dp_440"
android:background="@drawable/shape_round_gray"
>
<TextView
android:layout_width="wrap_content"
android:layout_height="@dimen/dp_56"
android:layout_marginTop="@dimen/dp_134"
android:text="是否退出导航?"
android:textColor="#FFF"
android:textSize="@dimen/sp_40"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"
/>
<TextView
android:id="@+id/tv_dialog_ok"
android:layout_width="@dimen/dp_395"
android:layout_height="@dimen/dp_128"
android:background="@drawable/shape_react_blue_grident"
android:gravity="center"
android:text="确认"
android:textColor="#FFF"
android:textSize="@dimen/dp_40"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
/>
<TextView
android:id="@+id/tv_dialog_cancel"
android:layout_width="@dimen/dp_395"
android:layout_height="@dimen/dp_128"
android:background="@drawable/shape_react_gray_grident"
android:gravity="center"
android:text="取消"
android:textColor="#FFF"
android:textSize="@dimen/dp_40"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintRight_toRightOf="parent"
/>
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@@ -0,0 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<color name="v2x_FFF_333">#FFFFFF</color>
<color name="module_switch_map_bg">#323C6F</color>
</resources>

View File

@@ -0,0 +1,4 @@
<resources>
<string name="app_name">mogo-module-extensions</string>
</resources>