diff --git a/.idea/codeStyles/Project.xml b/.idea/codeStyles/Project.xml
index 0d156937bb..663459aa50 100644
--- a/.idea/codeStyles/Project.xml
+++ b/.idea/codeStyles/Project.xml
@@ -3,18 +3,9 @@
-
diff --git a/.idea/misc.xml b/.idea/misc.xml
index cd77a1f062..21e99e2dc0 100644
--- a/.idea/misc.xml
+++ b/.idea/misc.xml
@@ -4,7 +4,7 @@
-
+
\ No newline at end of file
diff --git a/modules/mogo-module-common/src/main/java/com/mogo/module/common/entity/V2XMessageEntity.java b/modules/mogo-module-common/src/main/java/com/mogo/module/common/entity/V2XMessageEntity.java
index 3531741702..40ee54edc5 100644
--- a/modules/mogo-module-common/src/main/java/com/mogo/module/common/entity/V2XMessageEntity.java
+++ b/modules/mogo-module-common/src/main/java/com/mogo/module/common/entity/V2XMessageEntity.java
@@ -100,6 +100,8 @@ public class V2XMessageEntity implements Serializable {
int ALERT_ROAD_LIVE_CAR_WARNING = 1_007;
// 道路事件违章停车
int ALERT_ILLEGAL_PARK_WARNING = 1_008;
+ // 呼叫、请求直播事件
+ int ALERT_VOICE_CALL_FOR_LIVECAR_SHOW = 1_009;
// 自车求助
int ALERT_CAR_FOR_HELP = 8_000;
// obu事件
@@ -117,6 +119,7 @@ public class V2XMessageEntity implements Serializable {
V2XTypeEnum.ALERT_ROAD_LIVE_CAR_WARNING,
V2XTypeEnum.ALERT_ILLEGAL_PARK_WARNING,
V2XTypeEnum.ALERT_CAR_FOR_HELP,
+ V2XTypeEnum.ALERT_VOICE_CALL_FOR_LIVECAR_SHOW,
V2XTypeEnum.ALERT_OBU_EVENT,
})
@Target({
diff --git a/modules/mogo-module-v2x/build.gradle b/modules/mogo-module-v2x/build.gradle
index b80c5fc2de..1c8bc102ab 100644
--- a/modules/mogo-module-v2x/build.gradle
+++ b/modules/mogo-module-v2x/build.gradle
@@ -61,6 +61,10 @@ dependencies {
implementation rootProject.ext.dependencies.androidxviewpager2
implementation rootProject.ext.dependencies.localbroadcastmanager
+ implementation rootProject.ext.dependencies.videoarmv7
+ implementation rootProject.ext.dependencies.videoarm64
+ implementation rootProject.ext.dependencies.videojava
+
kapt rootProject.ext.dependencies.roomAnnotationProcessor
kapt rootProject.ext.dependencies.aroutercompiler
diff --git a/modules/mogo-module-v2x/src/main/java/com/mogo/module/v2x/V2XModuleProvider.java b/modules/mogo-module-v2x/src/main/java/com/mogo/module/v2x/V2XModuleProvider.java
index 84eb75fb33..2846401c23 100644
--- a/modules/mogo-module-v2x/src/main/java/com/mogo/module/v2x/V2XModuleProvider.java
+++ b/modules/mogo-module-v2x/src/main/java/com/mogo/module/v2x/V2XModuleProvider.java
@@ -27,6 +27,7 @@ import com.mogo.module.v2x.entity.net.V2XStrategyPushRes;
import com.mogo.module.v2x.network.V2XRefreshCallback;
import com.mogo.module.v2x.receiver.SceneBroadcastReceiver;
import com.mogo.module.v2x.scenario.impl.V2XScenarioManager;
+import com.mogo.module.v2x.scenario.scene.livecar.V2XVoiceCallLiveBiz;
import com.mogo.module.v2x.scenario.scene.park.V2XIllegalParkScenario;
import com.mogo.module.v2x.scenario.scene.park.V2XIllegalParkWindow;
import com.mogo.module.v2x.utils.FatigueDrivingUtils;
@@ -126,7 +127,7 @@ public class V2XModuleProvider implements
V2XVoiceManager.INSTANCE.init(context);
registerListener();
initData();
-
+ initBiz(context);
// 注册广播接收场景弹窗使用的
SceneBroadcastReceiver localReceiver = new SceneBroadcastReceiver();
LocalBroadcastManager localBroadcastManager = LocalBroadcastManager.getInstance(context);
@@ -138,6 +139,10 @@ public class V2XModuleProvider implements
V2XObuManager.getInstance().init();
}
+ private void initBiz(Context context) {
+ V2XVoiceCallLiveBiz.getInstance().init(context);
+ }
+
private void initData() {
try {
// 查询ACC状态
diff --git a/modules/mogo-module-v2x/src/main/java/com/mogo/module/v2x/entity/net/V2XLiveCrossRoad.java b/modules/mogo-module-v2x/src/main/java/com/mogo/module/v2x/entity/net/V2XLiveCrossRoad.java
new file mode 100644
index 0000000000..d99dec5ce4
--- /dev/null
+++ b/modules/mogo-module-v2x/src/main/java/com/mogo/module/v2x/entity/net/V2XLiveCrossRoad.java
@@ -0,0 +1,109 @@
+package com.mogo.module.v2x.entity.net;
+
+import com.mogo.commons.data.BaseData;
+
+import java.io.Serializable;
+
+/**
+ * author : unknown
+ * desc : 路口实况返回数据
+ */
+public class V2XLiveCrossRoad extends BaseData implements Serializable {
+ public V2XLiveCrossRoadEntity result;
+
+ public V2XLiveCrossRoadEntity getResult() {
+ return result;
+ }
+
+ public void setResult(V2XLiveCrossRoadEntity result) {
+ this.result = result;
+ }
+
+ @Override
+ public String toString() {
+ return "V2XLiveCrossRoad{" +
+ "result=" + result +
+ ", code=" + code +
+ ", msg='" + msg + '\'' +
+ '}';
+ }
+
+ public class V2XLiveCrossRoadEntity {
+ private int cameraParentId;
+ private int cameraId;
+ private String url;
+ private Double lat;
+ private Double lon;
+ private Double distance;
+
+ public V2XLiveCrossRoadEntity(int cameraParentId, int cameraId, String url, Double lat, Double lon, Double distance) {
+ this.cameraParentId = cameraParentId;
+ this.cameraId = cameraId;
+ this.url = url;
+ this.lat = lat;
+ this.lon = lon;
+ this.distance = distance;
+ }
+
+ public int getCameraParentId() {
+ return cameraParentId;
+ }
+
+ public void setCameraParentId(int cameraParentId) {
+ this.cameraParentId = cameraParentId;
+ }
+
+ public int getCameraId() {
+ return cameraId;
+ }
+
+ public void setCameraId(int cameraId) {
+ this.cameraId = cameraId;
+ }
+
+ public String getUrl() {
+ return url;
+ }
+
+ public void setUrl(String url) {
+ this.url = url;
+ }
+
+ public Double getLat() {
+ return lat;
+ }
+
+ public void setLat(Double lat) {
+ this.lat = lat;
+ }
+
+ public Double getLon() {
+ return lon;
+ }
+
+ public void setLon(Double lon) {
+ this.lon = lon;
+ }
+
+ public Double getDistance() {
+ return distance;
+ }
+
+ public void setDistance(Double distance) {
+ this.distance = distance;
+ }
+
+ @Override
+ public String toString() {
+ return "V2XLiveCrossRoadEntity{" +
+ "cameraParentId=" + cameraParentId +
+ ", cameraId=" + cameraId +
+ ", url='" + url + '\'' +
+ ", lat=" + lat +
+ ", lon=" + lon +
+ ", distance=" + distance +
+ '}';
+ }
+ }
+
+}
diff --git a/modules/mogo-module-v2x/src/main/java/com/mogo/module/v2x/network/V2XApiService.java b/modules/mogo-module-v2x/src/main/java/com/mogo/module/v2x/network/V2XApiService.java
index 2345952ffa..4ce5ecd7b6 100644
--- a/modules/mogo-module-v2x/src/main/java/com/mogo/module/v2x/network/V2XApiService.java
+++ b/modules/mogo-module-v2x/src/main/java/com/mogo/module/v2x/network/V2XApiService.java
@@ -4,6 +4,7 @@ import com.mogo.commons.data.BaseData;
import com.mogo.module.common.entity.MarkerResponse;
import com.mogo.module.v2x.entity.net.V2XDemoUserInfoRes;
import com.mogo.module.v2x.entity.net.V2XLiveCarRes;
+import com.mogo.module.v2x.entity.net.V2XLiveCrossRoad;
import com.mogo.module.v2x.entity.net.V2XLivePushVoRes;
import com.mogo.module.v2x.entity.net.V2XSeekHelpRes;
import com.mogo.module.v2x.entity.net.V2XStrategyPushRes;
@@ -147,4 +148,12 @@ public interface V2XApiService {
@FormUrlEncoded
@POST("/deva/poiInfoFabulous/car/poi/no/RespondingToHelp/v1")
Observable respondingToHelp(@FieldMap Map params);
+
+ /**
+ * 查询路口实况
+ */
+ @FormUrlEncoded
+ @POST("/yycp-geo-fence-carService/car/camera/no/nextTest/v1")
+// @POST("/yycp-geo-fence-carService/car/camera/no/next/v1")
+ Observable queryCrossRoadsLive(@FieldMap Map parameters);
}
diff --git a/modules/mogo-module-v2x/src/main/java/com/mogo/module/v2x/network/V2XRefreshModel.java b/modules/mogo-module-v2x/src/main/java/com/mogo/module/v2x/network/V2XRefreshModel.java
index 947cdffe39..1346610074 100644
--- a/modules/mogo-module-v2x/src/main/java/com/mogo/module/v2x/network/V2XRefreshModel.java
+++ b/modules/mogo-module-v2x/src/main/java/com/mogo/module/v2x/network/V2XRefreshModel.java
@@ -4,18 +4,22 @@ import android.content.Context;
import android.text.TextUtils;
import com.alibaba.android.arouter.launcher.ARouter;
+import com.mogo.commons.AbsMogoApplication;
import com.mogo.commons.data.BaseData;
import com.mogo.commons.network.ParamsProvider;
import com.mogo.commons.network.SubscribeImpl;
import com.mogo.commons.network.Utils;
import com.mogo.map.MogoLatLng;
+import com.mogo.map.location.MogoLocation;
import com.mogo.module.common.entity.MarkerResponse;
import com.mogo.module.service.ServiceConst;
import com.mogo.module.service.network.RefreshBody;
import com.mogo.module.v2x.V2XConst;
+import com.mogo.module.v2x.V2XServiceManager;
import com.mogo.module.v2x.entity.net.V2XDemoUserInfoRes;
import com.mogo.module.v2x.entity.net.V2XLiveCarBroadcastReq;
import com.mogo.module.v2x.entity.net.V2XLiveCarRes;
+import com.mogo.module.v2x.entity.net.V2XLiveCrossRoad;
import com.mogo.module.v2x.entity.net.V2XLivePushVoRes;
import com.mogo.module.v2x.entity.net.V2XSeekHelpRes;
import com.mogo.module.v2x.entity.net.V2XStrategyPushRes;
@@ -548,4 +552,42 @@ public class V2XRefreshModel {
});
}
}
+
+ public void queryCrossRoadsLive(V2XRefreshCallback callback) {
+ if (mV2XApiService != null) {
+ final Map map = new ParamsProvider.Builder(mContext).build();
+ MogoLocation lastKnowLocation = V2XServiceManager.getMapService().getSingletonLocationClient(AbsMogoApplication.getApp()).getLastKnowLocation();
+ double lat = lastKnowLocation.getLatitude();
+ double lon = lastKnowLocation.getLongitude();
+ String tmpLat = String.valueOf(lat);
+ String tmpLon = String.valueOf(lon);
+ float bearing = lastKnowLocation.getBearing();
+ String json = "{\"lat\":" + tmpLat + ",\"lon\":" + tmpLon + ",\"direction\":" + bearing + "}";
+ map.put("sn", Utils.getSn());
+ map.put("data", json);
+ mV2XApiService.queryCrossRoadsLive(map)
+ .subscribeOn(Schedulers.io())
+ .observeOn(AndroidSchedulers.mainThread())
+ .subscribe(new SubscribeImpl(RequestOptions.create(mContext)) {
+ @Override
+ public void onSuccess(V2XLiveCrossRoad o) {
+ super.onSuccess(o);
+ if (callback != null) {
+ callback.onSuccess(o);
+ }
+ }
+
+ @Override
+ public void onError(String message, int code) {
+ super.onError(message, code);
+ if (callback != null) {
+ if (TextUtils.isEmpty(message)) {
+ message = "网络错误,请稍后重试";
+ }
+ callback.onFail(message);
+ }
+ }
+ });
+ }
+ }
}
diff --git a/modules/mogo-module-v2x/src/main/java/com/mogo/module/v2x/scenario/impl/V2XScenarioManager.java b/modules/mogo-module-v2x/src/main/java/com/mogo/module/v2x/scenario/impl/V2XScenarioManager.java
index 029ffe5284..0e51fb64bb 100644
--- a/modules/mogo-module-v2x/src/main/java/com/mogo/module/v2x/scenario/impl/V2XScenarioManager.java
+++ b/modules/mogo-module-v2x/src/main/java/com/mogo/module/v2x/scenario/impl/V2XScenarioManager.java
@@ -14,6 +14,7 @@ import com.mogo.module.v2x.scenario.scene.animation.V2XAnimationScenario;
import com.mogo.module.v2x.scenario.scene.fatigue.V2XFatigueDrivingScenario;
import com.mogo.module.v2x.scenario.scene.help.V2XCarForHelpScenario;
import com.mogo.module.v2x.scenario.scene.livecar.V2XPushLiveCarScenario;
+import com.mogo.module.v2x.scenario.scene.livecar.V2XVoiceCallLiveScenario;
import com.mogo.module.v2x.scenario.scene.park.V2XIllegalParkScenario;
import com.mogo.module.v2x.scenario.scene.push.V2XPushEventScenario;
import com.mogo.module.v2x.scenario.scene.road.V2XRoadEventScenario;
@@ -96,6 +97,9 @@ public class V2XScenarioManager implements IV2XScenarioManager {
case V2XMessageEntity.V2XTypeEnum.ALERT_ILLEGAL_PARK_WARNING:
mV2XScenario = V2XIllegalParkScenario.getInstance();
break;
+ case V2XMessageEntity.V2XTypeEnum.ALERT_VOICE_CALL_FOR_LIVECAR_SHOW:
+ mV2XScenario = V2XVoiceCallLiveScenario.getInstance();
+ break;
default:
Logger.e(MODULE_NAME, "当前V2X消息类型未定义。");
TipToast.tip("当前V2X消息类型未定义");
diff --git a/modules/mogo-module-v2x/src/main/java/com/mogo/module/v2x/scenario/scene/livecar/V2XVoiceCallLiveBiz.java b/modules/mogo-module-v2x/src/main/java/com/mogo/module/v2x/scenario/scene/livecar/V2XVoiceCallLiveBiz.java
new file mode 100644
index 0000000000..3fa4c42b92
--- /dev/null
+++ b/modules/mogo-module-v2x/src/main/java/com/mogo/module/v2x/scenario/scene/livecar/V2XVoiceCallLiveBiz.java
@@ -0,0 +1,148 @@
+package com.mogo.module.v2x.scenario.scene.livecar;
+
+import android.content.Context;
+import android.text.TextUtils;
+
+import com.mogo.commons.voice.AIAssist;
+import com.mogo.module.common.entity.V2XMessageEntity;
+import com.mogo.module.common.entity.V2XPushMessageEntity;
+import com.mogo.module.v2x.R;
+import com.mogo.module.v2x.V2XDemoManager;
+import com.mogo.module.v2x.V2XServiceManager;
+import com.mogo.module.v2x.entity.net.V2XDemoUserInfoRes;
+import com.mogo.module.v2x.utils.ToastUtils;
+import com.mogo.module.v2x.voice.V2XVoiceCallbackListener;
+import com.mogo.module.v2x.voice.V2XVoiceManager;
+import com.mogo.service.statusmanager.StatusDescriptor;
+import com.mogo.utils.logger.Logger;
+
+import static com.mogo.module.v2x.V2XConst.MODULE_NAME;
+import static com.mogo.module.v2x.voice.V2XVoiceConstants.COMMAND_ZHIDAO_V2X_AHEAD_LIVE;
+import static com.mogo.module.v2x.voice.V2XVoiceConstants.COMMAND_ZHIDAO_V2X_CALL_FRONT_CAR_DEMO_UN_WAKEUP;
+import static com.mogo.module.v2x.voice.V2XVoiceConstants.COMMAND_ZHIDAO_V2X_CROSSROADS_LIVE;
+import static com.mogo.module.v2x.voice.V2XVoiceConstants.COMMAND_ZHIDAO_V2X_OPEN_ROAD_CAMERA_LIVE_UN_WAKEUP;
+import static com.mogo.service.statusmanager.StatusDescriptor.MAIN_PAGE_RESUME;
+
+/**
+ * author : unknown
+ * desc : TODO 演示使用的语音呼叫查看直播车辆 或者 路口实况 业务模块
+ */
+public class V2XVoiceCallLiveBiz {
+
+ private static final String REGISTER_LIFECYCLE_TAG = V2XVoiceCallLiveBiz.class.getSimpleName();
+
+ private V2XVoiceCallLiveBiz() {
+
+ }
+
+ private static volatile V2XVoiceCallLiveBiz mV2XVoiceCallLiveBiz;
+
+ public static V2XVoiceCallLiveBiz getInstance() {
+ if (mV2XVoiceCallLiveBiz == null) {
+ synchronized (V2XVoiceCallLiveBiz.class) {
+ if (mV2XVoiceCallLiveBiz == null) {
+ mV2XVoiceCallLiveBiz = new V2XVoiceCallLiveBiz();
+ }
+ }
+ }
+ return mV2XVoiceCallLiveBiz;
+ }
+
+ private Context mContext;
+
+ //语音词指令 查看前车视频回调
+ private V2XVoiceCallbackListener v2XVoiceCallbackFrontLiveCarListener = (command, intent) -> {
+ Logger.d(MODULE_NAME, "语音词指令 查看前车视频回调");
+ getFrontCarLive();
+ };
+
+ //语音词指令 查看路口实况回调
+ private V2XVoiceCallbackListener v2XVoiceCallbackOpenRoadCameraListener = (command, intent) -> {
+ Logger.d(MODULE_NAME, "语音词指令 查看路口实况回调");
+ AIAssist.getInstance(mContext).speakTTSVoice(mContext.getString(R.string.v2x_voice_see_crossroad_live));
+ getOpenRoadCameraLive();
+ };
+
+ public void init(Context context) {
+ Logger.d(MODULE_NAME, "init");
+ this.mContext = context;
+ registerLifecycleChange();
+ registerVoice();
+ }
+
+ private void registerLifecycleChange() {
+ V2XServiceManager.getMoGoStatusManager().registerStatusChangedListener(REGISTER_LIFECYCLE_TAG, MAIN_PAGE_RESUME, (descriptor, isTrue) -> {
+ if (descriptor == StatusDescriptor.MAIN_PAGE_RESUME) {
+ if (isTrue) {
+ registerVoice();
+ } else {
+ unRegisterVoice();
+ }
+ }
+ });
+ }
+
+ private void registerVoice() {
+ V2XVoiceManager.INSTANCE.registerUnWakeVoice(COMMAND_ZHIDAO_V2X_CALL_FRONT_CAR_DEMO_UN_WAKEUP, v2XVoiceCallbackFrontLiveCarListener)
+ .registerUnWakeVoice(COMMAND_ZHIDAO_V2X_OPEN_ROAD_CAMERA_LIVE_UN_WAKEUP, v2XVoiceCallbackOpenRoadCameraListener)
+ .registerWakeCmd(COMMAND_ZHIDAO_V2X_AHEAD_LIVE, v2XVoiceCallbackFrontLiveCarListener)
+ .registerWakeCmd(COMMAND_ZHIDAO_V2X_CROSSROADS_LIVE, v2XVoiceCallbackOpenRoadCameraListener);
+ }
+
+ private void unRegisterVoice() {
+ V2XVoiceManager.INSTANCE.unRegisterUnWakeVoice(COMMAND_ZHIDAO_V2X_CALL_FRONT_CAR_DEMO_UN_WAKEUP)
+ .unRegisterUnWakeVoice(COMMAND_ZHIDAO_V2X_OPEN_ROAD_CAMERA_LIVE_UN_WAKEUP)
+ .unRegisterWakeCmd(COMMAND_ZHIDAO_V2X_AHEAD_LIVE).unRegisterWakeCmd(COMMAND_ZHIDAO_V2X_CROSSROADS_LIVE);
+ }
+
+ public void getFrontCarLive() {
+ V2XDemoUserInfoRes.ResultBean.UserListBean.UserInfoBean userInfoBean = V2XDemoManager.getInstance().getV2XDemoUserInfoEntity1().getUserInfo();
+ String liveCarSn = userInfoBean.getSn();
+ if (TextUtils.isEmpty(liveCarSn)) {
+ ToastUtils.showShort("附近没有可直播车机");
+ Logger.d(MODULE_NAME, "getFrontCarLive : sn is null");
+ return;
+ }
+ V2XMessageEntity v2XMessageEntity = buildCallLiveParams(liveCarSn, null);
+ V2XVoiceCallLiveScenario.getInstance().setV2XWindow(new V2XVoiceCallLiveCarWindow());
+ V2XVoiceCallLiveScenario.getInstance().init(v2XMessageEntity);
+ }
+
+ public void getOpenRoadCameraLive() {
+ String liveUrl = "rtmp://154.8.189.110:19350/live/10_1";
+ V2XMessageEntity v2XMessageEntity = buildCallLiveParams(null, liveUrl);
+ V2XVoiceCallLiveScenario.getInstance().setV2XWindow(new V2XVoiceCrossRoadLiveWindow());
+ V2XVoiceCallLiveScenario.getInstance().init(v2XMessageEntity);
+// V2XRefreshModel.getInstance(mContext).queryCrossRoadsLive(new V2XRefreshCallback() {
+// @Override
+// public void onSuccess(V2XLiveCrossRoad result) {
+// if (result != null && result.getResult().getUrl() != null) {
+// String liveUrl = result.getResult().getUrl();
+// V2XMessageEntity v2XMessageEntity = buildCallLiveParams(null, liveUrl);
+// V2XVoiceCallLiveScenario.getInstance().setV2XWindow(new V2XVoiceCrossRoadLiveWindow());
+// V2XVoiceCallLiveScenario.getInstance().init(v2XMessageEntity);
+// } else {
+// Logger.d(MODULE_NAME, "getOpenRoadCameraLive 路口实况直播地址为空");
+// }
+// }
+//
+// @Override
+// public void onFail(String msg) {
+// Logger.d(MODULE_NAME, "getOpenRoadCameraLive : " + msg);
+// }
+// });
+ }
+
+ private V2XMessageEntity buildCallLiveParams(String sn, String liveUrl) {
+ V2XPushMessageEntity v2XPushMessageEntity = new V2XPushMessageEntity();
+ v2XPushMessageEntity.setVideoSn(sn);
+ v2XPushMessageEntity.setVideoUrl(liveUrl);
+ v2XPushMessageEntity.setShowWindow(true);
+ V2XMessageEntity v2XMessageEntity = new V2XMessageEntity<>();
+ v2XMessageEntity.setType(V2XMessageEntity.V2XTypeEnum.ALERT_VOICE_CALL_FOR_LIVECAR_SHOW);
+ v2XMessageEntity.setContent(v2XPushMessageEntity);
+ v2XMessageEntity.setShowState(true);
+ return v2XMessageEntity;
+ }
+
+}
diff --git a/modules/mogo-module-v2x/src/main/java/com/mogo/module/v2x/scenario/scene/livecar/V2XVoiceCallLiveCarWindow.java b/modules/mogo-module-v2x/src/main/java/com/mogo/module/v2x/scenario/scene/livecar/V2XVoiceCallLiveCarWindow.java
new file mode 100644
index 0000000000..fd4c5474e4
--- /dev/null
+++ b/modules/mogo-module-v2x/src/main/java/com/mogo/module/v2x/scenario/scene/livecar/V2XVoiceCallLiveCarWindow.java
@@ -0,0 +1,143 @@
+package com.mogo.module.v2x.scenario.scene.livecar;
+
+import android.content.Context;
+import android.os.Handler;
+import android.util.AttributeSet;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.widget.ImageView;
+import android.widget.RelativeLayout;
+import android.widget.TextView;
+
+import com.mogo.module.common.entity.MarkerCarInfo;
+import com.mogo.module.common.entity.V2XPushMessageEntity;
+import com.mogo.module.v2x.R;
+import com.mogo.module.v2x.V2XServiceManager;
+import com.mogo.module.v2x.listener.V2XWindowStatusListener;
+import com.mogo.module.v2x.scenario.view.IV2XWindow;
+import com.mogo.module.v2x.view.V2XCarLiveVideoView;
+import com.mogo.utils.logger.Logger;
+
+import static com.mogo.module.v2x.V2XConst.MODULE_NAME;
+
+public class V2XVoiceCallLiveCarWindow extends RelativeLayout
+ implements IV2XWindow {
+
+ private V2XCarLiveVideoView mV2XCarLiveVideoView;
+ private TextView tvCountDown;
+ private ImageView ivVideoPlayingSign;
+ private boolean isVideoPlay = false;
+
+ // 处理道路事件,30秒倒计时
+ private Handler handlerV2XEvent = new Handler();
+ private Runnable runnableV2XEvent;
+ private static final int COUNT_DOWN_TIMER = 1_000;
+ private static final int ALL_EXPIRE_TIMER = 1_000 * 30;
+ private static int EXPIRE_TIMER = ALL_EXPIRE_TIMER;
+
+ public V2XVoiceCallLiveCarWindow() {
+ this(V2XServiceManager.getContext(), null);
+ Logger.d(MODULE_NAME, "V2XVoiceCallLiveCarWindow INIT");
+ }
+
+ public V2XVoiceCallLiveCarWindow(Context context, AttributeSet attrs) {
+ this(context, attrs, 0);
+ }
+
+ public V2XVoiceCallLiveCarWindow(Context context, AttributeSet attrs, int defStyleAttr) {
+ super(context, attrs, defStyleAttr);
+ initView(context);
+ }
+
+ private void initView(Context context) {
+ Logger.w(MODULE_NAME, "V2X===初始化语音呼叫直播视图");
+ LayoutInflater.from(context).inflate(R.layout.window_see_carlive_video, this);
+ mV2XCarLiveVideoView = findViewById(R.id.videoPlayer);
+ tvCountDown = findViewById(R.id.tvCountDown);
+ ivVideoPlayingSign = findViewById(R.id.ivVideoPlayingSign);
+ mV2XCarLiveVideoView.addOnVideoStatusChangeListener(videoPlaying -> {
+ isVideoPlay = videoPlaying;
+ if (isVideoPlay) {
+ startCountDown();
+ } else {
+ stopCountDown();
+ }
+ });
+ }
+
+ @Override
+ public void show(V2XPushMessageEntity entity) {
+ if (entity != null) {
+ Logger.w(MODULE_NAME, "更新直播信息。。。。。" + entity);
+ // 启动播放
+ MarkerCarInfo.CarLiveInfo carLiveInfo = new MarkerCarInfo.CarLiveInfo();
+ carLiveInfo.setVideoChannel(entity.getVideoChannel());
+ carLiveInfo.setVideoSn(entity.getVideoSn());
+ carLiveInfo.setVideoUrl(entity.getVideoUrl());
+ Logger.w(MODULE_NAME, "更新直播信息 END");
+ mV2XCarLiveVideoView.setCarLiveInfo(carLiveInfo);
+ if (isVideoPlay) {
+ startCountDown();
+ }
+ }
+ }
+
+ @Override
+ public void close() {
+ // 停止倒计时
+ stopCountDown();
+ if (V2XServiceManager
+ .getMogoTopViewManager().isViewAdded(this)) {
+ //移除窗体
+ V2XServiceManager
+ .getMogoTopViewManager()
+ .removeView(this);
+ }
+ }
+
+ @Override
+ public View getView() {
+ return this;
+ }
+
+ @Override
+ public void setWindowStatusListener(V2XWindowStatusListener listener) {
+
+ }
+
+ /**
+ * 窗体倒计时
+ */
+ private void startCountDown() {
+ // 倒计时
+ if (runnableV2XEvent == null) {
+ runnableV2XEvent = () -> {
+ EXPIRE_TIMER = EXPIRE_TIMER - COUNT_DOWN_TIMER;
+ Logger.d(MODULE_NAME, "V2X=== Window 30秒倒计时开始,当前 :" + EXPIRE_TIMER / COUNT_DOWN_TIMER + " 秒");
+ tvCountDown.setVisibility(View.VISIBLE);
+ ivVideoPlayingSign.setVisibility(View.VISIBLE);
+ tvCountDown.setText(String.valueOf(EXPIRE_TIMER / COUNT_DOWN_TIMER));
+ if (EXPIRE_TIMER > 0) {
+ handlerV2XEvent.postDelayed(runnableV2XEvent, COUNT_DOWN_TIMER);
+ } else {
+ close();
+ }
+ };
+ } else {
+ handlerV2XEvent.removeCallbacks(runnableV2XEvent);
+ }
+ Logger.d(MODULE_NAME, "V2X=== Window 展示开始倒计时");
+ handlerV2XEvent.postDelayed(runnableV2XEvent, COUNT_DOWN_TIMER);
+ }
+
+ private void stopCountDown() {
+ Logger.d(MODULE_NAME, "V2X=== Window 倒计时停止。。。");
+ if (handlerV2XEvent != null && runnableV2XEvent != null) {
+ handlerV2XEvent.removeCallbacks(runnableV2XEvent);
+ runnableV2XEvent = null;
+ tvCountDown.setVisibility(View.GONE);
+ ivVideoPlayingSign.setVisibility(View.GONE);
+ EXPIRE_TIMER = ALL_EXPIRE_TIMER;
+ }
+ }
+}
diff --git a/modules/mogo-module-v2x/src/main/java/com/mogo/module/v2x/scenario/scene/livecar/V2XVoiceCallLiveScenario.java b/modules/mogo-module-v2x/src/main/java/com/mogo/module/v2x/scenario/scene/livecar/V2XVoiceCallLiveScenario.java
new file mode 100644
index 0000000000..8e8af5abc2
--- /dev/null
+++ b/modules/mogo-module-v2x/src/main/java/com/mogo/module/v2x/scenario/scene/livecar/V2XVoiceCallLiveScenario.java
@@ -0,0 +1,143 @@
+package com.mogo.module.v2x.scenario.scene.livecar;
+
+import android.view.View;
+import android.view.ViewGroup;
+
+import androidx.annotation.Nullable;
+
+import com.mogo.module.common.entity.V2XMessageEntity;
+import com.mogo.module.common.entity.V2XPushMessageEntity;
+import com.mogo.module.v2x.R;
+import com.mogo.module.v2x.V2XConst;
+import com.mogo.module.v2x.V2XServiceManager;
+import com.mogo.module.v2x.scenario.impl.AbsV2XScenario;
+import com.mogo.module.v2x.utils.V2XUtils;
+import com.mogo.service.windowview.IMogoTopViewStatusListener;
+import com.mogo.utils.TipToast;
+import com.mogo.utils.logger.Logger;
+
+import static com.mogo.module.v2x.V2XConst.MODULE_NAME;
+
+/**
+ * author : unknown
+ * desc : TODO 演示使用的语音呼叫查看直播场景,包括车辆直播 或者 路口实况 window,区分不同页面window逻辑实现
+ */
+public class V2XVoiceCallLiveScenario extends AbsV2XScenario implements IMogoTopViewStatusListener {
+
+ private V2XVoiceCallLiveScenario() {
+
+ }
+
+ private static volatile V2XVoiceCallLiveScenario mV2XVoiceCallLiveCarScenario;
+
+ public static V2XVoiceCallLiveScenario getInstance() {
+ if (mV2XVoiceCallLiveCarScenario == null) {
+ synchronized (V2XVoiceCallLiveScenario.class) {
+ if (mV2XVoiceCallLiveCarScenario == null) {
+ mV2XVoiceCallLiveCarScenario = new V2XVoiceCallLiveScenario();
+ }
+ }
+ }
+ return mV2XVoiceCallLiveCarScenario;
+ }
+
+ @Override
+ public void init(@Nullable V2XMessageEntity v2XMessageEntity) {
+ if (v2XMessageEntity == null) {
+ TipToast.shortTip("附近没有可直播车机");
+ }
+ if (v2XMessageEntity.isShowState()) {
+ if (!isSameScenario(v2XMessageEntity)
+ && V2XServiceManager.getMoGoStatusManager().isMainPageLaunched()) {
+ setV2XMessageEntity(v2XMessageEntity);
+ Logger.d(V2XConst.MODULE_NAME, "v2XMessageEntity : " + v2XMessageEntity + " getVideoSn : " + v2XMessageEntity.getContent().getVideoSn());
+ if (v2XMessageEntity != null) {
+ Logger.d(V2XConst.MODULE_NAME, "准备展示直播窗口");
+ show();
+ } else {
+ TipToast.shortTip("附近没有可直播车机");
+ Logger.e(V2XConst.MODULE_NAME, "直播地址为null");
+ }
+ } else {
+ setV2XMessageEntity(v2XMessageEntity);
+ Logger.w(V2XConst.MODULE_NAME, "要处理的场景已经存在,丢弃这次初始化");
+ }
+ } else {
+ close();
+ }
+ }
+
+ @Override
+ public void show() {
+ if (getV2XMessageEntity() != null && getV2XMessageEntity().getContent() != null) {
+ showWindow();
+ }
+ }
+
+ @Override
+ public void showWindow() {
+ if (getV2XWindow() != null) {
+ getV2XWindow().show(getV2XMessageEntity().getContent());
+ ViewGroup.LayoutParams layoutParams =
+ new ViewGroup.LayoutParams(
+ (int) V2XUtils.getApp().getResources().getDimension(R.dimen.module_v2x_event_window_width),
+ (int) V2XUtils.getApp().getResources().getDimension(R.dimen.module_v2x_event_see_live_window_height));
+ V2XServiceManager
+ .getMogoTopViewManager()
+ .addView(getV2XWindow().getView(), layoutParams, this);
+ V2XServiceManager.getMoGoV2XStatusManager().setLiveCarWindowShow(TAG, true);
+ }
+ }
+
+ @Override
+ public void closeWindow() {
+ if (getV2XWindow() != null) {
+ getV2XWindow().close();
+ }
+ V2XServiceManager.getMoGoV2XStatusManager().setLiveCarWindowShow(TAG, 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(MODULE_NAME, "展示 Window 动画结束");
+ }
+
+ @Override
+ public void onViewRemoved(View view) {
+ Logger.d(MODULE_NAME, "关闭 Window 动画结束");
+ getV2XWindow().close();
+ V2XServiceManager.getMoGoV2XStatusManager().setLiveCarWindowShow(TAG, false);
+ }
+
+ @Override
+ public void beforeViewAddAnim(View view) {
+ Logger.d(MODULE_NAME, "展示 Window 开始");
+ }
+
+ @Override
+ public void beforeViewRemoveAnim(View view) {
+ Logger.d(MODULE_NAME, "关闭 Window 开始");
+ setV2XMessageEntity(null);
+ V2XServiceManager.getMoGoV2XStatusManager().setLiveCarWindowShow(TAG, false);
+ }
+}
diff --git a/modules/mogo-module-v2x/src/main/java/com/mogo/module/v2x/scenario/scene/livecar/V2XVoiceCrossRoadLiveWindow.java b/modules/mogo-module-v2x/src/main/java/com/mogo/module/v2x/scenario/scene/livecar/V2XVoiceCrossRoadLiveWindow.java
new file mode 100644
index 0000000000..025321de65
--- /dev/null
+++ b/modules/mogo-module-v2x/src/main/java/com/mogo/module/v2x/scenario/scene/livecar/V2XVoiceCrossRoadLiveWindow.java
@@ -0,0 +1,145 @@
+package com.mogo.module.v2x.scenario.scene.livecar;
+
+import android.content.Context;
+import android.os.Handler;
+import android.util.AttributeSet;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.widget.ImageView;
+import android.widget.RelativeLayout;
+import android.widget.TextView;
+
+import com.mogo.module.common.entity.MarkerCarInfo;
+import com.mogo.module.common.entity.V2XPushMessageEntity;
+import com.mogo.module.v2x.R;
+import com.mogo.module.v2x.V2XServiceManager;
+import com.mogo.module.v2x.listener.V2XWindowStatusListener;
+import com.mogo.module.v2x.scenario.view.IV2XWindow;
+import com.mogo.module.v2x.view.V2XCrossRoadVideoView;
+import com.mogo.utils.logger.Logger;
+
+import static com.mogo.module.v2x.V2XConst.MODULE_NAME;
+
+public class V2XVoiceCrossRoadLiveWindow extends RelativeLayout
+ implements IV2XWindow {
+
+ private V2XCrossRoadVideoView mV2XCrossRoadVideoView;
+ private TextView tvCountDown;
+ private ImageView ivVideoPlayingSign;
+ private boolean isVideoPlay = false;
+
+ // 处理道路事件,30秒倒计时
+ private Handler handlerV2XEvent = new Handler();
+ private Runnable runnableV2XEvent;
+ private static final int COUNT_DOWN_TIMER = 1_000;
+ private static final int ALL_EXPIRE_TIMER = 1_000 * 30;
+ private static int EXPIRE_TIMER = ALL_EXPIRE_TIMER;
+
+ public V2XVoiceCrossRoadLiveWindow() {
+ this(V2XServiceManager.getContext(), null);
+ Logger.d(MODULE_NAME, "V2XVoiceCallLiveCarWindow INIT");
+ }
+
+ public V2XVoiceCrossRoadLiveWindow(Context context, AttributeSet attrs) {
+ this(context, attrs, 0);
+ }
+
+ public V2XVoiceCrossRoadLiveWindow(Context context, AttributeSet attrs, int defStyleAttr) {
+ super(context, attrs, defStyleAttr);
+ initView(context);
+ }
+
+ private void initView(Context context) {
+ Logger.w(MODULE_NAME, "V2X===初始化语音呼叫直播视图");
+ LayoutInflater.from(context).inflate(R.layout.window_see_crossroadlive_video, this);
+ mV2XCrossRoadVideoView = findViewById(R.id.videoPlayer);
+ tvCountDown = findViewById(R.id.tvCountDown);
+ ivVideoPlayingSign = findViewById(R.id.ivVideoPlayingSign);
+ mV2XCrossRoadVideoView.addOnVideoStatusChangeListener(videoPlaying -> {
+ isVideoPlay = videoPlaying;
+ if (isVideoPlay) {
+ startCountDown();
+ } else {
+ stopCountDown();
+ }
+ });
+ }
+
+ @Override
+ public void show(V2XPushMessageEntity entity) {
+ if (entity != null) {
+ Logger.w(MODULE_NAME, "更新直播信息。。。。。" + entity);
+ // 启动播放
+ MarkerCarInfo.CarLiveInfo carLiveInfo = new MarkerCarInfo.CarLiveInfo();
+ carLiveInfo.setVideoChannel(entity.getVideoChannel());
+ carLiveInfo.setVideoSn(entity.getVideoSn());
+ carLiveInfo.setVideoUrl(entity.getVideoUrl());
+ Logger.w(MODULE_NAME, "更新直播信息 END");
+ mV2XCrossRoadVideoView.setCarLiveInfo(carLiveInfo);
+ if (isVideoPlay) {
+ startCountDown();
+ }
+ }
+ }
+
+ @Override
+ public void close() {
+ // 停止倒计时
+ stopCountDown();
+ if (V2XServiceManager
+ .getMogoTopViewManager().isViewAdded(this)) {
+ //移除窗体
+ V2XServiceManager
+ .getMogoTopViewManager()
+ .removeView(this);
+ }
+ }
+
+ @Override
+ public View getView() {
+ return this;
+ }
+
+ @Override
+ public void setWindowStatusListener(V2XWindowStatusListener listener) {
+
+ }
+
+ /**
+ * 窗体倒计时
+ */
+ private void startCountDown() {
+ // 倒计时
+ if (runnableV2XEvent == null) {
+ runnableV2XEvent = () -> {
+ EXPIRE_TIMER = EXPIRE_TIMER - COUNT_DOWN_TIMER;
+ Logger.d(MODULE_NAME, "V2X=== Window 30秒倒计时开始,当前 :" + EXPIRE_TIMER / COUNT_DOWN_TIMER + " 秒");
+ tvCountDown.setVisibility(View.VISIBLE);
+ ivVideoPlayingSign.setVisibility(View.VISIBLE);
+ tvCountDown.setText(String.valueOf(EXPIRE_TIMER / COUNT_DOWN_TIMER));
+ if (EXPIRE_TIMER > 0) {
+ handlerV2XEvent.postDelayed(runnableV2XEvent, COUNT_DOWN_TIMER);
+ } else {
+ Logger.d(MODULE_NAME, "V2X=== Window 30秒倒计时结束。。。");
+ // 移出Window详细信息
+ close();
+ }
+ };
+ } else {
+ handlerV2XEvent.removeCallbacks(runnableV2XEvent);
+ }
+ Logger.d(MODULE_NAME, "V2X=== Window 展示开始倒计时");
+ handlerV2XEvent.postDelayed(runnableV2XEvent, COUNT_DOWN_TIMER);
+ }
+
+ private void stopCountDown() {
+ Logger.d(MODULE_NAME, "V2X=== Window 倒计时停止。。。");
+ if (handlerV2XEvent != null && runnableV2XEvent != null) {
+ handlerV2XEvent.removeCallbacks(runnableV2XEvent);
+ runnableV2XEvent = null;
+ tvCountDown.setVisibility(View.GONE);
+ ivVideoPlayingSign.setVisibility(View.GONE);
+ EXPIRE_TIMER = ALL_EXPIRE_TIMER;
+ }
+ }
+}
diff --git a/modules/mogo-module-v2x/src/main/java/com/mogo/module/v2x/view/SimpleCoverVideoPlayer.kt b/modules/mogo-module-v2x/src/main/java/com/mogo/module/v2x/view/SimpleCoverVideoPlayer.kt
new file mode 100644
index 0000000000..1fbf84639a
--- /dev/null
+++ b/modules/mogo-module-v2x/src/main/java/com/mogo/module/v2x/view/SimpleCoverVideoPlayer.kt
@@ -0,0 +1,178 @@
+package com.mogo.module.v2x.view
+
+import android.content.Context
+import android.util.AttributeSet
+import android.view.Surface
+import android.view.View
+import android.widget.ImageView
+import com.mogo.module.v2x.R
+import com.shuyu.gsyvideoplayer.GSYVideoManager
+import com.shuyu.gsyvideoplayer.utils.GSYVideoType
+import com.shuyu.gsyvideoplayer.video.StandardGSYVideoPlayer
+import com.shuyu.gsyvideoplayer.video.base.GSYVideoView
+import com.shuyu.gsyvideoplayer.video.base.GSYVideoViewBridge
+
+class SimpleCoverVideoPlayer : StandardGSYVideoPlayer {
+
+ companion object {
+ const val PLAY_EVT_PLAY_LOADING = 1000
+ const val PLAY_EVT_PLAY_BEGIN = 2000
+ const val PLAY_EVT_PLAY_ERROR = 3000
+ }
+
+ private var playListener: PlayListener? = null
+ private lateinit var start: ImageView
+
+ interface PlayListener {
+ fun onPlayEvent(event: Int)
+ }
+
+ constructor(context: Context?) : super(context)
+ constructor(context: Context?, attrs: AttributeSet?) : super(context, attrs)
+ constructor(context: Context?, fullFlag: Boolean?) : super(context, fullFlag)
+
+ override fun init(context: Context) {
+ super.init(context)
+ start = findViewById(R.id.start)
+ if (mThumbImageViewLayout != null
+ && (mCurrentState == -1 || mCurrentState == GSYVideoView.CURRENT_STATE_NORMAL || mCurrentState == GSYVideoView.CURRENT_STATE_ERROR)
+ ) {
+ mThumbImageViewLayout.visibility = View.VISIBLE
+ }
+ }
+
+ override fun getLayoutId(): Int {
+ return R.layout.item_v2x_crossroad_live_video
+ }
+
+ override fun getGSYVideoManager(): GSYVideoViewBridge {
+ GSYVideoManager.instance().initContext(context.applicationContext)
+ return GSYVideoManager.instance()
+ }
+
+ override fun setProgressAndTime(
+ progress: Int,
+ secProgress: Int,
+ currentTime: Int,
+ totalTime: Int,
+ forceChange: Boolean
+ ) {
+ super.setProgressAndTime(progress, secProgress, currentTime, totalTime, forceChange)
+ if (progress != 0) {
+ mProgressBar?.progress = progress
+ }
+ }
+
+ fun setPlayListener(listener: PlayListener) {
+ this.playListener = listener
+ }
+
+ override fun updateStartImage() {
+ }
+
+ override fun changeUiToCompleteShow() {
+ super.changeUiToCompleteShow()
+ mBottomContainer?.visibility = View.INVISIBLE
+ mProgressBar?.visibility = View.GONE
+ }
+
+ override fun hideAllWidget() {
+ super.hideAllWidget()
+ mBottomContainer?.visibility = View.INVISIBLE
+ mProgressBar?.visibility = View.GONE
+ }
+
+ override fun changeUiToPrepareingClear() {
+ super.changeUiToPrepareingClear()
+ mBottomContainer?.visibility = View.INVISIBLE
+ mProgressBar?.visibility = View.GONE
+ }
+
+ override fun changeUiToPlayingBufferingClear() {
+ super.changeUiToPlayingBufferingClear()
+ mBottomContainer?.visibility = View.INVISIBLE
+ mProgressBar?.visibility = View.GONE
+
+ }
+
+ override fun changeUiToClear() {
+ super.changeUiToClear()
+ mBottomContainer?.visibility = View.INVISIBLE
+ mProgressBar?.visibility = View.GONE
+ }
+
+ override fun changeUiToCompleteClear() {
+ super.changeUiToCompleteClear()
+ mBottomContainer?.visibility = View.INVISIBLE
+ mProgressBar?.visibility = View.GONE
+ }
+
+ override fun onAutoCompletion() {
+ super.onAutoCompletion()
+ mProgressBar?.progress = 0
+ }
+
+ override fun showWifiDialog() {
+ //直接播放,不显示WIFI对话框
+ startPlayLogic()
+ }
+
+ override fun onDetachedFromWindow() {
+ super.onDetachedFromWindow()
+ mProgressBar?.progress = 0
+ mFullPauseBitmap = null
+ }
+
+ override fun onClick(v: View?) {
+ super.onClick(v)
+ }
+
+ override fun onCompletion() {
+ isPostBufferUpdate = false
+ }
+
+ override fun onSurfaceUpdated(surface: Surface) {
+ super.onSurfaceUpdated(surface)
+ if (mThumbImageViewLayout != null && mThumbImageViewLayout.visibility == View.VISIBLE) {
+ mThumbImageViewLayout.visibility = View.INVISIBLE
+ }
+ }
+
+ override fun onPrepared() {
+ super.onPrepared()
+ playListener?.onPlayEvent(PLAY_EVT_PLAY_LOADING)
+ }
+
+ private var isPostBufferUpdate = false
+
+ override fun onBufferingUpdate(percent: Int) {
+ super.onBufferingUpdate(percent)
+ if (!isPostBufferUpdate && percent == 0) {
+ isPostBufferUpdate = true
+ playListener?.onPlayEvent(PLAY_EVT_PLAY_BEGIN)
+ }
+ }
+
+ override fun onError(what: Int, extra: Int) {
+ super.onError(what, extra)
+ playListener?.onPlayEvent(PLAY_EVT_PLAY_ERROR)
+ isPostBufferUpdate = false
+ }
+
+ override fun setViewShowState(view: View?, visibility: Int) {
+ if (view === mThumbImageViewLayout && visibility != View.VISIBLE) {
+ return
+ }
+ super.setViewShowState(view, visibility)
+ }
+
+ override fun onSurfaceAvailable(surface: Surface) {
+ super.onSurfaceAvailable(surface)
+ mProgressBar?.visibility = View.GONE
+ if (GSYVideoType.getRenderType() != GSYVideoType.TEXTURE) {
+ if (mThumbImageViewLayout != null && mThumbImageViewLayout.visibility == View.VISIBLE) {
+ mThumbImageViewLayout.visibility = View.INVISIBLE
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/modules/mogo-module-v2x/src/main/java/com/mogo/module/v2x/view/V2XCarLiveVideoView.java b/modules/mogo-module-v2x/src/main/java/com/mogo/module/v2x/view/V2XCarLiveVideoView.java
new file mode 100644
index 0000000000..9db24bde03
--- /dev/null
+++ b/modules/mogo-module-v2x/src/main/java/com/mogo/module/v2x/view/V2XCarLiveVideoView.java
@@ -0,0 +1,280 @@
+package com.mogo.module.v2x.view;
+
+import android.content.Context;
+import android.content.Intent;
+import android.graphics.PorterDuff;
+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 androidx.core.content.ContextCompat;
+
+import com.mogo.commons.AbsMogoApplication;
+import com.mogo.commons.voice.AIAssist;
+import com.mogo.module.common.entity.MarkerCarInfo;
+import com.mogo.module.v2x.R;
+import com.mogo.module.v2x.V2XServiceManager;
+import com.mogo.module.v2x.entity.net.V2XLivePushVoRes;
+import com.mogo.module.v2x.network.V2XRefreshCallback;
+import com.mogo.module.v2x.utils.V2XUtils;
+import com.mogo.module.v2x.voice.V2XVoiceCallbackListener;
+import com.mogo.module.v2x.voice.V2XVoiceConstants;
+import com.mogo.module.v2x.voice.V2XVoiceManager;
+import com.mogo.utils.logger.Logger;
+import com.tencent.rtmp.ITXLivePlayListener;
+import com.tencent.rtmp.TXLiveConstants;
+import com.tencent.rtmp.TXLivePlayer;
+import com.tencent.rtmp.ui.TXCloudVideoView;
+
+import static com.mogo.module.v2x.V2XConst.MODULE_NAME;
+
+/**
+ * author : donghongyu
+ * e-mail : 1358506549@qq.com
+ * date : 2020-02-0623:07
+ * desc :
+ * version: 1.0
+ */
+public class V2XCarLiveVideoView extends RoundLayout {
+ private final String TAG = "V2XLiveGSYVideoView";
+
+ private TXCloudVideoView mTxcVideoView;
+ private ProgressBar mLoading;
+ private TXLivePlayer mLivePlayer;
+ private ConstraintLayout mClLoadError;
+ private TextView mTvRefreshButton;
+
+ private MarkerCarInfo.CarLiveInfo mCarLiveInfo;
+ // 重新刷新直播流
+ private V2XVoiceCallbackListener v2XVoiceCallbackRefreshListener = new V2XVoiceCallbackListener() {
+ @Override
+ public void onCallback(String command, Intent intent) {
+ mLoading.setVisibility(VISIBLE);
+ mClLoadError.setVisibility(GONE);
+ if (mCarLiveInfo != null) {
+ startLive(mCarLiveInfo);
+ }
+ }
+ };
+
+ public V2XCarLiveVideoView(Context context) {
+ this(context, null);
+ }
+
+ public V2XCarLiveVideoView(Context context, AttributeSet attrs) {
+ this(context, attrs, 0);
+ }
+
+ public V2XCarLiveVideoView(Context context, AttributeSet attrs, int defStyleAttr) {
+ super(context, attrs, defStyleAttr);
+ initView(context);
+ }
+
+ private void initView(Context context) {
+ LayoutInflater.from(context)
+ .inflate(R.layout.view_video_layout_see_live, this);
+ //mPlayerView 即 step1 中添加的界面 view
+ mTxcVideoView = findViewById(R.id.txcVideoView);
+ //创建 player 对象
+ mLivePlayer = new TXLivePlayer(context);
+ //关键 player 对象与界面 view
+ mLivePlayer.setPlayerView(mTxcVideoView);
+ mLivePlayer.setMute(true);
+ mLivePlayer.enableHardwareDecode(true);
+
+ mLoading = findViewById(R.id.loading);
+ mLoading.getIndeterminateDrawable().setColorFilter(ContextCompat.getColor(context, R.color.live_video_progress_bar_loading_color), PorterDuff.Mode.MULTIPLY);
+
+ mClLoadError = findViewById(R.id.clLoadError);
+ mTvRefreshButton = findViewById(R.id.tvRefreshButton);
+ mTvRefreshButton.setOnClickListener(new OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ mLoading.setVisibility(VISIBLE);
+ mClLoadError.setVisibility(GONE);
+ if (mCarLiveInfo != null) {
+ startLive(mCarLiveInfo);
+ }
+ }
+ });
+ }
+
+ /**
+ * 设置直播信息
+ */
+ public void setCarLiveInfo(MarkerCarInfo.CarLiveInfo carLiveInfo) {
+ mCarLiveInfo = carLiveInfo;
+ }
+
+ /**
+ * 开始直播
+ *
+ * @param carLiveInfo 要直播的车机,如果没有直播的地址需要重新获取最新的直播地址
+ */
+ public void startLive(MarkerCarInfo.CarLiveInfo carLiveInfo) {
+ // 进行直播播放
+ if (mLivePlayer != null
+ && carLiveInfo != null) {
+ if (!TextUtils.isEmpty(carLiveInfo.getVideoUrl())) {
+ AIAssist.getInstance(AbsMogoApplication.getApp()).speakTTSVoice(AbsMogoApplication.getApp().getString(R.string.v2x_voice_see_front_car_live));
+ setCarLiveInfo(carLiveInfo);
+ playLiveVideo(carLiveInfo);
+ }
+ // 根据SN重新获取直播流地址
+ else {
+ V2XServiceManager
+ .getV2XRefreshModel()
+ .livePush(new V2XRefreshCallback() {
+ @Override
+ public void onSuccess(V2XLivePushVoRes result) {
+ AIAssist.getInstance(AbsMogoApplication.getApp()).speakTTSVoice(AbsMogoApplication.getApp().getString(R.string.v2x_voice_see_front_car_live));
+ mClLoadError.setVisibility(GONE);
+ mClLoadError.setVisibility(GONE);
+ try {
+ MarkerCarInfo.CarLiveInfo carRealLiveInfo = new MarkerCarInfo.CarLiveInfo();
+ carRealLiveInfo.setVideoUrl(result.getResult().getPlayUrl().getRtmp());
+ carRealLiveInfo.setVideoSn(carLiveInfo.getVideoSn());
+ carRealLiveInfo.setVideoChannel(result.getResult().getVideoChannel());
+ setCarLiveInfo(carLiveInfo);
+ playLiveVideo(carRealLiveInfo);
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+
+ @Override
+ public void onFail(String msg) {
+ Logger.e(MODULE_NAME, "播放器:" + msg);
+ AIAssist.getInstance(AbsMogoApplication.getApp()).speakTTSVoice(AbsMogoApplication.getApp().getString(R.string.v2x_voice_see_front_car_live_error));
+ mLoading.setVisibility(GONE);
+ mClLoadError.setVisibility(VISIBLE);
+ }
+ }, carLiveInfo.getVideoSn(), 0);
+ }
+ }
+ }
+
+ /**
+ * 播放直播流,且开始心跳
+ */
+ private void playLiveVideo(MarkerCarInfo.CarLiveInfo carLiveInfo) {
+ startHeartLive(carLiveInfo);
+ if (mLivePlayer != null) {
+ mLivePlayer.startPlay(carLiveInfo.getVideoUrl(), TXLivePlayer.PLAY_TYPE_LIVE_RTMP);
+ mLivePlayer.setPlayListener(new ITXLivePlayListener() {
+ @Override
+ public void onPlayEvent(int event, Bundle bundle) {
+ Logger.w(MODULE_NAME, "播放器:onPlayEvent==" + event + "===bundle===" + bundle);
+ if (event == TXLiveConstants.PLAY_EVT_PLAY_LOADING) {
+ mLoading.setVisibility(VISIBLE);
+ mClLoadError.setVisibility(GONE);
+ } else if (event == TXLiveConstants.PLAY_EVT_PLAY_BEGIN) {
+ refreshStatusToListener(true);
+ mLoading.setVisibility(GONE);
+ mClLoadError.setVisibility(GONE);
+ } else if (event < 0) {
+ refreshStatusToListener(false);
+ AIAssist.getInstance(V2XUtils.getApp()).speakTTSVoice("直播获取识败,可以对我说重试", null);
+ stopLive(mCarLiveInfo);
+ mLoading.setVisibility(GONE);
+ mClLoadError.setVisibility(VISIBLE);
+ // 注册语音交互
+ V2XVoiceManager.INSTANCE
+ .registerWakeCmd(V2XVoiceConstants.COMMAND_ZHIDAO_V2X_REFRESH_CAR_LIVE,
+ v2XVoiceCallbackRefreshListener)
+ .registerUnWakeVoice(V2XVoiceConstants.COMMAND_ZHIDAO_V2X_REFRESH_LIVE_UN_WAKEUP,
+ v2XVoiceCallbackRefreshListener);
+ }
+ }
+
+ @Override
+ public void onNetStatus(Bundle bundle) {
+ //Logger.w(MODULE_NAME, "播放器:onNetStatus===bundle===" + bundle);
+ }
+ });
+ }
+ }
+
+ // 刷新直播心跳
+ private void startHeartLive(MarkerCarInfo.CarLiveInfo carLiveInfo) {
+ try {
+ if (!TextUtils.isEmpty(carLiveInfo.getVideoSn())
+ && !TextUtils.isEmpty(carLiveInfo.getVideoChannel())) {
+ V2XServiceManager
+ .getV2XRefreshModel()
+ .refreshHeartBeat(carLiveInfo.getVideoSn(),
+ carLiveInfo.getVideoChannel(),
+ null);
+ }
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+
+ public void stopLive(MarkerCarInfo.CarLiveInfo carLiveInfo) {
+ try {
+ Logger.w(MODULE_NAME, "心跳:关闭直播...");
+ // 暂停
+ mLivePlayer.pause();
+ // true 代表清除最后一帧画面
+ mLivePlayer.stopPlay(true);
+ mTxcVideoView.onDestroy();
+ // 停止推流
+ V2XServiceManager
+ .getV2XRefreshModel()
+ .livePush(new V2XRefreshCallback() {
+ @Override
+ public void onSuccess(V2XLivePushVoRes result) {
+ Logger.d(MODULE_NAME, "播放器:" + result);
+ }
+
+ @Override
+ public void onFail(String msg) {
+ Logger.e(MODULE_NAME, "播放器:" + msg);
+ }
+ }, carLiveInfo.getVideoSn(), 1);
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+
+ @Override
+ protected void onAttachedToWindow() {
+ super.onAttachedToWindow();
+ if (mCarLiveInfo != null) {
+ startLive(mCarLiveInfo);
+ }
+ }
+
+ @Override
+ protected void onDetachedFromWindow() {
+ stopLive(mCarLiveInfo);
+ mLoading.setVisibility(VISIBLE);
+ // 反注册语音交互
+ V2XVoiceManager.INSTANCE
+ .unRegisterWakeCmd(V2XVoiceConstants.COMMAND_ZHIDAO_V2X_REFRESH_CAR_LIVE)
+ .unRegisterUnWakeVoice(V2XVoiceConstants.COMMAND_ZHIDAO_V2X_REFRESH_LIVE_UN_WAKEUP);
+ super.onDetachedFromWindow();
+ }
+
+ private void refreshStatusToListener(boolean videoPlaying) {
+ if (onVideoStatusChange != null) {
+ onVideoStatusChange.videoPlaying(videoPlaying);
+ }
+ }
+
+ private OnVideoStatusChange onVideoStatusChange;
+
+ public void addOnVideoStatusChangeListener(OnVideoStatusChange onVideoStatusChange) {
+ this.onVideoStatusChange = onVideoStatusChange;
+ }
+
+ public interface OnVideoStatusChange {
+ void videoPlaying(boolean videoPlaying);
+ }
+}
diff --git a/modules/mogo-module-v2x/src/main/java/com/mogo/module/v2x/view/V2XCrossRoadVideoView.java b/modules/mogo-module-v2x/src/main/java/com/mogo/module/v2x/view/V2XCrossRoadVideoView.java
new file mode 100644
index 0000000000..2bdac21791
--- /dev/null
+++ b/modules/mogo-module-v2x/src/main/java/com/mogo/module/v2x/view/V2XCrossRoadVideoView.java
@@ -0,0 +1,263 @@
+package com.mogo.module.v2x.view;
+
+import android.content.Context;
+import android.content.Intent;
+import android.graphics.PorterDuff;
+import android.text.TextUtils;
+import android.util.AttributeSet;
+import android.view.LayoutInflater;
+import android.widget.ProgressBar;
+import android.widget.TextView;
+
+import androidx.constraintlayout.widget.ConstraintLayout;
+import androidx.core.content.ContextCompat;
+
+import com.mogo.commons.AbsMogoApplication;
+import com.mogo.commons.voice.AIAssist;
+import com.mogo.module.common.entity.MarkerCarInfo;
+import com.mogo.module.v2x.R;
+import com.mogo.module.v2x.entity.net.V2XLiveCrossRoad;
+import com.mogo.module.v2x.network.V2XRefreshCallback;
+import com.mogo.module.v2x.network.V2XRefreshModel;
+import com.mogo.module.v2x.utils.V2XUtils;
+import com.mogo.module.v2x.voice.V2XVoiceCallbackListener;
+import com.mogo.module.v2x.voice.V2XVoiceConstants;
+import com.mogo.module.v2x.voice.V2XVoiceManager;
+import com.mogo.utils.logger.Logger;
+import com.shuyu.gsyvideoplayer.GSYVideoManager;
+import com.shuyu.gsyvideoplayer.builder.GSYVideoOptionBuilder;
+import com.shuyu.gsyvideoplayer.cache.CacheFactory;
+import com.shuyu.gsyvideoplayer.cache.ProxyCacheManager;
+import com.shuyu.gsyvideoplayer.model.VideoOptionModel;
+import com.shuyu.gsyvideoplayer.player.IjkPlayerManager;
+import com.shuyu.gsyvideoplayer.player.PlayerFactory;
+import com.shuyu.gsyvideoplayer.utils.GSYVideoType;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import tv.danmaku.ijk.media.player.IjkMediaPlayer;
+
+import static com.mogo.module.v2x.V2XConst.MODULE_NAME;
+import static com.mogo.module.v2x.view.SimpleCoverVideoPlayer.PLAY_EVT_PLAY_BEGIN;
+import static com.mogo.module.v2x.view.SimpleCoverVideoPlayer.PLAY_EVT_PLAY_LOADING;
+
+/**
+ * author : donghongyu
+ * e-mail : 1358506549@qq.com
+ * date : 2020-02-0623:07
+ * desc :
+ * version: 1.0
+ */
+public class V2XCrossRoadVideoView extends RoundLayout {
+
+ private static final String TAG = "CrossRoadVideo";
+
+ private SimpleCoverVideoPlayer mTxcVideoView;
+ private GSYVideoOptionBuilder gsyVideoOptionBuilder = new GSYVideoOptionBuilder();
+ private ProgressBar mLoading;
+ private ConstraintLayout mClLoadError;
+ private TextView mTvRefreshButton;
+ private boolean init = false;
+
+ private MarkerCarInfo.CarLiveInfo mCarLiveInfo;
+ // 重新刷新直播流
+ private V2XVoiceCallbackListener v2XVoiceCallbackRefreshListener = new V2XVoiceCallbackListener() {
+ @Override
+ public void onCallback(String command, Intent intent) {
+ mLoading.setVisibility(VISIBLE);
+ mClLoadError.setVisibility(GONE);
+ if (mCarLiveInfo != null) {
+ startLive(mCarLiveInfo);
+ }
+ }
+ };
+
+ public V2XCrossRoadVideoView(Context context) {
+ this(context, null);
+ }
+
+ public V2XCrossRoadVideoView(Context context, AttributeSet attrs) {
+ this(context, attrs, 0);
+ }
+
+ public V2XCrossRoadVideoView(Context context, AttributeSet attrs, int defStyleAttr) {
+ super(context, attrs, defStyleAttr);
+ initView(context);
+ }
+
+ private void initView(Context context) {
+ if(init){
+ return;
+ }
+ Logger.d("V2XCrossRoadVideoView", "V2X===初始化语音呼叫路口直播视图");
+ LayoutInflater.from(context)
+ .inflate(R.layout.view_video_layout_see_crossroad, this);
+ //mPlayerView 即 step1 中添加的界面 view
+ mTxcVideoView = findViewById(R.id.txcVideoView);
+ initGSYVideoConfig();
+
+ mLoading = findViewById(R.id.loading);
+ mLoading.getIndeterminateDrawable().setColorFilter(ContextCompat.getColor(context, R.color.live_video_progress_bar_loading_color), PorterDuff.Mode.MULTIPLY);
+
+ mClLoadError = findViewById(R.id.clLoadError);
+ mTvRefreshButton = findViewById(R.id.tvRefreshButton);
+ mTvRefreshButton.setOnClickListener(v -> {
+ mLoading.setVisibility(VISIBLE);
+ mClLoadError.setVisibility(GONE);
+ if (mCarLiveInfo != null) {
+ startLive(mCarLiveInfo);
+ }
+ });
+ init = true;
+ }
+
+ private void initGSYVideoConfig() {
+ PlayerFactory.setPlayManager(IjkPlayerManager.class);
+ CacheFactory.setCacheManager(ProxyCacheManager.class);
+ List list = new ArrayList<>();
+ list.add(new VideoOptionModel(IjkMediaPlayer.OPT_CATEGORY_FORMAT, "rtsp_transport", "tcp"));
+ list.add(new VideoOptionModel(IjkMediaPlayer.OPT_CATEGORY_FORMAT, "rtsp_flags", "prefer_tcp"));
+ list.add(new VideoOptionModel(IjkMediaPlayer.OPT_CATEGORY_FORMAT, "allowed_media_types", "video"));
+ list.add(new VideoOptionModel(IjkMediaPlayer.OPT_CATEGORY_FORMAT, "timeout", 20000));
+ list.add(new VideoOptionModel(IjkMediaPlayer.OPT_CATEGORY_FORMAT, "buffer_size", 1316));
+
+ list.add(new VideoOptionModel(IjkMediaPlayer.OPT_CATEGORY_FORMAT, "infbuf", 1));
+ list.add(new VideoOptionModel(IjkMediaPlayer.OPT_CATEGORY_FORMAT, "analyzeduration", 1));
+
+ list.add(new VideoOptionModel(IjkMediaPlayer.OPT_CATEGORY_FORMAT, "probesize", 10240));
+ list.add(new VideoOptionModel(IjkMediaPlayer.OPT_CATEGORY_FORMAT, "flush_packets", 1));
+ list.add(new VideoOptionModel(IjkMediaPlayer.OPT_CATEGORY_FORMAT, "dns_cache_clear", 1));
+ list.add(new VideoOptionModel(IjkMediaPlayer.OPT_CATEGORY_FORMAT, "dns_cache_timeout", -1));
+ list.add(new VideoOptionModel(IjkMediaPlayer.OPT_CATEGORY_FORMAT, "analyzeduration",1));
+ list.add(new VideoOptionModel(IjkMediaPlayer.OPT_CATEGORY_FORMAT, "packet-buffering", 0));
+ list.add(new VideoOptionModel(IjkMediaPlayer.OPT_CATEGORY_FORMAT, "reconnect",10));
+
+ GSYVideoManager.instance().setOptionModelList(list);
+ GSYVideoType.enableMediaCodec();
+ GSYVideoType.enableMediaCodecTexture();
+ GSYVideoType.setShowType(GSYVideoType.SCREEN_MATCH_FULL);
+ }
+
+ /**
+ * 设置直播信息
+ */
+ public void setCarLiveInfo(MarkerCarInfo.CarLiveInfo carLiveInfo) {
+ mCarLiveInfo = carLiveInfo;
+ }
+
+ /**
+ * 开始直播
+ *
+ * @param carLiveInfo 要直播的车机,如果没有直播的地址需要重新获取最新的直播地址
+ */
+ public void startLive(MarkerCarInfo.CarLiveInfo carLiveInfo) {
+ initView(this.getContext());
+ // 进行直播播放
+ if (mTxcVideoView != null
+ && carLiveInfo != null) {
+ if (!TextUtils.isEmpty(carLiveInfo.getVideoUrl())) {
+ setCarLiveInfo(carLiveInfo);
+ playLiveVideo(carLiveInfo);
+ }
+ //重新获取直播流地址
+ else {
+ V2XRefreshModel.getInstance(AbsMogoApplication.getApp()).queryCrossRoadsLive(new V2XRefreshCallback() {
+ @Override
+ public void onSuccess(V2XLiveCrossRoad result) {
+ if (result != null && result.getResult().getUrl() != null) {
+ String liveUrl = result.getResult().getUrl();
+ MarkerCarInfo.CarLiveInfo carLiveInfo = new MarkerCarInfo.CarLiveInfo();
+ carLiveInfo.setVideoUrl(liveUrl);
+ setCarLiveInfo(carLiveInfo);
+ playLiveVideo(carLiveInfo);
+ } else {
+ Logger.d(MODULE_NAME, "startLive 路口实况直播地址为空");
+ }
+ }
+
+ @Override
+ public void onFail(String msg) {
+ //获取路口实况失败
+ Logger.d(MODULE_NAME, "获取路口实况失败");
+ }
+ });
+ }
+ }
+ }
+
+ /**
+ * 播放直播流,且开始心跳
+ */
+ private void playLiveVideo(MarkerCarInfo.CarLiveInfo carLiveInfo) {
+ if (mTxcVideoView != null) {
+ mTxcVideoView.setPlayListener(event -> {
+ Logger.w(MODULE_NAME, "播放器:onPlayEvent==" + event);
+ if (event == PLAY_EVT_PLAY_LOADING) {
+ mLoading.setVisibility(VISIBLE);
+ mClLoadError.setVisibility(GONE);
+ } else if (event == PLAY_EVT_PLAY_BEGIN) {
+ refreshStatusToListener(true);
+ mLoading.setVisibility(GONE);
+ mClLoadError.setVisibility(GONE);
+ } else if (event < 0) {
+ refreshStatusToListener(false);
+ AIAssist.getInstance(V2XUtils.getApp()).speakTTSVoice("直播获取识败,可以对我说重试", null);
+ stopLive();
+ mLoading.setVisibility(GONE);
+ mClLoadError.setVisibility(VISIBLE);
+ // 注册语音交互
+ V2XVoiceManager.INSTANCE
+ .registerUnWakeVoice(V2XVoiceConstants.COMMAND_ZHIDAO_V2X_REFRESH_LIVE_UN_WAKEUP,
+ v2XVoiceCallbackRefreshListener);
+ }
+ });
+ gsyVideoOptionBuilder.setUrl(carLiveInfo.getVideoUrl()).setCacheWithPlay(false).setPlayTag(TAG)
+ .build(mTxcVideoView);
+ mTxcVideoView.getStartButton().performClick();
+ }
+ }
+
+ public void stopLive() {
+ try {
+ Logger.w(MODULE_NAME, "关闭直播...");
+ GSYVideoManager.releaseAllVideos();
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+
+ @Override
+ protected void onAttachedToWindow() {
+ super.onAttachedToWindow();
+ if (mCarLiveInfo != null) {
+ startLive(mCarLiveInfo);
+ }
+ }
+
+ @Override
+ protected void onDetachedFromWindow() {
+ stopLive();
+ mLoading.setVisibility(VISIBLE);
+ // 反注册语音交互
+ V2XVoiceManager.INSTANCE
+ .unRegisterUnWakeVoice(V2XVoiceConstants.COMMAND_ZHIDAO_V2X_REFRESH_LIVE_UN_WAKEUP);
+ super.onDetachedFromWindow();
+ }
+
+ private void refreshStatusToListener(boolean videoPlaying) {
+ if (onVideoStatusChange != null) {
+ onVideoStatusChange.videoPlaying(videoPlaying);
+ }
+ }
+
+ private OnVideoStatusChange onVideoStatusChange;
+
+ public void addOnVideoStatusChangeListener(OnVideoStatusChange onVideoStatusChange) {
+ this.onVideoStatusChange = onVideoStatusChange;
+ }
+
+ public interface OnVideoStatusChange {
+ void videoPlaying(boolean videoPlaying);
+ }
+}
diff --git a/modules/mogo-module-v2x/src/main/java/com/mogo/module/v2x/voice/V2XVoiceConstants.java b/modules/mogo-module-v2x/src/main/java/com/mogo/module/v2x/voice/V2XVoiceConstants.java
index 78aefa1956..7c96329347 100644
--- a/modules/mogo-module-v2x/src/main/java/com/mogo/module/v2x/voice/V2XVoiceConstants.java
+++ b/modules/mogo-module-v2x/src/main/java/com/mogo/module/v2x/voice/V2XVoiceConstants.java
@@ -86,6 +86,16 @@ public class V2XVoiceConstants {
*/
public static final String COMMAND_ZHIDAO_V2X_REFRESH_CAR_LIVE = "com.zhidao.user.action.retry";
+ /**
+ * 唤醒词:查看前车视频
+ */
+ public static final String COMMAND_ZHIDAO_V2X_AHEAD_LIVE = "com.zhidao.ahead.live";
+
+ /**
+ * 唤醒词:查看周围路口直播
+ */
+ public static final String COMMAND_ZHIDAO_V2X_CROSSROADS_LIVE = "com.zhidao.crossroads.live";
+
/**
* 应用内免唤醒
* 发起定向车聊聊
@@ -200,6 +210,19 @@ public class V2XVoiceConstants {
public static final String COMMAND_ZHIDAO_V2X_ILLEGAL_PARKMARKER_FEEDBACK_YOUYONG_UN_WAKEUP = "COMMAND_ZHIDAO_V2X_ILLEGAL_PARKMARKER_FEEDBACK_YOUYONG_UN_WAKEUP";
public static final String[] COMMAND_ZHIDAO_V2X_ILLEGAL_PARKMARKER_FEEDBACK_YOUYONG_UN_WAKEUP_WORDS = {"有用"};
+ /**
+ * 应用内免唤醒
+ * "查看前车视频","查看前车直播","查看前车视角"
+ */
+ public static final String COMMAND_ZHIDAO_V2X_CALL_FRONT_CAR_DEMO_UN_WAKEUP = "COMMAND_ZHIDAO_V2X_CALL_FRONT_CAR_DEMO_UN_WAKEUP";
+ public static final String[] COMMAND_ZHIDAO_V2X_CALL_FRONT_CAR_DEMO_UN_WAKEUP_WORDS = {"查看前车视频", "查看前车直播", "查看前车视角"};
+
+ /**
+ * 应用内免唤醒
+ */
+ public static final String COMMAND_ZHIDAO_V2X_OPEN_ROAD_CAMERA_LIVE_UN_WAKEUP = "COMMAND_ZHIDAO_V2X_OPEN_ROAD_CAMERA_LIVE_UN_WAKEUP";
+ public static final String[] COMMAND_ZHIDAO_V2X_OPEN_ROAD_CAMERA_LIVE_UN_WAKEUP_WORDS = {"查看路口实况", "查看路口直播", "查看路口视频"};
+
/**
* 违章停车
* 没用
@@ -252,6 +275,10 @@ public class V2XVoiceConstants {
sVoiceCmds.put(COMMAND_ZHIDAO_V2X_OPEN_SURROUNDING_EVENT_UN_WAKEUP, COMMAND_ZHIDAO_V2X_OPEN_SURROUNDING_EVENT_UN_WAKEUP_WORDS);
sVoiceCmds.put(COMMAND_ZHIDAO_V2X_OPEN_SHEAR_EVENT_UN_WAKEUP, COMMAND_ZHIDAO_V2X_OPEN_SHEAR_EVENT_UN_WAKEUP_WORDS);
+ //2020-6-24 顺义演示需求添加,现合并至launcher 更新时间:2020-08-25
+ sVoiceCmds.put(COMMAND_ZHIDAO_V2X_CALL_FRONT_CAR_DEMO_UN_WAKEUP, COMMAND_ZHIDAO_V2X_CALL_FRONT_CAR_DEMO_UN_WAKEUP_WORDS);
+ sVoiceCmds.put(COMMAND_ZHIDAO_V2X_OPEN_ROAD_CAMERA_LIVE_UN_WAKEUP, COMMAND_ZHIDAO_V2X_OPEN_ROAD_CAMERA_LIVE_UN_WAKEUP_WORDS);
+
//默认
/* sCmds.add(COMMAND_ZHIDAO_V2X_CALL_CHATTING);
diff --git a/modules/mogo-module-v2x/src/main/res/drawable/v2x_shape_bg_count_down_corner_14.xml b/modules/mogo-module-v2x/src/main/res/drawable/v2x_shape_bg_count_down_corner_14.xml
new file mode 100644
index 0000000000..9f90c34357
--- /dev/null
+++ b/modules/mogo-module-v2x/src/main/res/drawable/v2x_shape_bg_count_down_corner_14.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/modules/mogo-module-v2x/src/main/res/layout/item_v2x_crossroad_live_video.xml b/modules/mogo-module-v2x/src/main/res/layout/item_v2x_crossroad_live_video.xml
new file mode 100644
index 0000000000..938a27fd1b
--- /dev/null
+++ b/modules/mogo-module-v2x/src/main/res/layout/item_v2x_crossroad_live_video.xml
@@ -0,0 +1,23 @@
+
+
+
+
+
+
+
+
+
diff --git a/modules/mogo-module-v2x/src/main/res/layout/item_v2x_see_crossroad_live_video.xml b/modules/mogo-module-v2x/src/main/res/layout/item_v2x_see_crossroad_live_video.xml
new file mode 100644
index 0000000000..50615a0a07
--- /dev/null
+++ b/modules/mogo-module-v2x/src/main/res/layout/item_v2x_see_crossroad_live_video.xml
@@ -0,0 +1,53 @@
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/modules/mogo-module-v2x/src/main/res/layout/item_v2x_see_frontcar_live_video.xml b/modules/mogo-module-v2x/src/main/res/layout/item_v2x_see_frontcar_live_video.xml
new file mode 100644
index 0000000000..8ecc584a7d
--- /dev/null
+++ b/modules/mogo-module-v2x/src/main/res/layout/item_v2x_see_frontcar_live_video.xml
@@ -0,0 +1,53 @@
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/modules/mogo-module-v2x/src/main/res/layout/view_video_layout_see_crossroad.xml b/modules/mogo-module-v2x/src/main/res/layout/view_video_layout_see_crossroad.xml
new file mode 100644
index 0000000000..9a5eda56df
--- /dev/null
+++ b/modules/mogo-module-v2x/src/main/res/layout/view_video_layout_see_crossroad.xml
@@ -0,0 +1,70 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/modules/mogo-module-v2x/src/main/res/layout/view_video_layout_see_live.xml b/modules/mogo-module-v2x/src/main/res/layout/view_video_layout_see_live.xml
new file mode 100644
index 0000000000..0ad6257f83
--- /dev/null
+++ b/modules/mogo-module-v2x/src/main/res/layout/view_video_layout_see_live.xml
@@ -0,0 +1,70 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/modules/mogo-module-v2x/src/main/res/layout/window_see_carlive_video.xml b/modules/mogo-module-v2x/src/main/res/layout/window_see_carlive_video.xml
new file mode 100644
index 0000000000..0859547799
--- /dev/null
+++ b/modules/mogo-module-v2x/src/main/res/layout/window_see_carlive_video.xml
@@ -0,0 +1,14 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/modules/mogo-module-v2x/src/main/res/layout/window_see_crossroadlive_video.xml b/modules/mogo-module-v2x/src/main/res/layout/window_see_crossroadlive_video.xml
new file mode 100644
index 0000000000..02a8789b35
--- /dev/null
+++ b/modules/mogo-module-v2x/src/main/res/layout/window_see_crossroadlive_video.xml
@@ -0,0 +1,14 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/modules/mogo-module-v2x/src/main/res/values-xhdpi/dimens.xml b/modules/mogo-module-v2x/src/main/res/values-xhdpi/dimens.xml
index 45ca7333ff..9fe6c5b6a6 100644
--- a/modules/mogo-module-v2x/src/main/res/values-xhdpi/dimens.xml
+++ b/modules/mogo-module-v2x/src/main/res/values-xhdpi/dimens.xml
@@ -4,11 +4,13 @@
32px
32px
+ 1060px
350px
450px
390px
220px
+ 670px
147px
diff --git a/modules/mogo-module-v2x/src/main/res/values/dimens.xml b/modules/mogo-module-v2x/src/main/res/values/dimens.xml
index c6458087a1..9533e2707f 100644
--- a/modules/mogo-module-v2x/src/main/res/values/dimens.xml
+++ b/modules/mogo-module-v2x/src/main/res/values/dimens.xml
@@ -4,11 +4,13 @@
18px
20px
+ 642px
194px
250px
190px
130px
+ 670px
82px
diff --git a/modules/mogo-module-v2x/src/main/res/values/strings.xml b/modules/mogo-module-v2x/src/main/res/values/strings.xml
index 2413b8f3d5..bb63975aa1 100644
--- a/modules/mogo-module-v2x/src/main/res/values/strings.xml
+++ b/modules/mogo-module-v2x/src/main/res/values/strings.xml
@@ -8,5 +8,9 @@
周围5公里,共 %d 条交通信息
去分享
刷新
+ 小智已为您查询到前方最近车辆直播视频,请查看
+ 诶呀呀,没有查到前方车辆直播视屏,过一会再试试吧
+ 已为您打开路口直播实况
+ 诶呀呀,周围没有可用路口实况直播