Newer
Older
Endoscope / app / src / main / java / com / casic / endoscope / view / MainActivity.kt
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)
    }
}