package com.casic.endoscope.view import android.annotation.SuppressLint import android.graphics.PixelFormat import android.os.Bundle import android.util.Log import android.view.KeyEvent import android.view.MotionEvent import android.view.SurfaceHolder import androidx.lifecycle.lifecycleScope import com.casic.endoscope.R import com.casic.endoscope.databinding.ActivityMainBinding import com.casic.endoscope.extensions.createVideoFileDir import com.casic.endoscope.extensions.getChannel import com.casic.endoscope.extensions.initImmersionBar import com.casic.endoscope.extensions.toTime import com.casic.endoscope.utils.ProjectConstant import com.casic.endoscope.utils.hk.MessageCodeHub import com.casic.endoscope.utils.hk.SDKGuider import com.hikvision.netsdk.HCNetSDK import com.hikvision.netsdk.NET_DVR_JPEGPARA import com.hikvision.netsdk.NET_DVR_PREVIEWINFO import com.hikvision.netsdk.PTZCommand import com.pengxh.kt.lite.base.KotlinBaseActivity import com.pengxh.kt.lite.extensions.createImageFileDir import com.pengxh.kt.lite.extensions.show import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.launch import kotlinx.coroutines.withContext import java.text.SimpleDateFormat import java.util.Date import java.util.Locale import java.util.Timer import java.util.TimerTask @SuppressLint("all") class MainActivity : KotlinBaseActivity<ActivityMainBinding>(), SurfaceHolder.Callback { private val kTag = "MainActivity" private val hkSDK by lazy { HCNetSDK.getInstance() } private val timeFormat by lazy { SimpleDateFormat("yyyyMMddHHmmss", Locale.CHINA) } private val selectedSpeed = 7 private var clickTime = 0L private var previewHandle = -1 private var selectChannel = -1 private var returnUserId = -1 private var aChannelNum = 0 private var startAChannel = 0 private var dChannelNum = 0 private var startDChannel = 0 private var isPreviewSuccess = false //手指是否已经从方向控制盘抬起 private var isActionUp = true //焦距按钮是否已松开 private var isScaleButtonUp = true private var timer: Timer? = null private var timerTask: TimerTask? = null private var seconds = 0L override fun initViewBinding(): ActivityMainBinding { return ActivityMainBinding.inflate(layoutInflater) } override fun initOnCreate(savedInstanceState: Bundle?) { } override fun initEvent() { binding.imageButton.setOnClickListener { if (isPreviewSuccess) { lifecycleScope.launch(Dispatchers.IO) { val strJpeg = NET_DVR_JPEGPARA() strJpeg.wPicQuality = 1 strJpeg.wPicSize = 2 val imagePath = "/${createImageFileDir()}/${timeFormat.format(Date())}.png" hkSDK.NET_DVR_CaptureJPEGPicture( returnUserId, selectChannel, strJpeg, imagePath ) if (MessageCodeHub.getErrorCode() == 0) { withContext(Dispatchers.Main) { "画面抓取成功".show(this@MainActivity) } } } } } binding.videoButton.setOnClickListener { if (isPreviewSuccess) { val videoPath = "/${createVideoFileDir()}/${timeFormat.format(Date())}.mp4" hkSDK.NET_DVR_SaveRealData(returnUserId, videoPath) binding.videoButton.text = "长按停止" } } binding.videoButton.setOnLongClickListener { //停止视频抓取 hkSDK.NET_DVR_StopSaveRealData(returnUserId) binding.videoButton.text = "录像" true } binding.toggleButton.setOnCheckedChangeListener { _, isChecked -> if (isChecked) { val deviceItem = SDKGuider.sdkGuider.devManageGuider.DeviceItem() deviceItem.szDevName = "" deviceItem.devNetInfo = SDKGuider.sdkGuider.devManageGuider.DevNetInfo( ProjectConstant.HK_NET_IP, ProjectConstant.HK_NET_PORT, ProjectConstant.HK_NET_USERNAME, ProjectConstant.HK_NET_PASSWORD ) if (deviceItem.szDevName.isEmpty()) { deviceItem.szDevName = deviceItem.devNetInfo.szIp } val loginV40Jna = SDKGuider.sdkGuider.devManageGuider.login_v40_jna( deviceItem.szDevName, deviceItem.devNetInfo ) if (loginV40Jna) { //配置设备通道 try { val deviceInfo = SDKGuider.sdkGuider.devManageGuider.devList[0] returnUserId = deviceInfo.szUserId aChannelNum = deviceInfo.deviceInfoV40_jna.struDeviceV30.byChanNum.toInt() startAChannel = deviceInfo.deviceInfoV40_jna.struDeviceV30.byStartChan.toInt() dChannelNum = deviceInfo.deviceInfoV40_jna.struDeviceV30.byIPChanNum + deviceInfo.deviceInfoV40_jna.struDeviceV30.byHighDChanNum * 256 startDChannel = deviceInfo.deviceInfoV40_jna.struDeviceV30.byStartChan.toInt() var iAnalogStartChan = startAChannel var iDigitalStartChan = startDChannel val channelList = ArrayList<String>() for (i in 0 until aChannelNum) { channelList.add("ACamera_$iAnalogStartChan") iAnalogStartChan++ } for (i in 0 until dChannelNum) { channelList.add("DCamera_$iDigitalStartChan") iDigitalStartChan++ } selectChannel = Integer.valueOf(channelList[0].getChannel()) val streamList = ArrayList<String>() streamList.add("main_stream") streamList.add("sub_stream") streamList.add("third_stream") //开始预览 if (previewHandle != -1) { SDKGuider.sdkGuider.devPreviewGuider.RealPlay_Stop_jni(previewHandle) } val strutPlayInfo = NET_DVR_PREVIEWINFO() strutPlayInfo.lChannel = selectChannel strutPlayInfo.dwStreamType = 1 strutPlayInfo.bBlocked = 1 strutPlayInfo.hHwnd = binding.surfaceView.holder previewHandle = SDKGuider.sdkGuider.devPreviewGuider.RealPlay_V40_jni( returnUserId, strutPlayInfo, null ) if (previewHandle < 0) { Log.d(kTag, "initEvent: Err:${MessageCodeHub.getErrorCode()}") return@setOnCheckedChangeListener } isPreviewSuccess = true "预览开启成功".show(this) //开始计时 timer = Timer() timerTask = object : TimerTask() { override fun run() { seconds++ lifecycleScope.launch(Dispatchers.Main) { binding.runningTimeView.text = seconds.toTime() } } } timer?.schedule(timerTask, 0, 1000) } catch (e: IndexOutOfBoundsException) { e.printStackTrace() "设备未正常连接,无法开启预览".show(this) } } } else { if (!SDKGuider.sdkGuider.devPreviewGuider.RealPlay_Stop_jni(previewHandle)) { return@setOnCheckedChangeListener } previewHandle = -1 isPreviewSuccess = false "预览关闭成功".show(this) //停止计时 timerTask?.cancel() timer?.cancel() } } binding.leftButton.setOnTouchListener { _, event -> when (event.action) { MotionEvent.ACTION_DOWN -> { if (isPreviewSuccess && isActionUp) { hkSDK.NET_DVR_PTZControlWithSpeed( previewHandle, PTZCommand.PAN_LEFT, 0, selectedSpeed ) isActionUp = false } } MotionEvent.ACTION_UP -> { hkSDK.NET_DVR_PTZControl(previewHandle, PTZCommand.PAN_LEFT, 1) isActionUp = true } } true } binding.topButton.setOnTouchListener { _, event -> when (event.action) { MotionEvent.ACTION_DOWN -> { if (isPreviewSuccess && isActionUp) { hkSDK.NET_DVR_PTZControlWithSpeed( previewHandle, PTZCommand.TILT_UP, 0, selectedSpeed ) isActionUp = false } } MotionEvent.ACTION_UP -> { hkSDK.NET_DVR_PTZControl(previewHandle, PTZCommand.TILT_UP, 1) isActionUp = true } } true } binding.rightButton.setOnTouchListener { _, event -> when (event.action) { MotionEvent.ACTION_DOWN -> { if (isPreviewSuccess && isActionUp) { hkSDK.NET_DVR_PTZControlWithSpeed( previewHandle, PTZCommand.PAN_RIGHT, 0, selectedSpeed ) isActionUp = false } } MotionEvent.ACTION_UP -> { hkSDK.NET_DVR_PTZControl(previewHandle, PTZCommand.PAN_RIGHT, 1) isActionUp = true } } true } binding.bottomButton.setOnTouchListener { _, event -> when (event.action) { MotionEvent.ACTION_DOWN -> { if (isPreviewSuccess && isActionUp) { hkSDK.NET_DVR_PTZControlWithSpeed( previewHandle, PTZCommand.TILT_DOWN, 0, selectedSpeed ) isActionUp = false } } MotionEvent.ACTION_UP -> { hkSDK.NET_DVR_PTZControl(previewHandle, PTZCommand.TILT_DOWN, 1) isActionUp = true } } true } binding.downScaleButton.setOnTouchListener { _, event -> when (event.action) { MotionEvent.ACTION_DOWN -> { if (isPreviewSuccess && isScaleButtonUp) { hkSDK.NET_DVR_PTZControl(previewHandle, PTZCommand.ZOOM_OUT, 0) isScaleButtonUp = false } } MotionEvent.ACTION_UP -> { isScaleButtonUp = true hkSDK.NET_DVR_PTZControl(previewHandle, PTZCommand.ZOOM_OUT, 1) } } true } binding.upScaleButton.setOnTouchListener { _, event -> when (event.action) { MotionEvent.ACTION_DOWN -> { if (isPreviewSuccess && isScaleButtonUp) { hkSDK.NET_DVR_PTZControl(previewHandle, PTZCommand.ZOOM_IN, 0) isScaleButtonUp = false } } MotionEvent.ACTION_UP -> { isScaleButtonUp = true hkSDK.NET_DVR_PTZControl(previewHandle, PTZCommand.ZOOM_IN, 1) } } true } } override fun observeRequestState() { } override fun surfaceCreated(holder: SurfaceHolder) { binding.surfaceView.holder.setFormat(PixelFormat.TRANSLUCENT) if (-1 == previewHandle) { return } val surface = holder.surface if (surface.isValid) { if (-1 == SDKGuider.sdkGuider.devPreviewGuider.RealPlaySurfaceChanged_jni( previewHandle, 0, holder ) ) { Log.d(kTag, "surfaceCreated: ${MessageCodeHub.getErrorCode()}") } } } override fun surfaceChanged(holder: SurfaceHolder, format: Int, width: Int, height: Int) { } override fun surfaceDestroyed(holder: SurfaceHolder) { if (-1 == previewHandle) { return } if (holder.surface.isValid) { if (-1 == SDKGuider.sdkGuider.devPreviewGuider.RealPlaySurfaceChanged_jni( previewHandle, 0, null ) ) { Log.d(kTag, "surfaceDestroyed: ${MessageCodeHub.getErrorCode()}") } } } override fun setupTopBarLayout() { binding.rootView.initImmersionBar(this, true, R.color.white) } override fun onKeyDown(keyCode: Int, event: KeyEvent): Boolean { if (keyCode == KeyEvent.KEYCODE_BACK) { if (System.currentTimeMillis() - clickTime > 2000) { "再按一次退出应用".show(this) clickTime = System.currentTimeMillis() return true } else { super.onKeyDown(keyCode, event) } } return super.onKeyDown(keyCode, event) } }