[6.8.0][驾驶位视频流] 优化代码逻辑

This commit is contained in:
renwj
2024-11-28 11:46:13 +08:00
parent c50b69f14d
commit 1790758b08
4 changed files with 194 additions and 38 deletions

View File

@@ -8,7 +8,7 @@ import androidx.core.view.doOnAttach
import androidx.core.view.doOnDetach
import com.mogo.commons.constants.HostConst
import com.mogo.eagle.core.data.BaseResponse
import com.mogo.eagle.core.data.app.AppConfigInfo
import com.mogo.eagle.core.data.config.FunctionBuildConfig
import com.mogo.eagle.core.function.api.driver.video.IDriveSeatVideoProvider
import com.mogo.eagle.core.function.api.driver.video.IDriveSeatVideoProvider.Event
import com.mogo.eagle.core.function.api.driver.video.IDriveSeatVideoProvider.Event.Failed
@@ -16,6 +16,7 @@ import com.mogo.eagle.core.function.api.driver.video.IDriveSeatVideoProvider.Eve
import com.mogo.eagle.core.function.api.driver.video.IDriveSeatVideoProvider.Event.Playing
import com.mogo.eagle.core.function.call.datacenter.CallerDataCenterBizListener
import com.mogo.eagle.core.network.MoGoRetrofitFactory
import com.mogo.eagle.core.utilcode.mogo.AppIdentityModeUtils
import com.mogo.eagle.core.utilcode.util.AppStateManager
import com.tencent.liteav.basic.log.TXCLog
import com.tencent.rtmp.ITXLivePlayListener
@@ -26,31 +27,39 @@ import com.tencent.rtmp.ui.TXCloudVideoView
import com.zhjt.mogo_core_function_devatools.driver.video.vo.VideoUrlData
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.Job
import kotlinx.coroutines.SupervisorJob
import kotlinx.coroutines.channels.Channel
import kotlinx.coroutines.delay
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.channelFlow
import kotlinx.coroutines.launch
import retrofit2.http.GET
import retrofit2.http.Headers
import retrofit2.http.Query
import java.lang.ref.WeakReference
import java.util.concurrent.atomic.AtomicBoolean
import java.util.concurrent.atomic.AtomicReference
class DriveSeatVideoProviderImpl: IDriveSeatVideoProvider {
class DriveSeatVideoProviderImpl : IDriveSeatVideoProvider {
companion object {
private const val TAG = "DriveSeatVideoProvider"
}
@Volatile
private var target: WeakReference<TXCloudVideoView>? = null
@Volatile private var target: WeakReference<TXCloudVideoView>? = null
@Volatile
private var timer: Job? = null
@Volatile private var timer: Job? = null
private val scope by lazy { CoroutineScope(Dispatchers.IO + SupervisorJob()) }
private val chl by lazy { AtomicReference(Channel<Boolean>(Channel.CONFLATED)) }
private var data: VideoUrlData? = null
private val isPlaying by lazy { AtomicBoolean(false) }
internal interface IVideoLiveUrlApi {
@Headers("Content-Type:application/json;charset=UTF-8")
@GET("/eagleEye-mis/camera/monitor/watch/status")
@@ -82,6 +91,7 @@ class DriveSeatVideoProviderImpl: IDriveSeatVideoProvider {
Log.d(TAG, "getDriveVideoView --> $playUrl")
x.doOnAttach {
Log.d(TAG, "onAttachToWindow --> $playUrl")
start()
val player = TXLivePlayer(activity)
player.setPlayerView(x)
player.setMute(true)
@@ -100,12 +110,13 @@ class DriveSeatVideoProviderImpl: IDriveSeatVideoProvider {
playCallback?.invoke(Loading)
} else if (event == TXLiveConstants.PLAY_EVT_PLAY_BEGIN) {
Log.d(TAG, "play begin...")
start()
isPlaying.set(true)
playCallback?.invoke(Playing)
} else {
if (event < 0) {
Log.d(TAG, "play failed...$event, bundle: $bundle")
stop()
isPlaying.set(false)
playCallback?.invoke(Failed(bundle?.toString() ?: "播放失败"))
}
}
@@ -122,6 +133,7 @@ class DriveSeatVideoProviderImpl: IDriveSeatVideoProvider {
player.stopPlay(true)
stop()
} finally {
isPlaying.set(false)
target?.clear()
}
}
@@ -135,6 +147,27 @@ class DriveSeatVideoProviderImpl: IDriveSeatVideoProvider {
return data
}
@OptIn(ExperimentalCoroutinesApi::class) override fun poller(): Flow<Boolean> = channelFlow {
if (AppIdentityModeUtils.isDriver(FunctionBuildConfig.appIdentityMode)) {
throw AssertionError("此方法不支持司机屏使用")
}
val ch = chl.get()?.let {
if (it.isClosedForSend || it.isClosedForReceive) {
Log.d(TAG, "isClosed -> ${it.isClosedForReceive} -> ${it.isClosedForSend}")
val n = Channel<Boolean>(Channel.CONFLATED)
chl.set(n)
n
} else {
it
}
} ?: return@channelFlow
val iterator = ch.iterator()
while (iterator.hasNext()) {
send(iterator.next())
}
}
private fun start() {
timer?.cancel()
scope.launch {
@@ -144,6 +177,9 @@ class DriveSeatVideoProviderImpl: IDriveSeatVideoProvider {
val result = requestVideoInfo()
if (result != null) {
data = result
chl.get()?.trySend(true)
} else {
chl.get()?.trySend(false)
}
Log.d(TAG, "当次请求结束...")
delay(5000)
@@ -157,6 +193,13 @@ class DriveSeatVideoProviderImpl: IDriveSeatVideoProvider {
timer?.cancel()
}
override fun isVideoPlaying(): Boolean {
if (AppIdentityModeUtils.isDriver(FunctionBuildConfig.appIdentityMode)) {
throw AssertionError("此方法不支持司机屏使用")
}
return isPlaying.get()
}
private fun getApi(): IVideoLiveUrlApi? {
return MoGoRetrofitFactory.getInstanceNoCallAdapter(HostConst.HOST_RELEASE).create(IVideoLiveUrlApi::class.java)
}