云台控制
This commit is contained in:
@@ -548,6 +548,8 @@ class HomeMenuFragment : Fragment() {
|
||||
val intent = Intent(requireContext(), LiveVideoActivity::class.java)
|
||||
intent.putExtra("device_id", device.deviceId)
|
||||
intent.putExtra("device_name", device.name)
|
||||
intent.putExtra("deviceNo", device.deviceNo)
|
||||
intent.putExtra("light", device.light)
|
||||
startActivity(intent)
|
||||
} else {
|
||||
showDefenseDialog(
|
||||
|
||||
@@ -5,6 +5,8 @@ import android.content.res.Configuration
|
||||
import android.graphics.Color
|
||||
import android.os.Bundle
|
||||
import android.util.Log
|
||||
import android.view.GestureDetector
|
||||
import android.view.MotionEvent
|
||||
import android.view.View
|
||||
import androidx.recyclerview.widget.LinearLayoutManager
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
@@ -22,6 +24,9 @@ import com.shuyu.gsyvideoplayer.listener.GSYSampleCallBack
|
||||
import com.shuyu.gsyvideoplayer.utils.OrientationUtils
|
||||
import kotlinx.coroutines.launch
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
import android.os.Handler
|
||||
import android.os.Looper
|
||||
import com.ckkj.defense_device.view.MyGSYVideoPlayerLive
|
||||
|
||||
class LiveVideoActivity : BaseActivity() {
|
||||
private lateinit var binding: LiveVideoActivityBinding
|
||||
@@ -30,6 +35,7 @@ class LiveVideoActivity : BaseActivity() {
|
||||
private var isLightOn = false
|
||||
private var isConsoleVisible = false
|
||||
private var deviceId: String? = null
|
||||
private var deviceNo: String? = null
|
||||
private var alarmList: MutableList<DeviceAlarmBean> = mutableListOf()
|
||||
private var alarmAdapter: AlarmLogHorizontalAdapter? = null
|
||||
private var currentPage = 1
|
||||
@@ -39,6 +45,8 @@ class LiveVideoActivity : BaseActivity() {
|
||||
private var isLoading = false
|
||||
|
||||
private var orientationUtils: OrientationUtils? = null
|
||||
private val ptzHandler = Handler(Looper.getMainLooper())
|
||||
private var currentPtzDirection: String? = null
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
@@ -54,6 +62,8 @@ class LiveVideoActivity : BaseActivity() {
|
||||
|
||||
deviceId = intent.getStringExtra("device_id")
|
||||
val deviceName = intent.getStringExtra("device_name")
|
||||
deviceNo = intent.getStringExtra("deviceNo")
|
||||
val light = intent.getStringExtra("light")
|
||||
if (!deviceName.isNullOrEmpty()) {
|
||||
binding.tvTitle.text = deviceName
|
||||
}
|
||||
@@ -112,6 +122,21 @@ class LiveVideoActivity : BaseActivity() {
|
||||
hidePlayerControls()
|
||||
binding.exoPlayContextId.startPlayLogic()
|
||||
binding.exoPlayContextId.fullscreenButton.setOnClickListener {
|
||||
binding.exoPlayContextId.onPtzControlListener =
|
||||
object : MyGSYVideoPlayerLive.OnPtzControlListener {
|
||||
override fun onStartPtz(direction: String) {
|
||||
val no = deviceNo ?: return
|
||||
startPtz(deviceNo = no, direction = direction)
|
||||
}
|
||||
|
||||
override fun onStopPtz() {
|
||||
stopCurrentPtz()
|
||||
}
|
||||
|
||||
override fun onShoot() {
|
||||
deviceNo?.let { shoot(it) }
|
||||
}
|
||||
}
|
||||
orientationUtils?.resolveByClick()
|
||||
binding.exoPlayContextId.startWindowFullscreen(this, true, true)
|
||||
}
|
||||
@@ -237,6 +262,114 @@ class LiveVideoActivity : BaseActivity() {
|
||||
binding.ivVoice.setImageResource(R.mipmap.voice)
|
||||
}
|
||||
}
|
||||
|
||||
binding.ivUp.setOnTouchListener { v, event ->
|
||||
handlePtzTouch(
|
||||
view = v,
|
||||
event = event,
|
||||
direction = "up",
|
||||
action = { deviceNo }
|
||||
)
|
||||
}
|
||||
|
||||
binding.ivDown.setOnTouchListener { v, event ->
|
||||
handlePtzTouch(
|
||||
view = v,
|
||||
event = event,
|
||||
direction = "down",
|
||||
action = { deviceNo }
|
||||
)
|
||||
}
|
||||
|
||||
binding.ivLeft.setOnTouchListener { v, event ->
|
||||
handlePtzTouch(
|
||||
view = v,
|
||||
event = event,
|
||||
direction = "left",
|
||||
action = { deviceNo }
|
||||
)
|
||||
}
|
||||
|
||||
binding.ivRight.setOnTouchListener { v, event ->
|
||||
handlePtzTouch(
|
||||
view = v,
|
||||
event = event,
|
||||
direction = "right",
|
||||
action = { deviceNo }
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
private fun handlePtzTouch(
|
||||
view: View,
|
||||
event: MotionEvent,
|
||||
direction: String,
|
||||
action: () -> String?
|
||||
): Boolean {
|
||||
when (event.action) {
|
||||
MotionEvent.ACTION_DOWN -> {
|
||||
view.isPressed = true
|
||||
val deviceNo = action()
|
||||
if (!deviceNo.isNullOrEmpty()) {
|
||||
startPtz(deviceNo = deviceNo, direction = direction)
|
||||
}
|
||||
}
|
||||
|
||||
MotionEvent.ACTION_UP, MotionEvent.ACTION_CANCEL -> {
|
||||
view.isPressed = false
|
||||
stopCurrentPtz()
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
private fun startPtz(deviceNo: String, direction: String) {
|
||||
stopCurrentPtz()
|
||||
|
||||
currentPtzDirection = direction
|
||||
lifecycleScope.launch {
|
||||
try {
|
||||
val response = when (direction) {
|
||||
"up" -> RetrofitNetwork.getNetworkService().ptzUp(deviceNo)
|
||||
"down" -> RetrofitNetwork.getNetworkService().ptzDown(deviceNo)
|
||||
"left" -> RetrofitNetwork.getNetworkService().ptzLeft(deviceNo)
|
||||
"right" -> RetrofitNetwork.getNetworkService().ptzRight(deviceNo)
|
||||
else -> null
|
||||
}
|
||||
Log.d("LV", "PTZ $direction start response: ${response?.code}")
|
||||
} catch (e: Exception) {
|
||||
Log.e("LV", "PTZ $direction start failed", e)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun shoot(deviceNo: String) {
|
||||
Log.d("LV", "btnCapture click, deviceNo=$deviceNo, duration=0")
|
||||
lifecycleScope.launch {
|
||||
try {
|
||||
val response = RetrofitNetwork.getNetworkService().ptzShoot(
|
||||
deviceNo = deviceNo,
|
||||
duration = "0"
|
||||
)
|
||||
Log.d("LV", "PTZ shoot response: code=${response.code}, msg=${response.msg}")
|
||||
} catch (e: Exception) {
|
||||
Log.e("LV", "PTZ shoot failed", e)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun stopCurrentPtz() {
|
||||
val direction = currentPtzDirection ?: return
|
||||
currentPtzDirection = null
|
||||
|
||||
lifecycleScope.launch {
|
||||
try {
|
||||
val response = RetrofitNetwork.getNetworkService().ptzStop(deviceNo ?: return@launch)
|
||||
Log.d("LV", "PTZ $direction stop response: ${response.code}")
|
||||
} catch (e: Exception) {
|
||||
Log.e("LV", "PTZ $direction stop failed", e)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun fetchAlarmList(page: Int = 1) {
|
||||
@@ -284,6 +417,7 @@ class LiveVideoActivity : BaseActivity() {
|
||||
|
||||
override fun onDestroy() {
|
||||
super.onDestroy()
|
||||
ptzHandler.removeCallbacksAndMessages(null)
|
||||
orientationUtils?.releaseListener()
|
||||
binding.exoPlayContextId.release()
|
||||
}
|
||||
|
||||
@@ -271,5 +271,62 @@ interface ApiService {
|
||||
@POST("/app/joinTheFamily")
|
||||
suspend fun joinTheFamily(@Body request: JoinTheFamilyBean): GetCodeBean<Any>
|
||||
|
||||
/**
|
||||
* PTZ向上控制
|
||||
*/
|
||||
@POST("/app/ptz/{deviceNo}/up")
|
||||
suspend fun ptzUp(
|
||||
@retrofit2.http.Path("deviceNo") deviceNo: String,
|
||||
@Query("speed") speed: String = "5",
|
||||
@Query("duration") duration: String = "0"
|
||||
): GetCodeBean<Any>
|
||||
|
||||
/**
|
||||
* PTZ向下控制
|
||||
*/
|
||||
@POST("/app/ptz/{deviceNo}/down")
|
||||
suspend fun ptzDown(
|
||||
@retrofit2.http.Path("deviceNo") deviceNo: String,
|
||||
@Query("speed") speed: String = "5",
|
||||
@Query("duration") duration: String = "0"
|
||||
): GetCodeBean<Any>
|
||||
|
||||
/**
|
||||
* PTZ向左控制
|
||||
*/
|
||||
@POST("/app/ptz/{deviceNo}/left")
|
||||
suspend fun ptzLeft(
|
||||
@retrofit2.http.Path("deviceNo") deviceNo: String,
|
||||
@Query("speed") speed: String = "5",
|
||||
@Query("duration") duration: String = "0"
|
||||
): GetCodeBean<Any>
|
||||
|
||||
/**
|
||||
* PTZ向右控制
|
||||
*/
|
||||
@POST("/app/ptz/{deviceNo}/right")
|
||||
suspend fun ptzRight(
|
||||
@retrofit2.http.Path("deviceNo") deviceNo: String,
|
||||
@Query("speed") speed: String = "5",
|
||||
@Query("duration") duration: String = "0"
|
||||
): GetCodeBean<Any>
|
||||
|
||||
/**
|
||||
* PTZ停止控制
|
||||
*/
|
||||
@POST("/app/ptz/{deviceNo}/stop")
|
||||
suspend fun ptzStop(
|
||||
@retrofit2.http.Path("deviceNo") deviceNo: String,
|
||||
): GetCodeBean<Any>
|
||||
|
||||
/**
|
||||
* PTZ控制水枪喷水
|
||||
*/
|
||||
@POST("/app/ptz/{deviceNo}/shoot")
|
||||
suspend fun ptzShoot(
|
||||
@retrofit2.http.Path("deviceNo") deviceNo: String,
|
||||
@Query("duration") duration: String,
|
||||
): GetCodeBean<Any>
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -1,8 +1,10 @@
|
||||
package com.ckkj.defense_device.view
|
||||
|
||||
import android.util.Log
|
||||
import android.content.Context
|
||||
import android.util.AttributeSet
|
||||
import android.view.LayoutInflater
|
||||
import android.view.MotionEvent
|
||||
import android.view.View
|
||||
import com.ckkj.defense_device.R
|
||||
import com.shuyu.gsyvideoplayer.video.StandardGSYVideoPlayer
|
||||
@@ -12,6 +14,18 @@ class MyGSYVideoPlayerLive @JvmOverloads constructor(
|
||||
context: Context, attrs: AttributeSet? = null
|
||||
) : StandardGSYVideoPlayer(context, attrs) {
|
||||
|
||||
companion object {
|
||||
private const val TAG = "MyGSYVideoPlayerLive"
|
||||
}
|
||||
|
||||
interface OnPtzControlListener {
|
||||
fun onStartPtz(direction: String)
|
||||
fun onStopPtz()
|
||||
fun onShoot()
|
||||
}
|
||||
|
||||
var onPtzControlListener: OnPtzControlListener? = null
|
||||
|
||||
override fun init(context: Context) {
|
||||
super.init(context)
|
||||
startButton.visibility = View.GONE
|
||||
@@ -76,10 +90,54 @@ class MyGSYVideoPlayerLive @JvmOverloads constructor(
|
||||
|
||||
overlay.findViewById<View>(R.id.btnCapture)
|
||||
?.setOnClickListener {
|
||||
|
||||
Log.d("MyGSYVideoPlayerLive", "btnCapture clicked, onShoot invoked")
|
||||
onPtzControlListener?.onShoot()
|
||||
}
|
||||
|
||||
player.initPtzControls(overlay)
|
||||
|
||||
return player
|
||||
}
|
||||
|
||||
private fun initPtzControls(overlay: View) {
|
||||
val ptzListener = onPtzControlListener
|
||||
|
||||
overlay.findViewById<View>(R.id.ivUp)?.setOnTouchListener { v, event ->
|
||||
handlePtzTouch(v, event, "up", ptzListener)
|
||||
}
|
||||
|
||||
overlay.findViewById<View>(R.id.ivDown)?.setOnTouchListener { v, event ->
|
||||
handlePtzTouch(v, event, "down", ptzListener)
|
||||
}
|
||||
|
||||
overlay.findViewById<View>(R.id.ivLeft)?.setOnTouchListener { v, event ->
|
||||
handlePtzTouch(v, event, "left", ptzListener)
|
||||
}
|
||||
|
||||
overlay.findViewById<View>(R.id.ivRight)?.setOnTouchListener { v, event ->
|
||||
handlePtzTouch(v, event, "right", ptzListener)
|
||||
}
|
||||
}
|
||||
|
||||
private fun handlePtzTouch(
|
||||
view: View,
|
||||
event: MotionEvent,
|
||||
direction: String,
|
||||
listener: OnPtzControlListener?
|
||||
): Boolean {
|
||||
when (event.action) {
|
||||
MotionEvent.ACTION_DOWN -> {
|
||||
Log.d(TAG, "全屏PTZ长按开始 direction=$direction")
|
||||
view.isPressed = true
|
||||
listener?.onStartPtz(direction)
|
||||
}
|
||||
MotionEvent.ACTION_UP, MotionEvent.ACTION_CANCEL -> {
|
||||
Log.d(TAG, "全屏PTZ长按结束 direction=$direction")
|
||||
view.isPressed = false
|
||||
listener?.onStopPtz()
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user