import android.content.Context import android.graphics.PixelFormat import android.net.ConnectivityManager import android.net.Network import android.net.NetworkCapabilities import android.net.NetworkRequest import android.net.wifi.WifiManager import android.net.wifi.WifiNetworkSpecifier import android.os.Build import android.os.Bundle import android.util.Log import android.view.SurfaceHolder import androidx.lifecycle.ViewModelProvider import com.hikvision.netsdk.HCNetSDK 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.convertColor import com.pengxh.kt.lite.extensions.getSystemService import com.pengxh.kt.lite.extensions.show import com.pengxh.kt.lite.widget.SteeringWheelView import com.pengxh.kt.lite.widget.dialog.BottomActionSheet class HikVisionActivity : KotlinBaseActivity<ActivityHikvisionBinding>(), SurfaceHolder.Callback { private val kTag = "HikVisionActivity" private val context = this@HikVisionActivity private val hkSDK by lazy { HCNetSDK.getInstance() } private val wifiManager by lazy { getSystemService<WifiManager>() } private val wifiSsids = ArrayList<String>() private val cameraItems = ArrayList<String>() 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 connectivityManager: ConnectivityManager? = null private lateinit var regionViewModel: RegionViewModel //手指是否已经从方向控制盘抬起 private var isActionUp = true override fun initViewBinding(): ActivityHikvisionBinding { return ActivityHikvisionBinding.inflate(layoutInflater) } override fun setupTopBarLayout() { binding.rootView.initImmersionBar(this, false, R.color.mainThemeColor) binding.titleInclude.titleView.text = "摄像头区域配置" binding.titleInclude.rightOptionView.text = "重画" binding.titleInclude.rightOptionView.setOnClickListener { binding.regionView.clearRoutePath() } } override fun initOnCreate(savedInstanceState: Bundle?) { RuntimeCache.deviceModels.forEach { if (it.deviceType == DeviceType.CAMERA) { cameraItems.add("${it.host}:${it.port}") } } binding.configSelectView.text = cameraItems[0] //获取wifi列表 wifiSsids.clear() wifiManager?.scanResults?.forEach { res -> //只要YTJ-010002 if (res.SSID == "YTJ-010002") { wifiSsids.add(res.SSID) } } regionViewModel = ViewModelProvider(this)[RegionViewModel::class.java] regionViewModel.postResult.observe(this) { if (it.code == 200) { "区域配置成功".show(this) finish() } } } override fun observeRequestState() { } override fun initEvent() { binding.titleInclude.leftBackView.setOnClickListener { finish() } val bottomActionSheet = BottomActionSheet.Builder() .setContext(this) .setActionItemTitle(cameraItems) .setItemTextColor(R.color.mainThemeColor.convertColor(this)) .setOnActionSheetListener(object : BottomActionSheet.OnActionSheetListener { override fun onActionItemClick(position: Int) { binding.configSelectView.text = cameraItems[position] } }).build() binding.configSelectView.setOnClickListener { bottomActionSheet.show() } binding.netSelectView.setOnClickListener { BottomActionSheet.Builder() .setContext(this) .setActionItemTitle(wifiSsids) .setItemTextColor(R.color.mainThemeColor.convertColor(this)) .setOnActionSheetListener(object : BottomActionSheet.OnActionSheetListener { override fun onActionItemClick(position: Int) { binding.netSelectView.text = wifiSsids[position] //连接wifi if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) { val specifier = WifiNetworkSpecifier.Builder() .setSsid(wifiSsids[position]) .setWpa2Passphrase(LocaleConstant.WIFI_PASSWORD) .build() val request = NetworkRequest.Builder() .addTransportType(NetworkCapabilities.TRANSPORT_WIFI) .removeCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET) .setNetworkSpecifier(specifier) .build() connectivityManager = context.getSystemService( Context.CONNECTIVITY_SERVICE ) as ConnectivityManager connectivityManager?.requestNetwork(request, networkCallback) } } }).build().show() } binding.steeringWheelView.setOnWheelTouchListener(object : SteeringWheelView.OnWheelTouchListener { override fun onCenterClicked() { if (isPreviewSuccess) { closeHikVisionCamera() } else { val split = binding.configSelectView.text.split(":") openHikVisionCamera(split[0], split[1]) } } override fun onBottomTurn() { if (isPreviewSuccess && isActionUp) { hkSDK.NET_DVR_PTZControl(previewHandle, PTZCommand.TILT_DOWN, 0) isActionUp = false } } override fun onLeftTurn() { if (isPreviewSuccess && isActionUp) { hkSDK.NET_DVR_PTZControl(previewHandle, PTZCommand.PAN_LEFT, 0) isActionUp = false } } override fun onRightTurn() { if (isPreviewSuccess && isActionUp) { hkSDK.NET_DVR_PTZControl(previewHandle, PTZCommand.PAN_RIGHT, 0) isActionUp = false } } override fun onTopTurn() { if (isPreviewSuccess && isActionUp) { hkSDK.NET_DVR_PTZControl(previewHandle, PTZCommand.TILT_UP, 0) isActionUp = false } } override fun onActionTurnUp(dir: SteeringWheelView.Direction) { when (dir) { SteeringWheelView.Direction.LEFT -> { hkSDK.NET_DVR_PTZControl(previewHandle, PTZCommand.PAN_LEFT, 1) isActionUp = true } SteeringWheelView.Direction.TOP -> { hkSDK.NET_DVR_PTZControl(previewHandle, PTZCommand.TILT_UP, 1) isActionUp = true } SteeringWheelView.Direction.RIGHT -> { hkSDK.NET_DVR_PTZControl(previewHandle, PTZCommand.PAN_RIGHT, 1) isActionUp = true } SteeringWheelView.Direction.BOTTOM -> { hkSDK.NET_DVR_PTZControl(previewHandle, PTZCommand.TILT_DOWN, 1) isActionUp = true } } } }) binding.configButton.setOnClickListener { val region = binding.regionView.getConfirmedPoints() val data = region.reformatFloatArray() //发送数据的时候需要断开视频 regionViewModel.postRegion(this, "11,12", "#FF0000", data) } } private val networkCallback = object : ConnectivityManager.NetworkCallback() { override fun onAvailable(network: Network) { super.onAvailable(network) connectivityManager?.bindProcessToNetwork(network) } override fun onUnavailable() { } } private fun closeHikVisionCamera() { if (!SDKGuider.g_sdkGuider.m_comPreviewGuider.RealPlay_Stop_jni(previewHandle)) { return } "预览关闭成功".show(this) previewHandle = -1 isPreviewSuccess = false } private fun openHikVisionCamera(host: String, port: String) { val deviceItem = SDKGuider.g_sdkGuider.m_comDMGuider.DeviceItem() deviceItem.m_szDevName = "" deviceItem.m_struNetInfo = SDKGuider.g_sdkGuider.m_comDMGuider.DevNetInfo( host, port, LocaleConstant.HK_NET_USERNAME, LocaleConstant.HK_NET_PASSWORD ) if (deviceItem.m_szDevName.isEmpty()) { deviceItem.m_szDevName = deviceItem.m_struNetInfo.m_szIp } val loginV40Jna = SDKGuider.g_sdkGuider.m_comDMGuider.login_v40_jna( deviceItem.m_szDevName, deviceItem.m_struNetInfo ) if (loginV40Jna) { //配置设备通道 try { val deviceInfo = SDKGuider.g_sdkGuider.m_comDMGuider.devList[0] returnUserID = deviceInfo.m_lUserID aChannelNum = deviceInfo.m_struDeviceInfoV40_jna.struDeviceV30.byChanNum.toInt() startAChannel = deviceInfo.m_struDeviceInfoV40_jna.struDeviceV30.byStartChan.toInt() dChannelNum = deviceInfo.m_struDeviceInfoV40_jna.struDeviceV30.byIPChanNum + deviceInfo.m_struDeviceInfoV40_jna.struDeviceV30.byHighDChanNum * 256 startDChannel = deviceInfo.m_struDeviceInfoV40_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.g_sdkGuider.m_comPreviewGuider.RealPlay_Stop_jni(previewHandle) } val strutPlayInfo = NET_DVR_PREVIEWINFO() strutPlayInfo.lChannel = selectChannel strutPlayInfo.dwStreamType = 1 strutPlayInfo.bBlocked = 1 strutPlayInfo.hHwnd = binding.videoSurfaceView.holder previewHandle = SDKGuider.g_sdkGuider.m_comPreviewGuider.RealPlay_V40_jni( returnUserID, strutPlayInfo, null ) if (previewHandle < 0) { Log.d( kTag, "configDevice: NET_DVR_RealPlay_V40 fail, Err:${MessageCodeHub.getErrorCode()}" ) return } "预览开启成功".show(this) isPreviewSuccess = true } catch (e: IndexOutOfBoundsException) { e.printStackTrace() "设备未正常连接,无法开启预览".show(this) } } } override fun surfaceCreated(holder: SurfaceHolder) { binding.videoSurfaceView.holder.setFormat(PixelFormat.TRANSLUCENT) if (-1 == previewHandle) { return } val surface = holder.surface if (surface.isValid) { if (-1 == SDKGuider.g_sdkGuider.m_comPreviewGuider.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.g_sdkGuider.m_comPreviewGuider.RealPlaySurfaceChanged_jni( previewHandle, 0, null ) ) { Log.d(kTag, "surfaceCreated: ${MessageCodeHub.getErrorCode()}") } } } override fun onDestroy() { super.onDestroy() connectivityManager?.bindProcessToNetwork(null) connectivityManager?.unregisterNetworkCallback(networkCallback) } }