@@ -465,6 +465,10 @@ class MoGoHmiFragment : MvpFragment<MoGoWarningContract.View?, WaringPresenter?>
|
||||
}
|
||||
}
|
||||
|
||||
override fun startRoadCameraLive(flvUrl: String) {
|
||||
cameraListView?.startRoadCameraLive(flvUrl)
|
||||
}
|
||||
|
||||
private fun showCameraList(cameraList: List<CameraEntity>?) {
|
||||
context?.let {
|
||||
if (cameraViewFloat == null) {
|
||||
@@ -474,7 +478,11 @@ class MoGoHmiFragment : MvpFragment<MoGoWarningContract.View?, WaringPresenter?>
|
||||
}
|
||||
cameraListView!!.setClickListener(object : CameraListView.ClickListener {
|
||||
override fun onClose(v: View) {
|
||||
// Builder和cameraListView都置空
|
||||
dismissFloatView()
|
||||
// 丢弃开启摄像头推流请求,同时monitor回调hmi的startRoadCameraLive()
|
||||
// 也做了cameraListView的非空判断
|
||||
CallerMonitorManager.disposeCameraStream()
|
||||
}
|
||||
|
||||
override fun onShowLive(isShow: Boolean) {
|
||||
|
||||
@@ -36,7 +36,7 @@ class CameraListAdapter : Adapter<CameraListAdapter.CameraListHolder> {
|
||||
data?.let {
|
||||
val cameraEntity = it[position]
|
||||
holder.cameraInfo.text = with(cameraEntity) {
|
||||
if (!isCarLive()) "${roadName}${crossingName}${getHeadingStr()}" else sn
|
||||
if (!isCarLive()) "${roadName}${crossingName}${getHeadingStr()}" else "${street}${township}"
|
||||
}
|
||||
holder.bottomLine.visibility =
|
||||
if (it.size - 1 == position) View.INVISIBLE else View.VISIBLE
|
||||
|
||||
@@ -17,8 +17,10 @@ import com.mogo.cloud.passport.MoGoAiCloudClientConfig
|
||||
import com.mogo.cloud.trafficlive.api.ITrafficCarLiveCallBack
|
||||
import com.mogo.cloud.trafficlive.api.MoGoAiCloudTrafficLive
|
||||
import com.mogo.eagle.core.data.camera.CameraEntity
|
||||
import com.mogo.eagle.core.function.call.monitor.CallerMonitorManager
|
||||
import com.mogo.eagle.core.function.hmi.R
|
||||
import com.mogo.eagle.core.widget.media.video.SimpleVideoPlayer
|
||||
import com.mogo.utils.logger.Logger
|
||||
import com.shuyu.gsyvideoplayer.GSYVideoManager
|
||||
import com.shuyu.gsyvideoplayer.builder.GSYVideoOptionBuilder
|
||||
import com.shuyu.gsyvideoplayer.utils.GSYVideoType
|
||||
@@ -60,6 +62,7 @@ class CameraListView : FrameLayout {
|
||||
}
|
||||
private var liveSn: String? = ""
|
||||
private var isCarLive = false
|
||||
private var isFirstPage = true
|
||||
|
||||
@JvmOverloads
|
||||
constructor(context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0) : super(
|
||||
@@ -79,6 +82,7 @@ class CameraListView : FrameLayout {
|
||||
rvCameraList.adapter = CameraListAdapter(context, cameraInfoList) {
|
||||
it.tag?.let { cameraEntity ->
|
||||
showLiveView()
|
||||
isFirstPage = false
|
||||
isCloseStatus = false
|
||||
isPlaySuccess = false
|
||||
isCarLive = false
|
||||
@@ -86,7 +90,12 @@ class CameraListView : FrameLayout {
|
||||
when {
|
||||
!cameraEntity.isCarLive() -> {
|
||||
isCarLive = false
|
||||
if (!cameraEntity.flvUrl.isNullOrEmpty()) gsyVideoPlay(cameraEntity.flvUrl!!)
|
||||
// 开启摄像头推流
|
||||
cameraEntity.ip?.let { ip ->
|
||||
CallerMonitorManager.openCameraStream(ip)
|
||||
// 测试一直打开的顺义摄像头,不需要调接口让摄像头开启推流
|
||||
// if (!cameraEntity.flvUrl.isNullOrEmpty()) gsyVideoPlay(cameraEntity.flvUrl!!)
|
||||
}
|
||||
}
|
||||
else -> {
|
||||
isCarLive = true
|
||||
@@ -104,6 +113,7 @@ class CameraListView : FrameLayout {
|
||||
ivCloseIcon.setOnClickListener {
|
||||
isPlaySuccess = false
|
||||
isCarLive = false
|
||||
isFirstPage = true
|
||||
when {
|
||||
isCloseStatus -> clickListener?.onClose(it)// 直接退出
|
||||
else -> {// 返回摄像头列表
|
||||
@@ -124,6 +134,7 @@ class CameraListView : FrameLayout {
|
||||
GSYVideoType.setShowType(GSYVideoType.SCREEN_MATCH_FULL)
|
||||
svpPlayer.setPlayListener(object : SimpleVideoPlayer.PlayListener {
|
||||
override fun onPlayEvent(event: Int) {
|
||||
Logger.d(TAG, "onPlayEvent: event is:$event")
|
||||
when (event) {
|
||||
SimpleVideoPlayer.PLAY_EVT_PLAY_LOADING -> {
|
||||
|
||||
@@ -135,7 +146,9 @@ class CameraListView : FrameLayout {
|
||||
}
|
||||
else -> {
|
||||
showNoSignalView()
|
||||
valueAnimator.start()
|
||||
if (!valueAnimator.isStarted && !valueAnimator.isRunning) {
|
||||
valueAnimator.start()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -184,6 +197,10 @@ class CameraListView : FrameLayout {
|
||||
}
|
||||
}
|
||||
|
||||
fun startRoadCameraLive(flvUrl: String) {
|
||||
gsyVideoPlay(flvUrl)
|
||||
}
|
||||
|
||||
private fun handleSnLiveStatus(status: Int) {
|
||||
when (status) {
|
||||
0 -> {// 正在直播
|
||||
@@ -197,22 +214,38 @@ class CameraListView : FrameLayout {
|
||||
|
||||
private val trafficCarLiveCallBack = object : ITrafficCarLiveCallBack {
|
||||
override fun onLive(liveSn: String?) {
|
||||
// 开始直播
|
||||
progressBar.visibility = View.GONE
|
||||
surfaceView.visibility = View.VISIBLE
|
||||
isPlaySuccess = true
|
||||
Logger.d(TAG, "onLive")
|
||||
}
|
||||
|
||||
override fun onFirstFrame() {
|
||||
Logger.d(TAG, "onFirstFrame:isFirstPage is:$isFirstPage,isCarLive is:$isCarLive")
|
||||
if (!isFirstPage && isCarLive) {
|
||||
// 开始直播
|
||||
progressBar.visibility = View.GONE
|
||||
surfaceView.visibility = View.VISIBLE
|
||||
isPlaySuccess = true
|
||||
}
|
||||
}
|
||||
|
||||
override fun onDisConnect() {
|
||||
// 断开连接
|
||||
showNoSignalView()
|
||||
valueAnimator.start()
|
||||
Logger.e(TAG, "onDisConnect")
|
||||
if (!isFirstPage && isCarLive) {
|
||||
showNoSignalView()
|
||||
if (!valueAnimator.isStarted && !valueAnimator.isRunning) {
|
||||
valueAnimator.start()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun onError(errorMsg: String?) {
|
||||
// 发生错误
|
||||
showNoSignalView()
|
||||
valueAnimator.start()
|
||||
Logger.e(TAG, "onError msg is:${errorMsg}")
|
||||
if (!isFirstPage && isCarLive) {
|
||||
// 发生错误
|
||||
showNoSignalView()
|
||||
if (!valueAnimator.isStarted && !valueAnimator.isRunning) {
|
||||
valueAnimator.start()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -246,7 +279,6 @@ class CameraListView : FrameLayout {
|
||||
override fun onDetachedFromWindow() {
|
||||
super.onDetachedFromWindow()
|
||||
stopLive()
|
||||
svpPlayer.removeAllViews()
|
||||
valueAnimator.cancel()
|
||||
}
|
||||
|
||||
|
||||
@@ -7,9 +7,12 @@ import com.mogo.eagle.core.data.camera.Camera
|
||||
import com.mogo.eagle.core.data.camera.CameraEntity
|
||||
import com.mogo.eagle.core.data.camera.LiveCameraInfo
|
||||
import com.mogo.eagle.core.data.camera.ReqLiveCarBean
|
||||
import com.mogo.eagle.core.function.call.hmi.CallerHmiManager
|
||||
import com.mogo.eagle.core.function.call.map.CallerMapLocationListenerManager
|
||||
import com.mogo.eagle.core.function.monitoring.net.CameraListServices
|
||||
import com.mogo.module.common.MogoApisHandler
|
||||
import com.mogo.module.common.constants.HostConst
|
||||
import com.mogo.utils.logger.Logger
|
||||
import io.reactivex.android.schedulers.AndroidSchedulers
|
||||
import io.reactivex.disposables.Disposable
|
||||
import io.reactivex.schedulers.Schedulers
|
||||
@@ -21,8 +24,12 @@ class CronTaskManager {
|
||||
private val netWork by lazy {
|
||||
MogoApisHandler.getInstance().apis.networkApi
|
||||
}
|
||||
// 请求路侧摄像头
|
||||
private var disposable: Disposable? = null
|
||||
// 请求车侧摄像头
|
||||
private var carDisposable: Disposable? = null
|
||||
// 开启路侧摄像头推流
|
||||
private var streamDisposable: Disposable? = null
|
||||
private var cameraList: List<CameraEntity>? = null
|
||||
private var carCameraList: List<CameraEntity>? = null
|
||||
|
||||
@@ -51,33 +58,64 @@ class CronTaskManager {
|
||||
crossing.cameras.filter { camera ->
|
||||
!camera.flvUrl.isNullOrEmpty()
|
||||
}.map {
|
||||
CameraEntity(it.flvUrl, "", it.roadName, it.crossingName, it.getHeadingStr())
|
||||
CameraEntity(it.flvUrl, "", it.roadName,
|
||||
it.crossingName, it.getHeadingStr(), it.ip)
|
||||
}
|
||||
} ?: ArrayList()
|
||||
}
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribe({
|
||||
cameraList = it
|
||||
Logger.d(TAG, "requestCameraList返回结果为:$it")
|
||||
}, {
|
||||
it.printStackTrace()
|
||||
Logger.e(TAG, "message is:${it.message}, cause is:${it.cause}")
|
||||
})
|
||||
}
|
||||
|
||||
private fun requestCarCameraList() {
|
||||
carDisposable = netWork.create(CameraListServices::class.java, HostConst.LAUNCHER_SNAPSHOT_HOST)
|
||||
.getCarCameraList(ReqLiveCarBean(116.41710185, 39.96944794))
|
||||
CallerMapLocationListenerManager.getCurrentLocation()?.let { location ->
|
||||
carDisposable = netWork.create(CameraListServices::class.java, HostConst.LAUNCHER_SNAPSHOT_HOST)
|
||||
.getCarCameraList(ReqLiveCarBean(location.longitude, location.latitude))
|
||||
.subscribeOn(Schedulers.io())
|
||||
.map { liveCarCameraInfo ->
|
||||
liveCarCameraInfo.result?.liveCamera?.filter { liveCarCamera ->
|
||||
!liveCarCamera.videoSn.isNullOrEmpty()
|
||||
}?.map { cameraInfo ->
|
||||
CameraEntity(sn = cameraInfo.videoSn, street = cameraInfo.street, township = cameraInfo.township)
|
||||
} ?: ArrayList()
|
||||
}
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribe({
|
||||
carCameraList = it
|
||||
Logger.d(TAG, "requestCarCameraList返回结果为:$it")
|
||||
}, {
|
||||
Logger.e(TAG, "message is:${it.message}, cause is:${it.cause}")
|
||||
it.printStackTrace()
|
||||
})
|
||||
} ?: run {
|
||||
Logger.e(TAG, "CurrentLocation is null!")
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 开启从摄像头拉流
|
||||
*/
|
||||
fun requestOpenCamera(cameraIp: String) {
|
||||
streamDisposable?.let {
|
||||
if (!it.isDisposed) it.dispose()
|
||||
}
|
||||
streamDisposable = netWork.create(CameraListServices::class.java, HostConst.OPEN_CAMERA_STREAM_HOST)
|
||||
.openCameraStream(cameraIp)
|
||||
.subscribeOn(Schedulers.io())
|
||||
.map { liveCarCameraInfo ->
|
||||
liveCarCameraInfo.result?.liveCamera?.filter { liveCarCamera ->
|
||||
!liveCarCamera.videoSn.isNullOrEmpty()
|
||||
}?.map { cameraInfo ->
|
||||
CameraEntity(sn = cameraInfo.videoSn)
|
||||
} ?: ArrayList()
|
||||
}
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribe({
|
||||
carCameraList = it
|
||||
Logger.d(TAG, "openCameraStream返回结果为:$it")
|
||||
it.result?.let { streamResult ->
|
||||
if (!streamResult.flvUrl.isNullOrEmpty()) CallerHmiManager.startRoadCameraLive(streamResult.flvUrl!!)
|
||||
}
|
||||
}, {
|
||||
Logger.e(TAG, "openCameraStream&message is:${it.message}, cause is:${it.cause}")
|
||||
it.printStackTrace()
|
||||
})
|
||||
}
|
||||
@@ -89,11 +127,41 @@ class CronTaskManager {
|
||||
fun getCameraList() = ArrayList<CameraEntity>().apply {
|
||||
cameraList?.let { addAll(it) }
|
||||
carCameraList?.let { addAll(it) }
|
||||
// // 不需要走华哥打开推流的接口,顺义直接就可以播放的摄像头直播地址
|
||||
// add(
|
||||
// CameraEntity("https://video.zhidaohulian.com/live/origin_13_44.flv?txSecret=dc913522389abfc2ab1f2b72f9f4ef41&txTime=6AABBEB2",
|
||||
// "", "顺义测试道路",
|
||||
// "路口1", "朝向1", "183.242.46.150")
|
||||
// )
|
||||
// add(
|
||||
// CameraEntity("https://video.zhidaohulian.com/live/origin_13_45.flv?txSecret=7fee9c4ae986169d0e9bd0e1c1b7fab8&txTime=6AABBEB2",
|
||||
// "", "顺义测试道路",
|
||||
// "路口2", "朝向2", "183.242.46.150")
|
||||
// )
|
||||
// add(
|
||||
// CameraEntity("https://video.zhidaohulian.com/live/origin_13_46.flv?txSecret=d5ddbd2236743bcf177563bb6680a462&txTime=6AABBEB2",
|
||||
// "", "顺义测试道路",
|
||||
// "路口3", "朝向3", "183.242.46.150")
|
||||
// )
|
||||
// add(
|
||||
// CameraEntity("https://video.zhidaohulian.com/live/origin_13_48.flv?txSecret=397b1296eb548c737871fca242ff7ec5&txTime=6AABBEB2",
|
||||
// "", "顺义测试道路",
|
||||
// "路口4", "朝向4", "183.242.46.150")
|
||||
// )
|
||||
}
|
||||
|
||||
fun clear() {
|
||||
streamDisposable?.let {
|
||||
if (!it.isDisposed) it.dispose()
|
||||
}
|
||||
}
|
||||
|
||||
fun onDestroy() {
|
||||
disposable?.dispose()
|
||||
carDisposable?.dispose()
|
||||
streamDisposable?.let {
|
||||
if (!it.isDisposed) it.dispose()
|
||||
}
|
||||
cronHandler.removeMessages(CRON_TASK_TYPE)
|
||||
}
|
||||
}
|
||||
@@ -41,8 +41,18 @@ public class MoGoMonitoringProvider implements IMoGoMonitoringProvider {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDestroy() {
|
||||
public void openCameraStream(String cameraIp) {
|
||||
mCronTaskManager.requestOpenCamera(cameraIp);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void disposeCameraStream() {
|
||||
mCronTaskManager.clear();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDestroy() {
|
||||
mCronTaskManager.onDestroy();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,18 +1,19 @@
|
||||
package com.mogo.eagle.core.function.monitoring.net
|
||||
|
||||
import com.mogo.eagle.core.data.camera.CameraListInfo
|
||||
import com.mogo.eagle.core.data.camera.CameraStreamEntity
|
||||
import com.mogo.eagle.core.data.camera.LiveCarCameraInfo
|
||||
import com.mogo.eagle.core.data.camera.ReqLiveCarBean
|
||||
import io.reactivex.Single
|
||||
import retrofit2.http.Body
|
||||
import retrofit2.http.GET
|
||||
import retrofit2.http.POST
|
||||
import retrofit2.http.Query
|
||||
import retrofit2.http.*
|
||||
|
||||
interface CameraListServices {
|
||||
@GET("/yycp-smartTransportationAiCloud-service/eagle/device/list")
|
||||
fun getCameraList(@Query("roadId") roadId: String?): Single<CameraListInfo?>
|
||||
|
||||
@POST("/yycp-launcherSnapshot/launcherSnapshot/queryLiveCarByLocal")
|
||||
@POST("/yycp-launcherSnapshot/car/queryLiveCarByLocal")
|
||||
fun getCarCameraList(@Body reqBody: ReqLiveCarBean): Single<LiveCarCameraInfo?>
|
||||
|
||||
@GET("/openStream/{cameraIp}")
|
||||
fun openCameraStream(@Path("cameraIp") cameraIp: String): Single<CameraStreamEntity>
|
||||
}
|
||||
@@ -5,7 +5,10 @@ data class CameraEntity(
|
||||
var sn: String?="",
|
||||
var roadName: String?="",
|
||||
var crossingName: String?="",
|
||||
var headingDesc: String?=""
|
||||
var headingDesc: String?="",
|
||||
var ip: String? = "",
|
||||
var street: String? = "",
|
||||
var township: String? = ""
|
||||
) {
|
||||
fun isCarLive() = !sn.isNullOrEmpty()
|
||||
fun getHeadingStr() = if (headingDesc != null) headingDesc else ""
|
||||
|
||||
@@ -0,0 +1,16 @@
|
||||
package com.mogo.eagle.core.data.camera
|
||||
|
||||
import androidx.annotation.Keep
|
||||
import com.google.gson.annotations.SerializedName
|
||||
import com.mogo.eagle.core.data.BaseData
|
||||
|
||||
@Keep
|
||||
data class CameraStreamEntity (
|
||||
@SerializedName("result")
|
||||
var result: StreamResult?
|
||||
): BaseData()
|
||||
|
||||
data class StreamResult(
|
||||
@SerializedName("flvUrl")
|
||||
var flvUrl: String?
|
||||
)
|
||||
@@ -18,7 +18,10 @@ data class LiveResult(
|
||||
|
||||
@Keep
|
||||
data class LiveCameraInfo(
|
||||
var videoUrl: String,
|
||||
var videoChannel: String,
|
||||
var videoSn: String
|
||||
var videoUrl: String?,
|
||||
var videoChannel: String?,
|
||||
var videoSn: String?,
|
||||
var street: String?,
|
||||
var township: String?,
|
||||
var address: String?
|
||||
)
|
||||
@@ -136,4 +136,6 @@ interface IMoGoWaringProvider : IMoGoFunctionProvider {
|
||||
* 展示VIP标识
|
||||
*/
|
||||
fun vipIdentification(visible: Boolean)
|
||||
|
||||
fun startRoadCameraLive(flvUrl: String)
|
||||
}
|
||||
@@ -12,4 +12,11 @@ import java.util.List;
|
||||
*/
|
||||
public interface IMoGoMonitoringProvider extends IMoGoFunctionServerProvider {
|
||||
List<CameraEntity> getCameraList();
|
||||
|
||||
void openCameraStream(String cameraIp);
|
||||
|
||||
/**
|
||||
* 防止回调摄像头列表View的相关调用
|
||||
*/
|
||||
void disposeCameraStream();
|
||||
}
|
||||
|
||||
@@ -182,4 +182,7 @@ object CallerHmiManager : CallerBase() {
|
||||
waringProviderApi.vipIdentification(visible)
|
||||
}
|
||||
|
||||
fun startRoadCameraLive(flvUrl: String) {
|
||||
waringProviderApi.startRoadCameraLive(flvUrl)
|
||||
}
|
||||
}
|
||||
@@ -14,4 +14,12 @@ object CallerMonitorManager {
|
||||
fun getCameraList(): List<CameraEntity>? {
|
||||
return providerApi.cameraList
|
||||
}
|
||||
|
||||
fun openCameraStream(cameraIp: String) {
|
||||
providerApi.openCameraStream(cameraIp)
|
||||
}
|
||||
|
||||
fun disposeCameraStream() {
|
||||
providerApi.disposeCameraStream()
|
||||
}
|
||||
}
|
||||
@@ -62,21 +62,21 @@ SERVICE_CHAIN_VERSION=1.0.22
|
||||
LOGLIB_VERSION=1.0.4
|
||||
######## MogoAiCloudSDK Version ########
|
||||
# 网络请求
|
||||
MOGO_NETWORK_VERSION=1.1.54-live
|
||||
MOGO_NETWORK_VERSION=1.1.56-live
|
||||
# 鉴权
|
||||
MOGO_PASSPORT_VERSION=1.1.54-live
|
||||
MOGO_PASSPORT_VERSION=1.1.56-live
|
||||
# 常链接
|
||||
MOGO_SOCKET_VERSION=1.1.54-live
|
||||
MOGO_SOCKET_VERSION=1.1.56-live
|
||||
# 数据采集
|
||||
MOGO_REALTIME_VERSION=1.1.54-live
|
||||
MOGO_REALTIME_VERSION=1.1.56-live
|
||||
# 探路,道路事件发布,获取
|
||||
MOGO_TANLU_VERSION=1.1.54-live
|
||||
MOGO_TANLU_VERSION=1.1.56-live
|
||||
# 直播推流
|
||||
MOGO_LIVE_VERSION=1.1.54-live
|
||||
MOGO_LIVE_VERSION=1.1.56-live
|
||||
# 直播拉流
|
||||
MOGO_TRAFFICLIVE_VERSION=1.1.54-live
|
||||
MOGO_TRAFFICLIVE_VERSION=1.1.56-live
|
||||
# 定位服务
|
||||
MOGO_LOCATION_VERSION=1.1.54-live
|
||||
MOGO_LOCATION_VERSION=1.1.56-live
|
||||
######## MogoAiCloudSDK Version ########
|
||||
# 自研地图
|
||||
MAP_SDK_VERSION=V2.0.0.6-test
|
||||
|
||||
@@ -21,6 +21,7 @@ public class HostConst {
|
||||
public static final String IM_SOCKET_DOMAIN = "dzt-im.zhidaozhixing.com";
|
||||
public static final String WEBSOCKET_DOMAIN = "dzt-Instant.zhidaozhixing.com";
|
||||
public static final String CAMERA_STREAM_HOST = "http://dzt-smartTransportationAiCloud.zhidaozhixing.com";
|
||||
public static final String OPEN_CAMERA_STREAM_HOST = "http://10.0.16.6:18080";
|
||||
|
||||
public static final String SOCKET_CENTER_DOMAIN = "socketRegion";
|
||||
|
||||
|
||||
Reference in New Issue
Block a user